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

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",
@@ -6599,7 +6702,7 @@ async function verifyBundle(bundle) {
6599
6702
 
6600
6703
  // src/cli/deploy/index.ts
6601
6704
  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", `
6705
+ 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
6706
  Examples:
6604
6707
  $ concave deploy Deploy with interactive setup (first time)
6605
6708
  $ concave deploy Redeploy to configured target
@@ -6671,8 +6774,8 @@ async function runDeploy(projectRoot, options) {
6671
6774
  dryRun: options.dryRun,
6672
6775
  yes: options.yes,
6673
6776
  verbose: options.verbose,
6674
- noDb: options.db === false,
6675
- noStorage: options.storage === false,
6777
+ docstore: options.docstore,
6778
+ blobstore: options.blobstore,
6676
6779
  force: options.force,
6677
6780
  reset: options.reset
6678
6781
  });
@@ -6682,27 +6785,220 @@ async function runDeploy(projectRoot, options) {
6682
6785
  var import_picocolors5 = __toESM(require_picocolors(), 1);
6683
6786
 
6684
6787
  // src/cli/url-utils.ts
6685
- function detectBaseUrl(options) {
6788
+ import { existsSync, readFileSync } from "node:fs";
6789
+ import path11 from "node:path";
6790
+ var URL_ENV_KEYS = [
6791
+ "CONCAVE_URL",
6792
+ "CONVEX_URL",
6793
+ "NEXT_PUBLIC_CONCAVE_URL",
6794
+ "NEXT_PUBLIC_CONVEX_URL",
6795
+ "CONCAVE_SITE_URL",
6796
+ "CONVEX_SITE_URL",
6797
+ "NEXT_PUBLIC_CONCAVE_SITE_URL",
6798
+ "NEXT_PUBLIC_CONVEX_SITE_URL",
6799
+ "NEXT_PUBLIC_SITE_URL",
6800
+ "SITE_URL"
6801
+ ];
6802
+ var NETWORK_ERROR_CODES = new Set([
6803
+ "ECONNREFUSED",
6804
+ "ConnectionRefused",
6805
+ "ENOTFOUND",
6806
+ "EAI_AGAIN",
6807
+ "ETIMEDOUT",
6808
+ "EHOSTUNREACH",
6809
+ "ECONNRESET",
6810
+ "UND_ERR_CONNECT_TIMEOUT",
6811
+ "UND_ERR_SOCKET",
6812
+ "UND_ERR_HEADERS_TIMEOUT"
6813
+ ]);
6814
+ function resolveBaseUrl(options, cwd = process.cwd()) {
6686
6815
  if (options.url) {
6687
- return normalizeUrl(options.url);
6816
+ return {
6817
+ baseUrl: normalizeUrl(options.url),
6818
+ source: "url-option",
6819
+ sourceDetail: "--url"
6820
+ };
6688
6821
  }
6689
- if (process.env.CONCAVE_URL) {
6690
- return normalizeUrl(process.env.CONCAVE_URL);
6822
+ for (const key of URL_ENV_KEYS) {
6823
+ const value = process.env[key];
6824
+ if (value) {
6825
+ return {
6826
+ baseUrl: normalizeUrl(value),
6827
+ source: "environment",
6828
+ sourceDetail: key
6829
+ };
6830
+ }
6691
6831
  }
6692
- if (process.env.CONVEX_URL) {
6693
- return normalizeUrl(process.env.CONVEX_URL);
6832
+ const fromFiles = getUrlFromEnvFiles(cwd);
6833
+ if (fromFiles) {
6834
+ return {
6835
+ baseUrl: normalizeUrl(fromFiles.value),
6836
+ source: "environment-file",
6837
+ sourceDetail: `${fromFiles.key} from ${path11.relative(cwd, fromFiles.filePath) || path11.basename(fromFiles.filePath)}`
6838
+ };
6694
6839
  }
6695
6840
  const port = options.port || "3000";
6696
- return `http://localhost:${port}`;
6841
+ return {
6842
+ baseUrl: `http://localhost:${port}`,
6843
+ source: "default-port",
6844
+ sourceDetail: `localhost:${port}${options.port ? "" : " (default)"}`
6845
+ };
6846
+ }
6847
+ function formatBaseUrlSource(resolution) {
6848
+ switch (resolution.source) {
6849
+ case "url-option":
6850
+ return "the --url flag";
6851
+ case "environment":
6852
+ return `environment variable ${resolution.sourceDetail}`;
6853
+ case "environment-file":
6854
+ return resolution.sourceDetail;
6855
+ case "default-port":
6856
+ return `default local fallback (${resolution.sourceDetail})`;
6857
+ }
6858
+ }
6859
+ function describeConnectionFailure(error, resolution, executeUrl) {
6860
+ const code = extractErrorCode(error);
6861
+ const message = extractErrorMessage(error);
6862
+ const lower = message.toLowerCase();
6863
+ 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");
6864
+ if (!isNetworkFailure) {
6865
+ return null;
6866
+ }
6867
+ const details = [`Attempted endpoint: ${executeUrl}`, `URL resolved from: ${formatBaseUrlSource(resolution)}`];
6868
+ if (code) {
6869
+ details.push(`Network error code: ${code}`);
6870
+ }
6871
+ if (message && message.toLowerCase() !== "fetch failed") {
6872
+ details.push(`Network error: ${message}`);
6873
+ }
6874
+ details.push("Set the target explicitly with --url <url> or --port <n>.");
6875
+ details.push("Or set CONCAVE_URL / CONVEX_URL in your shell or .env.local.");
6876
+ details.push("Start a local server with: concave dev");
6877
+ return {
6878
+ summary: `✗ Could not connect to a Concave instance at ${resolution.baseUrl}`,
6879
+ details
6880
+ };
6697
6881
  }
6698
6882
  function normalizeUrl(url) {
6699
6883
  let normalized = url.trim();
6700
6884
  if (!normalized.startsWith("http://") && !normalized.startsWith("https://")) {
6701
- normalized = `https://${normalized}`;
6885
+ const host = normalized.split("/")[0].split(":")[0];
6886
+ if (host === "localhost" || host === "127.0.0.1" || host === "[::1]") {
6887
+ normalized = `http://${normalized}`;
6888
+ } else {
6889
+ normalized = `https://${normalized}`;
6890
+ }
6702
6891
  }
6703
6892
  normalized = normalized.replace(/\/+$/, "");
6704
6893
  return normalized;
6705
6894
  }
6895
+ function getUrlFromEnvFiles(cwd) {
6896
+ const envFiles = getEnvFileCandidates(cwd);
6897
+ const merged = new Map;
6898
+ for (const filePath of envFiles) {
6899
+ if (!existsSync(filePath)) {
6900
+ continue;
6901
+ }
6902
+ const parsed = parseDotEnv(readFileSync(filePath, "utf8"));
6903
+ for (const [key, value] of Object.entries(parsed)) {
6904
+ if (!merged.has(key)) {
6905
+ merged.set(key, { value, filePath });
6906
+ }
6907
+ }
6908
+ }
6909
+ for (const key of URL_ENV_KEYS) {
6910
+ const entry = merged.get(key);
6911
+ if (entry?.value) {
6912
+ return {
6913
+ key,
6914
+ value: entry.value,
6915
+ filePath: entry.filePath
6916
+ };
6917
+ }
6918
+ }
6919
+ return null;
6920
+ }
6921
+ function getEnvFileCandidates(cwd) {
6922
+ const convexRoot = detectConvexRoot(cwd);
6923
+ const candidates = [
6924
+ path11.join(convexRoot, ".env.local"),
6925
+ path11.join(convexRoot, ".env"),
6926
+ path11.join(cwd, ".env.local"),
6927
+ path11.join(cwd, ".env")
6928
+ ];
6929
+ return [...new Set(candidates)];
6930
+ }
6931
+ function detectConvexRoot(cwd) {
6932
+ const convexJsonPath = path11.join(cwd, "convex.json");
6933
+ const fallback = path11.join(cwd, "convex");
6934
+ if (!existsSync(convexJsonPath)) {
6935
+ return fallback;
6936
+ }
6937
+ try {
6938
+ const raw = JSON.parse(readFileSync(convexJsonPath, "utf8"));
6939
+ if (typeof raw?.functions !== "string") {
6940
+ return fallback;
6941
+ }
6942
+ const normalized = raw.functions.replace(/\\/g, "/").replace(/\/+$/, "").trim();
6943
+ if (!normalized) {
6944
+ return fallback;
6945
+ }
6946
+ const root = normalized.includes("/") ? path11.posix.dirname(normalized) : normalized;
6947
+ if (!root || root === ".") {
6948
+ return fallback;
6949
+ }
6950
+ return path11.resolve(cwd, root);
6951
+ } catch {
6952
+ return fallback;
6953
+ }
6954
+ }
6955
+ function parseDotEnv(content) {
6956
+ const result = {};
6957
+ const lines = content.split(`
6958
+ `);
6959
+ for (const line of lines) {
6960
+ const trimmed = line.trim();
6961
+ if (!trimmed || trimmed.startsWith("#")) {
6962
+ continue;
6963
+ }
6964
+ const match = trimmed.match(/^(?:export\s+)?([^=]+)=(.*)$/);
6965
+ if (!match) {
6966
+ continue;
6967
+ }
6968
+ const key = match[1].trim();
6969
+ let value = match[2].trim();
6970
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
6971
+ value = value.slice(1, -1);
6972
+ }
6973
+ value = value.replace(/\\n/g, `
6974
+ `).replace(/\\r/g, "\r").replace(/\\t/g, "\t");
6975
+ result[key] = value;
6976
+ }
6977
+ return result;
6978
+ }
6979
+ function extractErrorCode(error) {
6980
+ let cursor = error;
6981
+ for (let i = 0;i < 5 && cursor; i++) {
6982
+ if (typeof cursor.code === "string" && cursor.code.length > 0) {
6983
+ return cursor.code;
6984
+ }
6985
+ cursor = cursor.cause;
6986
+ }
6987
+ return;
6988
+ }
6989
+ function extractErrorMessage(error) {
6990
+ if (error instanceof Error) {
6991
+ return error.message || String(error);
6992
+ }
6993
+ if (typeof error === "string") {
6994
+ return error;
6995
+ }
6996
+ try {
6997
+ return JSON.stringify(error);
6998
+ } catch {
6999
+ return String(error);
7000
+ }
7001
+ }
6706
7002
 
6707
7003
  // src/cli/run.ts
6708
7004
  function isErrorResponse(response) {
@@ -6719,9 +7015,8 @@ async function runFunction(functionName, argsJson, options) {
6719
7015
  process.exit(1);
6720
7016
  }
6721
7017
  }
6722
- const baseUrl = detectBaseUrl(options);
6723
- const executeUrl = `${baseUrl}/api/execute`;
6724
- const normalizedPath = functionName.replace(/:/g, "/");
7018
+ const baseUrlResolution = resolveBaseUrl(options);
7019
+ const executeUrl = `${baseUrlResolution.baseUrl}/api/execute`;
6725
7020
  console.log(import_picocolors5.default.cyan(`\uD83D\uDE80 Running ${import_picocolors5.default.bold(functionName)}`));
6726
7021
  if (options.component) {
6727
7022
  console.log(import_picocolors5.default.dim(` Component: ${options.component}`));
@@ -6738,7 +7033,7 @@ async function runFunction(functionName, argsJson, options) {
6738
7033
  "Content-Type": "application/json"
6739
7034
  },
6740
7035
  body: JSON.stringify({
6741
- path: normalizedPath,
7036
+ path: functionName,
6742
7037
  args,
6743
7038
  format: "json",
6744
7039
  componentPath: options.component
@@ -6779,12 +7074,15 @@ async function runFunction(functionName, argsJson, options) {
6779
7074
  console.log(formatResult(result));
6780
7075
  }
6781
7076
  } 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`));
7077
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
7078
+ if (connectionFailure) {
7079
+ console.error(import_picocolors5.default.red(connectionFailure.summary));
7080
+ for (const line of connectionFailure.details) {
7081
+ console.error(import_picocolors5.default.dim(` ${line}`));
7082
+ }
6786
7083
  } else {
6787
- console.error(import_picocolors5.default.red("✗ Request failed:"), error.message);
7084
+ const message = error instanceof Error ? error.message : String(error);
7085
+ console.error(import_picocolors5.default.red("✗ Request failed:"), message);
6788
7086
  }
6789
7087
  process.exit(1);
6790
7088
  }
@@ -6820,17 +7118,17 @@ function isErrorResponse2(response) {
6820
7118
  return response.status === "error";
6821
7119
  }
6822
7120
  async function browseData(tableName, options) {
6823
- const baseUrl = detectBaseUrl(options);
6824
- const executeUrl = `${baseUrl}/api/execute`;
7121
+ const baseUrlResolution = resolveBaseUrl(options);
7122
+ const executeUrl = `${baseUrlResolution.baseUrl}/api/execute`;
6825
7123
  const componentPath = options.component;
6826
7124
  if (!tableName) {
6827
- await listTables(executeUrl, componentPath);
7125
+ await listTables(executeUrl, baseUrlResolution, componentPath);
6828
7126
  } else {
6829
7127
  const limit = options.limit ? parseInt(options.limit, 10) : 10;
6830
- await showTableData(executeUrl, tableName, limit, componentPath);
7128
+ await showTableData(executeUrl, baseUrlResolution, tableName, limit, componentPath);
6831
7129
  }
6832
7130
  }
6833
- async function listTables(executeUrl, componentPath) {
7131
+ async function listTables(executeUrl, baseUrlResolution, componentPath) {
6834
7132
  const header = componentPath ? import_picocolors6.default.cyan(`\uD83D\uDCCA Tables in Component: ${import_picocolors6.default.bold(componentPath)}
6835
7133
  `) : import_picocolors6.default.cyan(`\uD83D\uDCCA Database Tables
6836
7134
  `);
@@ -6842,8 +7140,9 @@ async function listTables(executeUrl, componentPath) {
6842
7140
  "Content-Type": "application/json"
6843
7141
  },
6844
7142
  body: JSON.stringify({
6845
- path: "_system/systemListTables",
7143
+ path: "_system:systemListTables",
6846
7144
  args: componentPath ? { componentPath } : {},
7145
+ type: "query",
6847
7146
  format: "json"
6848
7147
  })
6849
7148
  });
@@ -6865,17 +7164,20 @@ async function listTables(executeUrl, componentPath) {
6865
7164
  console.log(import_picocolors6.default.dim(`
6866
7165
  Use ${import_picocolors6.default.bold(`concave data <table>${componentHint}`)} to view table contents`));
6867
7166
  } 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`));
7167
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
7168
+ if (connectionFailure) {
7169
+ console.error(import_picocolors6.default.red(connectionFailure.summary));
7170
+ for (const line of connectionFailure.details) {
7171
+ console.error(import_picocolors6.default.dim(` ${line}`));
7172
+ }
6872
7173
  } else {
6873
- console.error(import_picocolors6.default.red("✗ Failed to list tables:"), error.message);
7174
+ const message = error instanceof Error ? error.message : String(error);
7175
+ console.error(import_picocolors6.default.red("✗ Failed to list tables:"), message);
6874
7176
  }
6875
7177
  process.exit(1);
6876
7178
  }
6877
7179
  }
6878
- async function showTableData(executeUrl, tableName, limit, componentPath) {
7180
+ async function showTableData(executeUrl, baseUrlResolution, tableName, limit, componentPath) {
6879
7181
  const header = componentPath ? import_picocolors6.default.cyan(`\uD83D\uDCCA Table: ${import_picocolors6.default.bold(tableName)} (Component: ${componentPath})
6880
7182
  `) : import_picocolors6.default.cyan(`\uD83D\uDCCA Table: ${import_picocolors6.default.bold(tableName)}
6881
7183
  `);
@@ -6887,13 +7189,14 @@ async function showTableData(executeUrl, tableName, limit, componentPath) {
6887
7189
  "Content-Type": "application/json"
6888
7190
  },
6889
7191
  body: JSON.stringify({
6890
- path: "_system/systemGetTableData",
7192
+ path: "_system:systemGetTableData",
6891
7193
  args: {
6892
7194
  tableName,
6893
7195
  componentPath,
6894
7196
  page: 1,
6895
7197
  pageSize: limit
6896
7198
  },
7199
+ type: "query",
6897
7200
  format: "json"
6898
7201
  })
6899
7202
  });
@@ -6940,12 +7243,15 @@ async function showTableData(executeUrl, tableName, limit, componentPath) {
6940
7243
  Showing first ${limit} documents. Use --limit to see more.`));
6941
7244
  }
6942
7245
  } 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`));
