@concavejs/cli 0.0.1-alpha.5 → 0.0.1-alpha.7

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/dist/cli.js CHANGED
@@ -19,7 +19,7 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
20
20
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
21
21
 
22
- // ../../node_modules/.bun/commander@14.0.1/node_modules/commander/lib/error.js
22
+ // ../../node_modules/commander/lib/error.js
23
23
  var require_error = __commonJS((exports) => {
24
24
  class CommanderError extends Error {
25
25
  constructor(exitCode, code, message) {
@@ -43,7 +43,7 @@ var require_error = __commonJS((exports) => {
43
43
  exports.InvalidArgumentError = InvalidArgumentError;
44
44
  });
45
45
 
46
- // ../../node_modules/.bun/commander@14.0.1/node_modules/commander/lib/argument.js
46
+ // ../../node_modules/commander/lib/argument.js
47
47
  var require_argument = __commonJS((exports) => {
48
48
  var { InvalidArgumentError } = require_error();
49
49
 
@@ -123,7 +123,7 @@ var require_argument = __commonJS((exports) => {
123
123
  exports.humanReadableArgName = humanReadableArgName;
124
124
  });
125
125
 
126
- // ../../node_modules/.bun/commander@14.0.1/node_modules/commander/lib/help.js
126
+ // ../../node_modules/commander/lib/help.js
127
127
  var require_help = __commonJS((exports) => {
128
128
  var { humanReadableArgName } = require_argument();
129
129
 
@@ -480,7 +480,7 @@ ${itemIndentStr}`);
480
480
  exports.stripColor = stripColor;
481
481
  });
482
482
 
483
- // ../../node_modules/.bun/commander@14.0.1/node_modules/commander/lib/option.js
483
+ // ../../node_modules/commander/lib/option.js
484
484
  var require_option = __commonJS((exports) => {
485
485
  var { InvalidArgumentError } = require_error();
486
486
 
@@ -664,7 +664,7 @@ var require_option = __commonJS((exports) => {
664
664
  exports.DualOptions = DualOptions;
665
665
  });
666
666
 
667
- // ../../node_modules/.bun/commander@14.0.1/node_modules/commander/lib/suggestSimilar.js
667
+ // ../../node_modules/commander/lib/suggestSimilar.js
668
668
  var require_suggestSimilar = __commonJS((exports) => {
669
669
  var maxDistance = 3;
670
670
  function editDistance(a, b) {
@@ -737,7 +737,7 @@ var require_suggestSimilar = __commonJS((exports) => {
737
737
  exports.suggestSimilar = suggestSimilar;
738
738
  });
739
739
 
740
- // ../../node_modules/.bun/commander@14.0.1/node_modules/commander/lib/command.js
740
+ // ../../node_modules/commander/lib/command.js
741
741
  var require_command = __commonJS((exports) => {
742
742
  var EventEmitter = __require("node:events").EventEmitter;
743
743
  var childProcess = __require("node:child_process");
@@ -1596,7 +1596,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1596
1596
  return arg.length > 1 && arg[0] === "-";
1597
1597
  }
1598
1598
  const negativeNumberArg = (arg) => {
1599
- if (!/^-\d*\.?\d+(e[+-]?\d+)?$/.test(arg))
1599
+ if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg))
1600
1600
  return false;
1601
1601
  return !this._getCommandAndAncestors().some((cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short)));
1602
1602
  };
@@ -2092,7 +2092,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2092
2092
  exports.useColor = useColor;
2093
2093
  });
2094
2094
 
2095
- // ../../node_modules/.bun/commander@14.0.1/node_modules/commander/index.js
2095
+ // ../../node_modules/commander/index.js
2096
2096
  var require_commander = __commonJS((exports) => {
2097
2097
  var { Argument } = require_argument();
2098
2098
  var { Command } = require_command();
@@ -2112,7 +2112,7 @@ var require_commander = __commonJS((exports) => {
2112
2112
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2113
2113
  });
2114
2114
 
2115
- // ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
2115
+ // ../../node_modules/picocolors/picocolors.js
2116
2116
  var require_picocolors = __commonJS((exports, module) => {
2117
2117
  var p = process || {};
2118
2118
  var argv = p.argv || [];
@@ -4544,7 +4544,7 @@ error: ${text}`);
4544
4544
  var node_default = node_exports;
4545
4545
  });
4546
4546
 
4547
- // ../../node_modules/.bun/commander@14.0.1/node_modules/commander/esm.mjs
4547
+ // ../../node_modules/commander/esm.mjs
4548
4548
  var import__ = __toESM(require_commander(), 1);
4549
4549
  var {
4550
4550
  program,
@@ -4938,6 +4938,11 @@ async function generateWorkerEntry(projectRoot, options = {}) {
4938
4938
  dashboardWorkerLine = "";
4939
4939
  }
4940
4940
  }
4941
+ const docstoreScheme = options.docstore || "do";
4942
+ const blobstoreScheme = options.blobstore;
4943
+ const { imports: docstoreImports, code: docstoreCode } = getDocstoreSnippet(docstoreScheme);
4944
+ const { imports: blobstoreImports, code: blobstoreCode } = getBlobstoreSnippet(blobstoreScheme);
4945
+ const adapterImports = [...new Set([...docstoreImports, ...blobstoreImports])];
4941
4946
  const runtimeOptions = `{
4942
4947
  worker: {
4943
4948
  bindings: {
@@ -4955,12 +4960,8 @@ async function generateWorkerEntry(projectRoot, options = {}) {
4955
4960
  moduleLoader: createModuleLoaderFromGlob(moduleLoaders, { trimPrefix: ${JSON.stringify(functionsImportPrefix)} }),${dashboardWorkerLine}
4956
4961
  },
4957
4962
  durableObject: {
4958
- docstore: ({ state }) => new DODocStore(state),
4959
- blobstore: ({ env }) => {
4960
- const bucket = env.STORAGE_BUCKET;
4961
- if (!bucket) return undefined;
4962
- return new R2BlobStore(bucket, env.R2_PUBLIC_URL);
4963
- },
4963
+ docstore: ${docstoreCode},
4964
+ blobstore: ${blobstoreCode},
4964
4965
  udfExecutor: ({ env, instance, docstore, blobstore }) => {
4965
4966
  const disableIsolated = env.DISABLE_ISOLATED_EXECUTION === "true" || env.DISABLE_ISOLATED_EXECUTION === true;
4966
4967
  if (env.UDF_WORKER && !disableIsolated) {
@@ -4984,8 +4985,8 @@ import {
4984
4985
  setConcaveModuleLoader,
4985
4986
  resolveNamespaceBinding,
4986
4987
  createScopedNamespace,
4987
- DODocStore,
4988
- R2BlobStore,
4988
+ ${adapterImports.map((i) => ` ${i},`).join(`
4989
+ `)}
4989
4990
  UdfExecInline,
4990
4991
  UdfExecIsolated,
4991
4992
  } from "./runtime.bundle.js";
@@ -5295,6 +5296,50 @@ process.on("SIGTERM", shutdown);
5295
5296
  outDir
5296
5297
  };
5297
5298
  }
5299
+ function getDocstoreSnippet(scheme) {
5300
+ switch (scheme) {
5301
+ case "d1":
5302
+ return {
5303
+ imports: ["D1DocStore"],
5304
+ code: `({ env }) => new D1DocStore(env.DB)`
5305
+ };
5306
+ case "hyperdrive":
5307
+ return {
5308
+ imports: ["HyperdriveDocStore"],
5309
+ code: `({ env }) => new HyperdriveDocStore(env.HYPERDRIVE)`
5310
+ };
5311
+ case "do":
5312
+ default:
5313
+ return {
5314
+ imports: ["DODocStore"],
5315
+ code: `({ state }) => new DODocStore(state)`
5316
+ };
5317
+ }
5318
+ }
5319
+ function getBlobstoreSnippet(scheme) {
5320
+ if (!scheme) {
5321
+ return {
5322
+ imports: [],
5323
+ code: `() => undefined`
5324
+ };
5325
+ }
5326
+ switch (scheme) {
5327
+ case "r2":
5328
+ return {
5329
+ imports: ["R2BlobStore"],
5330
+ code: `({ env }) => {
5331
+ const bucket = env.STORAGE_BUCKET;
5332
+ if (!bucket) return undefined;
5333
+ return new R2BlobStore(bucket, env.R2_PUBLIC_URL);
5334
+ }`
5335
+ };
5336
+ default:
5337
+ return {
5338
+ imports: [],
5339
+ code: `() => undefined`
5340
+ };
5341
+ }
5342
+ }
5298
5343
 
5299
5344
  // src/cli/config.ts
5300
5345
  import path5 from "node:path";
@@ -5382,6 +5427,8 @@ function createCloudflareState(accountId, workerName, workerUrl, options = {}) {
5382
5427
  accountId,
5383
5428
  workerName,
5384
5429
  workerUrl,
5430
+ docstoreUri: options.docstoreUri,
5431
+ blobstoreUri: options.blobstoreUri,
5385
5432
  d1DatabaseId: options.d1DatabaseId,
5386
5433
  d1DatabaseName: options.d1DatabaseName,
5387
5434
  r2BucketName: options.r2BucketName,
@@ -6089,6 +6136,35 @@ function printDryRunAction(action) {
6089
6136
  console.log(` ${import_picocolors.default.dim("Would:")} ${action}`);
6090
6137
  }
6091
6138
 
6139
+ // src/cli/deploy/backend-uri.ts
6140
+ var VALID_SCHEMES = ["do", "d1", "hyperdrive", "r2"];
6141
+ function parseBackendUri(uri) {
6142
+ const match = uri.match(/^([a-z0-9-]+):\/\/(.*)$/);
6143
+ if (!match) {
6144
+ throw new Error(`Invalid backend URI: "${uri}". Expected format: <scheme>://[resource] (e.g. "do://", "d1://my-db", "r2://my-bucket")`);
6145
+ }
6146
+ const scheme = match[1];
6147
+ const resource = match[2] || undefined;
6148
+ if (!VALID_SCHEMES.includes(scheme)) {
6149
+ throw new Error(`Unknown backend scheme: "${scheme}". Valid schemes: ${VALID_SCHEMES.join(", ")}`);
6150
+ }
6151
+ return { scheme, resource };
6152
+ }
6153
+ function resolveBackendResource(parsed, workerName, type) {
6154
+ if (parsed.resource)
6155
+ return parsed.resource;
6156
+ switch (parsed.scheme) {
6157
+ case "do":
6158
+ return;
6159
+ case "d1":
6160
+ return `${workerName}-db`;
6161
+ case "hyperdrive":
6162
+ throw new Error("hyperdrive:// requires a config ID (e.g. hyperdrive://my-config-id)");
6163
+ case "r2":
6164
+ return `${workerName}-storage`;
6165
+ }
6166
+ }
6167
+
6092
6168
  // src/cli/deploy/cloudflare.ts
6093
6169
  async function deployToCloudflare(projectRoot, options = {}) {
6094
6170
  const startTime = Date.now();
@@ -6148,10 +6224,18 @@ async function runFirstTimeSetup(projectRoot, _existingState, options) {
6148
6224
  const workerName = options.name || (options.yes ? defaultName : await askWorkerName(defaultName));
6149
6225
  console.log();
6150
6226
  printHeader(`Setting up resources for "${workerName}"`);
6227
+ const config = await loadConfig(projectRoot);
6228
+ const docstoreUri = options.docstore || config.docstore || "do://";
6229
+ const blobstoreUri = options.blobstore || config.blobstore || undefined;
6230
+ const docstoreParsed = parseBackendUri(docstoreUri);
6231
+ const blobstoreParsed = blobstoreUri ? parseBackendUri(blobstoreUri) : undefined;
6232
+ const docstoreResource = resolveBackendResource(docstoreParsed, workerName, "docstore");
6233
+ const blobstoreResource = blobstoreParsed ? resolveBackendResource(blobstoreParsed, workerName, "blobstore") : undefined;
6151
6234
  let d1DatabaseId;
6152
6235
  let d1DatabaseName;
6153
- if (!options.noDb) {
6154
- const dbName = `${workerName}-db`;
6236
+ let r2BucketName;
6237
+ if (docstoreParsed.scheme === "d1") {
6238
+ const dbName = docstoreResource;
6155
6239
  const dbSpinner = createSpinner(`Creating D1 database: ${dbName}`);
6156
6240
  if (options.dryRun) {
6157
6241
  dbSpinner.stop();
@@ -6189,9 +6273,8 @@ async function runFirstTimeSetup(projectRoot, _existingState, options) {
6189
6273
  }
6190
6274
  }
6191
6275
  }
6192
- let r2BucketName;
6193
- if (!options.noStorage) {
6194
- const bucketName = `${workerName}-storage`;
6276
+ if (blobstoreParsed?.scheme === "r2") {
6277
+ const bucketName = blobstoreResource;
6195
6278
  const bucketSpinner = createSpinner(`Creating R2 bucket: ${bucketName}`);
6196
6279
  if (options.dryRun) {
6197
6280
  bucketSpinner.stop();
@@ -6208,7 +6291,7 @@ async function runFirstTimeSetup(projectRoot, _existingState, options) {
6208
6291
  console.error(import_picocolors2.default.dim(`
6209
6292
  R2 is not enabled on this Cloudflare account.`));
6210
6293
  console.error(import_picocolors2.default.dim(" Enable R2 at: https://dash.cloudflare.com/?to=/:account/r2"));
6211
- console.error(import_picocolors2.default.dim(` Or use --no-storage to skip R2 bucket creation.
6294
+ console.error(import_picocolors2.default.dim(` Or remove --blobstore to skip R2 bucket creation.
6212
6295
  `));
6213
6296
  } else {
6214
6297
  console.error(import_picocolors2.default.dim(`
@@ -6224,6 +6307,8 @@ async function runFirstTimeSetup(projectRoot, _existingState, options) {
6224
6307
  console.log();
6225
6308
  printHeader("Building worker");
6226
6309
  await buildAndDeploy(projectRoot, workerName, {
6310
+ docstoreScheme: docstoreParsed.scheme,
6311
+ blobstoreScheme: blobstoreParsed?.scheme,
6227
6312
  d1DatabaseId,
6228
6313
  d1DatabaseName,
6229
6314
  r2BucketName,
@@ -6234,6 +6319,8 @@ async function runFirstTimeSetup(projectRoot, _existingState, options) {
6234
6319
  const workerUrl = getWorkerUrl(workerName);
6235
6320
  if (!options.dryRun) {
6236
6321
  const newState = createCloudflareState(accountId || "", workerName, workerUrl, {
6322
+ docstoreUri,
6323
+ blobstoreUri,
6237
6324
  d1DatabaseId,
6238
6325
  d1DatabaseName,
6239
6326
  r2BucketName
@@ -6257,7 +6344,11 @@ async function runRedeploy(projectRoot, state, options, startTime) {
6257
6344
  `));
6258
6345
  await wranglerLogin();
6259
6346
  }
6347
+ const docstoreParsed = cfState.docstoreUri ? parseBackendUri(cfState.docstoreUri) : undefined;
6348
+ const blobstoreParsed = cfState.blobstoreUri ? parseBackendUri(cfState.blobstoreUri) : undefined;
6260
6349
  await buildAndDeploy(projectRoot, workerName, {
6350
+ docstoreScheme: docstoreParsed?.scheme,
6351
+ blobstoreScheme: blobstoreParsed?.scheme,
6261
6352
  d1DatabaseId: cfState.d1DatabaseId,
6262
6353
  d1DatabaseName: cfState.d1DatabaseName,
6263
6354
  r2BucketName: cfState.r2BucketName,
@@ -6277,7 +6368,12 @@ async function buildAndDeploy(projectRoot, workerName, config) {
6277
6368
  try {
6278
6369
  const artifacts = await ensureProjectArtifacts(projectRoot);
6279
6370
  const runtimeBundlePath = await ensureRuntimeBundleAccessible(artifacts, projectRoot);
6280
- const result = await generateWorkerEntry(projectRoot, { runtimeBundlePath, dashboardHtmlPath: artifacts.dashboardHtmlPath });
6371
+ const result = await generateWorkerEntry(projectRoot, {
6372
+ runtimeBundlePath,
6373
+ dashboardHtmlPath: artifacts.dashboardHtmlPath,
6374
+ docstore: config.docstoreScheme,
6375
+ blobstore: config.blobstoreScheme
6376
+ });
6281
6377
  buildSpinner.succeed(`Bundled ${result.moduleCount} function${result.moduleCount === 1 ? "" : "s"}`);
6282
6378
  const configSpinner = createSpinner("Generating wrangler config...");
6283
6379
  const configPath = await generateWranglerConfig(projectRoot, workerName, config);
@@ -6304,7 +6400,6 @@ async function generateWranglerConfig(projectRoot, workerName, config) {
6304
6400
  compatibility_date: "2024-12-01",
6305
6401
  compatibility_flags: ["nodejs_compat"],
6306
6402
  assets: {
6307
- binding: "DASHBOARD_ASSETS",
6308
6403
  directory: "./static"
6309
6404
  },
6310
6405
  durable_objects: {
@@ -6320,7 +6415,7 @@ async function generateWranglerConfig(projectRoot, workerName, config) {
6320
6415
  }
6321
6416
  ]
6322
6417
  };
6323
- if (config.d1DatabaseId && config.d1DatabaseName) {
6418
+ if (config.docstoreScheme === "d1" && config.d1DatabaseId && config.d1DatabaseName) {
6324
6419
  wranglerConfig.d1_databases = [
6325
6420
  {
6326
6421
  binding: "DB",
@@ -6329,7 +6424,15 @@ async function generateWranglerConfig(projectRoot, workerName, config) {
6329
6424
  }
6330
6425
  ];
6331
6426
  }
6332
- if (config.r2BucketName) {
6427
+ if (config.docstoreScheme === "hyperdrive") {
6428
+ wranglerConfig.hyperdrive = [
6429
+ {
6430
+ binding: "HYPERDRIVE",
6431
+ id: config.d1DatabaseId
6432
+ }
6433
+ ];
6434
+ }
6435
+ if (config.blobstoreScheme === "r2" && config.r2BucketName) {
6333
6436
  wranglerConfig.r2_buckets = [
6334
6437
  {
6335
6438
  binding: "STORAGE_BUCKET",
@@ -6508,6 +6611,7 @@ async function bundleProject(projectRoot, _verbose) {
6508
6611
  sourcemap: false,
6509
6612
  logLevel: "silent",
6510
6613
  absWorkingDir: buildDir,
6614
+ external: ["node:*"],
6511
6615
  plugins: [componentDefinitionPlugin()]
6512
6616
  });
6513
6617
  if (buildResult.errors.length > 0) {
@@ -6599,7 +6703,7 @@ async function verifyBundle(bundle) {
6599
6703
 
6600
6704
  // src/cli/deploy/index.ts
6601
6705
  function registerDeployCommand(program2) {
6602
- program2.command("deploy").description("Deploy your Convex functions to production").option("--target <target>", "Deployment target (cloudflare/cf, cloud)").option("--env <name>", "Environment name (production, staging, preview)", "production").option("--name <name>", "Override worker/project name").option("--account <id>", "Cloudflare account ID (for users with multiple accounts)").option("--dry-run", "Show what would happen without executing").option("-y, --yes", "Skip confirmation prompts").option("--verbose", "Show detailed output").option("--no-db", "Skip D1 database creation (use DO SQLite only)").option("--no-storage", "Skip R2 bucket creation").option("--force", "Recreate all resources").option("--reset", "Clear saved deployment config and start fresh").option("--cloud-url <url>", "Concave cloud URL", process.env.CONCAVE_CLOUD_URL || "https://cloud.smolbase.com").option("--project-id <id>", "Project ID for cloud deployment").option("--project-slug <slug>", "Project slug for cloud deployment").addHelpText("after", `
6706
+ program2.command("deploy").description("Deploy your Convex functions to production").option("--target <target>", "Deployment target (cloudflare/cf, cloud)").option("--env <name>", "Environment name (production, staging, preview)", "production").option("--name <name>", "Override worker/project name").option("--account <id>", "Cloudflare account ID (for users with multiple accounts)").option("--dry-run", "Show what would happen without executing").option("-y, --yes", "Skip confirmation prompts").option("--verbose", "Show detailed output").option("--docstore <uri>", "DocStore backend (do://, d1://name, hyperdrive://id)").option("--blobstore <uri>", "BlobStore backend (r2://bucket)").option("--force", "Recreate all resources").option("--reset", "Clear saved deployment config and start fresh").option("--cloud-url <url>", "Concave cloud URL", process.env.CONCAVE_CLOUD_URL || "https://cloud.smolbase.com").option("--project-id <id>", "Project ID for cloud deployment").option("--project-slug <slug>", "Project slug for cloud deployment").addHelpText("after", `
6603
6707
  Examples:
6604
6708
  $ concave deploy Deploy with interactive setup (first time)
6605
6709
  $ concave deploy Redeploy to configured target
@@ -6671,8 +6775,8 @@ async function runDeploy(projectRoot, options) {
6671
6775
  dryRun: options.dryRun,
6672
6776
  yes: options.yes,
6673
6777
  verbose: options.verbose,
6674
- noDb: options.db === false,
6675
- noStorage: options.storage === false,
6778
+ docstore: options.docstore,
6779
+ blobstore: options.blobstore,
6676
6780
  force: options.force,
6677
6781
  reset: options.reset
6678
6782
  });
@@ -6682,27 +6786,220 @@ async function runDeploy(projectRoot, options) {
6682
6786
  var import_picocolors5 = __toESM(require_picocolors(), 1);
6683
6787
 
6684
6788
  // src/cli/url-utils.ts
6685
- function detectBaseUrl(options) {
6789
+ import { existsSync, readFileSync } from "node:fs";
6790
+ import path11 from "node:path";
6791
+ var URL_ENV_KEYS = [
6792
+ "CONCAVE_URL",
6793
+ "CONVEX_URL",
6794
+ "NEXT_PUBLIC_CONCAVE_URL",
6795
+ "NEXT_PUBLIC_CONVEX_URL",
6796
+ "CONCAVE_SITE_URL",
6797
+ "CONVEX_SITE_URL",
6798
+ "NEXT_PUBLIC_CONCAVE_SITE_URL",
6799
+ "NEXT_PUBLIC_CONVEX_SITE_URL",
6800
+ "NEXT_PUBLIC_SITE_URL",
6801
+ "SITE_URL"
6802
+ ];
6803
+ var NETWORK_ERROR_CODES = new Set([
6804
+ "ECONNREFUSED",
6805
+ "ConnectionRefused",
6806
+ "ENOTFOUND",
6807
+ "EAI_AGAIN",
6808
+ "ETIMEDOUT",
6809
+ "EHOSTUNREACH",
6810
+ "ECONNRESET",
6811
+ "UND_ERR_CONNECT_TIMEOUT",
6812
+ "UND_ERR_SOCKET",
6813
+ "UND_ERR_HEADERS_TIMEOUT"
6814
+ ]);
6815
+ function resolveBaseUrl(options, cwd = process.cwd()) {
6686
6816
  if (options.url) {
6687
- return normalizeUrl(options.url);
6817
+ return {
6818
+ baseUrl: normalizeUrl(options.url),
6819
+ source: "url-option",
6820
+ sourceDetail: "--url"
6821
+ };
6688
6822
  }
6689
- if (process.env.CONCAVE_URL) {
6690
- return normalizeUrl(process.env.CONCAVE_URL);
6823
+ for (const key of URL_ENV_KEYS) {
6824
+ const value = process.env[key];
6825
+ if (value) {
6826
+ return {
6827
+ baseUrl: normalizeUrl(value),
6828
+ source: "environment",
6829
+ sourceDetail: key
6830
+ };
6831
+ }
6691
6832
  }
6692
- if (process.env.CONVEX_URL) {
6693
- return normalizeUrl(process.env.CONVEX_URL);
6833
+ const fromFiles = getUrlFromEnvFiles(cwd);
6834
+ if (fromFiles) {
6835
+ return {
6836
+ baseUrl: normalizeUrl(fromFiles.value),
6837
+ source: "environment-file",
6838
+ sourceDetail: `${fromFiles.key} from ${path11.relative(cwd, fromFiles.filePath) || path11.basename(fromFiles.filePath)}`
6839
+ };
6694
6840
  }
6695
6841
  const port = options.port || "3000";
6696
- return `http://localhost:${port}`;
6842
+ return {
6843
+ baseUrl: `http://localhost:${port}`,
6844
+ source: "default-port",
6845
+ sourceDetail: `localhost:${port}${options.port ? "" : " (default)"}`
6846
+ };
6847
+ }
6848
+ function formatBaseUrlSource(resolution) {
6849
+ switch (resolution.source) {
6850
+ case "url-option":
6851
+ return "the --url flag";
6852
+ case "environment":
6853
+ return `environment variable ${resolution.sourceDetail}`;
6854
+ case "environment-file":
6855
+ return resolution.sourceDetail;
6856
+ case "default-port":
6857
+ return `default local fallback (${resolution.sourceDetail})`;
6858
+ }
6859
+ }
6860
+ function describeConnectionFailure(error, resolution, executeUrl) {
6861
+ const code = extractErrorCode(error);
6862
+ const message = extractErrorMessage(error);
6863
+ const lower = message.toLowerCase();
6864
+ const isNetworkFailure = !!code && NETWORK_ERROR_CODES.has(code) || lower.includes("fetch failed") || lower.includes("networkerror") || lower.includes("unable to connect") || lower.includes("could not connect") || lower.includes("connection refused") || lower.includes("timed out");
6865
+ if (!isNetworkFailure) {
6866
+ return null;
6867
+ }
6868
+ const details = [`Attempted endpoint: ${executeUrl}`, `URL resolved from: ${formatBaseUrlSource(resolution)}`];
6869
+ if (code) {
6870
+ details.push(`Network error code: ${code}`);
6871
+ }
6872
+ if (message && message.toLowerCase() !== "fetch failed") {
6873
+ details.push(`Network error: ${message}`);
6874
+ }
6875
+ details.push("Set the target explicitly with --url <url> or --port <n>.");
6876
+ details.push("Or set CONCAVE_URL / CONVEX_URL in your shell or .env.local.");
6877
+ details.push("Start a local server with: concave dev");
6878
+ return {
6879
+ summary: `✗ Could not connect to a Concave instance at ${resolution.baseUrl}`,
6880
+ details
6881
+ };
6697
6882
  }
6698
6883
  function normalizeUrl(url) {
6699
6884
  let normalized = url.trim();
6700
6885
  if (!normalized.startsWith("http://") && !normalized.startsWith("https://")) {
6701
- normalized = `https://${normalized}`;
6886
+ const host = normalized.split("/")[0].split(":")[0];
6887
+ if (host === "localhost" || host === "127.0.0.1" || host === "[::1]") {
6888
+ normalized = `http://${normalized}`;
6889
+ } else {
6890
+ normalized = `https://${normalized}`;
6891
+ }
6702
6892
  }
6703
6893
  normalized = normalized.replace(/\/+$/, "");
6704
6894
  return normalized;
6705
6895
  }
6896
+ function getUrlFromEnvFiles(cwd) {
6897
+ const envFiles = getEnvFileCandidates(cwd);
6898
+ const merged = new Map;
6899
+ for (const filePath of envFiles) {
6900
+ if (!existsSync(filePath)) {
6901
+ continue;
6902
+ }
6903
+ const parsed = parseDotEnv(readFileSync(filePath, "utf8"));
6904
+ for (const [key, value] of Object.entries(parsed)) {
6905
+ if (!merged.has(key)) {
6906
+ merged.set(key, { value, filePath });
6907
+ }
6908
+ }
6909
+ }
6910
+ for (const key of URL_ENV_KEYS) {
6911
+ const entry = merged.get(key);
6912
+ if (entry?.value) {
6913
+ return {
6914
+ key,
6915
+ value: entry.value,
6916
+ filePath: entry.filePath
6917
+ };
6918
+ }
6919
+ }
6920
+ return null;
6921
+ }
6922
+ function getEnvFileCandidates(cwd) {
6923
+ const convexRoot = detectConvexRoot(cwd);
6924
+ const candidates = [
6925
+ path11.join(convexRoot, ".env.local"),
6926
+ path11.join(convexRoot, ".env"),
6927
+ path11.join(cwd, ".env.local"),
6928
+ path11.join(cwd, ".env")
6929
+ ];
6930
+ return [...new Set(candidates)];
6931
+ }
6932
+ function detectConvexRoot(cwd) {
6933
+ const convexJsonPath = path11.join(cwd, "convex.json");
6934
+ const fallback = path11.join(cwd, "convex");
6935
+ if (!existsSync(convexJsonPath)) {
6936
+ return fallback;
6937
+ }
6938
+ try {
6939
+ const raw = JSON.parse(readFileSync(convexJsonPath, "utf8"));
6940
+ if (typeof raw?.functions !== "string") {
6941
+ return fallback;
6942
+ }
6943
+ const normalized = raw.functions.replace(/\\/g, "/").replace(/\/+$/, "").trim();
6944
+ if (!normalized) {
6945
+ return fallback;
6946
+ }
6947
+ const root = normalized.includes("/") ? path11.posix.dirname(normalized) : normalized;
6948
+ if (!root || root === ".") {
6949
+ return fallback;
6950
+ }
6951
+ return path11.resolve(cwd, root);
6952
+ } catch {
6953
+ return fallback;
6954
+ }
6955
+ }
6956
+ function parseDotEnv(content) {
6957
+ const result = {};
6958
+ const lines = content.split(`
6959
+ `);
6960
+ for (const line of lines) {
6961
+ const trimmed = line.trim();
6962
+ if (!trimmed || trimmed.startsWith("#")) {
6963
+ continue;
6964
+ }
6965
+ const match = trimmed.match(/^(?:export\s+)?([^=]+)=(.*)$/);
6966
+ if (!match) {
6967
+ continue;
6968
+ }
6969
+ const key = match[1].trim();
6970
+ let value = match[2].trim();
6971
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
6972
+ value = value.slice(1, -1);
6973
+ }
6974
+ value = value.replace(/\\n/g, `
6975
+ `).replace(/\\r/g, "\r").replace(/\\t/g, "\t");
6976
+ result[key] = value;
6977
+ }
6978
+ return result;
6979
+ }
6980
+ function extractErrorCode(error) {
6981
+ let cursor = error;
6982
+ for (let i = 0;i < 5 && cursor; i++) {
6983
+ if (typeof cursor.code === "string" && cursor.code.length > 0) {
6984
+ return cursor.code;
6985
+ }
6986
+ cursor = cursor.cause;
6987
+ }
6988
+ return;
6989
+ }
6990
+ function extractErrorMessage(error) {
6991
+ if (error instanceof Error) {
6992
+ return error.message || String(error);
6993
+ }
6994
+ if (typeof error === "string") {
6995
+ return error;
6996
+ }
6997
+ try {
6998
+ return JSON.stringify(error);
6999
+ } catch {
7000
+ return String(error);
7001
+ }
7002
+ }
6706
7003
 
6707
7004
  // src/cli/run.ts
6708
7005
  function isErrorResponse(response) {
@@ -6719,9 +7016,8 @@ async function runFunction(functionName, argsJson, options) {
6719
7016
  process.exit(1);
6720
7017
  }
6721
7018
  }
6722
- const baseUrl = detectBaseUrl(options);
6723
- const executeUrl = `${baseUrl}/api/execute`;
6724
- const normalizedPath = functionName.replace(/:/g, "/");
7019
+ const baseUrlResolution = resolveBaseUrl(options);
7020
+ const executeUrl = `${baseUrlResolution.baseUrl}/api/execute`;
6725
7021
  console.log(import_picocolors5.default.cyan(`\uD83D\uDE80 Running ${import_picocolors5.default.bold(functionName)}`));
6726
7022
  if (options.component) {
6727
7023
  console.log(import_picocolors5.default.dim(` Component: ${options.component}`));
@@ -6738,7 +7034,7 @@ async function runFunction(functionName, argsJson, options) {
6738
7034
  "Content-Type": "application/json"
6739
7035
  },
6740
7036
  body: JSON.stringify({
6741
- path: normalizedPath,
7037
+ path: functionName,
6742
7038
  args,
6743
7039
  format: "json",
6744
7040
  componentPath: options.component
@@ -6779,12 +7075,15 @@ async function runFunction(functionName, argsJson, options) {
6779
7075
  console.log(formatResult(result));
6780
7076
  }
6781
7077
  } catch (error) {
6782
- if (error.code === "ECONNREFUSED") {
6783
- console.error(import_picocolors5.default.red("✗ Could not connect to dev server"));
6784
- console.log(import_picocolors5.default.dim(` Make sure the dev server is running on ${baseUrl}`));
6785
- console.log(import_picocolors5.default.dim(` Run: npx concave dev`));
7078
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
7079
+ if (connectionFailure) {
7080
+ console.error(import_picocolors5.default.red(connectionFailure.summary));
7081
+ for (const line of connectionFailure.details) {
7082
+ console.error(import_picocolors5.default.dim(` ${line}`));
7083
+ }
6786
7084
  } else {
6787
- console.error(import_picocolors5.default.red("✗ Request failed:"), error.message);
7085
+ const message = error instanceof Error ? error.message : String(error);
7086
+ console.error(import_picocolors5.default.red("✗ Request failed:"), message);
6788
7087
  }
6789
7088
  process.exit(1);
6790
7089
  }
@@ -6820,17 +7119,17 @@ function isErrorResponse2(response) {
6820
7119
  return response.status === "error";
6821
7120
  }
6822
7121
  async function browseData(tableName, options) {
6823
- const baseUrl = detectBaseUrl(options);
6824
- const executeUrl = `${baseUrl}/api/execute`;
7122
+ const baseUrlResolution = resolveBaseUrl(options);
7123
+ const executeUrl = `${baseUrlResolution.baseUrl}/api/execute`;
6825
7124
  const componentPath = options.component;
6826
7125
  if (!tableName) {
6827
- await listTables(executeUrl, componentPath);
7126
+ await listTables(executeUrl, baseUrlResolution, componentPath);
6828
7127
  } else {
6829
7128
  const limit = options.limit ? parseInt(options.limit, 10) : 10;
6830
- await showTableData(executeUrl, tableName, limit, componentPath);
7129
+ await showTableData(executeUrl, baseUrlResolution, tableName, limit, componentPath);
6831
7130
  }
6832
7131
  }
6833
- async function listTables(executeUrl, componentPath) {
7132
+ async function listTables(executeUrl, baseUrlResolution, componentPath) {
6834
7133
  const header = componentPath ? import_picocolors6.default.cyan(`\uD83D\uDCCA Tables in Component: ${import_picocolors6.default.bold(componentPath)}
6835
7134
  `) : import_picocolors6.default.cyan(`\uD83D\uDCCA Database Tables
6836
7135
  `);
@@ -6842,8 +7141,9 @@ async function listTables(executeUrl, componentPath) {
6842
7141
  "Content-Type": "application/json"
6843
7142
  },
6844
7143
  body: JSON.stringify({
6845
- path: "_system/systemListTables",
7144
+ path: "_system:systemListTables",
6846
7145
  args: componentPath ? { componentPath } : {},
7146
+ type: "query",
6847
7147
  format: "json"
6848
7148
  })
6849
7149
  });
@@ -6865,17 +7165,20 @@ async function listTables(executeUrl, componentPath) {
6865
7165
  console.log(import_picocolors6.default.dim(`
6866
7166
  Use ${import_picocolors6.default.bold(`concave data <table>${componentHint}`)} to view table contents`));
6867
7167
  } catch (error) {
6868
- if (error.code === "ECONNREFUSED") {
6869
- console.error(import_picocolors6.default.red("✗ Could not connect to dev server"));
6870
- console.log(import_picocolors6.default.dim(` Make sure the dev server is running`));
6871
- console.log(import_picocolors6.default.dim(` Run: npx concave dev`));
7168
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
7169
+ if (connectionFailure) {
7170
+ console.error(import_picocolors6.default.red(connectionFailure.summary));
7171
+ for (const line of connectionFailure.details) {
7172
+ console.error(import_picocolors6.default.dim(` ${line}`));
7173
+ }
6872
7174
  } else {
6873
- console.error(import_picocolors6.default.red("✗ Failed to list tables:"), error.message);
7175
+ const message = error instanceof Error ? error.message : String(error);
7176
+ console.error(import_picocolors6.default.red("✗ Failed to list tables:"), message);
6874
7177
  }
6875
7178
  process.exit(1);
6876
7179
  }
6877
7180
  }
6878
- async function showTableData(executeUrl, tableName, limit, componentPath) {
7181
+ async function showTableData(executeUrl, baseUrlResolution, tableName, limit, componentPath) {
6879
7182
  const header = componentPath ? import_picocolors6.default.cyan(`\uD83D\uDCCA Table: ${import_picocolors6.default.bold(tableName)} (Component: ${componentPath})
6880
7183
  `) : import_picocolors6.default.cyan(`\uD83D\uDCCA Table: ${import_picocolors6.default.bold(tableName)}
6881
7184
  `);
@@ -6887,13 +7190,14 @@ async function showTableData(executeUrl, tableName, limit, componentPath) {
6887
7190
  "Content-Type": "application/json"
6888
7191
  },
6889
7192
  body: JSON.stringify({
6890
- path: "_system/systemGetTableData",
7193
+ path: "_system:systemGetTableData",
6891
7194
  args: {
6892
7195
  tableName,
6893
7196
  componentPath,
6894
7197
  page: 1,
6895
7198
  pageSize: limit
6896
7199
  },
7200
+ type: "query",
6897
7201
  format: "json"
6898
7202
  })
6899
7203
  });
@@ -6940,12 +7244,15 @@ async function showTableData(executeUrl, tableName, limit, componentPath) {
6940
7244
  Showing first ${limit} documents. Use --limit to see more.`));
6941
7245
  }
6942
7246
  } catch (error) {
6943
- if (error.code === "ECONNREFUSED") {
6944
- console.error(import_picocolors6.default.red("✗ Could not connect to dev server"));
6945
- console.log(import_picocolors6.default.dim(` Make sure the dev server is running`));
6946
- console.log(import_picocolors6.default.dim(` Run: npx concave dev`));
7247
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
7248
+ if (connectionFailure) {
7249
+ console.error(import_picocolors6.default.red(connectionFailure.summary));
7250
+ for (const line of connectionFailure.details) {
7251
+ console.error(import_picocolors6.default.dim(` ${line}`));
7252
+ }
6947
7253
  } else {
6948
- console.error(import_picocolors6.default.red("✗ Failed to query table:"), error.message);
7254
+ const message = error instanceof Error ? error.message : String(error);
7255
+ console.error(import_picocolors6.default.red("✗ Failed to query table:"), message);
6949
7256
  }
6950
7257
  process.exit(1);
6951
7258
  }
@@ -6994,11 +7301,11 @@ function formatValue(value) {
6994
7301
  // src/cli/type-codegen.ts
6995
7302
  var import_picocolors7 = __toESM(require_picocolors(), 1);
6996
7303
  import { promises as fs9 } from "node:fs";
6997
- import path11 from "node:path";
7304
+ import path12 from "node:path";
6998
7305
  async function generateTypes(projectRoot, options = {}) {
6999
7306
  const layout = await resolveProjectLayout(projectRoot);
7000
7307
  const convexDir = layout.functionsDir;
7001
- const generatedDir = path11.join(convexDir, "_generated");
7308
+ const generatedDir = path12.join(convexDir, "_generated");
7002
7309
  try {
7003
7310
  await fs9.access(convexDir);
7004
7311
  } catch {
@@ -7027,7 +7334,7 @@ async function discoverModules(convexDir) {
7027
7334
  if (entry.name.startsWith(".") || entry.name === "_generated" || entry.name === "node_modules") {
7028
7335
  continue;
7029
7336
  }
7030
- const fullPath = path11.join(dir, entry.name);
7337
+ const fullPath = path12.join(dir, entry.name);
7031
7338
  const entryRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
7032
7339
  if (entry.isDirectory()) {
7033
7340
  await walk(fullPath, entryRelativePath);
@@ -7200,7 +7507,7 @@ export type DatabaseReader = GenericDatabaseReader<DataModel>;
7200
7507
  */
7201
7508
  export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
7202
7509
  `;
7203
- await fs9.writeFile(path11.join(generatedDir, "server.d.ts"), content, "utf8");
7510
+ await fs9.writeFile(path12.join(generatedDir, "server.d.ts"), content, "utf8");
7204
7511
  }
7205
7512
  async function generateServerJs(generatedDir) {
7206
7513
  const content = `/* eslint-disable */
@@ -7293,7 +7600,7 @@ export const internalAction = internalActionGeneric;
7293
7600
  */
7294
7601
  export const httpAction = httpActionGeneric;
7295
7602
  `;
7296
- await fs9.writeFile(path11.join(generatedDir, "server.js"), content, "utf8");
7603
+ await fs9.writeFile(path12.join(generatedDir, "server.js"), content, "utf8");
7297
7604
  }
7298
7605
  async function generateDataModelTypes(generatedDir, hasSchema) {
7299
7606
  const content = `/* eslint-disable */
@@ -7357,7 +7664,7 @@ export type Id<TableName extends TableNames | SystemTableNames> =
7357
7664
  */
7358
7665
  ${hasSchema ? "export type DataModel = DataModelFromSchemaDefinition<typeof schema>;" : "export type DataModel = any;"}
7359
7666
  `;
7360
- await fs9.writeFile(path11.join(generatedDir, "dataModel.d.ts"), content, "utf8");
7667
+ await fs9.writeFile(path12.join(generatedDir, "dataModel.d.ts"), content, "utf8");
7361
7668
  }
7362
7669
  async function generateApiTypes(generatedDir, modules, _hasSchema) {
7363
7670
  const apiModules = modules.filter((m) => m.name !== "schema" && !m.name.startsWith("_") && m.name !== "http");
@@ -7415,7 +7722,7 @@ export declare const internal: FilterApi<
7415
7722
 
7416
7723
  export declare const components: AnyComponents;
7417
7724
  `;
7418
- await fs9.writeFile(path11.join(generatedDir, "api.d.ts"), content, "utf8");
7725
+ await fs9.writeFile(path12.join(generatedDir, "api.d.ts"), content, "utf8");
7419
7726
  }
7420
7727
  async function generateApiJs(generatedDir) {
7421
7728
  const content = `/* eslint-disable */
@@ -7443,13 +7750,13 @@ export const api = anyApi;
7443
7750
  export const internal = anyApi;
7444
7751
  export const components = componentsGeneric();
7445
7752
  `;
7446
- await fs9.writeFile(path11.join(generatedDir, "api.js"), content, "utf8");
7753
+ await fs9.writeFile(path12.join(generatedDir, "api.js"), content, "utf8");
7447
7754
  }
7448
7755
 
7449
7756
  // src/cli/type-codegen-runtime.ts
7450
7757
  var import_picocolors8 = __toESM(require_picocolors(), 1);
7451
7758
  import { promises as fs10 } from "node:fs";
7452
- import path12 from "node:path";
7759
+ import path13 from "node:path";
7453
7760
  import { pathToFileURL as pathToFileURL3 } from "node:url";
7454
7761
 
7455
7762
  // src/cli/validator-to-typescript.ts
@@ -7520,10 +7827,8 @@ function convertValidator(validator, options) {
7520
7827
  return `{ ${fields.join("; ")} }`;
7521
7828
  }
7522
7829
  case "record": {
7523
- const keys = validator.keys;
7524
- const values = validator.values;
7525
- const keyType = convertValidator(keys, options);
7526
- const valueType = convertValidator(values, options);
7830
+ const keyType = convertValidator(validator.keys, options);
7831
+ const valueType = convertValidator(validator.values.fieldType, options);
7527
7832
  return `Record<${keyType}, ${valueType}>`;
7528
7833
  }
7529
7834
  case "set": {
@@ -7568,7 +7873,7 @@ function returnsValidatorToTypeScript(returns, options = {}) {
7568
7873
  async function generateTypesWithRuntime(projectRoot, options = {}) {
7569
7874
  const layout = await resolveProjectLayout(projectRoot);
7570
7875
  const convexDir = layout.functionsDir;
7571
- const generatedDir = path12.join(convexDir, "_generated");
7876
+ const generatedDir = path13.join(convexDir, "_generated");
7572
7877
  console.log(import_picocolors8.default.cyan("\uD83D\uDD27 Generating TypeScript types (runtime analysis)"));
7573
7878
  console.log(import_picocolors8.default.dim(` Output: ${generatedDir}
7574
7879
  `));
@@ -7641,7 +7946,7 @@ async function discoverAndAnalyzeModules(convexDir, options) {
7641
7946
  const failed = [];
7642
7947
  const moduleFiles = await collectConvexModules2(convexDir);
7643
7948
  for (const filePath of moduleFiles) {
7644
- const relativePath = path12.relative(convexDir, filePath);
7949
+ const relativePath = path13.relative(convexDir, filePath);
7645
7950
  const moduleName = relativePath.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, "").replace(/\\/g, "/");
7646
7951
  if (moduleName === "schema" || moduleName === "http" || moduleName === "crons") {
7647
7952
  continue;
@@ -7771,7 +8076,7 @@ async function collectConvexModules2(convexDir) {
7771
8076
  if (entry.name.startsWith(".") || entry.name === "_generated" || entry.name === "node_modules") {
7772
8077
  continue;
7773
8078
  }
7774
- const fullPath = path12.join(dir, entry.name);
8079
+ const fullPath = path13.join(dir, entry.name);
7775
8080
  if (entry.isDirectory()) {
7776
8081
  await walk(fullPath);
7777
8082
  } else if (isConvexSourceFile3(entry.name)) {
@@ -7952,7 +8257,7 @@ export declare const internal: FilterApi<
7952
8257
 
7953
8258
  export declare const components: AnyComponents;
7954
8259
  `;
7955
- await fs10.writeFile(path12.join(generatedDir, "api.d.ts"), content, "utf8");
8260
+ await fs10.writeFile(path13.join(generatedDir, "api.d.ts"), content, "utf8");
7956
8261
  }
7957
8262
  async function generatePackageJson(generatedDir) {
7958
8263
  const content = {
@@ -7966,7 +8271,7 @@ async function generatePackageJson(generatedDir) {
7966
8271
  "./dataModel.d.ts": "./dataModel.d.ts"
7967
8272
  }
7968
8273
  };
7969
- await fs10.writeFile(path12.join(generatedDir, "package.json"), JSON.stringify(content, null, 2), "utf8");
8274
+ await fs10.writeFile(path13.join(generatedDir, "package.json"), JSON.stringify(content, null, 2), "utf8");
7970
8275
  }
7971
8276
  async function generateServerTypes2(generatedDir, _hasSchema) {
7972
8277
  const content = `/* eslint-disable */
@@ -8006,7 +8311,7 @@ export type ActionCtx = GenericActionCtx<DataModel>;
8006
8311
  export type DatabaseReader = GenericDatabaseReader<DataModel>;
8007
8312
  export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
8008
8313
  `;
8009
- await fs10.writeFile(path12.join(generatedDir, "server.d.ts"), content, "utf8");
8314
+ await fs10.writeFile(path13.join(generatedDir, "server.d.ts"), content, "utf8");
8010
8315
  }
8011
8316
  async function generateServerJs2(generatedDir) {
8012
8317
  const content = `/* eslint-disable */
@@ -8037,7 +8342,7 @@ export const action = actionGeneric;
8037
8342
  export const internalAction = internalActionGeneric;
8038
8343
  export const httpAction = httpActionGeneric;
8039
8344
  `;
8040
- await fs10.writeFile(path12.join(generatedDir, "server.js"), content, "utf8");
8345
+ await fs10.writeFile(path13.join(generatedDir, "server.js"), content, "utf8");
8041
8346
  }
8042
8347
  async function generateDataModelTypes2(generatedDir, hasSchema) {
8043
8348
  const content = `/* eslint-disable */
@@ -8065,7 +8370,7 @@ export type Id<TableName extends TableNames | SystemTableNames> = GenericId<Tabl
8065
8370
 
8066
8371
  ${hasSchema ? "export type DataModel = DataModelFromSchemaDefinition<typeof schema>;" : "export type DataModel = any;"}
8067
8372
  `;
8068
- await fs10.writeFile(path12.join(generatedDir, "dataModel.d.ts"), content, "utf8");
8373
+ await fs10.writeFile(path13.join(generatedDir, "dataModel.d.ts"), content, "utf8");
8069
8374
  }
8070
8375
  async function generateApiJs2(generatedDir) {
8071
8376
  const content = `/* eslint-disable */
@@ -8092,16 +8397,16 @@ export const api = anyApi;
8092
8397
  export const internal = anyApi;
8093
8398
  export const components = componentsGeneric();
8094
8399
  `;
8095
- await fs10.writeFile(path12.join(generatedDir, "api.js"), content, "utf8");
8400
+ await fs10.writeFile(path13.join(generatedDir, "api.js"), content, "utf8");
8096
8401
  }
8097
8402
 
8098
- // ../../node_modules/.bun/chokidar@4.0.3/node_modules/chokidar/esm/index.js
8403
+ // ../../node_modules/chokidar/esm/index.js
8099
8404
  import { stat as statcb } from "fs";
8100
8405
  import { stat as stat4, readdir as readdir2 } from "fs/promises";
8101
8406
  import { EventEmitter } from "events";
8102
8407
  import * as sysPath2 from "path";
8103
8408
 
8104
- // ../../node_modules/.bun/readdirp@4.1.2/node_modules/readdirp/esm/index.js
8409
+ // ../../node_modules/readdirp/esm/index.js
8105
8410
  import { stat as stat2, lstat, readdir, realpath } from "node:fs/promises";
8106
8411
  import { Readable } from "node:stream";
8107
8412
  import { resolve as presolve, relative as prelative, join as pjoin, sep as psep } from "node:path";
@@ -8172,7 +8477,7 @@ class ReaddirpStream extends Readable {
8172
8477
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
8173
8478
  const statMethod = opts.lstat ? lstat : stat2;
8174
8479
  if (wantBigintFsStats) {
8175
- this._stat = (path13) => statMethod(path13, { bigint: true });
8480
+ this._stat = (path14) => statMethod(path14, { bigint: true });
8176
8481
  } else {
8177
8482
  this._stat = statMethod;
8178
8483
  }
@@ -8197,8 +8502,8 @@ class ReaddirpStream extends Readable {
8197
8502
  const par = this.parent;
8198
8503
  const fil = par && par.files;
8199
8504
  if (fil && fil.length > 0) {
8200
- const { path: path13, depth } = par;
8201
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path13));
8505
+ const { path: path14, depth } = par;
8506
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path14));
8202
8507
  const awaited = await Promise.all(slice);
8203
8508
  for (const entry of awaited) {
8204
8509
  if (!entry)
@@ -8238,20 +8543,20 @@ class ReaddirpStream extends Readable {
8238
8543
  this.reading = false;
8239
8544
  }
8240
8545
  }
8241
- async _exploreDir(path13, depth) {
8546
+ async _exploreDir(path14, depth) {
8242
8547
  let files;
8243
8548
  try {
8244
- files = await readdir(path13, this._rdOptions);
8549
+ files = await readdir(path14, this._rdOptions);
8245
8550
  } catch (error) {
8246
8551
  this._onError(error);
8247
8552
  }
8248
- return { files, depth, path: path13 };
8553
+ return { files, depth, path: path14 };
8249
8554
  }
8250
- async _formatEntry(dirent, path13) {
8555
+ async _formatEntry(dirent, path14) {
8251
8556
  let entry;
8252
8557
  const basename = this._isDirent ? dirent.name : dirent;
8253
8558
  try {
8254
- const fullPath = presolve(pjoin(path13, basename));
8559
+ const fullPath = presolve(pjoin(path14, basename));
8255
8560
  entry = { path: prelative(this._root, fullPath), fullPath, basename };
8256
8561
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
8257
8562
  } catch (err) {
@@ -8321,7 +8626,7 @@ function readdirp(root, options = {}) {
8321
8626
  return new ReaddirpStream(options);
8322
8627
  }
8323
8628
 
8324
- // ../../node_modules/.bun/chokidar@4.0.3/node_modules/chokidar/esm/handler.js
8629
+ // ../../node_modules/chokidar/esm/handler.js
8325
8630
  import { watchFile, unwatchFile, watch as fs_watch } from "fs";
8326
8631
  import { open, stat as stat3, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
8327
8632
  import * as sysPath from "path";
@@ -8650,16 +8955,16 @@ var delFromSet = (main, prop, item) => {
8650
8955
  };
8651
8956
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
8652
8957
  var FsWatchInstances = new Map;
8653
- function createFsWatchInstance(path13, options, listener, errHandler, emitRaw) {
8958
+ function createFsWatchInstance(path14, options, listener, errHandler, emitRaw) {
8654
8959
  const handleEvent = (rawEvent, evPath) => {
8655
- listener(path13);
8656
- emitRaw(rawEvent, evPath, { watchedPath: path13 });
8657
- if (evPath && path13 !== evPath) {
8658
- fsWatchBroadcast(sysPath.resolve(path13, evPath), KEY_LISTENERS, sysPath.join(path13, evPath));
8960
+ listener(path14);
8961
+ emitRaw(rawEvent, evPath, { watchedPath: path14 });
8962
+ if (evPath && path14 !== evPath) {
8963
+ fsWatchBroadcast(sysPath.resolve(path14, evPath), KEY_LISTENERS, sysPath.join(path14, evPath));
8659
8964
  }
8660
8965
  };
8661
8966
  try {
8662
- return fs_watch(path13, {
8967
+ return fs_watch(path14, {
8663
8968
  persistent: options.persistent
8664
8969
  }, handleEvent);
8665
8970
  } catch (error) {
@@ -8675,12 +8980,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
8675
8980
  listener(val1, val2, val3);
8676
8981
  });
8677
8982
  };
8678
- var setFsWatchListener = (path13, fullPath, options, handlers) => {
8983
+ var setFsWatchListener = (path14, fullPath, options, handlers) => {
8679
8984
  const { listener, errHandler, rawEmitter } = handlers;
8680
8985
  let cont = FsWatchInstances.get(fullPath);
8681
8986
  let watcher;
8682
8987
  if (!options.persistent) {
8683
- watcher = createFsWatchInstance(path13, options, listener, errHandler, rawEmitter);
8988
+ watcher = createFsWatchInstance(path14, options, listener, errHandler, rawEmitter);
8684
8989
  if (!watcher)
8685
8990
  return;
8686
8991
  return watcher.close.bind(watcher);
@@ -8690,7 +8995,7 @@ var setFsWatchListener = (path13, fullPath, options, handlers) => {
8690
8995
  addAndConvert(cont, KEY_ERR, errHandler);
8691
8996
  addAndConvert(cont, KEY_RAW, rawEmitter);
8692
8997
  } else {
8693
- watcher = createFsWatchInstance(path13, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
8998
+ watcher = createFsWatchInstance(path14, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
8694
8999
  if (!watcher)
8695
9000
  return;
8696
9001
  watcher.on(EV.ERROR, async (error) => {
@@ -8699,7 +9004,7 @@ var setFsWatchListener = (path13, fullPath, options, handlers) => {
8699
9004
  cont.watcherUnusable = true;
8700
9005
  if (isWindows && error.code === "EPERM") {
8701
9006
  try {
8702
- const fd = await open(path13, "r");
9007
+ const fd = await open(path14, "r");
8703
9008
  await fd.close();
8704
9009
  broadcastErr(error);
8705
9010
  } catch (err) {}
@@ -8729,7 +9034,7 @@ var setFsWatchListener = (path13, fullPath, options, handlers) => {
8729
9034
  };
8730
9035
  };
8731
9036
  var FsWatchFileInstances = new Map;
8732
- var setFsWatchFileListener = (path13, fullPath, options, handlers) => {
9037
+ var setFsWatchFileListener = (path14, fullPath, options, handlers) => {
8733
9038
  const { listener, rawEmitter } = handlers;
8734
9039
  let cont = FsWatchFileInstances.get(fullPath);
8735
9040
  const copts = cont && cont.options;
@@ -8751,7 +9056,7 @@ var setFsWatchFileListener = (path13, fullPath, options, handlers) => {
8751
9056
  });
8752
9057
  const currmtime = curr.mtimeMs;
8753
9058
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
8754
- foreach(cont.listeners, (listener2) => listener2(path13, curr));
9059
+ foreach(cont.listeners, (listener2) => listener2(path14, curr));
8755
9060
  }
8756
9061
  })
8757
9062
  };
@@ -8774,13 +9079,13 @@ class NodeFsHandler {
8774
9079
  this.fsw = fsW;
8775
9080
  this._boundHandleError = (error) => fsW._handleError(error);
8776
9081
  }
8777
- _watchWithNodeFs(path13, listener) {
9082
+ _watchWithNodeFs(path14, listener) {
8778
9083
  const opts = this.fsw.options;
8779
- const directory = sysPath.dirname(path13);
8780
- const basename2 = sysPath.basename(path13);
9084
+ const directory = sysPath.dirname(path14);
9085
+ const basename2 = sysPath.basename(path14);
8781
9086
  const parent = this.fsw._getWatchedDir(directory);
8782
9087
  parent.add(basename2);
8783
- const absolutePath = sysPath.resolve(path13);
9088
+ const absolutePath = sysPath.resolve(path14);
8784
9089
  const options = {
8785
9090
  persistent: opts.persistent
8786
9091
  };
@@ -8790,12 +9095,12 @@ class NodeFsHandler {
8790
9095
  if (opts.usePolling) {
8791
9096
  const enableBin = opts.interval !== opts.binaryInterval;
8792
9097
  options.interval = enableBin && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
8793
- closer = setFsWatchFileListener(path13, absolutePath, options, {
9098
+ closer = setFsWatchFileListener(path14, absolutePath, options, {
8794
9099
  listener,
8795
9100
  rawEmitter: this.fsw._emitRaw
8796
9101
  });
8797
9102
  } else {
8798
- closer = setFsWatchListener(path13, absolutePath, options, {
9103
+ closer = setFsWatchListener(path14, absolutePath, options, {
8799
9104
  listener,
8800
9105
  errHandler: this._boundHandleError,
8801
9106
  rawEmitter: this.fsw._emitRaw
@@ -8813,7 +9118,7 @@ class NodeFsHandler {
8813
9118
  let prevStats = stats;
8814
9119
  if (parent.has(basename2))
8815
9120
  return;
8816
- const listener = async (path13, newStats) => {
9121
+ const listener = async (path14, newStats) => {
8817
9122
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
8818
9123
  return;
8819
9124
  if (!newStats || newStats.mtimeMs === 0) {
@@ -8827,11 +9132,11 @@ class NodeFsHandler {
8827
9132
  this.fsw._emit(EV.CHANGE, file, newStats2);
8828
9133
  }
8829
9134
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
8830
- this.fsw._closeFile(path13);
9135
+ this.fsw._closeFile(path14);
8831
9136
  prevStats = newStats2;
8832
9137
  const closer2 = this._watchWithNodeFs(file, listener);
8833
9138
  if (closer2)
8834
- this.fsw._addPathCloser(path13, closer2);
9139
+ this.fsw._addPathCloser(path14, closer2);
8835
9140
  } else {
8836
9141
  prevStats = newStats2;
8837
9142
  }
@@ -8855,7 +9160,7 @@ class NodeFsHandler {
8855
9160
  }
8856
9161
  return closer;
8857
9162
  }
8858
- async _handleSymlink(entry, directory, path13, item) {
9163
+ async _handleSymlink(entry, directory, path14, item) {
8859
9164
  if (this.fsw.closed) {
8860
9165
  return;
8861
9166
  }
@@ -8865,7 +9170,7 @@ class NodeFsHandler {
8865
9170
  this.fsw._incrReadyCount();
8866
9171
  let linkPath;
8867
9172
  try {
8868
- linkPath = await fsrealpath(path13);
9173
+ linkPath = await fsrealpath(path14);
8869
9174
  } catch (e) {
8870
9175
  this.fsw._emitReady();
8871
9176
  return true;
@@ -8875,12 +9180,12 @@ class NodeFsHandler {
8875
9180
  if (dir.has(item)) {
8876
9181
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
8877
9182
  this.fsw._symlinkPaths.set(full, linkPath);
8878
- this.fsw._emit(EV.CHANGE, path13, entry.stats);
9183
+ this.fsw._emit(EV.CHANGE, path14, entry.stats);
8879
9184
  }
8880
9185
  } else {
8881
9186
  dir.add(item);
8882
9187
  this.fsw._symlinkPaths.set(full, linkPath);
8883
- this.fsw._emit(EV.ADD, path13, entry.stats);
9188
+ this.fsw._emit(EV.ADD, path14, entry.stats);
8884
9189
  }
8885
9190
  this.fsw._emitReady();
8886
9191
  return true;
@@ -8909,9 +9214,9 @@ class NodeFsHandler {
8909
9214
  return;
8910
9215
  }
8911
9216
  const item = entry.path;
8912
- let path13 = sysPath.join(directory, item);
9217
+ let path14 = sysPath.join(directory, item);
8913
9218
  current.add(item);
8914
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path13, item)) {
9219
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path14, item)) {
8915
9220
  return;
8916
9221
  }
8917
9222
  if (this.fsw.closed) {
@@ -8920,8 +9225,8 @@ class NodeFsHandler {
8920
9225
  }
8921
9226
  if (item === target || !target && !previous.has(item)) {
8922
9227
  this.fsw._incrReadyCount();
8923
- path13 = sysPath.join(dir, sysPath.relative(dir, path13));
8924
- this._addToNodeFs(path13, initialAdd, wh, depth + 1);
9228
+ path14 = sysPath.join(dir, sysPath.relative(dir, path14));
9229
+ this._addToNodeFs(path14, initialAdd, wh, depth + 1);
8925
9230
  }
8926
9231
  }).on(EV.ERROR, this._boundHandleError);
8927
9232
  return new Promise((resolve2, reject) => {
@@ -8970,13 +9275,13 @@ class NodeFsHandler {
8970
9275
  }
8971
9276
  return closer;
8972
9277
  }
8973
- async _addToNodeFs(path13, initialAdd, priorWh, depth, target) {
9278
+ async _addToNodeFs(path14, initialAdd, priorWh, depth, target) {
8974
9279
  const ready = this.fsw._emitReady;
8975
- if (this.fsw._isIgnored(path13) || this.fsw.closed) {
9280
+ if (this.fsw._isIgnored(path14) || this.fsw.closed) {
8976
9281
  ready();
8977
9282
  return false;
8978
9283
  }
8979
- const wh = this.fsw._getWatchHelpers(path13);
9284
+ const wh = this.fsw._getWatchHelpers(path14);
8980
9285
  if (priorWh) {
8981
9286
  wh.filterPath = (entry) => priorWh.filterPath(entry);
8982
9287
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -8992,8 +9297,8 @@ class NodeFsHandler {
8992
9297
  const follow = this.fsw.options.followSymlinks;
8993
9298
  let closer;
8994
9299
  if (stats.isDirectory()) {
8995
- const absPath = sysPath.resolve(path13);
8996
- const targetPath = follow ? await fsrealpath(path13) : path13;
9300
+ const absPath = sysPath.resolve(path14);
9301
+ const targetPath = follow ? await fsrealpath(path14) : path14;
8997
9302
  if (this.fsw.closed)
8998
9303
  return;
8999
9304
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -9003,35 +9308,35 @@ class NodeFsHandler {
9003
9308
  this.fsw._symlinkPaths.set(absPath, targetPath);
9004
9309
  }
9005
9310
  } else if (stats.isSymbolicLink()) {
9006
- const targetPath = follow ? await fsrealpath(path13) : path13;
9311
+ const targetPath = follow ? await fsrealpath(path14) : path14;
9007
9312
  if (this.fsw.closed)
9008
9313
  return;
9009
9314
  const parent = sysPath.dirname(wh.watchPath);
9010
9315
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
9011
9316
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
9012
- closer = await this._handleDir(parent, stats, initialAdd, depth, path13, wh, targetPath);
9317
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path14, wh, targetPath);
9013
9318
  if (this.fsw.closed)
9014
9319
  return;
9015
9320
  if (targetPath !== undefined) {
9016
- this.fsw._symlinkPaths.set(sysPath.resolve(path13), targetPath);
9321
+ this.fsw._symlinkPaths.set(sysPath.resolve(path14), targetPath);
9017
9322
  }
9018
9323
  } else {
9019
9324
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
9020
9325
  }
9021
9326
  ready();
9022
9327
  if (closer)
9023
- this.fsw._addPathCloser(path13, closer);
9328
+ this.fsw._addPathCloser(path14, closer);
9024
9329
  return false;
9025
9330
  } catch (error) {
9026
9331
  if (this.fsw._handleError(error)) {
9027
9332
  ready();
9028
- return path13;
9333
+ return path14;
9029
9334
  }
9030
9335
  }
9031
9336
  }
9032
9337
  }
9033
9338
 
9034
- // ../../node_modules/.bun/chokidar@4.0.3/node_modules/chokidar/esm/index.js
9339
+ // ../../node_modules/chokidar/esm/index.js
9035
9340
  /*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */
9036
9341
  var SLASH = "/";
9037
9342
  var SLASH_SLASH = "//";
@@ -9069,26 +9374,26 @@ function createPattern(matcher) {
9069
9374
  }
9070
9375
  return () => false;
9071
9376
  }
9072
- function normalizePath(path13) {
9073
- if (typeof path13 !== "string")
9377
+ function normalizePath(path14) {
9378
+ if (typeof path14 !== "string")
9074
9379
  throw new Error("string expected");
9075
- path13 = sysPath2.normalize(path13);
9076
- path13 = path13.replace(/\\/g, "/");
9380
+ path14 = sysPath2.normalize(path14);
9381
+ path14 = path14.replace(/\\/g, "/");
9077
9382
  let prepend = false;
9078
- if (path13.startsWith("//"))
9383
+ if (path14.startsWith("//"))
9079
9384
  prepend = true;
9080
9385
  const DOUBLE_SLASH_RE2 = /\/\//;
9081
- while (path13.match(DOUBLE_SLASH_RE2))
9082
- path13 = path13.replace(DOUBLE_SLASH_RE2, "/");
9386
+ while (path14.match(DOUBLE_SLASH_RE2))
9387
+ path14 = path14.replace(DOUBLE_SLASH_RE2, "/");
9083
9388
  if (prepend)
9084
- path13 = "/" + path13;
9085
- return path13;
9389
+ path14 = "/" + path14;
9390
+ return path14;
9086
9391
  }
9087
9392
  function matchPatterns(patterns, testString, stats) {
9088
- const path13 = normalizePath(testString);
9393
+ const path14 = normalizePath(testString);
9089
9394
  for (let index = 0;index < patterns.length; index++) {
9090
9395
  const pattern = patterns[index];
9091
- if (pattern(path13, stats)) {
9396
+ if (pattern(path14, stats)) {
9092
9397
  return true;
9093
9398
  }
9094
9399
  }
@@ -9128,19 +9433,19 @@ var toUnix = (string) => {
9128
9433
  }
9129
9434
  return str;
9130
9435
  };
9131
- var normalizePathToUnix = (path13) => toUnix(sysPath2.normalize(toUnix(path13)));
9132
- var normalizeIgnored = (cwd = "") => (path13) => {
9133
- if (typeof path13 === "string") {
9134
- return normalizePathToUnix(sysPath2.isAbsolute(path13) ? path13 : sysPath2.join(cwd, path13));
9436
+ var normalizePathToUnix = (path14) => toUnix(sysPath2.normalize(toUnix(path14)));
9437
+ var normalizeIgnored = (cwd = "") => (path14) => {
9438
+ if (typeof path14 === "string") {
9439
+ return normalizePathToUnix(sysPath2.isAbsolute(path14) ? path14 : sysPath2.join(cwd, path14));
9135
9440
  } else {
9136
- return path13;
9441
+ return path14;
9137
9442
  }
9138
9443
  };
9139
- var getAbsolutePath = (path13, cwd) => {
9140
- if (sysPath2.isAbsolute(path13)) {
9141
- return path13;
9444
+ var getAbsolutePath = (path14, cwd) => {
9445
+ if (sysPath2.isAbsolute(path14)) {
9446
+ return path14;
9142
9447
  }
9143
- return sysPath2.join(cwd, path13);
9448
+ return sysPath2.join(cwd, path14);
9144
9449
  };
9145
9450
  var EMPTY_SET = Object.freeze(new Set);
9146
9451
 
@@ -9197,10 +9502,10 @@ var STAT_METHOD_F = "stat";
9197
9502
  var STAT_METHOD_L = "lstat";
9198
9503
 
9199
9504
  class WatchHelper {
9200
- constructor(path13, follow, fsw) {
9505
+ constructor(path14, follow, fsw) {
9201
9506
  this.fsw = fsw;
9202
- const watchPath = path13;
9203
- this.path = path13 = path13.replace(REPLACER_RE, "");
9507
+ const watchPath = path14;
9508
+ this.path = path14 = path14.replace(REPLACER_RE, "");
9204
9509
  this.watchPath = watchPath;
9205
9510
  this.fullWatchPath = sysPath2.resolve(watchPath);
9206
9511
  this.dirParts = [];
@@ -9313,20 +9618,20 @@ class FSWatcher extends EventEmitter {
9313
9618
  this._closePromise = undefined;
9314
9619
  let paths = unifyPaths(paths_);
9315
9620
  if (cwd) {
9316
- paths = paths.map((path13) => {
9317
- const absPath = getAbsolutePath(path13, cwd);
9621
+ paths = paths.map((path14) => {
9622
+ const absPath = getAbsolutePath(path14, cwd);
9318
9623
  return absPath;
9319
9624
  });
9320
9625
  }
9321
- paths.forEach((path13) => {
9322
- this._removeIgnoredPath(path13);
9626
+ paths.forEach((path14) => {
9627
+ this._removeIgnoredPath(path14);
9323
9628
  });
9324
9629
  this._userIgnored = undefined;
9325
9630
  if (!this._readyCount)
9326
9631
  this._readyCount = 0;
9327
9632
  this._readyCount += paths.length;
9328
- Promise.all(paths.map(async (path13) => {
9329
- const res = await this._nodeFsHandler._addToNodeFs(path13, !_internal, undefined, 0, _origAdd);
9633
+ Promise.all(paths.map(async (path14) => {
9634
+ const res = await this._nodeFsHandler._addToNodeFs(path14, !_internal, undefined, 0, _origAdd);
9330
9635
  if (res)
9331
9636
  this._emitReady();
9332
9637
  return res;
@@ -9345,17 +9650,17 @@ class FSWatcher extends EventEmitter {
9345
9650
  return this;
9346
9651
  const paths = unifyPaths(paths_);
9347
9652
  const { cwd } = this.options;
9348
- paths.forEach((path13) => {
9349
- if (!sysPath2.isAbsolute(path13) && !this._closers.has(path13)) {
9653
+ paths.forEach((path14) => {
9654
+ if (!sysPath2.isAbsolute(path14) && !this._closers.has(path14)) {
9350
9655
  if (cwd)
9351
- path13 = sysPath2.join(cwd, path13);
9352
- path13 = sysPath2.resolve(path13);
9656
+ path14 = sysPath2.join(cwd, path14);
9657
+ path14 = sysPath2.resolve(path14);
9353
9658
  }
9354
- this._closePath(path13);
9355
- this._addIgnoredPath(path13);
9356
- if (this._watched.has(path13)) {
9659
+ this._closePath(path14);
9660
+ this._addIgnoredPath(path14);
9661
+ if (this._watched.has(path14)) {
9357
9662
  this._addIgnoredPath({
9358
- path: path13,
9663
+ path: path14,
9359
9664
  recursive: true
9360
9665
  });
9361
9666
  }
@@ -9404,38 +9709,38 @@ class FSWatcher extends EventEmitter {
9404
9709
  if (event !== EVENTS.ERROR)
9405
9710
  this.emit(EVENTS.ALL, event, ...args);
9406
9711
  }
9407
- async _emit(event, path13, stats) {
9712
+ async _emit(event, path14, stats) {
9408
9713
  if (this.closed)
9409
9714
  return;
9410
9715
  const opts = this.options;
9411
9716
  if (isWindows)
9412
- path13 = sysPath2.normalize(path13);
9717
+ path14 = sysPath2.normalize(path14);
9413
9718
  if (opts.cwd)
9414
- path13 = sysPath2.relative(opts.cwd, path13);
9415
- const args = [path13];
9719
+ path14 = sysPath2.relative(opts.cwd, path14);
9720
+ const args = [path14];
9416
9721
  if (stats != null)
9417
9722
  args.push(stats);
9418
9723
  const awf = opts.awaitWriteFinish;
9419
9724
  let pw;
9420
- if (awf && (pw = this._pendingWrites.get(path13))) {
9725
+ if (awf && (pw = this._pendingWrites.get(path14))) {
9421
9726
  pw.lastChange = new Date;
9422
9727
  return this;
9423
9728
  }
9424
9729
  if (opts.atomic) {
9425
9730
  if (event === EVENTS.UNLINK) {
9426
- this._pendingUnlinks.set(path13, [event, ...args]);
9731
+ this._pendingUnlinks.set(path14, [event, ...args]);
9427
9732
  setTimeout(() => {
9428
- this._pendingUnlinks.forEach((entry, path14) => {
9733
+ this._pendingUnlinks.forEach((entry, path15) => {
9429
9734
  this.emit(...entry);
9430
9735
  this.emit(EVENTS.ALL, ...entry);
9431
- this._pendingUnlinks.delete(path14);
9736
+ this._pendingUnlinks.delete(path15);
9432
9737
  });
9433
9738
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
9434
9739
  return this;
9435
9740
  }
9436
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path13)) {
9741
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path14)) {
9437
9742
  event = EVENTS.CHANGE;
9438
- this._pendingUnlinks.delete(path13);
9743
+ this._pendingUnlinks.delete(path14);
9439
9744
  }
9440
9745
  }
9441
9746
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -9453,16 +9758,16 @@ class FSWatcher extends EventEmitter {
9453
9758
  this.emitWithAll(event, args);
9454
9759
  }
9455
9760
  };
9456
- this._awaitWriteFinish(path13, awf.stabilityThreshold, event, awfEmit);
9761
+ this._awaitWriteFinish(path14, awf.stabilityThreshold, event, awfEmit);
9457
9762
  return this;
9458
9763
  }
9459
9764
  if (event === EVENTS.CHANGE) {
9460
- const isThrottled = !this._throttle(EVENTS.CHANGE, path13, 50);
9765
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path14, 50);
9461
9766
  if (isThrottled)
9462
9767
  return this;
9463
9768
  }
9464
9769
  if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
9465
- const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path13) : path13;
9770
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path14) : path14;
9466
9771
  let stats2;
9467
9772
  try {
9468
9773
  stats2 = await stat4(fullPath);
@@ -9481,23 +9786,23 @@ class FSWatcher extends EventEmitter {
9481
9786
  }
9482
9787
  return error || this.closed;
9483
9788
  }
9484
- _throttle(actionType, path13, timeout) {
9789
+ _throttle(actionType, path14, timeout) {
9485
9790
  if (!this._throttled.has(actionType)) {
9486
9791
  this._throttled.set(actionType, new Map);
9487
9792
  }
9488
9793
  const action = this._throttled.get(actionType);
9489
9794
  if (!action)
9490
9795
  throw new Error("invalid throttle");
9491
- const actionPath = action.get(path13);
9796
+ const actionPath = action.get(path14);
9492
9797
  if (actionPath) {
9493
9798
  actionPath.count++;
9494
9799
  return false;
9495
9800
  }
9496
9801
  let timeoutObject;
9497
9802
  const clear = () => {
9498
- const item = action.get(path13);
9803
+ const item = action.get(path14);
9499
9804
  const count = item ? item.count : 0;
9500
- action.delete(path13);
9805
+ action.delete(path14);
9501
9806
  clearTimeout(timeoutObject);
9502
9807
  if (item)
9503
9808
  clearTimeout(item.timeoutObject);
@@ -9505,50 +9810,50 @@ class FSWatcher extends EventEmitter {
9505
9810
  };
9506
9811
  timeoutObject = setTimeout(clear, timeout);
9507
9812
  const thr = { timeoutObject, clear, count: 0 };
9508
- action.set(path13, thr);
9813
+ action.set(path14, thr);
9509
9814
  return thr;
9510
9815
  }
9511
9816
  _incrReadyCount() {
9512
9817
  return this._readyCount++;
9513
9818
  }
9514
- _awaitWriteFinish(path13, threshold, event, awfEmit) {
9819
+ _awaitWriteFinish(path14, threshold, event, awfEmit) {
9515
9820
  const awf = this.options.awaitWriteFinish;
9516
9821
  if (typeof awf !== "object")
9517
9822
  return;
9518
9823
  const pollInterval = awf.pollInterval;
9519
9824
  let timeoutHandler;
9520
- let fullPath = path13;
9521
- if (this.options.cwd && !sysPath2.isAbsolute(path13)) {
9522
- fullPath = sysPath2.join(this.options.cwd, path13);
9825
+ let fullPath = path14;
9826
+ if (this.options.cwd && !sysPath2.isAbsolute(path14)) {
9827
+ fullPath = sysPath2.join(this.options.cwd, path14);
9523
9828
  }
9524
9829
  const now = new Date;
9525
9830
  const writes = this._pendingWrites;
9526
9831
  function awaitWriteFinishFn(prevStat) {
9527
9832
  statcb(fullPath, (err, curStat) => {
9528
- if (err || !writes.has(path13)) {
9833
+ if (err || !writes.has(path14)) {
9529
9834
  if (err && err.code !== "ENOENT")
9530
9835
  awfEmit(err);
9531
9836
  return;
9532
9837
  }
9533
9838
  const now2 = Number(new Date);
9534
9839
  if (prevStat && curStat.size !== prevStat.size) {
9535
- writes.get(path13).lastChange = now2;
9840
+ writes.get(path14).lastChange = now2;
9536
9841
  }
9537
- const pw = writes.get(path13);
9842
+ const pw = writes.get(path14);
9538
9843
  const df = now2 - pw.lastChange;
9539
9844
  if (df >= threshold) {
9540
- writes.delete(path13);
9845
+ writes.delete(path14);
9541
9846
  awfEmit(undefined, curStat);
9542
9847
  } else {
9543
9848
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
9544
9849
  }
9545
9850
  });
9546
9851
  }
9547
- if (!writes.has(path13)) {
9548
- writes.set(path13, {
9852
+ if (!writes.has(path14)) {
9853
+ writes.set(path14, {
9549
9854
  lastChange: now,
9550
9855
  cancelWait: () => {
9551
- writes.delete(path13);
9856
+ writes.delete(path14);
9552
9857
  clearTimeout(timeoutHandler);
9553
9858
  return event;
9554
9859
  }
@@ -9556,8 +9861,8 @@ class FSWatcher extends EventEmitter {
9556
9861
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
9557
9862
  }
9558
9863
  }
9559
- _isIgnored(path13, stats) {
9560
- if (this.options.atomic && DOT_RE.test(path13))
9864
+ _isIgnored(path14, stats) {
9865
+ if (this.options.atomic && DOT_RE.test(path14))
9561
9866
  return true;
9562
9867
  if (!this._userIgnored) {
9563
9868
  const { cwd } = this.options;
@@ -9567,13 +9872,13 @@ class FSWatcher extends EventEmitter {
9567
9872
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
9568
9873
  this._userIgnored = anymatch(list, undefined);
9569
9874
  }
9570
- return this._userIgnored(path13, stats);
9875
+ return this._userIgnored(path14, stats);
9571
9876
  }
9572
- _isntIgnored(path13, stat5) {
9573
- return !this._isIgnored(path13, stat5);
9877
+ _isntIgnored(path14, stat5) {
9878
+ return !this._isIgnored(path14, stat5);
9574
9879
  }
9575
- _getWatchHelpers(path13) {
9576
- return new WatchHelper(path13, this.options.followSymlinks, this);
9880
+ _getWatchHelpers(path14) {
9881
+ return new WatchHelper(path14, this.options.followSymlinks, this);
9577
9882
  }
9578
9883
  _getWatchedDir(directory) {
9579
9884
  const dir = sysPath2.resolve(directory);
@@ -9587,57 +9892,57 @@ class FSWatcher extends EventEmitter {
9587
9892
  return Boolean(Number(stats.mode) & 256);
9588
9893
  }
9589
9894
  _remove(directory, item, isDirectory) {
9590
- const path13 = sysPath2.join(directory, item);
9591
- const fullPath = sysPath2.resolve(path13);
9592
- isDirectory = isDirectory != null ? isDirectory : this._watched.has(path13) || this._watched.has(fullPath);
9593
- if (!this._throttle("remove", path13, 100))
9895
+ const path14 = sysPath2.join(directory, item);
9896
+ const fullPath = sysPath2.resolve(path14);
9897
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path14) || this._watched.has(fullPath);
9898
+ if (!this._throttle("remove", path14, 100))
9594
9899
  return;
9595
9900
  if (!isDirectory && this._watched.size === 1) {
9596
9901
  this.add(directory, item, true);
9597
9902
  }
9598
- const wp = this._getWatchedDir(path13);
9903
+ const wp = this._getWatchedDir(path14);
9599
9904
  const nestedDirectoryChildren = wp.getChildren();
9600
- nestedDirectoryChildren.forEach((nested) => this._remove(path13, nested));
9905
+ nestedDirectoryChildren.forEach((nested) => this._remove(path14, nested));
9601
9906
  const parent = this._getWatchedDir(directory);
9602
9907
  const wasTracked = parent.has(item);
9603
9908
  parent.remove(item);
9604
9909
  if (this._symlinkPaths.has(fullPath)) {
9605
9910
  this._symlinkPaths.delete(fullPath);
9606
9911
  }
9607
- let relPath = path13;
9912
+ let relPath = path14;
9608
9913
  if (this.options.cwd)
9609
- relPath = sysPath2.relative(this.options.cwd, path13);
9914
+ relPath = sysPath2.relative(this.options.cwd, path14);
9610
9915
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
9611
9916
  const event = this._pendingWrites.get(relPath).cancelWait();
9612
9917
  if (event === EVENTS.ADD)
9613
9918
  return;
9614
9919
  }
9615
- this._watched.delete(path13);
9920
+ this._watched.delete(path14);
9616
9921
  this._watched.delete(fullPath);
9617
9922
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
9618
- if (wasTracked && !this._isIgnored(path13))
9619
- this._emit(eventName, path13);
9620
- this._closePath(path13);
9923
+ if (wasTracked && !this._isIgnored(path14))
9924
+ this._emit(eventName, path14);
9925
+ this._closePath(path14);
9621
9926
  }
9622
- _closePath(path13) {
9623
- this._closeFile(path13);
9624
- const dir = sysPath2.dirname(path13);
9625
- this._getWatchedDir(dir).remove(sysPath2.basename(path13));
9927
+ _closePath(path14) {
9928
+ this._closeFile(path14);
9929
+ const dir = sysPath2.dirname(path14);
9930
+ this._getWatchedDir(dir).remove(sysPath2.basename(path14));
9626
9931
  }
9627
- _closeFile(path13) {
9628
- const closers = this._closers.get(path13);
9932
+ _closeFile(path14) {
9933
+ const closers = this._closers.get(path14);
9629
9934
  if (!closers)
9630
9935
  return;
9631
9936
  closers.forEach((closer) => closer());
9632
- this._closers.delete(path13);
9937
+ this._closers.delete(path14);
9633
9938
  }
9634
- _addPathCloser(path13, closer) {
9939
+ _addPathCloser(path14, closer) {
9635
9940
  if (!closer)
9636
9941
  return;
9637
- let list = this._closers.get(path13);
9942
+ let list = this._closers.get(path14);
9638
9943
  if (!list) {
9639
9944
  list = [];
9640
- this._closers.set(path13, list);
9945
+ this._closers.set(path14, list);
9641
9946
  }
9642
9947
  list.push(closer);
9643
9948
  }
@@ -9668,8 +9973,8 @@ var esm_default = { watch, FSWatcher };
9668
9973
 
9669
9974
  // src/cli/cli.ts
9670
9975
  var import_picocolors9 = __toESM(require_picocolors(), 1);
9671
- import path14 from "node:path";
9672
- import { promises as fs12, existsSync } from "node:fs";
9976
+ import path15 from "node:path";
9977
+ import { promises as fs12, existsSync as existsSync2 } from "node:fs";
9673
9978
  import { spawn as spawn2, spawnSync } from "node:child_process";
9674
9979
  import { pathToFileURL as pathToFileURL4 } from "node:url";
9675
9980
  import { createRequire as createRequire3 } from "node:module";
@@ -9677,7 +9982,7 @@ import { createRequire as createRequire3 } from "node:module";
9677
9982
  // src/cli/auth-keys.ts
9678
9983
  import * as crypto2 from "crypto";
9679
9984
  import * as fs11 from "fs/promises";
9680
- import * as path13 from "path";
9985
+ import * as path14 from "path";
9681
9986
  var AUTH_KEYS_FILENAME = "auth-keys.json";
9682
9987
  async function generateAuthKeys() {
9683
9988
  return new Promise((resolve3, reject) => {
@@ -9724,7 +10029,7 @@ function createJwksFromPublicKey(publicKeyPem, kid) {
9724
10029
  };
9725
10030
  }
9726
10031
  async function loadOrGenerateAuthKeys(dataDir) {
9727
- const keysPath = path13.join(dataDir, AUTH_KEYS_FILENAME);
10032
+ const keysPath = path14.join(dataDir, AUTH_KEYS_FILENAME);
9728
10033
  try {
9729
10034
  const data = await fs11.readFile(keysPath, "utf-8");
9730
10035
  const stored = JSON.parse(data);
@@ -9751,7 +10056,7 @@ async function loadOrGenerateAuthKeys(dataDir) {
9751
10056
  }
9752
10057
  }
9753
10058
  async function detectAuthProjectFlavor(projectRoot) {
9754
- const packageJsonPath = path13.join(projectRoot, "package.json");
10059
+ const packageJsonPath = path14.join(projectRoot, "package.json");
9755
10060
  try {
9756
10061
  const raw = await fs11.readFile(packageJsonPath, "utf-8");
9757
10062
  const parsed = JSON.parse(raw);
@@ -9793,7 +10098,7 @@ function setupAuthEnvironment(keys, siteUrl, options = {}) {
9793
10098
  setEnv("AUTH_SKIP_VERIFICATION", "true");
9794
10099
  }
9795
10100
  // package.json
9796
- var version = "0.0.1-alpha.5";
10101
+ var version = "0.0.1-alpha.7";
9797
10102
 
9798
10103
  // src/cli/cli.ts
9799
10104
  var WATCH_IGNORE_PATTERNS = [
@@ -9801,6 +10106,7 @@ var WATCH_IGNORE_PATTERNS = [
9801
10106
  /(^|[/\\])\.git([/\\]|$)/,
9802
10107
  /(^|[/\\])_generated([/\\]|$)/
9803
10108
  ];
10109
+ var DEFAULT_CONVEX_VERSION_RANGE = "^1.27.3";
9804
10110
  var program2 = new Command;
9805
10111
  program2.name("concave").description("Concave development tools for Cloudflare Workers").version(version);
9806
10112
  function detectHostRuntime() {
@@ -9831,6 +10137,163 @@ function detectPreferredRuntime() {
9831
10137
  return "bun";
9832
10138
  return "node";
9833
10139
  }
10140
+ function detectPackageManager(projectRoot) {
10141
+ if (existsSync2(path15.join(projectRoot, "bun.lock")) || existsSync2(path15.join(projectRoot, "bun.lockb"))) {
10142
+ return "bun";
10143
+ }
10144
+ if (existsSync2(path15.join(projectRoot, "pnpm-lock.yaml"))) {
10145
+ return "pnpm";
10146
+ }
10147
+ if (existsSync2(path15.join(projectRoot, "yarn.lock"))) {
10148
+ return "yarn";
10149
+ }
10150
+ if (existsSync2(path15.join(projectRoot, "package-lock.json")) || existsSync2(path15.join(projectRoot, "npm-shrinkwrap.json"))) {
10151
+ return "npm";
10152
+ }
10153
+ return isBunAvailable() ? "bun" : "npm";
10154
+ }
10155
+ function getAddConvexCommand(packageManager) {
10156
+ switch (packageManager) {
10157
+ case "bun":
10158
+ return { cmd: "bun", args: ["add", "convex"], display: "bun add convex" };
10159
+ case "pnpm":
10160
+ return { cmd: "pnpm", args: ["add", "convex"], display: "pnpm add convex" };
10161
+ case "yarn":
10162
+ return { cmd: "yarn", args: ["add", "convex"], display: "yarn add convex" };
10163
+ default:
10164
+ return { cmd: "npm", args: ["install", "convex"], display: "npm install convex" };
10165
+ }
10166
+ }
10167
+ function getInstallCommand(packageManager) {
10168
+ switch (packageManager) {
10169
+ case "bun":
10170
+ return { cmd: "bun", args: ["install"], display: "bun install" };
10171
+ case "pnpm":
10172
+ return { cmd: "pnpm", args: ["install"], display: "pnpm install" };
10173
+ case "yarn":
10174
+ return { cmd: "yarn", args: ["install"], display: "yarn install" };
10175
+ default:
10176
+ return { cmd: "npm", args: ["install"], display: "npm install" };
10177
+ }
10178
+ }
10179
+ function isObjectRecord(value) {
10180
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10181
+ }
10182
+ function sanitizePackageName(input) {
10183
+ const normalized = input.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
10184
+ return normalized.length > 0 ? normalized : "concave-app";
10185
+ }
10186
+ function formatPathForDisplay(fromDir, targetPath) {
10187
+ const relative3 = path15.relative(fromDir, targetPath);
10188
+ if (!relative3 || relative3 === ".") {
10189
+ return ".";
10190
+ }
10191
+ if (!relative3.startsWith("..") && !path15.isAbsolute(relative3)) {
10192
+ return relative3;
10193
+ }
10194
+ return targetPath;
10195
+ }
10196
+ function hasConvexDependency(packageJson) {
10197
+ return !!(packageJson.dependencies?.convex || packageJson.devDependencies?.convex || packageJson.optionalDependencies?.convex || packageJson.peerDependencies?.convex);
10198
+ }
10199
+ function createDefaultPackageJson(projectRoot) {
10200
+ return {
10201
+ name: sanitizePackageName(path15.basename(projectRoot)),
10202
+ private: true,
10203
+ type: "module"
10204
+ };
10205
+ }
10206
+ async function readPackageJson(packageJsonPath) {
10207
+ if (!existsSync2(packageJsonPath)) {
10208
+ return null;
10209
+ }
10210
+ let parsed;
10211
+ try {
10212
+ const raw = await fs12.readFile(packageJsonPath, "utf8");
10213
+ parsed = JSON.parse(raw);
10214
+ } catch (error) {
10215
+ if (error instanceof SyntaxError) {
10216
+ throw new Error(`Invalid JSON in ${packageJsonPath}: ${error.message}`);
10217
+ }
10218
+ throw new Error(`Failed to read ${packageJsonPath}: ${error?.message ?? String(error)}`);
10219
+ }
10220
+ if (!isObjectRecord(parsed)) {
10221
+ throw new Error(`Invalid ${packageJsonPath}: expected a JSON object`);
10222
+ }
10223
+ return parsed;
10224
+ }
10225
+ async function writePackageJson(packageJsonPath, packageJson) {
10226
+ await fs12.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
10227
+ `, "utf8");
10228
+ }
10229
+ async function ensurePackageJsonWithConvexDependency(projectRoot) {
10230
+ const packageJsonPath = path15.join(projectRoot, "package.json");
10231
+ const existing = await readPackageJson(packageJsonPath);
10232
+ const packageJson = existing ?? createDefaultPackageJson(projectRoot);
10233
+ const createdPackageJson = existing === null;
10234
+ let addedConvexDependency = false;
10235
+ if (!hasConvexDependency(packageJson)) {
10236
+ packageJson.dependencies = {
10237
+ ...packageJson.dependencies ?? {},
10238
+ convex: DEFAULT_CONVEX_VERSION_RANGE
10239
+ };
10240
+ addedConvexDependency = true;
10241
+ }
10242
+ if (createdPackageJson || addedConvexDependency) {
10243
+ await writePackageJson(packageJsonPath, packageJson);
10244
+ }
10245
+ return {
10246
+ packageJsonPath,
10247
+ createdPackageJson,
10248
+ addedConvexDependency
10249
+ };
10250
+ }
10251
+ async function canResolveConvexRuntime(projectRoot) {
10252
+ const requireFromProject = createRequire3(path15.join(projectRoot, "__concave__.js"));
10253
+ try {
10254
+ requireFromProject.resolve("convex/values");
10255
+ requireFromProject.resolve("convex/server");
10256
+ return true;
10257
+ } catch {
10258
+ return false;
10259
+ }
10260
+ }
10261
+ function runInstallCommand(projectRoot, command) {
10262
+ const result = spawnSync(command.cmd, command.args, {
10263
+ cwd: projectRoot,
10264
+ stdio: "inherit"
10265
+ });
10266
+ if (result.error) {
10267
+ throw result.error;
10268
+ }
10269
+ if (result.status !== 0) {
10270
+ throw new Error(`"${command.display}" exited with code ${result.status ?? "unknown"}`);
10271
+ }
10272
+ }
10273
+ async function ensureConvexDependencyReady(projectRoot, commandName) {
10274
+ const packageManager = detectPackageManager(projectRoot);
10275
+ const addCommand = getAddConvexCommand(packageManager);
10276
+ const installCommand = getInstallCommand(packageManager);
10277
+ const packageJsonPath = path15.join(projectRoot, "package.json");
10278
+ const packageJson = await readPackageJson(packageJsonPath);
10279
+ if (!packageJson) {
10280
+ console.error(import_picocolors9.default.red("✗ Missing package.json"));
10281
+ console.error(import_picocolors9.default.dim(` \`concave ${commandName}\` requires the \`convex\` npm package.`));
10282
+ console.error(import_picocolors9.default.dim(` Run: ${addCommand.display}`));
10283
+ process.exit(1);
10284
+ }
10285
+ if (!hasConvexDependency(packageJson)) {
10286
+ console.error(import_picocolors9.default.red("✗ Missing dependency: convex"));
10287
+ console.error(import_picocolors9.default.dim(" Concave function files import `convex/values` and generated files import `convex/server`."));
10288
+ console.error(import_picocolors9.default.dim(` Run: ${addCommand.display}`));
10289
+ process.exit(1);
10290
+ }
10291
+ if (!await canResolveConvexRuntime(projectRoot)) {
10292
+ console.error(import_picocolors9.default.red("✗ Could not resolve installed package: convex"));
10293
+ console.error(import_picocolors9.default.dim(` Run: ${installCommand.display}`));
10294
+ process.exit(1);
10295
+ }
10296
+ }
9834
10297
  async function prepareLocalDataPaths(cwd) {
9835
10298
  const resolved = await resolveLocalDataPaths(cwd);
9836
10299
  return {
@@ -9839,7 +10302,7 @@ async function prepareLocalDataPaths(cwd) {
9839
10302
  storagePath: resolved.storagePath
9840
10303
  };
9841
10304
  }
9842
- function parseDotEnv(content) {
10305
+ function parseDotEnv2(content) {
9843
10306
  const result = {};
9844
10307
  const lines = content.split(`
9845
10308
  `);
@@ -9865,37 +10328,44 @@ function parseDotEnv(content) {
9865
10328
  }
9866
10329
  async function loadDevEnvironment(cwd, layout) {
9867
10330
  const candidates = [
9868
- path14.join(layout.convexRootDir, ".env.local"),
9869
- path14.join(layout.convexRootDir, ".env"),
9870
- path14.join(cwd, ".env.local"),
9871
- path14.join(cwd, ".env")
10331
+ path15.join(layout.convexRootDir, ".env.local"),
10332
+ path15.join(layout.convexRootDir, ".env"),
10333
+ path15.join(cwd, ".env.local"),
10334
+ path15.join(cwd, ".env")
9872
10335
  ];
9873
10336
  const loaded = [];
9874
10337
  for (const filePath of candidates) {
9875
- if (!existsSync(filePath)) {
10338
+ if (!existsSync2(filePath)) {
9876
10339
  continue;
9877
10340
  }
9878
10341
  const content = await fs12.readFile(filePath, "utf8");
9879
- const parsed = parseDotEnv(content);
10342
+ const parsed = parseDotEnv2(content);
9880
10343
  for (const [key, value] of Object.entries(parsed)) {
9881
10344
  if (process.env[key] === undefined) {
9882
10345
  process.env[key] = value;
9883
10346
  }
9884
10347
  }
9885
- loaded.push(path14.relative(cwd, filePath));
10348
+ loaded.push(path15.relative(cwd, filePath));
9886
10349
  }
9887
10350
  return loaded;
9888
10351
  }
9889
- program2.command("init").option("--force", "Overwrite starter files if they already exist").description("Initialize a Concave project (create convex/ and a starter function)").addHelpText("after", `
10352
+ program2.command("init [dir]").option("--force", "Overwrite starter files if they already exist").option("--install", "Install dependencies after scaffolding (default)").option("--no-install", "Skip installing dependencies after scaffolding").description("Initialize a Concave project (create starter files and setup dependencies)").addHelpText("after", `
9890
10353
  Examples:
9891
- $ concave init Create convex/ and a starter function
9892
- $ concave init --force Overwrite starter files
9893
- `).action(async (opts) => {
10354
+ $ concave init Initialize in current directory
10355
+ $ concave init my-app Initialize in ./my-app
10356
+ $ concave init --install Explicitly install dependencies
10357
+ $ concave init --no-install Scaffold without running package install
10358
+ $ concave init my-app --force Overwrite starter files
10359
+ `).action(async (dir, opts) => {
9894
10360
  const cwd = process.cwd();
9895
- const convexDir = path14.join(cwd, "convex");
9896
- const starterPath = path14.join(convexDir, "messages.ts");
10361
+ const projectRoot = path15.resolve(cwd, dir ?? ".");
10362
+ const displayRoot = formatPathForDisplay(cwd, projectRoot);
10363
+ const layout = await resolveProjectLayout(projectRoot);
10364
+ const convexDir = layout.functionsDir;
10365
+ const starterPath = path15.join(convexDir, "messages.ts");
10366
+ await fs12.mkdir(projectRoot, { recursive: true });
9897
10367
  await fs12.mkdir(convexDir, { recursive: true });
9898
- const starterExists = existsSync(starterPath);
10368
+ const starterExists = existsSync2(starterPath);
9899
10369
  if (!starterExists || opts.force) {
9900
10370
  const content = `import { query, mutation } from "./_generated/server";
9901
10371
  import { v } from "convex/values";
@@ -9916,12 +10386,40 @@ export const create = mutation({
9916
10386
  });
9917
10387
  `;
9918
10388
  await fs12.writeFile(starterPath, content, "utf8");
9919
- console.log(import_picocolors9.default.green(`✓ Created ${path14.relative(cwd, starterPath)}`));
10389
+ console.log(import_picocolors9.default.green(`✓ Created ${formatPathForDisplay(cwd, starterPath)}`));
9920
10390
  } else {
9921
- console.log(import_picocolors9.default.yellow(`⚠️ ${path14.relative(cwd, starterPath)} already exists (use --force to overwrite)`));
10391
+ console.log(import_picocolors9.default.yellow(`⚠️ ${formatPathForDisplay(cwd, starterPath)} already exists (use --force to overwrite)`));
10392
+ }
10393
+ const packageSetup = await ensurePackageJsonWithConvexDependency(projectRoot);
10394
+ if (packageSetup.createdPackageJson) {
10395
+ console.log(import_picocolors9.default.green(`✓ Created ${formatPathForDisplay(cwd, packageSetup.packageJsonPath)}`));
10396
+ }
10397
+ if (packageSetup.addedConvexDependency) {
10398
+ console.log(import_picocolors9.default.green(`✓ Added dependency: convex@${DEFAULT_CONVEX_VERSION_RANGE}`));
10399
+ }
10400
+ const packageManager = detectPackageManager(projectRoot);
10401
+ const installCommand = getInstallCommand(packageManager);
10402
+ const needsInstall = packageSetup.createdPackageJson || packageSetup.addedConvexDependency || !await canResolveConvexRuntime(projectRoot);
10403
+ if (opts.install !== false && needsInstall) {
10404
+ console.log(import_picocolors9.default.dim(`
10405
+ Installing dependencies with ${installCommand.display}...`));
10406
+ try {
10407
+ runInstallCommand(projectRoot, installCommand);
10408
+ console.log(import_picocolors9.default.green(`✓ Installed dependencies (${installCommand.display})`));
10409
+ } catch (error) {
10410
+ console.error(import_picocolors9.default.red(`✗ Failed to install dependencies: ${error?.message ?? String(error)}`));
10411
+ console.log(import_picocolors9.default.dim(` Run manually: ${installCommand.display}`));
10412
+ process.exit(1);
10413
+ }
10414
+ } else if (opts.install === false && needsInstall) {
10415
+ console.log(import_picocolors9.default.yellow(`⚠️ Dependencies not installed (--no-install)`));
10416
+ console.log(import_picocolors9.default.dim(` Run: ${installCommand.display}`));
9922
10417
  }
9923
10418
  console.log(import_picocolors9.default.dim(`
9924
10419
  Next steps:`));
10420
+ if (displayRoot !== ".") {
10421
+ console.log(import_picocolors9.default.dim(` cd ${displayRoot}`));
10422
+ }
9925
10423
  console.log(import_picocolors9.default.dim(" concave dev"));
9926
10424
  console.log(import_picocolors9.default.dim(" concave run messages:list"));
9927
10425
  });
@@ -9932,6 +10430,7 @@ Examples:
9932
10430
  $ concave dev --port 8080 Start dev server on port 8080
9933
10431
  `).action(async (opts) => {
9934
10432
  const cwd = process.cwd();
10433
+ await ensureConvexDependencyReady(cwd, "dev");
9935
10434
  const projectLayout = await resolveProjectLayout(cwd);
9936
10435
  try {
9937
10436
  const loadedEnvFiles = await loadDevEnvironment(cwd, projectLayout);
@@ -9981,11 +10480,14 @@ Examples:
9981
10480
  }
9982
10481
  let wranglerProcess;
9983
10482
  try {
9984
- const result = await generateWorkerEntry(cwd, { runtimeBundlePath, dashboardHtmlPath: artifacts.dashboardHtmlPath });
10483
+ const result = await generateWorkerEntry(cwd, {
10484
+ runtimeBundlePath,
10485
+ dashboardHtmlPath: artifacts.dashboardHtmlPath
10486
+ });
9985
10487
  console.log(import_picocolors9.default.green(`✓ Generated worker entry (${result.moduleCount} module${result.moduleCount === 1 ? "" : "s"})`));
9986
10488
  const configPath = await ensureWranglerConfig(cwd);
9987
- console.log(import_picocolors9.default.green(`✓ Using config: ${path14.basename(configPath)}`));
9988
- const relativeConfigPath = path14.relative(cwd, configPath);
10489
+ console.log(import_picocolors9.default.green(`✓ Using config: ${path15.basename(configPath)}`));
10490
+ const relativeConfigPath = path15.relative(cwd, configPath);
9989
10491
  const wranglerArgs = ["wrangler", "dev", "--config", relativeConfigPath];
9990
10492
  if (opts.port) {
9991
10493
  wranglerArgs.push("--port", opts.port);
@@ -10016,7 +10518,7 @@ Examples:
10016
10518
  try {
10017
10519
  await generateTypes(cwd, { silent: true });
10018
10520
  } catch {}
10019
- const relPath = path14.relative(cwd, filePath);
10521
+ const relPath = path15.relative(cwd, filePath);
10020
10522
  console.log(import_picocolors9.default.dim(` Updated worker entry (${event}: ${relPath || "convex/"}, ${regenResult.moduleCount} module${regenResult.moduleCount === 1 ? "" : "s"})`));
10021
10523
  } catch (error) {
10022
10524
  console.error(import_picocolors9.default.red("✗ Failed to update worker entry:"), error.message ?? error);
@@ -10104,6 +10606,24 @@ Examples:
10104
10606
  process.exit(1);
10105
10607
  }
10106
10608
  });
10609
+ program2.command("function-spec").option("--port <n>", "Port for the dev server", "3000").option("--url <url>", "Full URL to the dev server (overrides --port)").option("--component <path>", "Component path to inspect").option("--file", "Output as JSON to a file (function-spec.json)").description("List argument and return value specs for your Convex functions").addHelpText("after", `
10610
+ Examples:
10611
+ $ concave function-spec List all functions
10612
+ $ concave function-spec --file Output to function-spec.json
10613
+ $ concave function-spec --component presence List functions in a component
10614
+ `).action(async (opts) => {
10615
+ try {
10616
+ await listFunctionSpecs({
10617
+ port: opts.port,
10618
+ url: opts.url,
10619
+ component: opts.component,
10620
+ file: opts.file
10621
+ });
10622
+ } catch (error) {
10623
+ console.error(import_picocolors9.default.red("✗ Failed to list functions:"), error.message);
10624
+ process.exit(1);
10625
+ }
10626
+ });
10107
10627
  program2.command("codegen").option("--static", "Use static file scanning instead of runtime analysis").option("--verbose", "Show verbose output").description("Generate TypeScript type definitions for your Convex functions").addHelpText("after", `
10108
10628
  Examples:
10109
10629
  $ concave codegen Generate types using runtime analysis (default, more precise)
@@ -10111,6 +10631,7 @@ Examples:
10111
10631
  $ concave codegen --verbose Show detailed output
10112
10632
  `).action(async (opts) => {
10113
10633
  const cwd = process.cwd();
10634
+ await ensureConvexDependencyReady(cwd, "codegen");
10114
10635
  try {
10115
10636
  if (opts.static) {
10116
10637
  await generateTypes(cwd, { silent: false });
@@ -10161,7 +10682,7 @@ Examples:
10161
10682
  }
10162
10683
  try {
10163
10684
  const layout = await resolveProjectLayout(cwd);
10164
- if (!existsSync(layout.functionsDir)) {
10685
+ if (!existsSync2(layout.functionsDir)) {
10165
10686
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10166
10687
  console.log(import_picocolors9.default.dim(` Expected: ${layout.functionsDir}`));
10167
10688
  process.exit(1);
@@ -10179,10 +10700,10 @@ Examples:
10179
10700
  console.log(import_picocolors9.default.green(`✓ Generated standalone entry (${result.moduleCount} module${result.moduleCount === 1 ? "" : "s"})`));
10180
10701
  if (opts.verbose) {
10181
10702
  for (const file of result.sourceFiles) {
10182
- console.log(import_picocolors9.default.dim(` ${path14.relative(cwd, file)}`));
10703
+ console.log(import_picocolors9.default.dim(` ${path15.relative(cwd, file)}`));
10183
10704
  }
10184
10705
  }
10185
- const outfile = path14.resolve(cwd, opts.outfile);
10706
+ const outfile = path15.resolve(cwd, opts.outfile);
10186
10707
  const buildArgs = ["build", "--compile", result.entryFile, "--outfile", outfile];
10187
10708
  if (opts.target) {
10188
10709
  buildArgs.push("--target", `bun-${opts.target}`);
@@ -10212,13 +10733,13 @@ Examples:
10212
10733
  sizeStr = ` (${sizeMB} MB)`;
10213
10734
  } catch {}
10214
10735
  console.log(import_picocolors9.default.green(`
10215
- ✓ Built: ${path14.relative(cwd, outfile)}${sizeStr}`));
10736
+ ✓ Built: ${path15.relative(cwd, outfile)}${sizeStr}`));
10216
10737
  if (opts.target) {
10217
10738
  console.log(import_picocolors9.default.dim(` Target: bun-${opts.target}`));
10218
10739
  }
10219
10740
  console.log(import_picocolors9.default.dim(`
10220
10741
  Run it:`));
10221
- console.log(import_picocolors9.default.dim(` ./${path14.relative(cwd, outfile)} --port 3000`));
10742
+ console.log(import_picocolors9.default.dim(` ./${path15.relative(cwd, outfile)} --port 3000`));
10222
10743
  } catch (error) {
10223
10744
  console.error(import_picocolors9.default.red("✗ Build failed:"), error.message);
10224
10745
  if (opts.verbose && error.stack) {
@@ -10229,8 +10750,8 @@ Examples:
10229
10750
  });
10230
10751
  program2.parse();
10231
10752
  async function listComponents(options) {
10232
- const baseUrl = detectBaseUrl(options);
10233
- const executeUrl = `${baseUrl}/api/execute`;
10753
+ const baseUrlResolution = resolveBaseUrl(options);
10754
+ const executeUrl = `${baseUrlResolution.baseUrl}/api/execute`;
10234
10755
  console.log(import_picocolors9.default.cyan(`\uD83D\uDCE6 Installed Components
10235
10756
  `));
10236
10757
  try {
@@ -10240,8 +10761,9 @@ async function listComponents(options) {
10240
10761
  "Content-Type": "application/json"
10241
10762
  },
10242
10763
  body: JSON.stringify({
10243
- path: "_system/systemListComponents",
10764
+ path: "_system:systemListComponents",
10244
10765
  args: {},
10766
+ type: "query",
10245
10767
  format: "json"
10246
10768
  })
10247
10769
  });
@@ -10264,12 +10786,87 @@ async function listComponents(options) {
10264
10786
  console.log(import_picocolors9.default.dim(` Use ${import_picocolors9.default.bold("concave data --component <path>")} to view component tables`));
10265
10787
  console.log(import_picocolors9.default.dim(` Use ${import_picocolors9.default.bold("concave run --component <path> <func>")} to run component functions`));
10266
10788
  } catch (error) {
10267
- if (error.code === "ECONNREFUSED") {
10268
- console.error(import_picocolors9.default.red("✗ Could not connect to dev server"));
10269
- console.log(import_picocolors9.default.dim(` Make sure the dev server is running`));
10270
- console.log(import_picocolors9.default.dim(` Run: npx concave dev`));
10789
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
10790
+ if (connectionFailure) {
10791
+ console.error(import_picocolors9.default.red(connectionFailure.summary));
10792
+ for (const line of connectionFailure.details) {
10793
+ console.error(import_picocolors9.default.dim(` ${line}`));
10794
+ }
10271
10795
  } else {
10272
- console.error(import_picocolors9.default.red("✗ Failed to list components:"), error.message);
10796
+ const message = error instanceof Error ? error.message : String(error);
10797
+ console.error(import_picocolors9.default.red("✗ Failed to list components:"), message);
10798
+ }
10799
+ process.exit(1);
10800
+ }
10801
+ }
10802
+ async function listFunctionSpecs(options) {
10803
+ const baseUrlResolution = resolveBaseUrl(options);
10804
+ const executeUrl = `${baseUrlResolution.baseUrl}/api/execute`;
10805
+ try {
10806
+ const response = await fetch(executeUrl, {
10807
+ method: "POST",
10808
+ headers: {
10809
+ "Content-Type": "application/json"
10810
+ },
10811
+ body: JSON.stringify({
10812
+ path: "_system:systemListFunctions",
10813
+ args: options.component ? { componentPath: options.component } : {},
10814
+ type: "query",
10815
+ format: "json"
10816
+ })
10817
+ });
10818
+ if (!response.ok) {
10819
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
10820
+ }
10821
+ const result = await response.json();
10822
+ const functions = result.value || result.result || [];
10823
+ if (options.file) {
10824
+ const outPath = path15.resolve("function-spec.json");
10825
+ await fs12.writeFile(outPath, JSON.stringify(functions, null, 2) + `
10826
+ `);
10827
+ console.log(import_picocolors9.default.green(`✓ Wrote ${functions.length} function specs to ${outPath}`));
10828
+ return;
10829
+ }
10830
+ if (functions.length === 0) {
10831
+ console.log(import_picocolors9.default.dim(" No functions found"));
10832
+ return;
10833
+ }
10834
+ const header = options.component ? import_picocolors9.default.cyan(`\uD83D\uDCCB Functions in Component: ${import_picocolors9.default.bold(options.component)}
10835
+ `) : import_picocolors9.default.cyan(`\uD83D\uDCCB Functions
10836
+ `);
10837
+ console.log(header);
10838
+ const byModule = new Map;
10839
+ for (const fn of functions) {
10840
+ const mod = fn.module || fn.path?.split(":")[0] || "(unknown)";
10841
+ if (!byModule.has(mod))
10842
+ byModule.set(mod, []);
10843
+ byModule.get(mod).push(fn);
10844
+ }
10845
+ for (const [mod, fns] of byModule) {
10846
+ console.log(import_picocolors9.default.bold(` ${mod}`));
10847
+ for (const fn of fns) {
10848
+ const typeTag = fn.type === "query" ? import_picocolors9.default.blue("query") : fn.type === "mutation" ? import_picocolors9.default.yellow("mutation") : fn.type === "action" ? import_picocolors9.default.magenta("action") : import_picocolors9.default.dim(fn.type || "?");
10849
+ const vis = fn.visibility === "internal" ? import_picocolors9.default.dim(" (internal)") : "";
10850
+ console.log(` ${import_picocolors9.default.green(fn.name)} ${typeTag}${vis}`);
10851
+ if (fn.args) {
10852
+ console.log(import_picocolors9.default.dim(` args: ${JSON.stringify(fn.args)}`));
10853
+ }
10854
+ if (fn.returns) {
10855
+ console.log(import_picocolors9.default.dim(` returns: ${JSON.stringify(fn.returns)}`));
10856
+ }
10857
+ }
10858
+ console.log();
10859
+ }
10860
+ } catch (error) {
10861
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
10862
+ if (connectionFailure) {
10863
+ console.error(import_picocolors9.default.red(connectionFailure.summary));
10864
+ for (const line of connectionFailure.details) {
10865
+ console.error(import_picocolors9.default.dim(` ${line}`));
10866
+ }
10867
+ } else {
10868
+ const message = error instanceof Error ? error.message : String(error);
10869
+ console.error(import_picocolors9.default.red("✗ Failed to list functions:"), message);
10273
10870
  }
10274
10871
  process.exit(1);
10275
10872
  }
@@ -10297,7 +10894,7 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
10297
10894
  const functionsDir = resolvedLayout.functionsDir;
10298
10895
  const watchDir = resolvedLayout.convexRootDir;
10299
10896
  const port = opts.port ? parseInt(opts.port, 10) : config.port ?? 3000;
10300
- if (!existsSync(functionsDir)) {
10897
+ if (!existsSync2(functionsDir)) {
10301
10898
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10302
10899
  console.log(import_picocolors9.default.dim(" Create a Convex functions directory with your UDF files"));
10303
10900
  console.log(import_picocolors9.default.dim(` Expected location: ${functionsDir}`));
@@ -10337,7 +10934,7 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
10337
10934
  console.log(import_picocolors9.default.cyan(`
10338
10935
  \uD83D\uDE80 Server ready at ${import_picocolors9.default.bold(displayUrl)}`));
10339
10936
  console.log(import_picocolors9.default.dim(` Dashboard: ${displayUrl}/_dashboard`));
10340
- console.log(import_picocolors9.default.dim(` Functions: ${path14.relative(cwd, functionsDir)}/`));
10937
+ console.log(import_picocolors9.default.dim(` Functions: ${path15.relative(cwd, functionsDir)}/`));
10341
10938
  console.log(import_picocolors9.default.dim(`
10342
10939
  Press Ctrl+C to stop
10343
10940
  `));
@@ -10374,13 +10971,13 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
10374
10971
  persistent: true
10375
10972
  });
10376
10973
  let reloadTimer;
10377
- const scheduleReload = (event, filePath) => {
10974
+ const scheduleReload = (_event, filePath) => {
10378
10975
  if (reloadTimer) {
10379
10976
  clearTimeout(reloadTimer);
10380
10977
  }
10381
10978
  reloadTimer = setTimeout(async () => {
10382
10979
  reloadTimer = undefined;
10383
- const relPath = path14.relative(cwd, filePath);
10980
+ const relPath = path15.relative(cwd, filePath);
10384
10981
  try {
10385
10982
  await generateTypes(cwd, { silent: true });
10386
10983
  } catch {}
@@ -10428,7 +11025,7 @@ async function runBunDevServerForked(cwd, opts, artifacts, layout) {
10428
11025
  const functionsDir = layout.functionsDir;
10429
11026
  const convexDir = layout.convexRootDir;
10430
11027
  const port = opts.port ? parseInt(opts.port, 10) : config.port ?? 3000;
10431
- if (!existsSync(functionsDir)) {
11028
+ if (!existsSync2(functionsDir)) {
10432
11029
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10433
11030
  console.log(import_picocolors9.default.dim(" Create a Convex functions directory with your UDF files"));
10434
11031
  console.log(import_picocolors9.default.dim(` Expected location: ${functionsDir}`));
@@ -10448,7 +11045,7 @@ async function runBunDevServerForked(cwd, opts, artifacts, layout) {
10448
11045
  } catch (error) {
10449
11046
  console.warn(import_picocolors9.default.yellow(`⚠️ Auth keys setup failed: ${error.message}`));
10450
11047
  }
10451
- const tempScriptPath = path14.join(localData.dataDir, ".bun-dev-server.js");
11048
+ const tempScriptPath = path15.join(localData.dataDir, ".bun-dev-server.js");
10452
11049
  const dashboardModulePath = artifacts.dashboardHtmlPath.replace(/\\/g, "/");
10453
11050
  const scriptContent = `import { BunServer } from "${artifacts.bunRuntime.serverEntryPath.replace(/\\/g, "/")}";
10454
11051
  import { DASHBOARD_HTML } from ${JSON.stringify(dashboardModulePath)};
@@ -10465,7 +11062,7 @@ const displayUrl = server.url.replace(/127\\.0\\.0\\.1|0\\.0\\.0\\.0/, "localhos
10465
11062
 
10466
11063
  console.log("\\n\uD83D\uDE80 Server ready at " + displayUrl);
10467
11064
  console.log(" Dashboard: " + displayUrl + "/_dashboard");
10468
- console.log(" Functions: ${path14.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
11065
+ console.log(" Functions: ${path15.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
10469
11066
  console.log("\\n Press Ctrl+C to stop\\n");
10470
11067
 
10471
11068
  // Handle graceful shutdown
@@ -10539,7 +11136,7 @@ function hasTsxLoader() {
10539
11136
  const arg = argv[i];
10540
11137
  if (arg === "--import") {
10541
11138
  const next = argv[i + 1];
10542
- if (next && next.includes("tsx")) {
11139
+ if (next?.includes("tsx")) {
10543
11140
  return true;
10544
11141
  }
10545
11142
  i++;
@@ -10556,7 +11153,7 @@ function resolveTsxLoaderPath() {
10556
11153
  let tsxLoaderPath = "tsx";
10557
11154
  try {
10558
11155
  const tsxPackagePath = require2.resolve("tsx/package.json");
10559
- tsxLoaderPath = path14.join(path14.dirname(tsxPackagePath), "dist/loader.mjs");
11156
+ tsxLoaderPath = path15.join(path15.dirname(tsxPackagePath), "dist/loader.mjs");
10560
11157
  } catch {
10561
11158
  tsxLoaderPath = "tsx";
10562
11159
  }
@@ -10604,7 +11201,7 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
10604
11201
  const functionsDir = resolvedLayout.functionsDir;
10605
11202
  const watchDir = resolvedLayout.convexRootDir;
10606
11203
  const port = opts.port ? parseInt(opts.port, 10) : config.port ?? 3000;
10607
- if (!existsSync(functionsDir)) {
11204
+ if (!existsSync2(functionsDir)) {
10608
11205
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10609
11206
  console.log(import_picocolors9.default.dim(" Create a Convex functions directory with your UDF files"));
10610
11207
  console.log(import_picocolors9.default.dim(` Expected location: ${functionsDir}`));
@@ -10644,7 +11241,7 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
10644
11241
  console.log(import_picocolors9.default.cyan(`
10645
11242
  \uD83D\uDE80 Server ready at ${import_picocolors9.default.bold(displayUrl)}`));
10646
11243
  console.log(import_picocolors9.default.dim(` Dashboard: ${displayUrl}/_dashboard`));
10647
- console.log(import_picocolors9.default.dim(` Functions: ${path14.relative(cwd, functionsDir)}/`));
11244
+ console.log(import_picocolors9.default.dim(` Functions: ${path15.relative(cwd, functionsDir)}/`));
10648
11245
  console.log(import_picocolors9.default.dim(`
10649
11246
  Press Ctrl+C to stop
10650
11247
  `));
@@ -10681,13 +11278,13 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
10681
11278
  persistent: true
10682
11279
  });
10683
11280
  let reloadTimer;
10684
- const scheduleReload = (event, filePath) => {
11281
+ const scheduleReload = (_event, filePath) => {
10685
11282
  if (reloadTimer) {
10686
11283
  clearTimeout(reloadTimer);
10687
11284
  }
10688
11285
  reloadTimer = setTimeout(async () => {
10689
11286
  reloadTimer = undefined;
10690
- const relPath = path14.relative(cwd, filePath);
11287
+ const relPath = path15.relative(cwd, filePath);
10691
11288
  try {
10692
11289
  await generateTypes(cwd, { silent: true });
10693
11290
  } catch {}
@@ -10735,7 +11332,7 @@ async function runNodeDevServerForked(cwd, opts, artifacts, layout) {
10735
11332
  const convexDir = layout.convexRootDir;
10736
11333
  const functionsDir = layout.functionsDir;
10737
11334
  const port = opts.port ? parseInt(opts.port, 10) : config.port ?? 3000;
10738
- if (!existsSync(functionsDir)) {
11335
+ if (!existsSync2(functionsDir)) {
10739
11336
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10740
11337
  console.log(import_picocolors9.default.dim(" Create a Convex functions directory with your UDF files"));
10741
11338
  console.log(import_picocolors9.default.dim(` Expected location: ${functionsDir}`));
@@ -10759,11 +11356,11 @@ async function runNodeDevServerForked(cwd, opts, artifacts, layout) {
10759
11356
  let tsxLoaderPath;
10760
11357
  try {
10761
11358
  const tsxPackagePath = require2.resolve("tsx/package.json");
10762
- tsxLoaderPath = path14.join(path14.dirname(tsxPackagePath), "dist/loader.mjs");
11359
+ tsxLoaderPath = path15.join(path15.dirname(tsxPackagePath), "dist/loader.mjs");
10763
11360
  } catch {
10764
11361
  tsxLoaderPath = "tsx";
10765
11362
  }
10766
- const tempScriptPath = path14.join(localData.dataDir, ".node-dev-server.mjs");
11363
+ const tempScriptPath = path15.join(localData.dataDir, ".node-dev-server.mjs");
10767
11364
  const nodeDashboardModulePath = artifacts.dashboardHtmlPath.replace(/\\/g, "/");
10768
11365
  const scriptContent = `import { NodeServer } from "${artifacts.nodeRuntime.serverEntryPath.replace(/\\/g, "/")}";
10769
11366
  import { DASHBOARD_HTML } from ${JSON.stringify(nodeDashboardModulePath)};
@@ -10780,7 +11377,7 @@ const displayUrl = server.url.replace(/127\\.0\\.0\\.1|0\\.0\\.0\\.0/, "localhos
10780
11377
 
10781
11378
  console.log("\\n\uD83D\uDE80 Server ready at " + displayUrl);
10782
11379
  console.log(" Dashboard: " + displayUrl + "/_dashboard");
10783
- console.log(" Functions: ${path14.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
11380
+ console.log(" Functions: ${path15.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
10784
11381
  console.log("\\n Press Ctrl+C to stop\\n");
10785
11382
 
10786
11383
  // Handle graceful shutdown
@@ -10805,12 +11402,7 @@ process.on("SIGTERM", async () => {
10805
11402
  });
10806
11403
  `;
10807
11404
  await fs12.writeFile(tempScriptPath, scriptContent, "utf8");
10808
- const nodeArgs = [
10809
- "--experimental-sqlite",
10810
- "--import",
10811
- tsxLoaderPath,
10812
- tempScriptPath
10813
- ];
11405
+ const nodeArgs = ["--experimental-sqlite", "--import", tsxLoaderPath, tempScriptPath];
10814
11406
  const executable = detectHostRuntime() === "node" ? process.execPath : "node";
10815
11407
  const nodeProcess = spawn2(executable, nodeArgs, {
10816
11408
  cwd,
@@ -10829,9 +11421,9 @@ process.on("SIGTERM", async () => {
10829
11421
  }
10830
11422
  async function ensureWranglerConfig(cwd) {
10831
11423
  const userConfigs = [
10832
- path14.join(cwd, "wrangler.jsonc"),
10833
- path14.join(cwd, "wrangler.json"),
10834
- path14.join(cwd, "wrangler.toml")
11424
+ path15.join(cwd, "wrangler.jsonc"),
11425
+ path15.join(cwd, "wrangler.json"),
11426
+ path15.join(cwd, "wrangler.toml")
10835
11427
  ];
10836
11428
  for (const configPath of userConfigs) {
10837
11429
  try {
@@ -10840,8 +11432,8 @@ async function ensureWranglerConfig(cwd) {
10840
11432
  } catch {}
10841
11433
  }
10842
11434
  const concavePaths = getConcaveProjectPaths(cwd);
10843
- const generatedConfigPath = path14.join(concavePaths.concaveDir, "wrangler.jsonc");
10844
- const assetsDirectory = path14.join(concavePaths.concaveDir, "static");
11435
+ const generatedConfigPath = path15.join(concavePaths.concaveDir, "wrangler.jsonc");
11436
+ const assetsDirectory = path15.join(concavePaths.concaveDir, "static");
10845
11437
  await fs12.mkdir(assetsDirectory, { recursive: true });
10846
11438
  const config = {
10847
11439
  name: "concave-app",
@@ -10849,7 +11441,6 @@ async function ensureWranglerConfig(cwd) {
10849
11441
  compatibility_date: "2025-10-01",
10850
11442
  compatibility_flags: ["enable_ctx_exports", "nodejs_compat", "nodejs_als"],
10851
11443
  assets: {
10852
- binding: "DASHBOARD_ASSETS",
10853
11444
  directory: "./static"
10854
11445
  },
10855
11446
  durable_objects: {
@@ -10863,22 +11454,9 @@ async function ensureWranglerConfig(cwd) {
10863
11454
  tag: "concave-v1",
10864
11455
  new_sqlite_classes: ["ConcaveDO", "SyncDO"]
10865
11456
  }
10866
- ],
10867
- d1_databases: [
10868
- {
10869
- binding: "DB",
10870
- database_name: "concave-db",
10871
- database_id: "REPLACE_ME"
10872
- }
10873
- ],
10874
- r2_buckets: [
10875
- {
10876
- binding: "STORAGE_BUCKET",
10877
- bucket_name: "concave-storage"
10878
- }
10879
11457
  ]
10880
11458
  };
10881
- await fs12.mkdir(path14.dirname(generatedConfigPath), { recursive: true });
11459
+ await fs12.mkdir(path15.dirname(generatedConfigPath), { recursive: true });
10882
11460
  await fs12.writeFile(generatedConfigPath, JSON.stringify(config, null, 2), "utf8");
10883
11461
  return generatedConfigPath;
10884
11462
  }