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