Skip to content

Commit 5962601

Browse files
committed
feat: enhance serve command with prebuilt flag and add tsup configuration for production builds
1 parent b449478 commit 5962601

5 files changed

Lines changed: 45 additions & 4 deletions

File tree

apps/server/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"private": true,
77
"scripts": {
88
"dev": "objectstack dev",
9-
"start": "objectstack serve",
9+
"build": "tsup",
10+
"start": "objectstack serve dist/objectstack.config.js --prebuilt",
1011
"doctor": "objectstack doctor",
1112
"typecheck": "tsc --noEmit",
1213
"test": "objectstack test",
@@ -45,6 +46,7 @@
4546
"@objectstack/cli": "workspace:*",
4647
"esbuild": "^0.28.0",
4748
"ts-node": "^10.9.2",
49+
"tsup": "^8.0.0",
4850
"tsx": "^4.21.0",
4951
"typescript": "^6.0.2"
5052
}

apps/server/tsup.config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
import { defineConfig } from 'tsup';
4+
5+
// Compile the host config to dist/ so production `start` can run via
6+
// `objectstack serve dist/objectstack.config.js --prebuilt` and skip
7+
// the esbuild/bundle-require runtime overhead used in dev.
8+
export default defineConfig({
9+
entry: ['objectstack.config.ts'],
10+
outDir: 'dist',
11+
format: ['esm'],
12+
target: 'node20',
13+
splitting: false,
14+
sourcemap: true,
15+
clean: true,
16+
dts: false,
17+
// All workspace deps + native modules stay external — they resolve
18+
// from node_modules at runtime just like in dev.
19+
external: [/^@objectstack\//, /^@example\//, /^@hono\//, 'hono', '@libsql/client'],
20+
});

packages/cli/src/commands/serve.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export default class Serve extends Command {
6262
dev: Flags.boolean({ description: 'Run in development mode (load devPlugins)' }),
6363
ui: Flags.boolean({ description: 'Enable Studio UI at /_studio/ (default: true in dev mode)', allowNo: true }),
6464
server: Flags.boolean({ description: 'Start HTTP server plugin', default: true, allowNo: true }),
65+
prebuilt: Flags.boolean({ description: 'Skip esbuild/bundle-require — load config as native ESM (production mode)', default: false }),
6566
};
6667

6768
async run(): Promise<void> {
@@ -141,9 +142,11 @@ export default class Serve extends Command {
141142
console.debug = (...args: any[]) => { if (!bootQuiet) originalConsoleDebug(...args); };
142143

143144
// Load configuration
144-
const { mod } = await bundleRequire({
145-
filepath: absolutePath,
146-
});
145+
// --prebuilt: load as native ESM (no esbuild, no bundle-require) —
146+
// intended for production where the config has been compiled to dist/.
147+
const { mod } = flags.prebuilt
148+
? { mod: await import(absolutePath.startsWith('/') ? `file://${absolutePath}` : absolutePath) }
149+
: await bundleRequire({ filepath: absolutePath });
147150

148151
const config = mod.default || mod;
149152

packages/plugins/plugin-auth/src/auth-manager.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,19 @@ export class AuthManager {
232232
if (pluginConfig?.organization) {
233233
plugins.push(organization({
234234
schema: buildOrganizationPluginSchema(),
235+
// No mailer is wired in framework yet — log the accept URL so
236+
// operators / UI can fall back to copy-paste flows. Replace this
237+
// with a real mail integration when available.
238+
sendInvitationEmail: async ({ email, invitation, organization: org, inviter }) => {
239+
const baseUrl = (this.config.baseUrl ?? '').replace(/\/$/, '');
240+
const acceptUrl = `${baseUrl}/accept-invitation/${invitation.id}`;
241+
console.warn(
242+
`[AuthManager] Invitation email not configured. ` +
243+
`To: ${email} (org: ${org?.name ?? invitation.organizationId}, ` +
244+
`role: ${invitation.role}, inviter: ${inviter?.user?.email ?? 'unknown'}) ` +
245+
`URL: ${acceptUrl}`,
246+
);
247+
},
235248
}));
236249
}
237250

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)