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