diff --git a/web/package-lock.json b/web/package-lock.json index dbf8f2ee..e5760755 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -21,6 +21,7 @@ "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/eslint__js": "^8.42.3", + "@types/node": "^20.14.10", "eslint": "^8.57.0", "svelte": "^4.2.7", "svelte-check": "^3.6.0", @@ -973,6 +974,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", @@ -3167,6 +3177,12 @@ } } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/web/package.json b/web/package.json index a1834827..4512cc02 100644 --- a/web/package.json +++ b/web/package.json @@ -29,6 +29,7 @@ "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/eslint__js": "^8.42.3", + "@types/node": "^20.14.10", "eslint": "^8.57.0", "svelte": "^4.2.7", "svelte-check": "^3.6.0", diff --git a/web/src/routes/version.json/+server.ts b/web/src/routes/version.json/+server.ts new file mode 100644 index 00000000..3fa01ca5 --- /dev/null +++ b/web/src/routes/version.json/+server.ts @@ -0,0 +1,58 @@ +import { error, json } from '@sveltejs/kit'; +import { readFile } from 'node:fs/promises'; +import { join, parse } from 'node:path'; +import { existsSync } from 'node:fs'; +import { cwd } from 'node:process'; + +const findFile = (file: string) => { + let dir = cwd(); + + while (dir !== parse(dir).root) { + if (existsSync(join(dir, file))) { + return dir; + } + + dir = join(dir, '../'); + } +} + +const root = findFile('.git'); +const pack = findFile('package.json'); + +export async function GET() { + if (!root) { + return error(500, 'no git repository root found'); + } else if (!pack) { + return error(500, 'no package root found'); + } + + const readGit = (filename: string) => readFile(join(root, filename), 'utf8'); + + const commit = (await readGit('.git/logs/HEAD')) + ?.split('\n') + ?.filter(String) + ?.pop() + ?.split(' ')[1]; + + const branch = (await readGit('.git/HEAD')) + ?.replace(/^ref: refs\/heads\//, '') + ?.trim(); + + const remote = (await readGit('.git/config')) + ?.split('\n') + ?.find(line => line.includes('url = ') && line.endsWith('.git')) + ?.split(':')[1] + ?.replace(/\.git$/, ''); + + const { version } = JSON.parse( + await readFile(join(pack, 'package.json'), 'utf8') + ); + + if (!commit || !branch || !remote || !version) { + return error(500, 'failed to extract project metadata'); + } + + return json({ commit, branch, remote, version }); +} + +export const prerender = true; \ No newline at end of file