diff --git a/package.json b/package.json index 1dc02f5..f92a1ec 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "dev": "concurrently \"npm run dev:server\" \"vite\"", "dev:desktop": "concurrently \"npm run dev:server\" \"vite\" \"tsc -p tsconfig.desktop.json --watch --preserveWatchOutput\" \"wait-on tcp:127.0.0.1:4000 http://127.0.0.1:5173 file:dist/desktop/main.js && cross-env METAPI_DESKTOP_DEV_SERVER_URL=http://127.0.0.1:5173 METAPI_DESKTOP_EXTERNAL_SERVER_URL=http://127.0.0.1:4000 electron dist/desktop/main.js\"", "build:web": "vite build", - "build:server": "tsc -p tsconfig.server.json", + "build:server": "tsc -p tsconfig.server.json && tsx scripts/dev/copy-runtime-db-generated.ts", "build:desktop": "tsc -p tsconfig.desktop.json", "build": "npm run build:web && npm run build:server && npm run build:desktop", "dist:desktop": "npm run build && electron-builder --config electron-builder.yml --publish never", diff --git a/scripts/dev/copy-runtime-db-generated.test.ts b/scripts/dev/copy-runtime-db-generated.test.ts new file mode 100644 index 0000000..cf75051 --- /dev/null +++ b/scripts/dev/copy-runtime-db-generated.test.ts @@ -0,0 +1,38 @@ +import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { join } from 'node:path'; +import { tmpdir } from 'node:os'; +import { afterEach, describe, expect, it } from 'vitest'; +import { copyRuntimeDbGeneratedAssets } from './copy-runtime-db-generated.js'; + +const tempDirs: string[] = []; + +afterEach(() => { + while (tempDirs.length > 0) { + const dir = tempDirs.pop(); + if (dir) { + rmSync(dir, { recursive: true, force: true }); + } + } +}); + +describe('copyRuntimeDbGeneratedAssets', () => { + it('copies generated runtime db artifacts into dist', () => { + const repoRoot = mkdtempSync(join(tmpdir(), 'metapi-runtime-db-assets-')); + tempDirs.push(repoRoot); + + const sourceDir = join(repoRoot, 'src', 'server', 'db', 'generated'); + const nestedDir = join(sourceDir, 'fixtures'); + mkdirSync(nestedDir, { recursive: true }); + writeFileSync(join(sourceDir, 'mysql.bootstrap.sql'), 'create table demo ();'); + writeFileSync(join(nestedDir, 'baseline.json'), '{"ok":true}'); + + copyRuntimeDbGeneratedAssets(repoRoot); + + expect( + readFileSync(join(repoRoot, 'dist', 'server', 'db', 'generated', 'mysql.bootstrap.sql'), 'utf8'), + ).toBe('create table demo ();'); + expect( + readFileSync(join(repoRoot, 'dist', 'server', 'db', 'generated', 'fixtures', 'baseline.json'), 'utf8'), + ).toBe('{"ok":true}'); + }); +}); diff --git a/scripts/dev/copy-runtime-db-generated.ts b/scripts/dev/copy-runtime-db-generated.ts new file mode 100644 index 0000000..61b3c0f --- /dev/null +++ b/scripts/dev/copy-runtime-db-generated.ts @@ -0,0 +1,23 @@ +import { cpSync, existsSync, mkdirSync } from 'node:fs'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +function resolveRepoRoot(): string { + return resolve(dirname(fileURLToPath(import.meta.url)), '../..'); +} + +export function copyRuntimeDbGeneratedAssets(repoRoot: string = resolveRepoRoot()): void { + const sourceDir = resolve(repoRoot, 'src/server/db/generated'); + const targetDir = resolve(repoRoot, 'dist/server/db/generated'); + + if (!existsSync(sourceDir)) { + throw new Error(`Runtime DB generated assets directory does not exist: ${sourceDir}`); + } + + mkdirSync(dirname(targetDir), { recursive: true }); + cpSync(sourceDir, targetDir, { recursive: true, force: true }); +} + +if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { + copyRuntimeDbGeneratedAssets(); +}