spfn 0.2.0-beta.15 → 0.2.0-beta.17

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.
Files changed (2) hide show
  1. package/dist/index.js +128 -93
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -755,7 +755,7 @@ var init_deployment_config = __esm({
755
755
 
756
756
  // src/utils/version.ts
757
757
  function getCliVersion() {
758
- return "0.2.0-beta.15";
758
+ return "0.2.0-beta.17";
759
759
  }
760
760
  function getTagFromVersion(version) {
761
761
  const match = version.match(/-([a-z]+)\./i);
@@ -2228,6 +2228,8 @@ async function dbPush() {
2228
2228
 
2229
2229
  // src/commands/db/migrate.ts
2230
2230
  import chalk16 from "chalk";
2231
+ import { join as join16 } from "path";
2232
+ import { existsSync as existsSync18 } from "fs";
2231
2233
 
2232
2234
  // src/commands/db/backup.ts
2233
2235
  import { promises as fs3 } from "fs";
@@ -2580,7 +2582,8 @@ async function dbBackup(options) {
2580
2582
  }
2581
2583
 
2582
2584
  // src/commands/db/migrate.ts
2583
- import "@spfn/core/config";
2585
+ import { env as env4 } from "@spfn/core/config";
2586
+ import { loadEnv as loadEnv4 } from "@spfn/core/server";
2584
2587
  async function dbMigrate(options = {}) {
2585
2588
  try {
2586
2589
  validateDatabasePrerequisites();
@@ -2596,35 +2599,67 @@ async function dbMigrate(options = {}) {
2596
2599
  });
2597
2600
  console.log("");
2598
2601
  }
2599
- const { discoverFunctionMigrations: discoverFunctionMigrations2, executeFunctionMigrations: executeFunctionMigrations2 } = await Promise.resolve().then(() => (init_function_migrations(), function_migrations_exports));
2602
+ const { drizzle } = await import("drizzle-orm/postgres-js");
2603
+ const { migrate } = await import("drizzle-orm/postgres-js/migrator");
2604
+ const postgres = await import("postgres");
2605
+ loadEnv4();
2606
+ if (!env4.DATABASE_URL) {
2607
+ console.error(chalk16.red("\u274C DATABASE_URL not found in environment"));
2608
+ process.exit(1);
2609
+ }
2610
+ const { discoverFunctionMigrations: discoverFunctionMigrations2 } = await Promise.resolve().then(() => (init_function_migrations(), function_migrations_exports));
2600
2611
  const functions = discoverFunctionMigrations2(process.cwd());
2601
2612
  if (functions.length > 0) {
2602
- console.log(chalk16.blue("\u{1F4E6} Applying function package migrations:"));
2603
- functions.forEach((func) => {
2604
- console.log(chalk16.dim(` - ${func.packageName}`));
2605
- });
2613
+ const fnConn = postgres.default(env4.DATABASE_URL, { max: 1 });
2614
+ const fnDb = drizzle(fnConn);
2606
2615
  try {
2607
- await executeFunctionMigrations2(functions);
2616
+ console.log(chalk16.blue("\u{1F4E6} Applying function package migrations:"));
2617
+ functions.forEach((func) => {
2618
+ console.log(chalk16.dim(` - ${func.packageName}`));
2619
+ });
2620
+ for (const func of functions) {
2621
+ console.log(chalk16.blue(`
2622
+ \u{1F4E6} Running ${func.packageName} migrations...`));
2623
+ await migrate(fnDb, { migrationsFolder: func.migrationsDir });
2624
+ console.log(chalk16.green(` \u2713 ${func.packageName} migrations applied`));
2625
+ }
2608
2626
  console.log(chalk16.green("\u2705 Function migrations applied\n"));
2609
- } catch (error) {
2610
- console.error(chalk16.red("\n\u274C Failed to apply function migrations"));
2611
- console.error(chalk16.red(error instanceof Error ? error.message : "Unknown error"));
2612
- process.exit(1);
2627
+ } finally {
2628
+ await fnConn.end();
2613
2629
  }
2614
2630
  }
2615
- await runWithSpinner(
2616
- "Running project migrations...",
2617
- "migrate",
2618
- "Project migrations applied successfully",
2619
- "Failed to run project migrations"
2620
- );
2631
+ const projectMigrationsDir = join16(process.cwd(), "src/server/drizzle");
2632
+ if (existsSync18(projectMigrationsDir)) {
2633
+ const projConn = postgres.default(env4.DATABASE_URL, { max: 1 });
2634
+ const projDb = drizzle(projConn);
2635
+ try {
2636
+ const beforeCount = await projConn`
2637
+ SELECT count(*)::int as count FROM drizzle.__drizzle_migrations
2638
+ `;
2639
+ console.log(chalk16.blue(`\u{1F4E6} Running project migrations... (${beforeCount[0].count} already recorded)`));
2640
+ await migrate(projDb, { migrationsFolder: projectMigrationsDir });
2641
+ const afterCount = await projConn`
2642
+ SELECT count(*)::int as count FROM drizzle.__drizzle_migrations
2643
+ `;
2644
+ const applied = afterCount[0].count - beforeCount[0].count;
2645
+ if (applied > 0) {
2646
+ console.log(chalk16.green(`\u2705 Project migrations applied successfully (${applied} new)`));
2647
+ } else {
2648
+ console.log(chalk16.yellow(`\u26A0\uFE0F No new project migrations to apply (${afterCount[0].count} already recorded)`));
2649
+ }
2650
+ } finally {
2651
+ await projConn.end();
2652
+ }
2653
+ } else {
2654
+ console.log(chalk16.dim("No project migrations found (src/server/drizzle)"));
2655
+ }
2621
2656
  }
2622
2657
 
2623
2658
  // src/commands/db/studio.ts
2624
2659
  import chalk17 from "chalk";
2625
- import { existsSync as existsSync18, writeFileSync as writeFileSync10, unlinkSync as unlinkSync3 } from "fs";
2660
+ import { existsSync as existsSync19, writeFileSync as writeFileSync10, unlinkSync as unlinkSync3 } from "fs";
2626
2661
  import { spawn as spawn3 } from "child_process";
2627
- import { env as env4 } from "@spfn/core/config";
2662
+ import { env as env5 } from "@spfn/core/config";
2628
2663
  import "@spfn/core/config";
2629
2664
  async function dbStudio(requestedPort) {
2630
2665
  console.log(chalk17.blue("\u{1F3A8} Opening Drizzle Studio...\n"));
@@ -2641,12 +2676,12 @@ async function dbStudio(requestedPort) {
2641
2676
  console.error(chalk17.red(error instanceof Error ? error.message : "Failed to find available port"));
2642
2677
  process.exit(1);
2643
2678
  }
2644
- const hasUserConfig = existsSync18("./drizzle.config.ts");
2679
+ const hasUserConfig = existsSync19("./drizzle.config.ts");
2645
2680
  const tempConfigPath = `./drizzle.config.${process.pid}.${Date.now()}.temp.ts`;
2646
2681
  try {
2647
2682
  const configPath = hasUserConfig ? "./drizzle.config.ts" : tempConfigPath;
2648
2683
  if (!hasUserConfig) {
2649
- if (!env4.DATABASE_URL) {
2684
+ if (!env5.DATABASE_URL) {
2650
2685
  console.error(chalk17.red("\u274C DATABASE_URL not found in environment"));
2651
2686
  console.log(chalk17.yellow("\n\u{1F4A1} Tip: Add DATABASE_URL to your .env file"));
2652
2687
  process.exit(1);
@@ -2667,7 +2702,7 @@ async function dbStudio(requestedPort) {
2667
2702
  env: { ...process.env, NODE_TLS_REJECT_UNAUTHORIZED: "0" }
2668
2703
  });
2669
2704
  const cleanup = () => {
2670
- if (!hasUserConfig && existsSync18(tempConfigPath)) {
2705
+ if (!hasUserConfig && existsSync19(tempConfigPath)) {
2671
2706
  unlinkSync3(tempConfigPath);
2672
2707
  }
2673
2708
  };
@@ -2697,7 +2732,7 @@ async function dbStudio(requestedPort) {
2697
2732
  process.exit(0);
2698
2733
  });
2699
2734
  } catch (error) {
2700
- if (!hasUserConfig && existsSync18(tempConfigPath)) {
2735
+ if (!hasUserConfig && existsSync19(tempConfigPath)) {
2701
2736
  unlinkSync3(tempConfigPath);
2702
2737
  }
2703
2738
  console.error(chalk17.red("\u274C Failed to start Drizzle Studio"));
@@ -2750,12 +2785,12 @@ import { spawn as spawn4 } from "child_process";
2750
2785
  import chalk20 from "chalk";
2751
2786
  import ora9 from "ora";
2752
2787
  import prompts4 from "prompts";
2753
- import { env as env5 } from "@spfn/core/config";
2754
- import { loadEnv as loadEnv4 } from "@spfn/core/server";
2788
+ import { env as env6 } from "@spfn/core/config";
2789
+ import { loadEnv as loadEnv5 } from "@spfn/core/server";
2755
2790
  async function dbRestore(backupFile, options = {}) {
2756
2791
  console.log(chalk20.blue("\u267B\uFE0F Restoring database from backup...\n"));
2757
- loadEnv4();
2758
- const dbUrl = env5.DATABASE_URL;
2792
+ loadEnv5();
2793
+ const dbUrl = env6.DATABASE_URL;
2759
2794
  if (!dbUrl) {
2760
2795
  console.error(chalk20.red("\u274C DATABASE_URL not found in environment"));
2761
2796
  console.log(chalk20.yellow("\n\u{1F4A1} Tip: Add DATABASE_URL to your .env file"));
@@ -3081,8 +3116,8 @@ dbCommand.command("backup:clean").description("Clean old database backups").opti
3081
3116
 
3082
3117
  // src/commands/add.ts
3083
3118
  import { Command as Command10 } from "commander";
3084
- import { existsSync as existsSync19, readFileSync as readFileSync6 } from "fs";
3085
- import { join as join16 } from "path";
3119
+ import { existsSync as existsSync20, readFileSync as readFileSync6 } from "fs";
3120
+ import { join as join17 } from "path";
3086
3121
  import { exec as exec2 } from "child_process";
3087
3122
  import { promisify as promisify2 } from "util";
3088
3123
  import chalk23 from "chalk";
@@ -3100,9 +3135,9 @@ async function addPackage(packageName) {
3100
3135
  \u{1F4E6} Setting up ${packageName}...
3101
3136
  `));
3102
3137
  try {
3103
- const pkgPath = join16(process.cwd(), "node_modules", ...packageName.split("/"));
3104
- const pkgJsonPath = join16(pkgPath, "package.json");
3105
- if (!existsSync19(pkgJsonPath)) {
3138
+ const pkgPath = join17(process.cwd(), "node_modules", ...packageName.split("/"));
3139
+ const pkgJsonPath = join17(pkgPath, "package.json");
3140
+ if (!existsSync20(pkgJsonPath)) {
3106
3141
  const installSpinner = ora11("Installing package...").start();
3107
3142
  try {
3108
3143
  await execAsync2(`pnpm add ${packageName}`);
@@ -3114,7 +3149,7 @@ async function addPackage(packageName) {
3114
3149
  } else {
3115
3150
  console.log(chalk23.gray("\u2713 Package already installed (using local version)\n"));
3116
3151
  }
3117
- if (!existsSync19(pkgJsonPath)) {
3152
+ if (!existsSync20(pkgJsonPath)) {
3118
3153
  throw new Error(`Package ${packageName} not found after installation`);
3119
3154
  }
3120
3155
  const pkgJson = JSON.parse(readFileSync6(pkgJsonPath, "utf-8"));
@@ -3122,8 +3157,8 @@ async function addPackage(packageName) {
3122
3157
  console.log(chalk23.blue(`
3123
3158
  \u{1F5C4}\uFE0F Setting up database for ${packageName}...
3124
3159
  `));
3125
- const { env: env6 } = await import("@spfn/core/config");
3126
- if (!env6.DATABASE_URL) {
3160
+ const { env: env7 } = await import("@spfn/core/config");
3161
+ if (!env7.DATABASE_URL) {
3127
3162
  console.log(chalk23.yellow("\u26A0\uFE0F DATABASE_URL not found"));
3128
3163
  console.log(chalk23.gray("Skipping database setup. Run migrations manually when ready:\n"));
3129
3164
  console.log(chalk23.gray(` pnpm spfn db push
@@ -3170,8 +3205,8 @@ var addCommand = new Command10("add").description("Install and set up SPFN ecosy
3170
3205
  init_logger();
3171
3206
  import { Command as Command11 } from "commander";
3172
3207
  import ora12 from "ora";
3173
- import { join as join25 } from "path";
3174
- import { existsSync as existsSync22 } from "fs";
3208
+ import { join as join26 } from "path";
3209
+ import { existsSync as existsSync23 } from "fs";
3175
3210
  import chalk25 from "chalk";
3176
3211
 
3177
3212
  // src/commands/generate/prompts.ts
@@ -3264,11 +3299,11 @@ async function confirmConfiguration(config) {
3264
3299
  }
3265
3300
 
3266
3301
  // src/commands/generate/generators/structure.ts
3267
- import { join as join24 } from "path";
3302
+ import { join as join25 } from "path";
3268
3303
  import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync17 } from "fs";
3269
3304
 
3270
3305
  // src/commands/generate/generators/config.ts
3271
- import { join as join18 } from "path";
3306
+ import { join as join19 } from "path";
3272
3307
  import { writeFileSync as writeFileSync11, mkdirSync as mkdirSync3 } from "fs";
3273
3308
 
3274
3309
  // src/commands/generate/string-utils.ts
@@ -3298,29 +3333,29 @@ function toSafeSchemaName(str) {
3298
3333
  }
3299
3334
 
3300
3335
  // src/commands/generate/template-loader.ts
3301
- import { readFileSync as readFileSync7, existsSync as existsSync20 } from "fs";
3302
- import { join as join17, dirname as dirname2 } from "path";
3336
+ import { readFileSync as readFileSync7, existsSync as existsSync21 } from "fs";
3337
+ import { join as join18, dirname as dirname2 } from "path";
3303
3338
  import { fileURLToPath as fileURLToPath2 } from "url";
3304
3339
  function findTemplatesPath2() {
3305
3340
  const __filename = fileURLToPath2(import.meta.url);
3306
3341
  const __dirname2 = dirname2(__filename);
3307
- const distPath = join17(__dirname2, "commands", "generate", "templates");
3308
- if (existsSync20(distPath)) {
3342
+ const distPath = join18(__dirname2, "commands", "generate", "templates");
3343
+ if (existsSync21(distPath)) {
3309
3344
  return distPath;
3310
3345
  }
3311
- const sameDirPath = join17(__dirname2, "templates");
3312
- if (existsSync20(sameDirPath)) {
3346
+ const sameDirPath = join18(__dirname2, "templates");
3347
+ if (existsSync21(sameDirPath)) {
3313
3348
  return sameDirPath;
3314
3349
  }
3315
- const srcPath = join17(__dirname2, "..", "..", "src", "commands", "generate", "templates");
3316
- if (existsSync20(srcPath)) {
3350
+ const srcPath = join18(__dirname2, "..", "..", "src", "commands", "generate", "templates");
3351
+ if (existsSync21(srcPath)) {
3317
3352
  return srcPath;
3318
3353
  }
3319
3354
  throw new Error(`Templates directory not found. Tried: ${distPath}, ${sameDirPath}, ${srcPath}`);
3320
3355
  }
3321
3356
  function loadTemplate(templateName, variables) {
3322
3357
  const templatesDir = findTemplatesPath2();
3323
- const templatePath = join17(templatesDir, `${templateName}.template`);
3358
+ const templatePath = join18(templatesDir, `${templateName}.template`);
3324
3359
  let content = readFileSync7(templatePath, "utf-8");
3325
3360
  for (const [key, value] of Object.entries(variables)) {
3326
3361
  const regex = new RegExp(`\\{\\{${key}\\}\\}`, "g");
@@ -3424,7 +3459,7 @@ function generatePackageJson(fnDir, scope, fnName, description) {
3424
3459
  }
3425
3460
  };
3426
3461
  writeFileSync11(
3427
- join18(fnDir, "package.json"),
3462
+ join19(fnDir, "package.json"),
3428
3463
  JSON.stringify(content, null, 4) + "\n"
3429
3464
  );
3430
3465
  }
@@ -3458,7 +3493,7 @@ function generateTsConfig(fnDir) {
3458
3493
  exclude: ["node_modules", "dist", "**/*.test.ts", "**/__tests__/**"]
3459
3494
  };
3460
3495
  writeFileSync11(
3461
- join18(fnDir, "tsconfig.json"),
3496
+ join19(fnDir, "tsconfig.json"),
3462
3497
  JSON.stringify(content, null, 4) + "\n"
3463
3498
  );
3464
3499
  }
@@ -3534,7 +3569,7 @@ export default defineConfig({
3534
3569
  ],
3535
3570
  });
3536
3571
  `;
3537
- writeFileSync11(join18(fnDir, "tsup.config.ts"), content);
3572
+ writeFileSync11(join19(fnDir, "tsup.config.ts"), content);
3538
3573
  }
3539
3574
  function generateDrizzleConfig(fnDir, scope, fnName) {
3540
3575
  const schemaName = `spfn_${toSnakeCase(fnName)}`;
@@ -3554,7 +3589,7 @@ export default defineConfig({
3554
3589
  schemaFilter: ['${schemaName}'], // Only generate for ${fnName} schema
3555
3590
  });
3556
3591
  `;
3557
- writeFileSync11(join18(fnDir, "drizzle.config.ts"), content);
3592
+ writeFileSync11(join19(fnDir, "drizzle.config.ts"), content);
3558
3593
  }
3559
3594
  function generateExampleGenerator(fnDir, scope, fnName) {
3560
3595
  const pascalName = toPascalCase(fnName);
@@ -3623,10 +3658,10 @@ export const moduleName = '${fnName}';
3623
3658
  };
3624
3659
  }
3625
3660
  `;
3626
- const generatorsDir = join18(fnDir, "src/server/generators");
3661
+ const generatorsDir = join19(fnDir, "src/server/generators");
3627
3662
  mkdirSync3(generatorsDir, { recursive: true });
3628
3663
  writeFileSync11(
3629
- join18(generatorsDir, "example-generator.ts"),
3664
+ join19(generatorsDir, "example-generator.ts"),
3630
3665
  content
3631
3666
  );
3632
3667
  const indexContent = `/**
@@ -3641,7 +3676,7 @@ export const moduleName = '${fnName}';
3641
3676
  export { create${pascalName}ExampleGenerator } from './example-generator.js';
3642
3677
  `;
3643
3678
  writeFileSync11(
3644
- join18(generatorsDir, "index.ts"),
3679
+ join19(generatorsDir, "index.ts"),
3645
3680
  indexContent
3646
3681
  );
3647
3682
  }
@@ -4130,15 +4165,15 @@ Contributions are welcome! Please follow the development workflow above.
4130
4165
 
4131
4166
  MIT
4132
4167
  `;
4133
- writeFileSync11(join18(fnDir, "README.md"), content);
4168
+ writeFileSync11(join19(fnDir, "README.md"), content);
4134
4169
  }
4135
4170
 
4136
4171
  // src/commands/generate/generators/entity.ts
4137
- import { join as join19 } from "path";
4138
- import { writeFileSync as writeFileSync12, existsSync as existsSync21 } from "fs";
4172
+ import { join as join20 } from "path";
4173
+ import { writeFileSync as writeFileSync12, existsSync as existsSync22 } from "fs";
4139
4174
  function generateSchema(fnDir, scope, fnName) {
4140
- const schemaFilePath = join19(fnDir, "src/server/entities/schema.ts");
4141
- if (existsSync21(schemaFilePath)) {
4175
+ const schemaFilePath = join20(fnDir, "src/server/entities/schema.ts");
4176
+ if (existsSync22(schemaFilePath)) {
4142
4177
  return;
4143
4178
  }
4144
4179
  const packageName = `${scope}/${fnName}`;
@@ -4169,7 +4204,7 @@ function generateEntity(fnDir, scope, fnName, entityName) {
4169
4204
  SCHEMA_FILE_NAME: schemaFileName
4170
4205
  });
4171
4206
  writeFileSync12(
4172
- join19(fnDir, `src/server/entities/${toKebabCase(entityName)}.ts`),
4207
+ join20(fnDir, `src/server/entities/${toKebabCase(entityName)}.ts`),
4173
4208
  content
4174
4209
  );
4175
4210
  }
@@ -4177,11 +4212,11 @@ function generateEntitiesIndex(fnDir, entities) {
4177
4212
  const schemaExport = `export * from './schema';`;
4178
4213
  const entityExports = entities.map((entity) => `export * from './${toKebabCase(entity)}';`).join("\n");
4179
4214
  const content = [schemaExport, entityExports].filter(Boolean).join("\n");
4180
- writeFileSync12(join19(fnDir, "src/server/entities/index.ts"), content + "\n");
4215
+ writeFileSync12(join20(fnDir, "src/server/entities/index.ts"), content + "\n");
4181
4216
  }
4182
4217
 
4183
4218
  // src/commands/generate/generators/repository.ts
4184
- import { join as join20 } from "path";
4219
+ import { join as join21 } from "path";
4185
4220
  import { writeFileSync as writeFileSync13 } from "fs";
4186
4221
  function generateRepository(fnDir, entityName) {
4187
4222
  const pascalName = toPascalCase(entityName);
@@ -4192,17 +4227,17 @@ function generateRepository(fnDir, entityName) {
4192
4227
  REPO_NAME: repoName
4193
4228
  });
4194
4229
  writeFileSync13(
4195
- join20(fnDir, `src/server/repositories/${toKebabCase(entityName)}.repository.ts`),
4230
+ join21(fnDir, `src/server/repositories/${toKebabCase(entityName)}.repository.ts`),
4196
4231
  content
4197
4232
  );
4198
4233
  }
4199
4234
  function generateRepositoriesIndex(fnDir, entities) {
4200
4235
  const exports = entities.map((entity) => `export * from './${toKebabCase(entity)}.repository';`).join("\n");
4201
- writeFileSync13(join20(fnDir, "src/server/repositories/index.ts"), exports + "\n");
4236
+ writeFileSync13(join21(fnDir, "src/server/repositories/index.ts"), exports + "\n");
4202
4237
  }
4203
4238
 
4204
4239
  // src/commands/generate/generators/route.ts
4205
- import { join as join21 } from "path";
4240
+ import { join as join22 } from "path";
4206
4241
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync14 } from "fs";
4207
4242
  function generateRoute(fnDir, entityName) {
4208
4243
  const pascalName = toPascalCase(entityName);
@@ -4214,13 +4249,13 @@ function generateRoute(fnDir, entityName) {
4214
4249
  REPO_NAME: repoName,
4215
4250
  KEBAB_NAME: kebabName
4216
4251
  });
4217
- const routeDir = join21(fnDir, `src/server/routes/${kebabName}`);
4252
+ const routeDir = join22(fnDir, `src/server/routes/${kebabName}`);
4218
4253
  mkdirSync4(routeDir, { recursive: true });
4219
- writeFileSync14(join21(routeDir, "index.ts"), content);
4254
+ writeFileSync14(join22(routeDir, "index.ts"), content);
4220
4255
  }
4221
4256
 
4222
4257
  // src/commands/generate/generators/contract.ts
4223
- import { join as join22 } from "path";
4258
+ import { join as join23 } from "path";
4224
4259
  import { writeFileSync as writeFileSync15 } from "fs";
4225
4260
  function generateContract(fnDir, entityName) {
4226
4261
  const pascalName = toPascalCase(entityName);
@@ -4229,13 +4264,13 @@ function generateContract(fnDir, entityName) {
4229
4264
  ENTITY_NAME: entityName
4230
4265
  });
4231
4266
  writeFileSync15(
4232
- join22(fnDir, `src/lib/contracts/${toKebabCase(entityName)}.ts`),
4267
+ join23(fnDir, `src/lib/contracts/${toKebabCase(entityName)}.ts`),
4233
4268
  content
4234
4269
  );
4235
4270
  }
4236
4271
 
4237
4272
  // src/commands/generate/generators/index-files.ts
4238
- import { join as join23 } from "path";
4273
+ import { join as join24 } from "path";
4239
4274
  import { writeFileSync as writeFileSync16 } from "fs";
4240
4275
  function generateMainIndex(fnDir, fnName) {
4241
4276
  const content = `/**
@@ -4262,7 +4297,7 @@ export * from '@/lib/types/index';
4262
4297
 
4263
4298
  export * from '@/server/entities/index';
4264
4299
  `;
4265
- writeFileSync16(join23(fnDir, "src/index.ts"), content);
4300
+ writeFileSync16(join24(fnDir, "src/index.ts"), content);
4266
4301
  }
4267
4302
  function generateServerIndex(fnDir) {
4268
4303
  const content = `/**
@@ -4297,7 +4332,7 @@ export * from '@/server/repositories/index';
4297
4332
 
4298
4333
  // TODO: Export helpers here
4299
4334
  `;
4300
- writeFileSync16(join23(fnDir, "src/server.ts"), content);
4335
+ writeFileSync16(join24(fnDir, "src/server.ts"), content);
4301
4336
  }
4302
4337
  function generateClientIndex(fnDir) {
4303
4338
  const content = `/**
@@ -4330,7 +4365,7 @@ export * from './client/store';
4330
4365
 
4331
4366
  export * from './client/components';
4332
4367
  `;
4333
- writeFileSync16(join23(fnDir, "src/client.ts"), content);
4368
+ writeFileSync16(join24(fnDir, "src/client.ts"), content);
4334
4369
  }
4335
4370
  function generateTypesFile(fnDir, fnName) {
4336
4371
  const content = `/**
@@ -4342,7 +4377,7 @@ function generateTypesFile(fnDir, fnName) {
4342
4377
 
4343
4378
  export * from '@/lib/types/index';
4344
4379
  `;
4345
- writeFileSync16(join23(fnDir, "src/types.ts"), content);
4380
+ writeFileSync16(join24(fnDir, "src/types.ts"), content);
4346
4381
  }
4347
4382
 
4348
4383
  // src/commands/generate/generators/structure.ts
@@ -4364,7 +4399,7 @@ async function generateFunctionStructure(options) {
4364
4399
  "src/client/store",
4365
4400
  "src/client/components"
4366
4401
  ];
4367
- dirs.forEach((dir) => mkdirSync5(join24(fnDir, dir), { recursive: true }));
4402
+ dirs.forEach((dir) => mkdirSync5(join25(fnDir, dir), { recursive: true }));
4368
4403
  generatePackageJson(fnDir, scope, fnName, description);
4369
4404
  generateTsConfig(fnDir);
4370
4405
  generateTsupConfig(fnDir);
@@ -4384,15 +4419,15 @@ async function generateFunctionStructure(options) {
4384
4419
  generateEntitiesIndex(fnDir, entities);
4385
4420
  generateRepositoriesIndex(fnDir, entities);
4386
4421
  } else {
4387
- writeFileSync17(join24(fnDir, "src/server/entities/index.ts"), "// Export your entities here\nexport {}\n");
4388
- writeFileSync17(join24(fnDir, "src/server/repositories/index.ts"), "// Export your repositories here\nexport {}\n");
4389
- }
4390
- writeFileSync17(join24(fnDir, "src/client/hooks/index.ts"), "/**\n * Client Hooks\n */\n\n// TODO: Add hooks (e.g., useAuth, useData, etc.)\nexport {}\n");
4391
- writeFileSync17(join24(fnDir, "src/client/store/index.ts"), "/**\n * Client Store\n */\n\n// TODO: Add Zustand store if needed\nexport {}\n");
4392
- writeFileSync17(join24(fnDir, "src/client/components/index.ts"), "/**\n * Client Components\n */\n\n// TODO: Add React components\nexport {}\n");
4393
- writeFileSync17(join24(fnDir, "src/client/index.ts"), "/**\n * Client Module Entry\n */\n\nexport * from './hooks';\nexport * from './store';\nexport * from './components';\n");
4394
- writeFileSync17(join24(fnDir, "src/lib/types/index.ts"), "/**\n * Shared Type Definitions\n */\n\n// Add your shared types here\nexport {}\n");
4395
- writeFileSync17(join24(fnDir, "src/lib/contracts/index.ts"), "/**\n * API Contracts\n */\n\n// Export your contracts here\nexport {}\n");
4422
+ writeFileSync17(join25(fnDir, "src/server/entities/index.ts"), "// Export your entities here\nexport {}\n");
4423
+ writeFileSync17(join25(fnDir, "src/server/repositories/index.ts"), "// Export your repositories here\nexport {}\n");
4424
+ }
4425
+ writeFileSync17(join25(fnDir, "src/client/hooks/index.ts"), "/**\n * Client Hooks\n */\n\n// TODO: Add hooks (e.g., useAuth, useData, etc.)\nexport {}\n");
4426
+ writeFileSync17(join25(fnDir, "src/client/store/index.ts"), "/**\n * Client Store\n */\n\n// TODO: Add Zustand store if needed\nexport {}\n");
4427
+ writeFileSync17(join25(fnDir, "src/client/components/index.ts"), "/**\n * Client Components\n */\n\n// TODO: Add React components\nexport {}\n");
4428
+ writeFileSync17(join25(fnDir, "src/client/index.ts"), "/**\n * Client Module Entry\n */\n\nexport * from './hooks';\nexport * from './store';\nexport * from './components';\n");
4429
+ writeFileSync17(join25(fnDir, "src/lib/types/index.ts"), "/**\n * Shared Type Definitions\n */\n\n// Add your shared types here\nexport {}\n");
4430
+ writeFileSync17(join25(fnDir, "src/lib/contracts/index.ts"), "/**\n * API Contracts\n */\n\n// Export your contracts here\nexport {}\n");
4396
4431
  generateMainIndex(fnDir, fnName);
4397
4432
  generateServerIndex(fnDir);
4398
4433
  generateClientIndex(fnDir);
@@ -4416,8 +4451,8 @@ async function generateFunction(name, options) {
4416
4451
  logger.error("Function name is required");
4417
4452
  process.exit(1);
4418
4453
  }
4419
- const fnDir = join25(cwd, fnName);
4420
- if (existsSync22(fnDir)) {
4454
+ const fnDir = join26(cwd, fnName);
4455
+ if (existsSync23(fnDir)) {
4421
4456
  logger.error(`Directory ${fnName} already exists at ${fnDir}`);
4422
4457
  process.exit(1);
4423
4458
  }
@@ -4482,7 +4517,7 @@ generateCommand.command("fn").description("Generate a new SPFN function module")
4482
4517
  // src/commands/env.ts
4483
4518
  import { Command as Command12 } from "commander";
4484
4519
  import chalk26 from "chalk";
4485
- import { existsSync as existsSync23, readFileSync as readFileSync8, writeFileSync as writeFileSync18 } from "fs";
4520
+ import { existsSync as existsSync24, readFileSync as readFileSync8, writeFileSync as writeFileSync18 } from "fs";
4486
4521
  import { resolve } from "path";
4487
4522
  import { parse } from "dotenv";
4488
4523
  var VALID_ENVS = ["local", "development", "staging", "production", "test"];
@@ -4766,7 +4801,7 @@ async function initEnvFiles(options) {
4766
4801
  }
4767
4802
  function writeEnvTemplate(cwd, file, vars, force) {
4768
4803
  const filePath = resolve(cwd, file);
4769
- if (existsSync23(filePath) && !force) {
4804
+ if (existsSync24(filePath) && !force) {
4770
4805
  console.log(chalk26.yellow(` \u23ED\uFE0F ${file} already exists (use --force to overwrite)`));
4771
4806
  return;
4772
4807
  }
@@ -4815,7 +4850,7 @@ async function checkEnvFiles(options) {
4815
4850
  const warnings = [];
4816
4851
  for (const file of filesToCheck) {
4817
4852
  const filePath = resolve(cwd, file);
4818
- if (!existsSync23(filePath)) {
4853
+ if (!existsSync24(filePath)) {
4819
4854
  continue;
4820
4855
  }
4821
4856
  const content = readFileSync8(filePath, "utf-8");
@@ -4892,8 +4927,8 @@ async function validateEnvVars(options) {
4892
4927
  const packages = options.packages || ["@spfn/core"];
4893
4928
  const targetEnv = options.env ? validateEnvOption(options.env) : void 0;
4894
4929
  if (targetEnv) {
4895
- const { loadEnv: loadEnv5 } = await import("@spfn/core/env/loader");
4896
- const result = loadEnv5({ nodeEnv: targetEnv });
4930
+ const { loadEnv: loadEnv6 } = await import("@spfn/core/env/loader");
4931
+ const result = loadEnv6({ nodeEnv: targetEnv });
4897
4932
  console.log(chalk26.blue.bold(`
4898
4933
  \u{1F50D} Validating environment variables for ${chalk26.cyan(targetEnv)}
4899
4934
  `));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spfn",
3
- "version": "0.2.0-beta.15",
3
+ "version": "0.2.0-beta.17",
4
4
  "description": "Superfunction CLI - Add SPFN to your Next.js project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -67,7 +67,7 @@
67
67
  "postgres": "^3.4.0",
68
68
  "prompts": "^2.4.2",
69
69
  "tsup": "^8.5.0",
70
- "@spfn/core": "0.2.0-beta.16"
70
+ "@spfn/core": "0.2.0-beta.19"
71
71
  },
72
72
  "devDependencies": {
73
73
  "@types/fs-extra": "^11.0.4",