spfn 0.3.0-beta.2 → 0.3.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -134,9 +134,8 @@ no pre-build needed.
134
134
  |--------|-------------|---------|
135
135
  | `--server-only` | Run only the SPFN/Hono server (also auto-selected if Next.js isn't a dependency) | off |
136
136
  | `--watch` | Restart the server on `src/server` changes (chokidar) | off |
137
- | `-p, --port <port>` | Server port | from `server.config.ts` / env (`4000` in server-only fallback) |
138
- | `-H, --host <host>` | Server host | `localhost` |
139
- | `--routes <path>` | Routes directory path | server default |
137
+ | `-p, --port <port>` | SPFN server port (sets `SPFN_PORT`) | `spfn.config.js` `ports.server`, then `8790` |
138
+ | `-H, --host <host>` | SPFN server host (sets `SPFN_HOST`) | `spfn.config.js` `host`, then `localhost` |
140
139
  | `--allow-pending-migrations` | Start even when migrations are pending (they are listed as a warning) | off |
141
140
 
142
141
  Note: hot reload is **off by default** — pass `--watch` to restart on file changes.
@@ -165,11 +164,19 @@ if `.spfn/server`, `.spfn/prod-server.mjs`, or `.next` are missing.
165
164
  |--------|-------------|---------|
166
165
  | `--server-only` | Run only the SPFN server | off |
167
166
  | `--next-only` | Run only Next.js | off |
168
- | `-p, --port <port>` | SPFN server port (sets `SPFN_PORT`) | `8790` |
169
- | `-h, --host <host>` | SPFN server host (sets `SPFN_HOST`) | `0.0.0.0` |
167
+ | `-p, --port <port>` | SPFN server port (sets `SPFN_PORT`) | `spfn.config.js` `ports.server`, then `8790` |
168
+ | `-h, --host <host>` | SPFN server host (sets `SPFN_HOST`) | `spfn.config.js` `host`, then `localhost` |
170
169
  | `--allow-pending-migrations` | Start even when migrations are pending (they are listed as a warning) | off |
171
170
 
172
- Next.js is started on `0.0.0.0:3790`. Both run together via `concurrently --kill-others`.
171
+ Both run together via `concurrently --kill-others`.
172
+
173
+ Neither flag has a default value, deliberately. A default is indistinguishable
174
+ from a value the operator typed, and it was forwarded as `SPFN_PORT` either way —
175
+ which overrode the app's own configuration. Pass nothing and `spfn.config.js`
176
+ decides; pass a flag and it wins.
177
+
178
+ Next.js is started on the port `spfn.config.js` gives as `ports.next` (`3790` by
179
+ default), overridable with `NEXT_PORT`.
173
180
 
174
181
  Pending migrations stop the boot unless `--allow-pending-migrations` or
175
182
  `SPFN_ALLOW_PENDING_MIGRATIONS=true` is set — see [Database](#spfn-db). `--next-only`
@@ -580,7 +587,7 @@ docker compose -f docker-compose.production.yml up --build -d
580
587
 
581
588
  The Dockerfile (`node:22-alpine`) installs with `pnpm --frozen-lockfile`, runs
582
589
  `pnpm run spfn:build`, prunes dev deps, exposes `3790`/`8790`, health-checks
583
- `http://localhost:8790/health`, and starts via `pnpm run spfn:start`.
590
+ `http://localhost:8790/_core/health`, and starts via `pnpm run spfn:start`.
584
591
 
585
592
  Run migrations against the target DB before/with deploy:
586
593
 
@@ -595,7 +602,7 @@ the gate is one that never served the 500s. If a rollout has to proceed anyway,
595
602
  logged as a warning instead.
596
603
 
597
604
  A readiness probe can catch the same drift on a cluster the local gate never sees. When
598
- detailed health is on, `GET /health` carries a `migrations` object with per-package
605
+ detailed health is on, `GET /_core/health` carries a `migrations` object with per-package
599
606
  applied/pending counts — assert `migrations.pending === 0` in the probe to hold a
600
607
  drifted pod out of rotation. Reporting drift does not, by itself, change the overall
601
608
  health `status`.
package/dist/index.js CHANGED
@@ -808,11 +808,33 @@ async function setupDeploymentConfig(cwd, packageJson, packageManager) {
808
808
  const configContent = `/**
809
809
  * SPFN Configuration
810
810
  *
811
- * This file configures your SPFN application deployment settings.
811
+ * This file describes how your app is served and deployed. It is committed, so
812
+ * keep secrets out of it.
812
813
  *
813
814
  * @type {import('spfn').SpfnConfig}
814
815
  */
815
816
  export default {
817
+ /**
818
+ * Ports the two processes bind.
819
+ *
820
+ * This is the only place either number is written. The Dockerfile, the
821
+ * compose file and \`spfn dev\` / \`spfn start\` all read it, so changing a
822
+ * port here changes it everywhere.
823
+ *
824
+ * Overridable per environment with NEXT_PORT and SPFN_PORT \u2014 a container
825
+ * setting one of those wins over what is written here.
826
+ */
827
+ ports: {
828
+ next: 3790,
829
+ server: 8790,
830
+ },
831
+
832
+ /**
833
+ * Host the SPFN API server binds. A container sets SPFN_HOST=0.0.0.0; a
834
+ * developer machine has no reason to publish its dev server to the network.
835
+ */
836
+ host: 'localhost',
837
+
816
838
  /**
817
839
  * Package manager to use for dependency installation
818
840
  * Options: 'npm' | 'yarn' | 'pnpm' | 'bun'
@@ -922,7 +944,7 @@ var init_deployment_config = __esm({
922
944
 
923
945
  // src/utils/version.ts
924
946
  function getCliVersion() {
925
- return "0.3.0-beta.2";
947
+ return "0.3.0-beta.3";
926
948
  }
927
949
  function getTagFromVersion(version) {
928
950
  const match = version.match(/-([a-z]+)\./i);
@@ -982,7 +1004,7 @@ async function setupPackageJson(cwd, packageJsonPath, packageJson, packageManage
982
1004
  }
983
1005
  packageJson.scripts["spfn:dev"] = "spfn dev";
984
1006
  packageJson.scripts["spfn:server"] = "spfn dev --server-only";
985
- packageJson.scripts["spfn:next"] = "next dev --turbo --port 3790";
1007
+ packageJson.scripts["spfn:next"] = "next dev --turbo";
986
1008
  packageJson.scripts["spfn:start"] = "spfn start";
987
1009
  packageJson.scripts["spfn:build"] = "spfn build";
988
1010
  packageJson.scripts["codegen"] = "spfn codegen run";
@@ -1483,7 +1505,7 @@ async function initializeSpfn(options = {}) {
1483
1505
  console.log(` ${mode === "full" ? "4" : "3"}. Run: ` + chalk4.cyan(`${getRunCommand(pm)} spfn:dev`));
1484
1506
  console.log(` ${mode === "full" ? "5" : "4"}. Visit:`);
1485
1507
  console.log(" - Next.js: " + chalk4.cyan("http://localhost:3790"));
1486
- console.log(" - API: " + chalk4.cyan("http://localhost:8790/health"));
1508
+ console.log(" - API: " + chalk4.cyan("http://localhost:8790/_core/health"));
1487
1509
  if (mode === "full") {
1488
1510
  console.log(" - MCP: " + chalk4.cyan("http://localhost:8790/mcp"));
1489
1511
  }
@@ -2122,6 +2144,7 @@ async function resolveKeychainEnv(cwd) {
2122
2144
  }
2123
2145
 
2124
2146
  // src/commands/dev.ts
2147
+ import { loadAppConfig, resolvePorts, resolveHost } from "@spfn/core/app-config";
2125
2148
  function ignoreDotfilesUnder(root) {
2126
2149
  return (watchedPath) => relative(root, watchedPath).split(sep2).some((segment) => segment.startsWith(".") && segment !== "." && segment !== "..");
2127
2150
  }
@@ -2145,13 +2168,22 @@ function waitForReadyFile(filePath, timeoutMs = 3e4) {
2145
2168
  });
2146
2169
  });
2147
2170
  }
2148
- var devCommand = new Command4("dev").description("Start SPFN development server (detects and runs Next.js + Hono)").option("-p, --port <port>", "Server port").option("-H, --host <host>", "Server host").option("--routes <path>", "Routes directory path").option("--server-only", "Run only Hono server (skip Next.js)").option("--watch", "Enable hot reload (watch mode)").option("--allow-pending-migrations", "Start even when migrations are pending (they are listed as a warning)").action(async (options) => {
2171
+ var devCommand = new Command4("dev").description("Start SPFN development server (detects and runs Next.js + Hono)").option("-p, --port <port>", "Server port").option("-H, --host <host>", "Server host").option("--server-only", "Run only Hono server (skip Next.js)").option("--watch", "Enable hot reload (watch mode)").option("--allow-pending-migrations", "Start even when migrations are pending (they are listed as a warning)").action(async (options) => {
2149
2172
  process.setMaxListeners(20);
2150
2173
  if (!process.env.NODE_ENV) {
2151
2174
  process.env.NODE_ENV = "development";
2152
2175
  }
2153
2176
  const cwd = process.cwd();
2154
2177
  const serverDir = join15(cwd, "src", "server");
2178
+ if (options.port) {
2179
+ process.env.SPFN_PORT = String(options.port);
2180
+ }
2181
+ if (options.host) {
2182
+ process.env.SPFN_HOST = String(options.host);
2183
+ }
2184
+ const appConfig = await loadAppConfig(cwd);
2185
+ const { next: nextPort, server: serverPort } = resolvePorts(appConfig);
2186
+ const serverHost = resolveHost(appConfig);
2155
2187
  if (!existsSync14(serverDir)) {
2156
2188
  logger.error("src/server directory not found.");
2157
2189
  logger.info('Run "spfn init" first to initialize SPFN in your project.');
@@ -2197,11 +2229,7 @@ var devCommand = new Command4("dev").description("Start SPFN development server
2197
2229
  if (existsSync14(readySignal)) {
2198
2230
  unlinkSync(readySignal);
2199
2231
  }
2200
- const configParts = [];
2201
- if (options.port) configParts.push(`port: ${options.port}`);
2202
- if (options.host) configParts.push(`host: '${options.host}'`);
2203
- if (options.routes) configParts.push(`routesPath: '${options.routes}'`);
2204
- configParts.push("debug: true");
2232
+ const configParts = ["debug: true"];
2205
2233
  const readyFile = join15(tempDir, "server-ready");
2206
2234
  writeFileSync10(serverEntry, `
2207
2235
  import { writeFileSync } from 'fs';
@@ -2274,9 +2302,7 @@ catch (error)
2274
2302
  const pm = detectPackageManager(cwd);
2275
2303
  if (options.serverOnly || !hasNext) {
2276
2304
  const watchMode2 = options.watch === true;
2277
- const host = options.host ?? process.env.HOST ?? "localhost";
2278
- const port = options.port ?? process.env.PORT ?? "4000";
2279
- logger.info(`Starting SPFN Server on http://${host}:${port}${watchMode2 ? " (watch mode)" : ""}
2305
+ logger.info(`Starting SPFN Server on http://${serverHost}:${serverPort}${watchMode2 ? " (watch mode)" : ""}
2280
2306
  `);
2281
2307
  let serverProcess2 = null;
2282
2308
  let watcherProcess2 = null;
@@ -2392,7 +2418,7 @@ catch (error)
2392
2418
  };
2393
2419
  const startNext = () => {
2394
2420
  const nextCmd = pm === "npm" ? "npm" : pm;
2395
- const nextArgs = pm === "npm" ? ["run", "spfn:next"] : ["run", "spfn:next"];
2421
+ const nextArgs = ["run", "spfn:next", "--", "--port", String(nextPort)];
2396
2422
  nextProcess = execa6(nextCmd, nextArgs, {
2397
2423
  cwd,
2398
2424
  stdio: "inherit",
@@ -2498,6 +2524,19 @@ import { execa as execa7 } from "execa";
2498
2524
  import ora5 from "ora";
2499
2525
  import chalk7 from "chalk";
2500
2526
  import { build } from "tsup";
2527
+ function renderProdServerEntry() {
2528
+ return `// Load environment variables FIRST (before any imports that depend on them)
2529
+ // Use centralized environment loader for standard dotenv priority
2530
+ await import('@spfn/core/config');
2531
+
2532
+ // Now import server (logger singleton will be created with correct NODE_ENV)
2533
+ const { startServer } = await import('@spfn/core/server');
2534
+
2535
+ // No address here on purpose: SPFN_PORT / SPFN_HOST and spfn.config.js decide,
2536
+ // and startServer reads both.
2537
+ await startServer({ debug: false });
2538
+ `;
2539
+ }
2501
2540
  async function buildProject(options) {
2502
2541
  if (!process.env.NODE_ENV) {
2503
2542
  process.env.NODE_ENV = "production";
@@ -2571,6 +2610,12 @@ async function buildProject(options) {
2571
2610
  entry: ["src/server/**/*.ts"],
2572
2611
  format: ["esm"],
2573
2612
  outDir: ".spfn/server",
2613
+ // Pin the extension. Left to tsup it follows the app's
2614
+ // package.json — `.mjs` normally, `.js` under
2615
+ // `"type": "module"` — and @spfn/core looks the compiled
2616
+ // server.config up by name, so an app that declared that field
2617
+ // shipped a production server running on defaults.
2618
+ outExtension: () => ({ js: ".mjs" }),
2574
2619
  clean: true,
2575
2620
  splitting: false,
2576
2621
  tsconfig: "src/server/tsconfig.json",
@@ -2590,29 +2635,7 @@ async function buildProject(options) {
2590
2635
  }
2591
2636
  });
2592
2637
  const prodServerPath = join16(cwd, ".spfn", "prod-server.mjs");
2593
- const prodServerContent = `// Load environment variables FIRST (before any imports that depend on them)
2594
- // Use centralized environment loader for standard dotenv priority
2595
- const { env } = await import('@spfn/core/config');
2596
-
2597
- // Now import server (logger singleton will be created with correct NODE_ENV)
2598
- const { startServer } = await import('@spfn/core/server');
2599
- import { join } from 'path';
2600
- import { fileURLToPath } from 'url';
2601
- import { dirname } from 'path';
2602
-
2603
- const __dirname = dirname(fileURLToPath(import.meta.url));
2604
-
2605
- // Environment variables: from .env files OR injected by container/kubernetes
2606
- const port = env.SPFN_PORT || '8790';
2607
- const host = env.SPFN_HOST || '0.0.0.0';
2608
-
2609
- await startServer({
2610
- port: Number(port),
2611
- host,
2612
- routesPath: join(__dirname, 'server', 'routes'),
2613
- debug: false
2614
- });
2615
- `;
2638
+ const prodServerContent = renderProdServerEntry();
2616
2639
  writeFileSync11(prodServerPath, prodServerContent);
2617
2640
  spinner.succeed(`SPFN server build completed \u2192 .spfn/server`);
2618
2641
  const routesDir = join16(cwd, ".spfn", "server", "routes");
@@ -2676,7 +2699,8 @@ import { existsSync as existsSync16, readFileSync as readFileSync8 } from "fs";
2676
2699
  import { join as join17 } from "path";
2677
2700
  import { execa as execa8 } from "execa";
2678
2701
  import chalk8 from "chalk";
2679
- var startCommand = new Command6("start").description("Start SPFN production server (Next.js + Hono)").option("--server-only", "Run only SPFN server (skip Next.js)").option("--next-only", "Run only Next.js (skip SPFN server)").option("-p, --port <port>", "Server port", "8790").option("-h, --host <host>", "Server host", "0.0.0.0").option("--allow-pending-migrations", "Start even when migrations are pending (they are listed as a warning)").action(async (options) => {
2702
+ import { loadAppConfig as loadAppConfig2, resolvePorts as resolvePorts2 } from "@spfn/core/app-config";
2703
+ var startCommand = new Command6("start").description("Start SPFN production server (Next.js + Hono)").option("--server-only", "Run only SPFN server (skip Next.js)").option("--next-only", "Run only Next.js (skip SPFN server)").option("-p, --port <port>", "SPFN server port (default: spfn.config.js ports.server, then 8790)").option("-h, --host <host>", "SPFN server host (default: spfn.config.js host, then localhost)").option("--allow-pending-migrations", "Start even when migrations are pending (they are listed as a warning)").action(async (options) => {
2680
2704
  if (!process.env.NODE_ENV) {
2681
2705
  process.env.NODE_ENV = "production";
2682
2706
  }
@@ -2705,8 +2729,13 @@ var startCommand = new Command6("start").description("Start SPFN production serv
2705
2729
  logger.error('.spfn/prod-server.mjs not found. Please run "spfn build" first.');
2706
2730
  process.exit(1);
2707
2731
  }
2708
- process.env.SPFN_PORT = options.port;
2709
- process.env.SPFN_HOST = options.host;
2732
+ if (options.port) {
2733
+ process.env.SPFN_PORT = options.port;
2734
+ }
2735
+ if (options.host) {
2736
+ process.env.SPFN_HOST = options.host;
2737
+ }
2738
+ const nextPort = resolvePorts2(await loadAppConfig2(cwd)).next;
2710
2739
  if (!options.nextOnly) {
2711
2740
  const { checkPendingMigrationsBeforeStart: checkPendingMigrationsBeforeStart2 } = await Promise.resolve().then(() => (init_migration_status(), migration_status_exports));
2712
2741
  const migrationCheck = await checkPendingMigrationsBeforeStart2(
@@ -2722,8 +2751,7 @@ var startCommand = new Command6("start").description("Start SPFN production serv
2722
2751
  }
2723
2752
  }
2724
2753
  if (options.serverOnly || !hasNext) {
2725
- logger.info(`Starting SPFN Server (production) on http://${options.host}:${options.port}
2726
- `);
2754
+ logger.info("Starting SPFN Server (production)\n");
2727
2755
  try {
2728
2756
  await execa8("node", [serverEntry], {
2729
2757
  stdio: "inherit",
@@ -2737,9 +2765,10 @@ var startCommand = new Command6("start").description("Start SPFN production serv
2737
2765
  return;
2738
2766
  }
2739
2767
  if (options.nextOnly) {
2740
- logger.info("Starting Next.js (production) on http://0.0.0.0:3790\n");
2768
+ logger.info(`Starting Next.js (production) on http://0.0.0.0:${nextPort}
2769
+ `);
2741
2770
  try {
2742
- await execa8("npx", ["next", "start", "-H", "0.0.0.0", "-p", "3790"], {
2771
+ await execa8("npx", ["next", "start", "-H", "0.0.0.0", "-p", String(nextPort)], {
2743
2772
  stdio: "inherit",
2744
2773
  cwd
2745
2774
  });
@@ -2749,12 +2778,11 @@ var startCommand = new Command6("start").description("Start SPFN production serv
2749
2778
  }
2750
2779
  return;
2751
2780
  }
2752
- const nextCmd = "next start -H 0.0.0.0 -p 3790";
2781
+ const nextCmd = `next start -H 0.0.0.0 -p ${nextPort}`;
2753
2782
  const serverCmd = `node "${serverEntry}"`;
2754
2783
  console.log(chalk8.blue.bold("\n\u{1F680} Starting SPFN production server...\n"));
2755
- logger.info("Next.js: http://0.0.0.0:3790");
2756
- logger.info(`SPFN API: http://${options.host}:${options.port}
2757
- `);
2784
+ logger.info(`Next.js: http://0.0.0.0:${nextPort}`);
2785
+ logger.info("SPFN API: announced by the server below\n");
2758
2786
  try {
2759
2787
  await execa8(
2760
2788
  pm === "npm" ? "npx" : pm,
@@ -24,12 +24,15 @@ RUN pnpm prune --prod
24
24
  # Environment
25
25
  ENV NODE_ENV=production
26
26
 
27
- # Expose ports
27
+ # Expose ports. Docker cannot read spfn.config.js, so these two numbers are the
28
+ # one place they are repeated — keep them in step with `ports` in that file, or
29
+ # set NEXT_PORT / SPFN_PORT here and in the compose file instead.
28
30
  EXPOSE 3790 8790
29
31
 
30
- # Health check
32
+ # Health check. Falls back to the same default the framework uses, so setting
33
+ # SPFN_PORT alone moves both the server and its probe.
31
34
  HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
32
- CMD node -e "require('http').get('http://localhost:8790/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
35
+ CMD node -e "require('http').get('http://localhost:'+(process.env.SPFN_PORT||8790)+'/_core/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
33
36
 
34
37
  # Start application
35
38
  CMD ["pnpm", "run", "spfn:start"]
@@ -21,7 +21,7 @@ docker compose up -d
21
21
  Then open:
22
22
 
23
23
  - Next.js — http://localhost:3790
24
- - API health — http://localhost:8790/health
24
+ - API health — http://localhost:8790/_core/health
25
25
 
26
26
  ## Project structure
27
27
 
@@ -22,13 +22,20 @@ services:
22
22
  context: .
23
23
  dockerfile: Dockerfile
24
24
  ports:
25
- - "3790:3790" # Next.js
26
- - "8790:8790" # SPFN API
25
+ - "${NEXT_PORT:-3790}:${NEXT_PORT:-3790}" # Next.js
26
+ - "${SPFN_PORT:-8790}:${SPFN_PORT:-8790}" # SPFN API
27
27
  environment:
28
28
  # Required: Set these via .env file or environment
29
29
  - DATABASE_URL=${DATABASE_URL}
30
30
  - REDIS_URL=${REDIS_URL:-redis://redis:6379}
31
31
  - NODE_ENV=production
32
+ # Ports: leave unset and spfn.config.js decides. Set either one to
33
+ # override it for this deployment — the mapping above follows.
34
+ - NEXT_PORT=${NEXT_PORT:-}
35
+ - SPFN_PORT=${SPFN_PORT:-}
36
+ # A container has to bind every interface; a developer machine does not,
37
+ # which is why localhost is the default and this line is here.
38
+ - SPFN_HOST=0.0.0.0
32
39
  # Optional: Frontend API URL
33
40
  - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-http://localhost:8790}
34
41
  restart: unless-stopped
@@ -8,7 +8,6 @@ import { authRouter, authenticate } from '@spfn/auth/server';
8
8
  import { defineRouter } from '@spfn/core/route';
9
9
  import { mcpRouter } from './mcp';
10
10
  import { getRoot } from './routes/root';
11
- import { getHealth } from './routes/health';
12
11
  import {
13
12
  listExamples,
14
13
  getExample,
@@ -19,7 +18,6 @@ import {
19
18
 
20
19
  export const appRouter = defineRouter({
21
20
  getRoot,
22
- getHealth,
23
21
  listExamples,
24
22
  getExample,
25
23
  createExample,
@@ -7,7 +7,7 @@ export const getRoot = route.get('/')
7
7
  version: '1.0.0',
8
8
  status: 'running',
9
9
  endpoints: {
10
- health: '/health',
10
+ health: '/_core/health',
11
11
  examples: '/examples',
12
12
  auth: '/_auth',
13
13
  mcp: '/mcp',
@@ -7,8 +7,6 @@ import { defineServerConfig } from '@spfn/core/server';
7
7
  import { appRouter } from '@/server/router';
8
8
 
9
9
  export default defineServerConfig()
10
- .port(8790)
11
- .host('0.0.0.0')
12
10
  .routes(appRouter)
13
11
  .lifecycle(createAuthLifecycle())
14
12
  .build();
@@ -6,7 +6,6 @@
6
6
 
7
7
  import { defineRouter } from '@spfn/core/route';
8
8
  import { getRoot } from './routes/root';
9
- import { getHealth } from './routes/health';
10
9
  import { listExamples, getExample, createExample, updateExample, deleteExample } from './routes/examples';
11
10
 
12
11
  /**
@@ -14,7 +13,6 @@ import { listExamples, getExample, createExample, updateExample, deleteExample }
14
13
  */
15
14
  export const appRouter = defineRouter({
16
15
  getRoot,
17
- getHealth,
18
16
  listExamples,
19
17
  getExample,
20
18
  createExample,
@@ -14,7 +14,7 @@ export const getRoot = route.get('/')
14
14
  version: '1.0.0',
15
15
  status: 'running',
16
16
  endpoints: {
17
- health: '/health',
17
+ health: '/_core/health',
18
18
  examples: '/examples',
19
19
  },
20
20
  message: 'Welcome to SPFN! Visit /examples for usage examples.',
@@ -5,7 +5,5 @@ import { defineServerConfig } from '@spfn/core/server';
5
5
  import { appRouter } from '@/server/router';
6
6
 
7
7
  export default defineServerConfig()
8
- .port(8790)
9
- .host('0.0.0.0')
10
8
  .routes(appRouter)
11
9
  .build();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spfn",
3
- "version": "0.3.0-beta.2",
3
+ "version": "0.3.0-beta.3",
4
4
  "description": "Scaffold a full-stack TypeScript backend onto a Next.js app built with an AI coding agent: auth, database, typed routes and codegen, one fixed vertical slice per feature",
5
5
  "type": "module",
6
6
  "bin": {
@@ -57,7 +57,7 @@
57
57
  "node": ">=20.0.0"
58
58
  },
59
59
  "peerDependencies": {
60
- "@spfn/core": ">=0.3.0-beta.1 <0.4.0",
60
+ "@spfn/core": ">=0.3.0-beta.3 <0.4.0",
61
61
  "typescript": "^5.3.0"
62
62
  },
63
63
  "peerDependenciesMeta": {
@@ -1,9 +0,0 @@
1
- import { route } from '@spfn/core/route';
2
-
3
- export const getHealth = route.get('/health')
4
- .skip(['auth'])
5
- .handler(async () => ({
6
- status: 'ok',
7
- timestamp: Date.now(),
8
- uptime: process.uptime(),
9
- }));
@@ -1,18 +0,0 @@
1
- /**
2
- * Health Check Route
3
- *
4
- * Minimal endpoint for monitoring systems, load balancers, and orchestrators.
5
- * Used by Kubernetes probes, uptime monitors, etc.
6
- */
7
-
8
- import { route } from '@spfn/core/route';
9
-
10
- export const getHealth = route.get('/health')
11
- .handler(async () =>
12
- {
13
- return {
14
- status: 'ok',
15
- timestamp: Date.now(),
16
- uptime: process.uptime(),
17
- };
18
- });