Skip to content

Commit 987e25f

Browse files
committed
feat(templates): refactor CRM and Todo templates to use static imports and improve loading mechanism
1 parent b051d9f commit 987e25f

4 files changed

Lines changed: 24 additions & 27 deletions

File tree

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,19 @@
11
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
22

3-
import { fileURLToPath, pathToFileURL } from 'node:url';
4-
import * as path from 'node:path';
3+
// Static relative import — bundle-require/esbuild inlines the CRM bundle
4+
// into the server's bundled config at boot time, so seeding does not rely
5+
// on Node resolving a `.ts` file at runtime (which `@example/app-crm`
6+
// would require, because workspace packages are marked external by the
7+
// CLI's bundler).
8+
import crmBundle from '../../../../examples/app-crm/objectstack.config';
59
import type { ProjectTemplate } from './types.js';
610

7-
// Resolve the CRM bundle relative to THIS file so the path survives any
8-
// compilation/build output layout. Using a file:// URL means we can hand
9-
// the path to a dynamic import() without TypeScript trying to type-check
10-
// the target (which lives outside apps/server's rootDir).
11-
const HERE = path.dirname(fileURLToPath(import.meta.url));
12-
const BUNDLE_PATH = path.resolve(HERE, '../../../../examples/app-crm/objectstack.config.ts');
13-
const BUNDLE_URL = pathToFileURL(BUNDLE_PATH).href;
14-
15-
// Lazy dynamic import — the bundle's Zod evaluation is deferred until the
16-
// template is actually selected, so a schema drift in the example cannot
17-
// crash control-plane bootstrap.
18-
const dyn = (spec: string): Promise<any> =>
19-
(new Function('s', 'return import(s)') as (s: string) => Promise<any>)(spec);
20-
2111
export const crmTemplate: ProjectTemplate = {
2212
id: 'crm',
2313
label: 'CRM Starter',
2414
description: 'Accounts, Contacts, Opportunities — full CRM example.',
2515
category: 'business',
2616
async load() {
27-
const mod = await dyn(BUNDLE_URL);
28-
// ESM default can be nested under `.default.default` when the
29-
// loader double-wraps (tsx + file:// URL). Unwrap defensively.
30-
return mod?.default?.manifest ? mod.default : (mod?.default?.default ?? mod?.default ?? mod);
17+
return crmBundle;
3118
},
3219
};
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
22

3+
// Static relative import — bundle-require/esbuild inlines the Todo bundle
4+
// into the server's bundled config at boot time, so seeding does not rely
5+
// on Node resolving a `.ts` file at runtime (which `@example/app-todo`
6+
// would require, because workspace packages are marked external by the
7+
// CLI's bundler).
8+
import todoBundle from '../../../../examples/app-todo/objectstack.config';
39
import type { ProjectTemplate } from './types.js';
410

5-
const dyn = (spec: string) =>
6-
(new Function('s', 'return import(s)') as (s: string) => Promise<any>)(spec);
7-
811
export const todoTemplate: ProjectTemplate = {
912
id: 'todo',
1013
label: 'Todo List',
1114
description: 'Lightweight task tracker — single-object example.',
1215
category: 'starter',
1316
async load() {
14-
const mod = await dyn('../../../../examples/app-todo/objectstack.config.ts');
15-
return mod.default;
17+
return todoBundle;
1618
},
1719
};

apps/server/test/multi-project-e2e.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ function expect(actual: any) {
6767
}
6868

6969
// ---------------------------------------------------------------------------
70-
// Env setup must happen BEFORE importing the server — bootstrap.ts reads
71-
// OBJECTSTACK_DATABASE_URL when selecting the control-plane driver.
70+
// Env setup must happen BEFORE importing the server — objectstack.config.ts
71+
// reads OBJECTSTACK_DATABASE_URL when selecting the control-plane driver.
7272
// ---------------------------------------------------------------------------
7373

7474
const workdir = mkdtempSync(join(tmpdir(), 'objectstack-e2e-'));
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Ambient declaration for example-app template bundles statically imported
2+
// by `server/templates/*.ts`. Those paths live outside this package's
3+
// `include` scope so TS cannot discover their types; we accept `any` here
4+
// and rely on the `StackBundle` shape returned by the seeder at runtime.
5+
declare module '*/objectstack.config' {
6+
const bundle: any;
7+
export default bundle;
8+
}

0 commit comments

Comments
 (0)