7246
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
7247
+ if (connectionFailure) {
7248
+ console.error(import_picocolors6.default.red(connectionFailure.summary));
7249
+ for (const line of connectionFailure.details) {
7250
+ console.error(import_picocolors6.default.dim(` ${line}`));
7251
+ }
6947
7252
  } else {
6948
- console.error(import_picocolors6.default.red("✗ Failed to query table:"), error.message);
7253
+ const message = error instanceof Error ? error.message : String(error);
7254
+ console.error(import_picocolors6.default.red("✗ Failed to query table:"), message);
6949
7255
  }
6950
7256
  process.exit(1);
6951
7257
  }
@@ -6994,11 +7300,11 @@ function formatValue(value) {
6994
7300
  // src/cli/type-codegen.ts
6995
7301
  var import_picocolors7 = __toESM(require_picocolors(), 1);
6996
7302
  import { promises as fs9 } from "node:fs";
6997
- import path11 from "node:path";
7303
+ import path12 from "node:path";
6998
7304
  async function generateTypes(projectRoot, options = {}) {
6999
7305
  const layout = await resolveProjectLayout(projectRoot);
7000
7306
  const convexDir = layout.functionsDir;
7001
- const generatedDir = path11.join(convexDir, "_generated");
7307
+ const generatedDir = path12.join(convexDir, "_generated");
7002
7308
  try {
7003
7309
  await fs9.access(convexDir);
7004
7310
  } catch {
@@ -7027,7 +7333,7 @@ async function discoverModules(convexDir) {
7027
7333
  if (entry.name.startsWith(".") || entry.name === "_generated" || entry.name === "node_modules") {
7028
7334
  continue;
7029
7335
  }
7030
- const fullPath = path11.join(dir, entry.name);
7336
+ const fullPath = path12.join(dir, entry.name);
7031
7337
  const entryRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
7032
7338
  if (entry.isDirectory()) {
7033
7339
  await walk(fullPath, entryRelativePath);
@@ -7200,7 +7506,7 @@ export type DatabaseReader = GenericDatabaseReader<DataModel>;
7200
7506
  */
7201
7507
  export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
7202
7508
  `;
7203
- await fs9.writeFile(path11.join(generatedDir, "server.d.ts"), content, "utf8");
7509
+ await fs9.writeFile(path12.join(generatedDir, "server.d.ts"), content, "utf8");
7204
7510
  }
7205
7511
  async function generateServerJs(generatedDir) {
7206
7512
  const content = `/* eslint-disable */
@@ -7293,7 +7599,7 @@ export const internalAction = internalActionGeneric;
7293
7599
  */
7294
7600
  export const httpAction = httpActionGeneric;
7295
7601
  `;
7296
- await fs9.writeFile(path11.join(generatedDir, "server.js"), content, "utf8");
7602
+ await fs9.writeFile(path12.join(generatedDir, "server.js"), content, "utf8");
7297
7603
  }
7298
7604
  async function generateDataModelTypes(generatedDir, hasSchema) {
7299
7605
  const content = `/* eslint-disable */
@@ -7357,7 +7663,7 @@ export type Id<TableName extends TableNames | SystemTableNames> =
7357
7663
  */
7358
7664
  ${hasSchema ? "export type DataModel = DataModelFromSchemaDefinition<typeof schema>;" : "export type DataModel = any;"}
7359
7665
  `;
7360
- await fs9.writeFile(path11.join(generatedDir, "dataModel.d.ts"), content, "utf8");
7666
+ await fs9.writeFile(path12.join(generatedDir, "dataModel.d.ts"), content, "utf8");
7361
7667
  }
7362
7668
  async function generateApiTypes(generatedDir, modules, _hasSchema) {
7363
7669
  const apiModules = modules.filter((m) => m.name !== "schema" && !m.name.startsWith("_") && m.name !== "http");
@@ -7415,7 +7721,7 @@ export declare const internal: FilterApi<
7415
7721
 
7416
7722
  export declare const components: AnyComponents;
7417
7723
  `;
7418
- await fs9.writeFile(path11.join(generatedDir, "api.d.ts"), content, "utf8");
7724
+ await fs9.writeFile(path12.join(generatedDir, "api.d.ts"), content, "utf8");
7419
7725
  }
7420
7726
  async function generateApiJs(generatedDir) {
7421
7727
  const content = `/* eslint-disable */
@@ -7443,13 +7749,13 @@ export const api = anyApi;
7443
7749
  export const internal = anyApi;
7444
7750
  export const components = componentsGeneric();
7445
7751
  `;
7446
- await fs9.writeFile(path11.join(generatedDir, "api.js"), content, "utf8");
7752
+ await fs9.writeFile(path12.join(generatedDir, "api.js"), content, "utf8");
7447
7753
  }
7448
7754
 
7449
7755
  // src/cli/type-codegen-runtime.ts
7450
7756
  var import_picocolors8 = __toESM(require_picocolors(), 1);
7451
7757
  import { promises as fs10 } from "node:fs";
7452
- import path12 from "node:path";
7758
+ import path13 from "node:path";
7453
7759
  import { pathToFileURL as pathToFileURL3 } from "node:url";
7454
7760
 
7455
7761
  // src/cli/validator-to-typescript.ts
@@ -7520,10 +7826,8 @@ function convertValidator(validator, options) {
7520
7826
  return `{ ${fields.join("; ")} }`;
7521
7827
  }
7522
7828
  case "record": {
7523
- const keys = validator.keys;
7524
- const values = validator.values;
7525
- const keyType = convertValidator(keys, options);
7526
- const valueType = convertValidator(values, options);
7829
+ const keyType = convertValidator(validator.keys, options);
7830
+ const valueType = convertValidator(validator.values.fieldType, options);
7527
7831
  return `Record<${keyType}, ${valueType}>`;
7528
7832
  }
7529
7833
  case "set": {
@@ -7568,7 +7872,7 @@ function returnsValidatorToTypeScript(returns, options = {}) {
7568
7872
  async function generateTypesWithRuntime(projectRoot, options = {}) {
7569
7873
  const layout = await resolveProjectLayout(projectRoot);
7570
7874
  const convexDir = layout.functionsDir;
7571
- const generatedDir = path12.join(convexDir, "_generated");
7875
+ const generatedDir = path13.join(convexDir, "_generated");
7572
7876
  console.log(import_picocolors8.default.cyan("\uD83D\uDD27 Generating TypeScript types (runtime analysis)"));
7573
7877
  console.log(import_picocolors8.default.dim(` Output: ${generatedDir}
7574
7878
  `));
@@ -7641,7 +7945,7 @@ async function discoverAndAnalyzeModules(convexDir, options) {
7641
7945
  const failed = [];
7642
7946
  const moduleFiles = await collectConvexModules2(convexDir);
7643
7947
  for (const filePath of moduleFiles) {
7644
- const relativePath = path12.relative(convexDir, filePath);
7948
+ const relativePath = path13.relative(convexDir, filePath);
7645
7949
  const moduleName = relativePath.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, "").replace(/\\/g, "/");
7646
7950
  if (moduleName === "schema" || moduleName === "http" || moduleName === "crons") {
7647
7951
  continue;
@@ -7771,7 +8075,7 @@ async function collectConvexModules2(convexDir) {
7771
8075
  if (entry.name.startsWith(".") || entry.name === "_generated" || entry.name === "node_modules") {
7772
8076
  continue;
7773
8077
  }
7774
- const fullPath = path12.join(dir, entry.name);
8078
+ const fullPath = path13.join(dir, entry.name);
7775
8079
  if (entry.isDirectory()) {
7776
8080
  await walk(fullPath);
7777
8081
  } else if (isConvexSourceFile3(entry.name)) {
@@ -7952,7 +8256,7 @@ export declare const internal: FilterApi<
7952
8256
 
7953
8257
  export declare const components: AnyComponents;
7954
8258
  `;
7955
- await fs10.writeFile(path12.join(generatedDir, "api.d.ts"), content, "utf8");
8259
+ await fs10.writeFile(path13.join(generatedDir, "api.d.ts"), content, "utf8");
7956
8260
  }
7957
8261
  async function generatePackageJson(generatedDir) {
7958
8262
  const content = {
@@ -7966,7 +8270,7 @@ async function generatePackageJson(generatedDir) {
7966
8270
  "./dataModel.d.ts": "./dataModel.d.ts"
7967
8271
  }
7968
8272
  };
7969
- await fs10.writeFile(path12.join(generatedDir, "package.json"), JSON.stringify(content, null, 2), "utf8");
8273
+ await fs10.writeFile(path13.join(generatedDir, "package.json"), JSON.stringify(content, null, 2), "utf8");
7970
8274
  }
7971
8275
  async function generateServerTypes2(generatedDir, _hasSchema) {
7972
8276
  const content = `/* eslint-disable */
@@ -8006,7 +8310,7 @@ export type ActionCtx = GenericActionCtx<DataModel>;
8006
8310
  export type DatabaseReader = GenericDatabaseReader<DataModel>;
8007
8311
  export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
8008
8312
  `;
8009
- await fs10.writeFile(path12.join(generatedDir, "server.d.ts"), content, "utf8");
8313
+ await fs10.writeFile(path13.join(generatedDir, "server.d.ts"), content, "utf8");
8010
8314
  }
8011
8315
  async function generateServerJs2(generatedDir) {
8012
8316
  const content = `/* eslint-disable */
@@ -8037,7 +8341,7 @@ export const action = actionGeneric;
8037
8341
  export const internalAction = internalActionGeneric;
8038
8342
  export const httpAction = httpActionGeneric;
8039
8343
  `;
8040
- await fs10.writeFile(path12.join(generatedDir, "server.js"), content, "utf8");
8344
+ await fs10.writeFile(path13.join(generatedDir, "server.js"), content, "utf8");
8041
8345
  }
8042
8346
  async function generateDataModelTypes2(generatedDir, hasSchema) {
8043
8347
  const content = `/* eslint-disable */
@@ -8065,7 +8369,7 @@ export type Id<TableName extends TableNames | SystemTableNames> = GenericId<Tabl
8065
8369
 
8066
8370
  ${hasSchema ? "export type DataModel = DataModelFromSchemaDefinition<typeof schema>;" : "export type DataModel = any;"}
8067
8371
  `;
8068
- await fs10.writeFile(path12.join(generatedDir, "dataModel.d.ts"), content, "utf8");
8372
+ await fs10.writeFile(path13.join(generatedDir, "dataModel.d.ts"), content, "utf8");
8069
8373
  }
8070
8374
  async function generateApiJs2(generatedDir) {
8071
8375
  const content = `/* eslint-disable */
@@ -8092,16 +8396,16 @@ export const api = anyApi;
8092
8396
  export const internal = anyApi;
8093
8397
  export const components = componentsGeneric();
8094
8398
  `;
8095
- await fs10.writeFile(path12.join(generatedDir, "api.js"), content, "utf8");
8399
+ await fs10.writeFile(path13.join(generatedDir, "api.js"), content, "utf8");
8096
8400
  }
8097
8401
 
8098
- // ../../node_modules/.bun/chokidar@4.0.3/node_modules/chokidar/esm/index.js
8402
+ // ../../node_modules/chokidar/esm/index.js
8099
8403
  import { stat as statcb } from "fs";
8100
8404
  import { stat as stat4, readdir as readdir2 } from "fs/promises";
8101
8405
  import { EventEmitter } from "events";
8102
8406
  import * as sysPath2 from "path";
8103
8407
 
8104
- // ../../node_modules/.bun/readdirp@4.1.2/node_modules/readdirp/esm/index.js
8408
+ // ../../node_modules/readdirp/esm/index.js
8105
8409
  import { stat as stat2, lstat, readdir, realpath } from "node:fs/promises";
8106
8410
  import { Readable } from "node:stream";
8107
8411
  import { resolve as presolve, relative as prelative, join as pjoin, sep as psep } from "node:path";
@@ -8172,7 +8476,7 @@ class ReaddirpStream extends Readable {
8172
8476
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
8173
8477
  const statMethod = opts.lstat ? lstat : stat2;
8174
8478
  if (wantBigintFsStats) {
8175
- this._stat = (path13) => statMethod(path13, { bigint: true });
8479
+ this._stat = (path14) => statMethod(path14, { bigint: true });
8176
8480
  } else {
8177
8481
  this._stat = statMethod;
8178
8482
  }
@@ -8197,8 +8501,8 @@ class ReaddirpStream extends Readable {
8197
8501
  const par = this.parent;
8198
8502
  const fil = par && par.files;
8199
8503
  if (fil && fil.length > 0) {
8200
- const { path: path13, depth } = par;
8201
- const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path13));
8504
+ const { path: path14, depth } = par;
8505
+ const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path14));
8202
8506
  const awaited = await Promise.all(slice);
8203
8507
  for (const entry of awaited) {
8204
8508
  if (!entry)
@@ -8238,20 +8542,20 @@ class ReaddirpStream extends Readable {
8238
8542
  this.reading = false;
8239
8543
  }
8240
8544
  }
8241
- async _exploreDir(path13, depth) {
8545
+ async _exploreDir(path14, depth) {
8242
8546
  let files;
8243
8547
  try {
8244
- files = await readdir(path13, this._rdOptions);
8548
+ files = await readdir(path14, this._rdOptions);
8245
8549
  } catch (error) {
8246
8550
  this._onError(error);
8247
8551
  }
8248
- return { files, depth, path: path13 };
8552
+ return { files, depth, path: path14 };
8249
8553
  }
8250
- async _formatEntry(dirent, path13) {
8554
+ async _formatEntry(dirent, path14) {
8251
8555
  let entry;
8252
8556
  const basename = this._isDirent ? dirent.name : dirent;
8253
8557
  try {
8254
- const fullPath = presolve(pjoin(path13, basename));
8558
+ const fullPath = presolve(pjoin(path14, basename));
8255
8559
  entry = { path: prelative(this._root, fullPath), fullPath, basename };
8256
8560
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
8257
8561
  } catch (err) {
@@ -8321,7 +8625,7 @@ function readdirp(root, options = {}) {
8321
8625
  return new ReaddirpStream(options);
8322
8626
  }
8323
8627
 
8324
- // ../../node_modules/.bun/chokidar@4.0.3/node_modules/chokidar/esm/handler.js
8628
+ // ../../node_modules/chokidar/esm/handler.js
8325
8629
  import { watchFile, unwatchFile, watch as fs_watch } from "fs";
8326
8630
  import { open, stat as stat3, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
8327
8631
  import * as sysPath from "path";
@@ -8650,16 +8954,16 @@ var delFromSet = (main, prop, item) => {
8650
8954
  };
8651
8955
  var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
8652
8956
  var FsWatchInstances = new Map;
8653
- function createFsWatchInstance(path13, options, listener, errHandler, emitRaw) {
8957
+ function createFsWatchInstance(path14, options, listener, errHandler, emitRaw) {
8654
8958
  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));
8959
+ listener(path14);
8960
+ emitRaw(rawEvent, evPath, { watchedPath: path14 });
8961
+ if (evPath && path14 !== evPath) {
8962
+ fsWatchBroadcast(sysPath.resolve(path14, evPath), KEY_LISTENERS, sysPath.join(path14, evPath));
8659
8963
  }
8660
8964
  };
8661
8965
  try {
8662
- return fs_watch(path13, {
8966
+ return fs_watch(path14, {
8663
8967
  persistent: options.persistent
8664
8968
  }, handleEvent);
8665
8969
  } catch (error) {
@@ -8675,12 +8979,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
8675
8979
  listener(val1, val2, val3);
8676
8980
  });
8677
8981
  };
8678
- var setFsWatchListener = (path13, fullPath, options, handlers) => {
8982
+ var setFsWatchListener = (path14, fullPath, options, handlers) => {
8679
8983
  const { listener, errHandler, rawEmitter } = handlers;
8680
8984
  let cont = FsWatchInstances.get(fullPath);
8681
8985
  let watcher;
8682
8986
  if (!options.persistent) {
8683
- watcher = createFsWatchInstance(path13, options, listener, errHandler, rawEmitter);
8987
+ watcher = createFsWatchInstance(path14, options, listener, errHandler, rawEmitter);
8684
8988
  if (!watcher)
8685
8989
  return;
8686
8990
  return watcher.close.bind(watcher);
@@ -8690,7 +8994,7 @@ var setFsWatchListener = (path13, fullPath, options, handlers) => {
8690
8994
  addAndConvert(cont, KEY_ERR, errHandler);
8691
8995
  addAndConvert(cont, KEY_RAW, rawEmitter);
8692
8996
  } else {
8693
- watcher = createFsWatchInstance(path13, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
8997
+ watcher = createFsWatchInstance(path14, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
8694
8998
  if (!watcher)
8695
8999
  return;
8696
9000
  watcher.on(EV.ERROR, async (error) => {
@@ -8699,7 +9003,7 @@ var setFsWatchListener = (path13, fullPath, options, handlers) => {
8699
9003
  cont.watcherUnusable = true;
8700
9004
  if (isWindows && error.code === "EPERM") {
8701
9005
  try {
8702
- const fd = await open(path13, "r");
9006
+ const fd = await open(path14, "r");
8703
9007
  await fd.close();
8704
9008
  broadcastErr(error);
8705
9009
  } catch (err) {}
@@ -8729,7 +9033,7 @@ var setFsWatchListener = (path13, fullPath, options, handlers) => {
8729
9033
  };
8730
9034
  };
8731
9035
  var FsWatchFileInstances = new Map;
8732
- var setFsWatchFileListener = (path13, fullPath, options, handlers) => {
9036
+ var setFsWatchFileListener = (path14, fullPath, options, handlers) => {
8733
9037
  const { listener, rawEmitter } = handlers;
8734
9038
  let cont = FsWatchFileInstances.get(fullPath);
8735
9039
  const copts = cont && cont.options;
@@ -8751,7 +9055,7 @@ var setFsWatchFileListener = (path13, fullPath, options, handlers) => {
8751
9055
  });
8752
9056
  const currmtime = curr.mtimeMs;
8753
9057
  if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
8754
- foreach(cont.listeners, (listener2) => listener2(path13, curr));
9058
+ foreach(cont.listeners, (listener2) => listener2(path14, curr));
8755
9059
  }
8756
9060
  })
8757
9061
  };
@@ -8774,13 +9078,13 @@ class NodeFsHandler {
8774
9078
  this.fsw = fsW;
8775
9079
  this._boundHandleError = (error) => fsW._handleError(error);
8776
9080
  }
8777
- _watchWithNodeFs(path13, listener) {
9081
+ _watchWithNodeFs(path14, listener) {
8778
9082
  const opts = this.fsw.options;
8779
- const directory = sysPath.dirname(path13);
8780
- const basename2 = sysPath.basename(path13);
9083
+ const directory = sysPath.dirname(path14);
9084
+ const basename2 = sysPath.basename(path14);
8781
9085
  const parent = this.fsw._getWatchedDir(directory);
8782
9086
  parent.add(basename2);
8783
- const absolutePath = sysPath.resolve(path13);
9087
+ const absolutePath = sysPath.resolve(path14);
8784
9088
  const options = {
8785
9089
  persistent: opts.persistent
8786
9090
  };
@@ -8790,12 +9094,12 @@ class NodeFsHandler {
8790
9094
  if (opts.usePolling) {
8791
9095
  const enableBin = opts.interval !== opts.binaryInterval;
8792
9096
  options.interval = enableBin && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
8793
- closer = setFsWatchFileListener(path13, absolutePath, options, {
9097
+ closer = setFsWatchFileListener(path14, absolutePath, options, {
8794
9098
  listener,
8795
9099
  rawEmitter: this.fsw._emitRaw
8796
9100
  });
8797
9101
  } else {
8798
- closer = setFsWatchListener(path13, absolutePath, options, {
9102
+ closer = setFsWatchListener(path14, absolutePath, options, {
8799
9103
  listener,
8800
9104
  errHandler: this._boundHandleError,
8801
9105
  rawEmitter: this.fsw._emitRaw
@@ -8813,7 +9117,7 @@ class NodeFsHandler {
8813
9117
  let prevStats = stats;
8814
9118
  if (parent.has(basename2))
8815
9119
  return;
8816
- const listener = async (path13, newStats) => {
9120
+ const listener = async (path14, newStats) => {
8817
9121
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
8818
9122
  return;
8819
9123
  if (!newStats || newStats.mtimeMs === 0) {
@@ -8827,11 +9131,11 @@ class NodeFsHandler {
8827
9131
  this.fsw._emit(EV.CHANGE, file, newStats2);
8828
9132
  }
8829
9133
  if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
8830
- this.fsw._closeFile(path13);
9134
+ this.fsw._closeFile(path14);
8831
9135
  prevStats = newStats2;
8832
9136
  const closer2 = this._watchWithNodeFs(file, listener);
8833
9137
  if (closer2)
8834
- this.fsw._addPathCloser(path13, closer2);
9138
+ this.fsw._addPathCloser(path14, closer2);
8835
9139
  } else {
8836
9140
  prevStats = newStats2;
8837
9141
  }
@@ -8855,7 +9159,7 @@ class NodeFsHandler {
8855
9159
  }
8856
9160
  return closer;
8857
9161
  }
8858
- async _handleSymlink(entry, directory, path13, item) {
9162
+ async _handleSymlink(entry, directory, path14, item) {
8859
9163
  if (this.fsw.closed) {
8860
9164
  return;
8861
9165
  }
@@ -8865,7 +9169,7 @@ class NodeFsHandler {
8865
9169
  this.fsw._incrReadyCount();
8866
9170
  let linkPath;
8867
9171
  try {
8868
- linkPath = await fsrealpath(path13);
9172
+ linkPath = await fsrealpath(path14);
8869
9173
  } catch (e) {
8870
9174
  this.fsw._emitReady();
8871
9175
  return true;
@@ -8875,12 +9179,12 @@ class NodeFsHandler {
8875
9179
  if (dir.has(item)) {
8876
9180
  if (this.fsw._symlinkPaths.get(full) !== linkPath) {
8877
9181
  this.fsw._symlinkPaths.set(full, linkPath);
8878
- this.fsw._emit(EV.CHANGE, path13, entry.stats);
9182
+ this.fsw._emit(EV.CHANGE, path14, entry.stats);
8879
9183
  }
8880
9184
  } else {
8881
9185
  dir.add(item);
8882
9186
  this.fsw._symlinkPaths.set(full, linkPath);
8883
- this.fsw._emit(EV.ADD, path13, entry.stats);
9187
+ this.fsw._emit(EV.ADD, path14, entry.stats);
8884
9188
  }
8885
9189
  this.fsw._emitReady();
8886
9190
  return true;
@@ -8909,9 +9213,9 @@ class NodeFsHandler {
8909
9213
  return;
8910
9214
  }
8911
9215
  const item = entry.path;
8912
- let path13 = sysPath.join(directory, item);
9216
+ let path14 = sysPath.join(directory, item);
8913
9217
  current.add(item);
8914
- if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path13, item)) {
9218
+ if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path14, item)) {
8915
9219
  return;
8916
9220
  }
8917
9221
  if (this.fsw.closed) {
@@ -8920,8 +9224,8 @@ class NodeFsHandler {
8920
9224
  }
8921
9225
  if (item === target || !target && !previous.has(item)) {
8922
9226
  this.fsw._incrReadyCount();
8923
- path13 = sysPath.join(dir, sysPath.relative(dir, path13));
8924
- this._addToNodeFs(path13, initialAdd, wh, depth + 1);
9227
+ path14 = sysPath.join(dir, sysPath.relative(dir, path14));
9228
+ this._addToNodeFs(path14, initialAdd, wh, depth + 1);
8925
9229
  }
8926
9230
  }).on(EV.ERROR, this._boundHandleError);
8927
9231
  return new Promise((resolve2, reject) => {
@@ -8970,13 +9274,13 @@ class NodeFsHandler {
8970
9274
  }
8971
9275
  return closer;
8972
9276
  }
8973
- async _addToNodeFs(path13, initialAdd, priorWh, depth, target) {
9277
+ async _addToNodeFs(path14, initialAdd, priorWh, depth, target) {
8974
9278
  const ready = this.fsw._emitReady;
8975
- if (this.fsw._isIgnored(path13) || this.fsw.closed) {
9279
+ if (this.fsw._isIgnored(path14) || this.fsw.closed) {
8976
9280
  ready();
8977
9281
  return false;
8978
9282
  }
8979
- const wh = this.fsw._getWatchHelpers(path13);
9283
+ const wh = this.fsw._getWatchHelpers(path14);
8980
9284
  if (priorWh) {
8981
9285
  wh.filterPath = (entry) => priorWh.filterPath(entry);
8982
9286
  wh.filterDir = (entry) => priorWh.filterDir(entry);
@@ -8992,8 +9296,8 @@ class NodeFsHandler {
8992
9296
  const follow = this.fsw.options.followSymlinks;
8993
9297
  let closer;
8994
9298
  if (stats.isDirectory()) {
8995
- const absPath = sysPath.resolve(path13);
8996
- const targetPath = follow ? await fsrealpath(path13) : path13;
9299
+ const absPath = sysPath.resolve(path14);
9300
+ const targetPath = follow ? await fsrealpath(path14) : path14;
8997
9301
  if (this.fsw.closed)
8998
9302
  return;
8999
9303
  closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
@@ -9003,35 +9307,35 @@ class NodeFsHandler {
9003
9307
  this.fsw._symlinkPaths.set(absPath, targetPath);
9004
9308
  }
9005
9309
  } else if (stats.isSymbolicLink()) {
9006
- const targetPath = follow ? await fsrealpath(path13) : path13;
9310
+ const targetPath = follow ? await fsrealpath(path14) : path14;
9007
9311
  if (this.fsw.closed)
9008
9312
  return;
9009
9313
  const parent = sysPath.dirname(wh.watchPath);
9010
9314
  this.fsw._getWatchedDir(parent).add(wh.watchPath);
9011
9315
  this.fsw._emit(EV.ADD, wh.watchPath, stats);
9012
- closer = await this._handleDir(parent, stats, initialAdd, depth, path13, wh, targetPath);
9316
+ closer = await this._handleDir(parent, stats, initialAdd, depth, path14, wh, targetPath);
9013
9317
  if (this.fsw.closed)
9014
9318
  return;
9015
9319
  if (targetPath !== undefined) {
9016
- this.fsw._symlinkPaths.set(sysPath.resolve(path13), targetPath);
9320
+ this.fsw._symlinkPaths.set(sysPath.resolve(path14), targetPath);
9017
9321
  }
9018
9322
  } else {
9019
9323
  closer = this._handleFile(wh.watchPath, stats, initialAdd);
9020
9324
  }
9021
9325
  ready();
9022
9326
  if (closer)
9023
- this.fsw._addPathCloser(path13, closer);
9327
+ this.fsw._addPathCloser(path14, closer);
9024
9328
  return false;
9025
9329
  } catch (error) {
9026
9330
  if (this.fsw._handleError(error)) {
9027
9331
  ready();
9028
- return path13;
9332
+ return path14;
9029
9333
  }
9030
9334
  }
9031
9335
  }
9032
9336
  }
9033
9337
 
9034
- // ../../node_modules/.bun/chokidar@4.0.3/node_modules/chokidar/esm/index.js
9338
+ // ../../node_modules/chokidar/esm/index.js
9035
9339
  /*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */
9036
9340
  var SLASH = "/";
9037
9341
  var SLASH_SLASH = "//";
@@ -9069,26 +9373,26 @@ function createPattern(matcher) {
9069
9373
  }
9070
9374
  return () => false;
9071
9375
  }
9072
- function normalizePath(path13) {
9073
- if (typeof path13 !== "string")
9376
+ function normalizePath(path14) {
9377
+ if (typeof path14 !== "string")
9074
9378
  throw new Error("string expected");
9075
- path13 = sysPath2.normalize(path13);
9076
- path13 = path13.replace(/\\/g, "/");
9379
+ path14 = sysPath2.normalize(path14);
9380
+ path14 = path14.replace(/\\/g, "/");
9077
9381
  let prepend = false;
9078
- if (path13.startsWith("//"))
9382
+ if (path14.startsWith("//"))
9079
9383
  prepend = true;
9080
9384
  const DOUBLE_SLASH_RE2 = /\/\//;
9081
- while (path13.match(DOUBLE_SLASH_RE2))
9082
- path13 = path13.replace(DOUBLE_SLASH_RE2, "/");
9385
+ while (path14.match(DOUBLE_SLASH_RE2))
9386
+ path14 = path14.replace(DOUBLE_SLASH_RE2, "/");
9083
9387
  if (prepend)
9084
- path13 = "/" + path13;
9085
- return path13;
9388
+ path14 = "/" + path14;
9389
+ return path14;
9086
9390
  }
9087
9391
  function matchPatterns(patterns, testString, stats) {
9088
- const path13 = normalizePath(testString);
9392
+ const path14 = normalizePath(testString);
9089
9393
  for (let index = 0;index < patterns.length; index++) {
9090
9394
  const pattern = patterns[index];
9091
- if (pattern(path13, stats)) {
9395
+ if (pattern(path14, stats)) {
9092
9396
  return true;
9093
9397
  }
9094
9398
  }
@@ -9128,19 +9432,19 @@ var toUnix = (string) => {
9128
9432
  }
9129
9433
  return str;
9130
9434
  };
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));
9435
+ var normalizePathToUnix = (path14) => toUnix(sysPath2.normalize(toUnix(path14)));
9436
+ var normalizeIgnored = (cwd = "") => (path14) => {
9437
+ if (typeof path14 === "string") {
9438
+ return normalizePathToUnix(sysPath2.isAbsolute(path14) ? path14 : sysPath2.join(cwd, path14));
9135
9439
  } else {
9136
- return path13;
9440
+ return path14;
9137
9441
  }
9138
9442
  };
9139
- var getAbsolutePath = (path13, cwd) => {
9140
- if (sysPath2.isAbsolute(path13)) {
9141
- return path13;
9443
+ var getAbsolutePath = (path14, cwd) => {
9444
+ if (sysPath2.isAbsolute(path14)) {
9445
+ return path14;
9142
9446
  }
9143
- return sysPath2.join(cwd, path13);
9447
+ return sysPath2.join(cwd, path14);
9144
9448
  };
9145
9449
  var EMPTY_SET = Object.freeze(new Set);
9146
9450
 
@@ -9197,10 +9501,10 @@ var STAT_METHOD_F = "stat";
9197
9501
  var STAT_METHOD_L = "lstat";
9198
9502
 
9199
9503
  class WatchHelper {
9200
- constructor(path13, follow, fsw) {
9504
+ constructor(path14, follow, fsw) {
9201
9505
  this.fsw = fsw;
9202
- const watchPath = path13;
9203
- this.path = path13 = path13.replace(REPLACER_RE, "");
9506
+ const watchPath = path14;
9507
+ this.path = path14 = path14.replace(REPLACER_RE, "");
9204
9508
  this.watchPath = watchPath;
9205
9509
  this.fullWatchPath = sysPath2.resolve(watchPath);
9206
9510
  this.dirParts = [];
@@ -9313,20 +9617,20 @@ class FSWatcher extends EventEmitter {
9313
9617
  this._closePromise = undefined;
9314
9618
  let paths = unifyPaths(paths_);
9315
9619
  if (cwd) {
9316
- paths = paths.map((path13) => {
9317
- const absPath = getAbsolutePath(path13, cwd);
9620
+ paths = paths.map((path14) => {
9621
+ const absPath = getAbsolutePath(path14, cwd);
9318
9622
  return absPath;
9319
9623
  });
9320
9624
  }
9321
- paths.forEach((path13) => {
9322
- this._removeIgnoredPath(path13);
9625
+ paths.forEach((path14) => {
9626
+ this._removeIgnoredPath(path14);
9323
9627
  });
9324
9628
  this._userIgnored = undefined;
9325
9629
  if (!this._readyCount)
9326
9630
  this._readyCount = 0;
9327
9631
  this._readyCount += paths.length;
9328
- Promise.all(paths.map(async (path13) => {
9329
- const res = await this._nodeFsHandler._addToNodeFs(path13, !_internal, undefined, 0, _origAdd);
9632
+ Promise.all(paths.map(async (path14) => {
9633
+ const res = await this._nodeFsHandler._addToNodeFs(path14, !_internal, undefined, 0, _origAdd);
9330
9634
  if (res)
9331
9635
  this._emitReady();
9332
9636
  return res;
@@ -9345,17 +9649,17 @@ class FSWatcher extends EventEmitter {
9345
9649
  return this;
9346
9650
  const paths = unifyPaths(paths_);
9347
9651
  const { cwd } = this.options;
9348
- paths.forEach((path13) => {
9349
- if (!sysPath2.isAbsolute(path13) && !this._closers.has(path13)) {
9652
+ paths.forEach((path14) => {
9653
+ if (!sysPath2.isAbsolute(path14) && !this._closers.has(path14)) {
9350
9654
  if (cwd)
9351
- path13 = sysPath2.join(cwd, path13);
9352
- path13 = sysPath2.resolve(path13);
9655
+ path14 = sysPath2.join(cwd, path14);
9656
+ path14 = sysPath2.resolve(path14);
9353
9657
  }
9354
- this._closePath(path13);
9355
- this._addIgnoredPath(path13);
9356
- if (this._watched.has(path13)) {
9658
+ this._closePath(path14);
9659
+ this._addIgnoredPath(path14);
9660
+ if (this._watched.has(path14)) {
9357
9661
  this._addIgnoredPath({
9358
- path: path13,
9662
+ path: path14,
9359
9663
  recursive: true
9360
9664
  });
9361
9665
  }
@@ -9404,38 +9708,38 @@ class FSWatcher extends EventEmitter {
9404
9708
  if (event !== EVENTS.ERROR)
9405
9709
  this.emit(EVENTS.ALL, event, ...args);
9406
9710
  }
9407
- async _emit(event, path13, stats) {
9711
+ async _emit(event, path14, stats) {
9408
9712
  if (this.closed)
9409
9713
  return;
9410
9714
  const opts = this.options;
9411
9715
  if (isWindows)
9412
- path13 = sysPath2.normalize(path13);
9716
+ path14 = sysPath2.normalize(path14);
9413
9717
  if (opts.cwd)
9414
- path13 = sysPath2.relative(opts.cwd, path13);
9415
- const args = [path13];
9718
+ path14 = sysPath2.relative(opts.cwd, path14);
9719
+ const args = [path14];
9416
9720
  if (stats != null)
9417
9721
  args.push(stats);
9418
9722
  const awf = opts.awaitWriteFinish;
9419
9723
  let pw;
9420
- if (awf && (pw = this._pendingWrites.get(path13))) {
9724
+ if (awf && (pw = this._pendingWrites.get(path14))) {
9421
9725
  pw.lastChange = new Date;
9422
9726
  return this;
9423
9727
  }
9424
9728
  if (opts.atomic) {
9425
9729
  if (event === EVENTS.UNLINK) {
9426
- this._pendingUnlinks.set(path13, [event, ...args]);
9730
+ this._pendingUnlinks.set(path14, [event, ...args]);
9427
9731
  setTimeout(() => {
9428
- this._pendingUnlinks.forEach((entry, path14) => {
9732
+ this._pendingUnlinks.forEach((entry, path15) => {
9429
9733
  this.emit(...entry);
9430
9734
  this.emit(EVENTS.ALL, ...entry);
9431
- this._pendingUnlinks.delete(path14);
9735
+ this._pendingUnlinks.delete(path15);
9432
9736
  });
9433
9737
  }, typeof opts.atomic === "number" ? opts.atomic : 100);
9434
9738
  return this;
9435
9739
  }
9436
- if (event === EVENTS.ADD && this._pendingUnlinks.has(path13)) {
9740
+ if (event === EVENTS.ADD && this._pendingUnlinks.has(path14)) {
9437
9741
  event = EVENTS.CHANGE;
9438
- this._pendingUnlinks.delete(path13);
9742
+ this._pendingUnlinks.delete(path14);
9439
9743
  }
9440
9744
  }
9441
9745
  if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
@@ -9453,16 +9757,16 @@ class FSWatcher extends EventEmitter {
9453
9757
  this.emitWithAll(event, args);
9454
9758
  }
9455
9759
  };
9456
- this._awaitWriteFinish(path13, awf.stabilityThreshold, event, awfEmit);
9760
+ this._awaitWriteFinish(path14, awf.stabilityThreshold, event, awfEmit);
9457
9761
  return this;
9458
9762
  }
9459
9763
  if (event === EVENTS.CHANGE) {
9460
- const isThrottled = !this._throttle(EVENTS.CHANGE, path13, 50);
9764
+ const isThrottled = !this._throttle(EVENTS.CHANGE, path14, 50);
9461
9765
  if (isThrottled)
9462
9766
  return this;
9463
9767
  }
9464
9768
  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;
9769
+ const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path14) : path14;
9466
9770
  let stats2;
9467
9771
  try {
9468
9772
  stats2 = await stat4(fullPath);
@@ -9481,23 +9785,23 @@ class FSWatcher extends EventEmitter {
9481
9785
  }
9482
9786
  return error || this.closed;
9483
9787
  }
9484
- _throttle(actionType, path13, timeout) {
9788
+ _throttle(actionType, path14, timeout) {
9485
9789
  if (!this._throttled.has(actionType)) {
9486
9790
  this._throttled.set(actionType, new Map);
9487
9791
  }
9488
9792
  const action = this._throttled.get(actionType);
9489
9793
  if (!action)
9490
9794
  throw new Error("invalid throttle");
9491
- const actionPath = action.get(path13);
9795
+ const actionPath = action.get(path14);
9492
9796
  if (actionPath) {
9493
9797
  actionPath.count++;
9494
9798
  return false;
9495
9799
  }
9496
9800
  let timeoutObject;
9497
9801
  const clear = () => {
9498
- const item = action.get(path13);
9802
+ const item = action.get(path14);
9499
9803
  const count = item ? item.count : 0;
9500
- action.delete(path13);
9804
+ action.delete(path14);
9501
9805
  clearTimeout(timeoutObject);
9502
9806
  if (item)
9503
9807
  clearTimeout(item.timeoutObject);
@@ -9505,50 +9809,50 @@ class FSWatcher extends EventEmitter {
9505
9809
  };
9506
9810
  timeoutObject = setTimeout(clear, timeout);
9507
9811
  const thr = { timeoutObject, clear, count: 0 };
9508
- action.set(path13, thr);
9812
+ action.set(path14, thr);
9509
9813
  return thr;
9510
9814
  }
9511
9815
  _incrReadyCount() {
9512
9816
  return this._readyCount++;
9513
9817
  }
9514
- _awaitWriteFinish(path13, threshold, event, awfEmit) {
9818
+ _awaitWriteFinish(path14, threshold, event, awfEmit) {
9515
9819
  const awf = this.options.awaitWriteFinish;
9516
9820
  if (typeof awf !== "object")
9517
9821
  return;
9518
9822
  const pollInterval = awf.pollInterval;
9519
9823
  let timeoutHandler;
9520
- let fullPath = path13;
9521
- if (this.options.cwd && !sysPath2.isAbsolute(path13)) {
9522
- fullPath = sysPath2.join(this.options.cwd, path13);
9824
+ let fullPath = path14;
9825
+ if (this.options.cwd && !sysPath2.isAbsolute(path14)) {
9826
+ fullPath = sysPath2.join(this.options.cwd, path14);
9523
9827
  }
9524
9828
  const now = new Date;
9525
9829
  const writes = this._pendingWrites;
9526
9830
  function awaitWriteFinishFn(prevStat) {
9527
9831
  statcb(fullPath, (err, curStat) => {
9528
- if (err || !writes.has(path13)) {
9832
+ if (err || !writes.has(path14)) {
9529
9833
  if (err && err.code !== "ENOENT")
9530
9834
  awfEmit(err);
9531
9835
  return;
9532
9836
  }
9533
9837
  const now2 = Number(new Date);
9534
9838
  if (prevStat && curStat.size !== prevStat.size) {
9535
- writes.get(path13).lastChange = now2;
9839
+ writes.get(path14).lastChange = now2;
9536
9840
  }
9537
- const pw = writes.get(path13);
9841
+ const pw = writes.get(path14);
9538
9842
  const df = now2 - pw.lastChange;
9539
9843
  if (df >= threshold) {
9540
- writes.delete(path13);
9844
+ writes.delete(path14);
9541
9845
  awfEmit(undefined, curStat);
9542
9846
  } else {
9543
9847
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
9544
9848
  }
9545
9849
  });
9546
9850
  }
9547
- if (!writes.has(path13)) {
9548
- writes.set(path13, {
9851
+ if (!writes.has(path14)) {
9852
+ writes.set(path14, {
9549
9853
  lastChange: now,
9550
9854
  cancelWait: () => {
9551
- writes.delete(path13);
9855
+ writes.delete(path14);
9552
9856
  clearTimeout(timeoutHandler);
9553
9857
  return event;
9554
9858
  }
@@ -9556,8 +9860,8 @@ class FSWatcher extends EventEmitter {
9556
9860
  timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
9557
9861
  }
9558
9862
  }
9559
- _isIgnored(path13, stats) {
9560
- if (this.options.atomic && DOT_RE.test(path13))
9863
+ _isIgnored(path14, stats) {
9864
+ if (this.options.atomic && DOT_RE.test(path14))
9561
9865
  return true;
9562
9866
  if (!this._userIgnored) {
9563
9867
  const { cwd } = this.options;
@@ -9567,13 +9871,13 @@ class FSWatcher extends EventEmitter {
9567
9871
  const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
9568
9872
  this._userIgnored = anymatch(list, undefined);
9569
9873
  }
9570
- return this._userIgnored(path13, stats);
9874
+ return this._userIgnored(path14, stats);
9571
9875
  }
9572
- _isntIgnored(path13, stat5) {
9573
- return !this._isIgnored(path13, stat5);
9876
+ _isntIgnored(path14, stat5) {
9877
+ return !this._isIgnored(path14, stat5);
9574
9878
  }
9575
- _getWatchHelpers(path13) {
9576
- return new WatchHelper(path13, this.options.followSymlinks, this);
9879
+ _getWatchHelpers(path14) {
9880
+ return new WatchHelper(path14, this.options.followSymlinks, this);
9577
9881
  }
9578
9882
  _getWatchedDir(directory) {
9579
9883
  const dir = sysPath2.resolve(directory);
@@ -9587,57 +9891,57 @@ class FSWatcher extends EventEmitter {
9587
9891
  return Boolean(Number(stats.mode) & 256);
9588
9892
  }
9589
9893
  _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))
9894
+ const path14 = sysPath2.join(directory, item);
9895
+ const fullPath = sysPath2.resolve(path14);
9896
+ isDirectory = isDirectory != null ? isDirectory : this._watched.has(path14) || this._watched.has(fullPath);
9897
+ if (!this._throttle("remove", path14, 100))
9594
9898
  return;
9595
9899
  if (!isDirectory && this._watched.size === 1) {
9596
9900
  this.add(directory, item, true);
9597
9901
  }
9598
- const wp = this._getWatchedDir(path13);
9902
+ const wp = this._getWatchedDir(path14);
9599
9903
  const nestedDirectoryChildren = wp.getChildren();
9600
- nestedDirectoryChildren.forEach((nested) => this._remove(path13, nested));
9904
+ nestedDirectoryChildren.forEach((nested) => this._remove(path14, nested));
9601
9905
  const parent = this._getWatchedDir(directory);
9602
9906
  const wasTracked = parent.has(item);
9603
9907
  parent.remove(item);
9604
9908
  if (this._symlinkPaths.has(fullPath)) {
9605
9909
  this._symlinkPaths.delete(fullPath);
9606
9910
  }
9607
- let relPath = path13;
9911
+ let relPath = path14;
9608
9912
  if (this.options.cwd)
9609
- relPath = sysPath2.relative(this.options.cwd, path13);
9913
+ relPath = sysPath2.relative(this.options.cwd, path14);
9610
9914
  if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
9611
9915
  const event = this._pendingWrites.get(relPath).cancelWait();
9612
9916
  if (event === EVENTS.ADD)
9613
9917
  return;
9614
9918
  }
9615
- this._watched.delete(path13);
9919
+ this._watched.delete(path14);
9616
9920
  this._watched.delete(fullPath);
9617
9921
  const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
9618
- if (wasTracked && !this._isIgnored(path13))
9619
- this._emit(eventName, path13);
9620
- this._closePath(path13);
9922
+ if (wasTracked && !this._isIgnored(path14))
9923
+ this._emit(eventName, path14);
9924
+ this._closePath(path14);
9621
9925
  }
9622
- _closePath(path13) {
9623
- this._closeFile(path13);
9624
- const dir = sysPath2.dirname(path13);
9625
- this._getWatchedDir(dir).remove(sysPath2.basename(path13));
9926
+ _closePath(path14) {
9927
+ this._closeFile(path14);
9928
+ const dir = sysPath2.dirname(path14);
9929
+ this._getWatchedDir(dir).remove(sysPath2.basename(path14));
9626
9930
  }
9627
- _closeFile(path13) {
9628
- const closers = this._closers.get(path13);
9931
+ _closeFile(path14) {
9932
+ const closers = this._closers.get(path14);
9629
9933
  if (!closers)
9630
9934
  return;
9631
9935
  closers.forEach((closer) => closer());
9632
- this._closers.delete(path13);
9936
+ this._closers.delete(path14);
9633
9937
  }
9634
- _addPathCloser(path13, closer) {
9938
+ _addPathCloser(path14, closer) {
9635
9939
  if (!closer)
9636
9940
  return;
9637
- let list = this._closers.get(path13);
9941
+ let list = this._closers.get(path14);
9638
9942
  if (!list) {
9639
9943
  list = [];
9640
- this._closers.set(path13, list);
9944
+ this._closers.set(path14, list);
9641
9945
  }
9642
9946
  list.push(closer);
9643
9947
  }
@@ -9668,8 +9972,8 @@ var esm_default = { watch, FSWatcher };
9668
9972
 
9669
9973
  // src/cli/cli.ts
9670
9974
  var import_picocolors9 = __toESM(require_picocolors(), 1);
9671
- import path14 from "node:path";
9672
- import { promises as fs12, existsSync } from "node:fs";
9975
+ import path15 from "node:path";
9976
+ import { promises as fs12, existsSync as existsSync2 } from "node:fs";
9673
9977
  import { spawn as spawn2, spawnSync } from "node:child_process";
9674
9978
  import { pathToFileURL as pathToFileURL4 } from "node:url";
9675
9979
  import { createRequire as createRequire3 } from "node:module";
@@ -9677,7 +9981,7 @@ import { createRequire as createRequire3 } from "node:module";
9677
9981
  // src/cli/auth-keys.ts
9678
9982
  import * as crypto2 from "crypto";
9679
9983
  import * as fs11 from "fs/promises";
9680
- import * as path13 from "path";
9984
+ import * as path14 from "path";
9681
9985
  var AUTH_KEYS_FILENAME = "auth-keys.json";
9682
9986
  async function generateAuthKeys() {
9683
9987
  return new Promise((resolve3, reject) => {
@@ -9724,7 +10028,7 @@ function createJwksFromPublicKey(publicKeyPem, kid) {
9724
10028
  };
9725
10029
  }
9726
10030
  async function loadOrGenerateAuthKeys(dataDir) {
9727
- const keysPath = path13.join(dataDir, AUTH_KEYS_FILENAME);
10031
+ const keysPath = path14.join(dataDir, AUTH_KEYS_FILENAME);
9728
10032
  try {
9729
10033
  const data = await fs11.readFile(keysPath, "utf-8");
9730
10034
  const stored = JSON.parse(data);
@@ -9751,7 +10055,7 @@ async function loadOrGenerateAuthKeys(dataDir) {
9751
10055
  }
9752
10056
  }
9753
10057
  async function detectAuthProjectFlavor(projectRoot) {
9754
- const packageJsonPath = path13.join(projectRoot, "package.json");
10058
+ const packageJsonPath = path14.join(projectRoot, "package.json");
9755
10059
  try {
9756
10060
  const raw = await fs11.readFile(packageJsonPath, "utf-8");
9757
10061
  const parsed = JSON.parse(raw);
@@ -9793,7 +10097,7 @@ function setupAuthEnvironment(keys, siteUrl, options = {}) {
9793
10097
  setEnv("AUTH_SKIP_VERIFICATION", "true");
9794
10098
  }
9795
10099
  // package.json
9796
- var version = "0.0.1-alpha.5";
10100
+ var version = "0.0.1-alpha.6";
9797
10101
 
9798
10102
  // src/cli/cli.ts
9799
10103
  var WATCH_IGNORE_PATTERNS = [
@@ -9801,6 +10105,7 @@ var WATCH_IGNORE_PATTERNS = [
9801
10105
  /(^|[/\\])\.git([/\\]|$)/,
9802
10106
  /(^|[/\\])_generated([/\\]|$)/
9803
10107
  ];
10108
+ var DEFAULT_CONVEX_VERSION_RANGE = "^1.27.3";
9804
10109
  var program2 = new Command;
9805
10110
  program2.name("concave").description("Concave development tools for Cloudflare Workers").version(version);
9806
10111
  function detectHostRuntime() {
@@ -9831,6 +10136,171 @@ function detectPreferredRuntime() {
9831
10136
  return "bun";
9832
10137
  return "node";
9833
10138
  }
10139
+ function detectPackageManager(projectRoot) {
10140
+ if (existsSync2(path15.join(projectRoot, "bun.lock")) || existsSync2(path15.join(projectRoot, "bun.lockb"))) {
10141
+ return "bun";
10142
+ }
10143
+ if (existsSync2(path15.join(projectRoot, "pnpm-lock.yaml"))) {
10144
+ return "pnpm";
10145
+ }
10146
+ if (existsSync2(path15.join(projectRoot, "yarn.lock"))) {
10147
+ return "yarn";
10148
+ }
10149
+ if (existsSync2(path15.join(projectRoot, "package-lock.json")) || existsSync2(path15.join(projectRoot, "npm-shrinkwrap.json"))) {
10150
+ return "npm";
10151
+ }
10152
+ return isBunAvailable() ? "bun" : "npm";
10153
+ }
10154
+ function getAddConvexCommand(packageManager) {
10155
+ switch (packageManager) {
10156
+ case "bun":
10157
+ return { cmd: "bun", args: ["add", "convex"], display: "bun add convex" };
10158
+ case "pnpm":
10159
+ return { cmd: "pnpm", args: ["add", "convex"], display: "pnpm add convex" };
10160
+ case "yarn":
10161
+ return { cmd: "yarn", args: ["add", "convex"], display: "yarn add convex" };
10162
+ default:
10163
+ return { cmd: "npm", args: ["install", "convex"], display: "npm install convex" };
10164
+ }
10165
+ }
10166
+ function getInstallCommand(packageManager) {
10167
+ switch (packageManager) {
10168
+ case "bun":
10169
+ return { cmd: "bun", args: ["install"], display: "bun install" };
10170
+ case "pnpm":
10171
+ return { cmd: "pnpm", args: ["install"], display: "pnpm install" };
10172
+ case "yarn":
10173
+ return { cmd: "yarn", args: ["install"], display: "yarn install" };
10174
+ default:
10175
+ return { cmd: "npm", args: ["install"], display: "npm install" };
10176
+ }
10177
+ }
10178
+ function isObjectRecord(value) {
10179
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10180
+ }
10181
+ function sanitizePackageName(input) {
10182
+ const normalized = input.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
10183
+ return normalized.length > 0 ? normalized : "concave-app";
10184
+ }
10185
+ function formatPathForDisplay(fromDir, targetPath) {
10186
+ const relative3 = path15.relative(fromDir, targetPath);
10187
+ if (!relative3 || relative3 === ".") {
10188
+ return ".";
10189
+ }
10190
+ if (!relative3.startsWith("..") && !path15.isAbsolute(relative3)) {
10191
+ return relative3;
10192
+ }
10193
+ return targetPath;
10194
+ }
10195
+ function hasConvexDependency(packageJson) {
10196
+ return !!(packageJson.dependencies?.convex || packageJson.devDependencies?.convex || packageJson.optionalDependencies?.convex || packageJson.peerDependencies?.convex);
10197
+ }
10198
+ function createDefaultPackageJson(projectRoot) {
10199
+ return {
10200
+ name: sanitizePackageName(path15.basename(projectRoot)),
10201
+ private: true,
10202
+ type: "module"
10203
+ };
10204
+ }
10205
+ async function readPackageJson(packageJsonPath) {
10206
+ if (!existsSync2(packageJsonPath)) {
10207
+ return null;
10208
+ }
10209
+ let parsed;
10210
+ try {
10211
+ const raw = await fs12.readFile(packageJsonPath, "utf8");
10212
+ parsed = JSON.parse(raw);
10213
+ } catch (error) {
10214
+ if (error instanceof SyntaxError) {
10215
+ throw new Error(`Invalid JSON in ${packageJsonPath}: ${error.message}`);
10216
+ }
10217
+ throw new Error(`Failed to read ${packageJsonPath}: ${error?.message ?? String(error)}`);
10218
+ }
10219
+ if (!isObjectRecord(parsed)) {
10220
+ throw new Error(`Invalid ${packageJsonPath}: expected a JSON object`);
10221
+ }
10222
+ return parsed;
10223
+ }
10224
+ async function writePackageJson(packageJsonPath, packageJson) {
10225
+ await fs12.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
10226
+ `, "utf8");
10227
+ }
10228
+ async function ensurePackageJsonWithConvexDependency(projectRoot) {
10229
+ const packageJsonPath = path15.join(projectRoot, "package.json");
10230
+ const existing = await readPackageJson(packageJsonPath);
10231
+ const packageJson = existing ?? createDefaultPackageJson(projectRoot);
10232
+ const createdPackageJson = existing === null;
10233
+ let addedConvexDependency = false;
10234
+ if (!hasConvexDependency(packageJson)) {
10235
+ packageJson.dependencies = {
10236
+ ...packageJson.dependencies ?? {},
10237
+ convex: DEFAULT_CONVEX_VERSION_RANGE
10238
+ };
10239
+ addedConvexDependency = true;
10240
+ }
10241
+ if (createdPackageJson || addedConvexDependency) {
10242
+ await writePackageJson(packageJsonPath, packageJson);
10243
+ }
10244
+ return {
10245
+ packageJsonPath,
10246
+ createdPackageJson,
10247
+ addedConvexDependency
10248
+ };
10249
+ }
10250
+ async function canResolveConvexRuntime(projectRoot) {
10251
+ const nodeModulesConvex = path15.join(projectRoot, "node_modules", "convex", "package.json");
10252
+ if (existsSync2(nodeModulesConvex)) {
10253
+ return true;
10254
+ }
10255
+ const hasYarnPnp = existsSync2(path15.join(projectRoot, ".pnp.cjs")) || existsSync2(path15.join(projectRoot, ".pnp.js"));
10256
+ if (!hasYarnPnp) {
10257
+ return false;
10258
+ }
10259
+ const requireFromProject = createRequire3(path15.join(projectRoot, "__concave__.js"));
10260
+ try {
10261
+ requireFromProject.resolve("convex/values");
10262
+ requireFromProject.resolve("convex/server");
10263
+ return true;
10264
+ } catch {
10265
+ return false;
10266
+ }
10267
+ }
10268
+ function runInstallCommand(projectRoot, command) {
10269
+ const result = spawnSync(command.cmd, command.args, {
10270
+ cwd: projectRoot,
10271
+ stdio: "inherit"
10272
+ });
10273
+ if (result.error) {
10274
+ throw result.error;
10275
+ }
10276
+ if (result.status !== 0) {
10277
+ throw new Error(`"${command.display}" exited with code ${result.status ?? "unknown"}`);
10278
+ }
10279
+ }
10280
+ async function ensureConvexDependencyReady(projectRoot, commandName) {
10281
+ const packageManager = detectPackageManager(projectRoot);
10282
+ const addCommand = getAddConvexCommand(packageManager);
10283
+ const installCommand = getInstallCommand(packageManager);
10284
+ const packageJsonPath = path15.join(projectRoot, "package.json");
10285
+ const packageJson = await readPackageJson(packageJsonPath);
10286
+ if (!packageJson) {
10287
+ console.error(import_picocolors9.default.red("✗ Missing package.json"));
10288
+ console.error(import_picocolors9.default.dim(` \`concave ${commandName}\` requires the \`convex\` npm package.`));
10289
+ console.error(import_picocolors9.default.dim(` Run: ${addCommand.display}`));
10290
+ process.exit(1);
10291
+ }
10292
+ if (!hasConvexDependency(packageJson)) {
10293
+ console.error(import_picocolors9.default.red("✗ Missing dependency: convex"));
10294
+ console.error(import_picocolors9.default.dim(" Concave function files import `convex/values` and generated files import `convex/server`."));
10295
+ console.error(import_picocolors9.default.dim(` Run: ${addCommand.display}`));
10296
+ process.exit(1);
10297
+ }
10298
+ if (!await canResolveConvexRuntime(projectRoot)) {
10299
+ console.error(import_picocolors9.default.red("✗ Could not resolve installed package: convex"));
10300
+ console.error(import_picocolors9.default.dim(` Run: ${installCommand.display}`));
10301
+ process.exit(1);
10302
+ }
10303
+ }
9834
10304
  async function prepareLocalDataPaths(cwd) {
9835
10305
  const resolved = await resolveLocalDataPaths(cwd);
9836
10306
  return {
@@ -9839,7 +10309,7 @@ async function prepareLocalDataPaths(cwd) {
9839
10309
  storagePath: resolved.storagePath
9840
10310
  };
9841
10311
  }
9842
- function parseDotEnv(content) {
10312
+ function parseDotEnv2(content) {
9843
10313
  const result = {};
9844
10314
  const lines = content.split(`
9845
10315
  `);
@@ -9865,37 +10335,44 @@ function parseDotEnv(content) {
9865
10335
  }
9866
10336
  async function loadDevEnvironment(cwd, layout) {
9867
10337
  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")
10338
+ path15.join(layout.convexRootDir, ".env.local"),
10339
+ path15.join(layout.convexRootDir, ".env"),
10340
+ path15.join(cwd, ".env.local"),
10341
+ path15.join(cwd, ".env")
9872
10342
  ];
9873
10343
  const loaded = [];
9874
10344
  for (const filePath of candidates) {
9875
- if (!existsSync(filePath)) {
10345
+ if (!existsSync2(filePath)) {
9876
10346
  continue;
9877
10347
  }
9878
10348
  const content = await fs12.readFile(filePath, "utf8");
9879
- const parsed = parseDotEnv(content);
10349
+ const parsed = parseDotEnv2(content);
9880
10350
  for (const [key, value] of Object.entries(parsed)) {
9881
10351
  if (process.env[key] === undefined) {
9882
10352
  process.env[key] = value;
9883
10353
  }
9884
10354
  }
9885
- loaded.push(path14.relative(cwd, filePath));
10355
+ loaded.push(path15.relative(cwd, filePath));
9886
10356
  }
9887
10357
  return loaded;
9888
10358
  }
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", `
10359
+ 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
10360
  Examples:
9891
- $ concave init Create convex/ and a starter function
9892
- $ concave init --force Overwrite starter files
9893
- `).action(async (opts) => {
10361
+ $ concave init Initialize in current directory
10362
+ $ concave init my-app Initialize in ./my-app
10363
+ $ concave init --install Explicitly install dependencies
10364
+ $ concave init --no-install Scaffold without running package install
10365
+ $ concave init my-app --force Overwrite starter files
10366
+ `).action(async (dir, opts) => {
9894
10367
  const cwd = process.cwd();
9895
- const convexDir = path14.join(cwd, "convex");
9896
- const starterPath = path14.join(convexDir, "messages.ts");
10368
+ const projectRoot = path15.resolve(cwd, dir ?? ".");
10369
+ const displayRoot = formatPathForDisplay(cwd, projectRoot);
10370
+ const layout = await resolveProjectLayout(projectRoot);
10371
+ const convexDir = layout.functionsDir;
10372
+ const starterPath = path15.join(convexDir, "messages.ts");
10373
+ await fs12.mkdir(projectRoot, { recursive: true });
9897
10374
  await fs12.mkdir(convexDir, { recursive: true });
9898
- const starterExists = existsSync(starterPath);
10375
+ const starterExists = existsSync2(starterPath);
9899
10376
  if (!starterExists || opts.force) {
9900
10377
  const content = `import { query, mutation } from "./_generated/server";
9901
10378
  import { v } from "convex/values";
@@ -9916,12 +10393,40 @@ export const create = mutation({
9916
10393
  });
9917
10394
  `;
9918
10395
  await fs12.writeFile(starterPath, content, "utf8");
9919
- console.log(import_picocolors9.default.green(`✓ Created ${path14.relative(cwd, starterPath)}`));
10396
+ console.log(import_picocolors9.default.green(`✓ Created ${formatPathForDisplay(cwd, starterPath)}`));
9920
10397
  } else {
9921
- console.log(import_picocolors9.default.yellow(`⚠️ ${path14.relative(cwd, starterPath)} already exists (use --force to overwrite)`));
10398
+ console.log(import_picocolors9.default.yellow(`⚠️ ${formatPathForDisplay(cwd, starterPath)} already exists (use --force to overwrite)`));
10399
+ }
10400
+ const packageSetup = await ensurePackageJsonWithConvexDependency(projectRoot);
10401
+ if (packageSetup.createdPackageJson) {
10402
+ console.log(import_picocolors9.default.green(`✓ Created ${formatPathForDisplay(cwd, packageSetup.packageJsonPath)}`));
10403
+ }
10404
+ if (packageSetup.addedConvexDependency) {
10405
+ console.log(import_picocolors9.default.green(`✓ Added dependency: convex@${DEFAULT_CONVEX_VERSION_RANGE}`));
10406
+ }
10407
+ const packageManager = detectPackageManager(projectRoot);
10408
+ const installCommand = getInstallCommand(packageManager);
10409
+ const needsInstall = packageSetup.createdPackageJson || packageSetup.addedConvexDependency || !await canResolveConvexRuntime(projectRoot);
10410
+ if (opts.install !== false && needsInstall) {
10411
+ console.log(import_picocolors9.default.dim(`
10412
+ Installing dependencies with ${installCommand.display}...`));
10413
+ try {
10414
+ runInstallCommand(projectRoot, installCommand);
10415
+ console.log(import_picocolors9.default.green(`✓ Installed dependencies (${installCommand.display})`));
10416
+ } catch (error) {
10417
+ console.error(import_picocolors9.default.red(`✗ Failed to install dependencies: ${error?.message ?? String(error)}`));
10418
+ console.log(import_picocolors9.default.dim(` Run manually: ${installCommand.display}`));
10419
+ process.exit(1);
10420
+ }
10421
+ } else if (opts.install === false && needsInstall) {
10422
+ console.log(import_picocolors9.default.yellow(`⚠️ Dependencies not installed (--no-install)`));
10423
+ console.log(import_picocolors9.default.dim(` Run: ${installCommand.display}`));
9922
10424
  }
9923
10425
  console.log(import_picocolors9.default.dim(`
9924
10426
  Next steps:`));
10427
+ if (displayRoot !== ".") {
10428
+ console.log(import_picocolors9.default.dim(` cd ${displayRoot}`));
10429
+ }
9925
10430
  console.log(import_picocolors9.default.dim(" concave dev"));
9926
10431
  console.log(import_picocolors9.default.dim(" concave run messages:list"));
9927
10432
  });
@@ -9932,6 +10437,7 @@ Examples:
9932
10437
  $ concave dev --port 8080 Start dev server on port 8080
9933
10438
  `).action(async (opts) => {
9934
10439
  const cwd = process.cwd();
10440
+ await ensureConvexDependencyReady(cwd, "dev");
9935
10441
  const projectLayout = await resolveProjectLayout(cwd);
9936
10442
  try {
9937
10443
  const loadedEnvFiles = await loadDevEnvironment(cwd, projectLayout);
@@ -9981,11 +10487,14 @@ Examples:
9981
10487
  }
9982
10488
  let wranglerProcess;
9983
10489
  try {
9984
- const result = await generateWorkerEntry(cwd, { runtimeBundlePath, dashboardHtmlPath: artifacts.dashboardHtmlPath });
10490
+ const result = await generateWorkerEntry(cwd, {
10491
+ runtimeBundlePath,
10492
+ dashboardHtmlPath: artifacts.dashboardHtmlPath
10493
+ });
9985
10494
  console.log(import_picocolors9.default.green(`✓ Generated worker entry (${result.moduleCount} module${result.moduleCount === 1 ? "" : "s"})`));
9986
10495
  const configPath = await ensureWranglerConfig(cwd);
9987
- console.log(import_picocolors9.default.green(`✓ Using config: ${path14.basename(configPath)}`));
9988
- const relativeConfigPath = path14.relative(cwd, configPath);
10496
+ console.log(import_picocolors9.default.green(`✓ Using config: ${path15.basename(configPath)}`));
10497
+ const relativeConfigPath = path15.relative(cwd, configPath);
9989
10498
  const wranglerArgs = ["wrangler", "dev", "--config", relativeConfigPath];
9990
10499
  if (opts.port) {
9991
10500
  wranglerArgs.push("--port", opts.port);
@@ -10016,7 +10525,7 @@ Examples:
10016
10525
  try {
10017
10526
  await generateTypes(cwd, { silent: true });
10018
10527
  } catch {}
10019
- const relPath = path14.relative(cwd, filePath);
10528
+ const relPath = path15.relative(cwd, filePath);
10020
10529
  console.log(import_picocolors9.default.dim(` Updated worker entry (${event}: ${relPath || "convex/"}, ${regenResult.moduleCount} module${regenResult.moduleCount === 1 ? "" : "s"})`));
10021
10530
  } catch (error) {
10022
10531
  console.error(import_picocolors9.default.red("✗ Failed to update worker entry:"), error.message ?? error);
@@ -10104,6 +10613,24 @@ Examples:
10104
10613
  process.exit(1);
10105
10614
  }
10106
10615
  });
10616
+ 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", `
10617
+ Examples:
10618
+ $ concave function-spec List all functions
10619
+ $ concave function-spec --file Output to function-spec.json
10620
+ $ concave function-spec --component presence List functions in a component
10621
+ `).action(async (opts) => {
10622
+ try {
10623
+ await listFunctionSpecs({
10624
+ port: opts.port,
10625
+ url: opts.url,
10626
+ component: opts.component,
10627
+ file: opts.file
10628
+ });
10629
+ } catch (error) {
10630
+ console.error(import_picocolors9.default.red("✗ Failed to list functions:"), error.message);
10631
+ process.exit(1);
10632
+ }
10633
+ });
10107
10634
  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
10635
  Examples:
10109
10636
  $ concave codegen Generate types using runtime analysis (default, more precise)
@@ -10111,6 +10638,7 @@ Examples:
10111
10638
  $ concave codegen --verbose Show detailed output
10112
10639
  `).action(async (opts) => {
10113
10640
  const cwd = process.cwd();
10641
+ await ensureConvexDependencyReady(cwd, "codegen");
10114
10642
  try {
10115
10643
  if (opts.static) {
10116
10644
  await generateTypes(cwd, { silent: false });
@@ -10161,7 +10689,7 @@ Examples:
10161
10689
  }
10162
10690
  try {
10163
10691
  const layout = await resolveProjectLayout(cwd);
10164
- if (!existsSync(layout.functionsDir)) {
10692
+ if (!existsSync2(layout.functionsDir)) {
10165
10693
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10166
10694
  console.log(import_picocolors9.default.dim(` Expected: ${layout.functionsDir}`));
10167
10695
  process.exit(1);
@@ -10179,10 +10707,10 @@ Examples:
10179
10707
  console.log(import_picocolors9.default.green(`✓ Generated standalone entry (${result.moduleCount} module${result.moduleCount === 1 ? "" : "s"})`));
10180
10708
  if (opts.verbose) {
10181
10709
  for (const file of result.sourceFiles) {
10182
- console.log(import_picocolors9.default.dim(` ${path14.relative(cwd, file)}`));
10710
+ console.log(import_picocolors9.default.dim(` ${path15.relative(cwd, file)}`));
10183
10711
  }
10184
10712
  }
10185
- const outfile = path14.resolve(cwd, opts.outfile);
10713
+ const outfile = path15.resolve(cwd, opts.outfile);
10186
10714
  const buildArgs = ["build", "--compile", result.entryFile, "--outfile", outfile];
10187
10715
  if (opts.target) {
10188
10716
  buildArgs.push("--target", `bun-${opts.target}`);
@@ -10212,13 +10740,13 @@ Examples:
10212
10740
  sizeStr = ` (${sizeMB} MB)`;
10213
10741
  } catch {}
10214
10742
  console.log(import_picocolors9.default.green(`
10215
- ✓ Built: ${path14.relative(cwd, outfile)}${sizeStr}`));
10743
+ ✓ Built: ${path15.relative(cwd, outfile)}${sizeStr}`));
10216
10744
  if (opts.target) {
10217
10745
  console.log(import_picocolors9.default.dim(` Target: bun-${opts.target}`));
10218
10746
  }
10219
10747
  console.log(import_picocolors9.default.dim(`
10220
10748
  Run it:`));
10221
- console.log(import_picocolors9.default.dim(` ./${path14.relative(cwd, outfile)} --port 3000`));
10749
+ console.log(import_picocolors9.default.dim(` ./${path15.relative(cwd, outfile)} --port 3000`));
10222
10750
  } catch (error) {
10223
10751
  console.error(import_picocolors9.default.red("✗ Build failed:"), error.message);
10224
10752
  if (opts.verbose && error.stack) {
@@ -10229,8 +10757,8 @@ Examples:
10229
10757
  });
10230
10758
  program2.parse();
10231
10759
  async function listComponents(options) {
10232
- const baseUrl = detectBaseUrl(options);
10233
- const executeUrl = `${baseUrl}/api/execute`;
10760
+ const baseUrlResolution = resolveBaseUrl(options);
10761
+ const executeUrl = `${baseUrlResolution.baseUrl}/api/execute`;
10234
10762
  console.log(import_picocolors9.default.cyan(`\uD83D\uDCE6 Installed Components
10235
10763
  `));
10236
10764
  try {
@@ -10240,8 +10768,9 @@ async function listComponents(options) {
10240
10768
  "Content-Type": "application/json"
10241
10769
  },
10242
10770
  body: JSON.stringify({
10243
- path: "_system/systemListComponents",
10771
+ path: "_system:systemListComponents",
10244
10772
  args: {},
10773
+ type: "query",
10245
10774
  format: "json"
10246
10775
  })
10247
10776
  });
@@ -10264,12 +10793,87 @@ async function listComponents(options) {
10264
10793
  console.log(import_picocolors9.default.dim(` Use ${import_picocolors9.default.bold("concave data --component <path>")} to view component tables`));
10265
10794
  console.log(import_picocolors9.default.dim(` Use ${import_picocolors9.default.bold("concave run --component <path> <func>")} to run component functions`));
10266
10795
  } 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`));
10796
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
10797
+ if (connectionFailure) {
10798
+ console.error(import_picocolors9.default.red(connectionFailure.summary));
10799
+ for (const line of connectionFailure.details) {
10800
+ console.error(import_picocolors9.default.dim(` ${line}`));
10801
+ }
10802
+ } else {
10803
+ const message = error instanceof Error ? error.message : String(error);
10804
+ console.error(import_picocolors9.default.red("✗ Failed to list components:"), message);
10805
+ }
10806
+ process.exit(1);
10807
+ }
10808
+ }
10809
+ async function listFunctionSpecs(options) {
10810
+ const baseUrlResolution = resolveBaseUrl(options);
10811
+ const executeUrl = `${baseUrlResolution.baseUrl}/api/execute`;
10812
+ try {
10813
+ const response = await fetch(executeUrl, {
10814
+ method: "POST",
10815
+ headers: {
10816
+ "Content-Type": "application/json"
10817
+ },
10818
+ body: JSON.stringify({
10819
+ path: "_system:systemListFunctions",
10820
+ args: options.component ? { componentPath: options.component } : {},
10821
+ type: "query",
10822
+ format: "json"
10823
+ })
10824
+ });
10825
+ if (!response.ok) {
10826
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
10827
+ }
10828
+ const result = await response.json();
10829
+ const functions = result.value || result.result || [];
10830
+ if (options.file) {
10831
+ const outPath = path15.resolve("function-spec.json");
10832
+ await fs12.writeFile(outPath, JSON.stringify(functions, null, 2) + `
10833
+ `);
10834
+ console.log(import_picocolors9.default.green(`✓ Wrote ${functions.length} function specs to ${outPath}`));
10835
+ return;
10836
+ }
10837
+ if (functions.length === 0) {
10838
+ console.log(import_picocolors9.default.dim(" No functions found"));
10839
+ return;
10840
+ }
10841
+ const header = options.component ? import_picocolors9.default.cyan(`\uD83D\uDCCB Functions in Component: ${import_picocolors9.default.bold(options.component)}
10842
+ `) : import_picocolors9.default.cyan(`\uD83D\uDCCB Functions
10843
+ `);
10844
+ console.log(header);
10845
+ const byModule = new Map;
10846
+ for (const fn of functions) {
10847
+ const mod = fn.module || fn.path?.split(":")[0] || "(unknown)";
10848
+ if (!byModule.has(mod))
10849
+ byModule.set(mod, []);
10850
+ byModule.get(mod).push(fn);
10851
+ }
10852
+ for (const [mod, fns] of byModule) {
10853
+ console.log(import_picocolors9.default.bold(` ${mod}`));
10854
+ for (const fn of fns) {
10855
+ 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 || "?");
10856
+ const vis = fn.visibility === "internal" ? import_picocolors9.default.dim(" (internal)") : "";
10857
+ console.log(` ${import_picocolors9.default.green(fn.name)} ${typeTag}${vis}`);
10858
+ if (fn.args) {
10859
+ console.log(import_picocolors9.default.dim(` args: ${JSON.stringify(fn.args)}`));
10860
+ }
10861
+ if (fn.returns) {
10862
+ console.log(import_picocolors9.default.dim(` returns: ${JSON.stringify(fn.returns)}`));
10863
+ }
10864
+ }
10865
+ console.log();
10866
+ }
10867
+ } catch (error) {
10868
+ const connectionFailure = describeConnectionFailure(error, baseUrlResolution, executeUrl);
10869
+ if (connectionFailure) {
10870
+ console.error(import_picocolors9.default.red(connectionFailure.summary));
10871
+ for (const line of connectionFailure.details) {
10872
+ console.error(import_picocolors9.default.dim(` ${line}`));
10873
+ }
10271
10874
  } else {
10272
- console.error(import_picocolors9.default.red("✗ Failed to list components:"), error.message);
10875
+ const message = error instanceof Error ? error.message : String(error);
10876
+ console.error(import_picocolors9.default.red("✗ Failed to list functions:"), message);
10273
10877
  }
10274
10878
  process.exit(1);
10275
10879
  }
@@ -10297,7 +10901,7 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
10297
10901
  const functionsDir = resolvedLayout.functionsDir;
10298
10902
  const watchDir = resolvedLayout.convexRootDir;
10299
10903
  const port = opts.port ? parseInt(opts.port, 10) : config.port ?? 3000;
10300
- if (!existsSync(functionsDir)) {
10904
+ if (!existsSync2(functionsDir)) {
10301
10905
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10302
10906
  console.log(import_picocolors9.default.dim(" Create a Convex functions directory with your UDF files"));
10303
10907
  console.log(import_picocolors9.default.dim(` Expected location: ${functionsDir}`));
@@ -10337,7 +10941,7 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
10337
10941
  console.log(import_picocolors9.default.cyan(`
10338
10942
  \uD83D\uDE80 Server ready at ${import_picocolors9.default.bold(displayUrl)}`));
10339
10943
  console.log(import_picocolors9.default.dim(` Dashboard: ${displayUrl}/_dashboard`));
10340
- console.log(import_picocolors9.default.dim(` Functions: ${path14.relative(cwd, functionsDir)}/`));
10944
+ console.log(import_picocolors9.default.dim(` Functions: ${path15.relative(cwd, functionsDir)}/`));
10341
10945
  console.log(import_picocolors9.default.dim(`
10342
10946
  Press Ctrl+C to stop
10343
10947
  `));
@@ -10374,13 +10978,13 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
10374
10978
  persistent: true
10375
10979
  });
10376
10980
  let reloadTimer;
10377
- const scheduleReload = (event, filePath) => {
10981
+ const scheduleReload = (_event, filePath) => {
10378
10982
  if (reloadTimer) {
10379
10983
  clearTimeout(reloadTimer);
10380
10984
  }
10381
10985
  reloadTimer = setTimeout(async () => {
10382
10986
  reloadTimer = undefined;
10383
- const relPath = path14.relative(cwd, filePath);
10987
+ const relPath = path15.relative(cwd, filePath);
10384
10988
  try {
10385
10989
  await generateTypes(cwd, { silent: true });
10386
10990
  } catch {}
@@ -10428,7 +11032,7 @@ async function runBunDevServerForked(cwd, opts, artifacts, layout) {
10428
11032
  const functionsDir = layout.functionsDir;
10429
11033
  const convexDir = layout.convexRootDir;
10430
11034
  const port = opts.port ? parseInt(opts.port, 10) : config.port ?? 3000;
10431
- if (!existsSync(functionsDir)) {
11035
+ if (!existsSync2(functionsDir)) {
10432
11036
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10433
11037
  console.log(import_picocolors9.default.dim(" Create a Convex functions directory with your UDF files"));
10434
11038
  console.log(import_picocolors9.default.dim(` Expected location: ${functionsDir}`));
@@ -10448,7 +11052,7 @@ async function runBunDevServerForked(cwd, opts, artifacts, layout) {
10448
11052
  } catch (error) {
10449
11053
  console.warn(import_picocolors9.default.yellow(`⚠️ Auth keys setup failed: ${error.message}`));
10450
11054
  }
10451
- const tempScriptPath = path14.join(localData.dataDir, ".bun-dev-server.js");
11055
+ const tempScriptPath = path15.join(localData.dataDir, ".bun-dev-server.js");
10452
11056
  const dashboardModulePath = artifacts.dashboardHtmlPath.replace(/\\/g, "/");
10453
11057
  const scriptContent = `import { BunServer } from "${artifacts.bunRuntime.serverEntryPath.replace(/\\/g, "/")}";
10454
11058
  import { DASHBOARD_HTML } from ${JSON.stringify(dashboardModulePath)};
@@ -10465,7 +11069,7 @@ const displayUrl = server.url.replace(/127\\.0\\.0\\.1|0\\.0\\.0\\.0/, "localhos
10465
11069
 
10466
11070
  console.log("\\n\uD83D\uDE80 Server ready at " + displayUrl);
10467
11071
  console.log(" Dashboard: " + displayUrl + "/_dashboard");
10468
- console.log(" Functions: ${path14.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
11072
+ console.log(" Functions: ${path15.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
10469
11073
  console.log("\\n Press Ctrl+C to stop\\n");
10470
11074
 
10471
11075
  // Handle graceful shutdown
@@ -10539,7 +11143,7 @@ function hasTsxLoader() {
10539
11143
  const arg = argv[i];
10540
11144
  if (arg === "--import") {
10541
11145
  const next = argv[i + 1];
10542
- if (next && next.includes("tsx")) {
11146
+ if (next?.includes("tsx")) {
10543
11147
  return true;
10544
11148
  }
10545
11149
  i++;
@@ -10556,7 +11160,7 @@ function resolveTsxLoaderPath() {
10556
11160
  let tsxLoaderPath = "tsx";
10557
11161
  try {
10558
11162
  const tsxPackagePath = require2.resolve("tsx/package.json");
10559
- tsxLoaderPath = path14.join(path14.dirname(tsxPackagePath), "dist/loader.mjs");
11163
+ tsxLoaderPath = path15.join(path15.dirname(tsxPackagePath), "dist/loader.mjs");
10560
11164
  } catch {
10561
11165
  tsxLoaderPath = "tsx";
10562
11166
  }
@@ -10604,7 +11208,7 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
10604
11208
  const functionsDir = resolvedLayout.functionsDir;
10605
11209
  const watchDir = resolvedLayout.convexRootDir;
10606
11210
  const port = opts.port ? parseInt(opts.port, 10) : config.port ?? 3000;
10607
- if (!existsSync(functionsDir)) {
11211
+ if (!existsSync2(functionsDir)) {
10608
11212
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10609
11213
  console.log(import_picocolors9.default.dim(" Create a Convex functions directory with your UDF files"));
10610
11214
  console.log(import_picocolors9.default.dim(` Expected location: ${functionsDir}`));
@@ -10644,7 +11248,7 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
10644
11248
  console.log(import_picocolors9.default.cyan(`
10645
11249
  \uD83D\uDE80 Server ready at ${import_picocolors9.default.bold(displayUrl)}`));
10646
11250
  console.log(import_picocolors9.default.dim(` Dashboard: ${displayUrl}/_dashboard`));
10647
- console.log(import_picocolors9.default.dim(` Functions: ${path14.relative(cwd, functionsDir)}/`));
11251
+ console.log(import_picocolors9.default.dim(` Functions: ${path15.relative(cwd, functionsDir)}/`));
10648
11252
  console.log(import_picocolors9.default.dim(`
10649
11253
  Press Ctrl+C to stop
10650
11254
  `));
@@ -10681,13 +11285,13 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
10681
11285
  persistent: true
10682
11286
  });
10683
11287
  let reloadTimer;
10684
- const scheduleReload = (event, filePath) => {
11288
+ const scheduleReload = (_event, filePath) => {
10685
11289
  if (reloadTimer) {
10686
11290
  clearTimeout(reloadTimer);
10687
11291
  }
10688
11292
  reloadTimer = setTimeout(async () => {
10689
11293
  reloadTimer = undefined;
10690
- const relPath = path14.relative(cwd, filePath);
11294
+ const relPath = path15.relative(cwd, filePath);
10691
11295
  try {
10692
11296
  await generateTypes(cwd, { silent: true });
10693
11297
  } catch {}
@@ -10735,7 +11339,7 @@ async function runNodeDevServerForked(cwd, opts, artifacts, layout) {
10735
11339
  const convexDir = layout.convexRootDir;
10736
11340
  const functionsDir = layout.functionsDir;
10737
11341
  const port = opts.port ? parseInt(opts.port, 10) : config.port ?? 3000;
10738
- if (!existsSync(functionsDir)) {
11342
+ if (!existsSync2(functionsDir)) {
10739
11343
  console.error(import_picocolors9.default.red("✗ No Convex functions directory found"));
10740
11344
  console.log(import_picocolors9.default.dim(" Create a Convex functions directory with your UDF files"));
10741
11345
  console.log(import_picocolors9.default.dim(` Expected location: ${functionsDir}`));
@@ -10759,11 +11363,11 @@ async function runNodeDevServerForked(cwd, opts, artifacts, layout) {
10759
11363
  let tsxLoaderPath;
10760
11364
  try {
10761
11365
  const tsxPackagePath = require2.resolve("tsx/package.json");
10762
- tsxLoaderPath = path14.join(path14.dirname(tsxPackagePath), "dist/loader.mjs");
11366
+ tsxLoaderPath = path15.join(path15.dirname(tsxPackagePath), "dist/loader.mjs");
10763
11367
  } catch {
10764
11368
  tsxLoaderPath = "tsx";
10765
11369
  }
10766
- const tempScriptPath = path14.join(localData.dataDir, ".node-dev-server.mjs");
11370
+ const tempScriptPath = path15.join(localData.dataDir, ".node-dev-server.mjs");
10767
11371
  const nodeDashboardModulePath = artifacts.dashboardHtmlPath.replace(/\\/g, "/");
10768
11372
  const scriptContent = `import { NodeServer } from "${artifacts.nodeRuntime.serverEntryPath.replace(/\\/g, "/")}";
10769
11373
  import { DASHBOARD_HTML } from ${JSON.stringify(nodeDashboardModulePath)};
@@ -10780,7 +11384,7 @@ const displayUrl = server.url.replace(/127\\.0\\.0\\.1|0\\.0\\.0\\.0/, "localhos
10780
11384
 
10781
11385
  console.log("\\n\uD83D\uDE80 Server ready at " + displayUrl);
10782
11386
  console.log(" Dashboard: " + displayUrl + "/_dashboard");
10783
- console.log(" Functions: ${path14.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
11387
+ console.log(" Functions: ${path15.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
10784
11388
  console.log("\\n Press Ctrl+C to stop\\n");
10785
11389
 
10786
11390
  // Handle graceful shutdown
@@ -10805,12 +11409,7 @@ process.on("SIGTERM", async () => {
10805
11409
  });
10806
11410
  `;
10807
11411
  await fs12.writeFile(tempScriptPath, scriptContent, "utf8");
10808
- const nodeArgs = [
10809
- "--experimental-sqlite",
10810
- "--import",
10811
- tsxLoaderPath,
10812
- tempScriptPath
10813
- ];
11412
+ const nodeArgs = ["--experimental-sqlite", "--import", tsxLoaderPath, tempScriptPath];
10814
11413
  const executable = detectHostRuntime() === "node" ? process.execPath : "node";
10815
11414
  const nodeProcess = spawn2(executable, nodeArgs, {
10816
11415
  cwd,
@@ -10829,9 +11428,9 @@ process.on("SIGTERM", async () => {
10829
11428
  }
10830
11429
  async function ensureWranglerConfig(cwd) {
10831
11430
  const userConfigs = [
10832
- path14.join(cwd, "wrangler.jsonc"),
10833
- path14.join(cwd, "wrangler.json"),
10834
- path14.join(cwd, "wrangler.toml")
11431
+ path15.join(cwd, "wrangler.jsonc"),
11432
+ path15.join(cwd, "wrangler.json"),
11433
+ path15.join(cwd, "wrangler.toml")
10835
11434
  ];
10836
11435
  for (const configPath of userConfigs) {
10837
11436
  try {
@@ -10840,8 +11439,8 @@ async function ensureWranglerConfig(cwd) {
10840
11439
  } catch {}
10841
11440
  }
10842
11441
  const concavePaths = getConcaveProjectPaths(cwd);
10843
- const generatedConfigPath = path14.join(concavePaths.concaveDir, "wrangler.jsonc");
10844
- const assetsDirectory = path14.join(concavePaths.concaveDir, "static");
11442
+ const generatedConfigPath = path15.join(concavePaths.concaveDir, "wrangler.jsonc");
11443
+ const assetsDirectory = path15.join(concavePaths.concaveDir, "static");
10845
11444
  await fs12.mkdir(assetsDirectory, { recursive: true });
10846
11445
  const config = {
10847
11446
  name: "concave-app",
@@ -10849,7 +11448,6 @@ async function ensureWranglerConfig(cwd) {
10849
11448
  compatibility_date: "2025-10-01",
10850
11449
  compatibility_flags: ["enable_ctx_exports", "nodejs_compat", "nodejs_als"],
10851
11450
  assets: {
10852
- binding: "DASHBOARD_ASSETS",
10853
11451
  directory: "./static"
10854
11452
  },
10855
11453
  durable_objects: {
@@ -10863,22 +11461,9 @@ async function ensureWranglerConfig(cwd) {
10863
11461
  tag: "concave-v1",
10864
11462
  new_sqlite_classes: ["ConcaveDO", "SyncDO"]
10865
11463
  }
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
11464
  ]
10880
11465
  };
10881
- await fs12.mkdir(path14.dirname(generatedConfigPath), { recursive: true });
11466
+ await fs12.mkdir(path15.dirname(generatedConfigPath), { recursive: true });
10882
11467
  await fs12.writeFile(generatedConfigPath, JSON.stringify(config, null, 2), "utf8");
10883
11468
  return generatedConfigPath;
10884
11469
  }