@concavejs/cli 0.0.1-alpha.7 → 0.0.1-alpha.9
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 +3998 -3098
- package/dist/assets/runtime-cf/runtime.bundle.js +19079 -12601
- package/dist/assets/runtime-node/server/index.js +3837 -2930
- package/dist/cli.js +924 -318
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -3921,7 +3921,7 @@ ${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`;
|
|
|
3921
3921
|
}
|
|
3922
3922
|
var fs8 = __require("fs");
|
|
3923
3923
|
var os = __require("os");
|
|
3924
|
-
var
|
|
3924
|
+
var path11 = __require("path");
|
|
3925
3925
|
var ESBUILD_BINARY_PATH = process.env.ESBUILD_BINARY_PATH || ESBUILD_BINARY_PATH;
|
|
3926
3926
|
var isValidBinaryPath = (x) => !!x && x !== "/usr/bin/esbuild";
|
|
3927
3927
|
var packageDarwin_arm64 = "@esbuild/darwin-arm64";
|
|
@@ -3979,19 +3979,19 @@ ${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`;
|
|
|
3979
3979
|
}
|
|
3980
3980
|
function pkgForSomeOtherPlatform() {
|
|
3981
3981
|
const libMainJS = __require.resolve("esbuild");
|
|
3982
|
-
const nodeModulesDirectory =
|
|
3983
|
-
if (
|
|
3982
|
+
const nodeModulesDirectory = path11.dirname(path11.dirname(path11.dirname(libMainJS)));
|
|
3983
|
+
if (path11.basename(nodeModulesDirectory) === "node_modules") {
|
|
3984
3984
|
for (const unixKey in knownUnixlikePackages) {
|
|
3985
3985
|
try {
|
|
3986
3986
|
const pkg = knownUnixlikePackages[unixKey];
|
|
3987
|
-
if (fs8.existsSync(
|
|
3987
|
+
if (fs8.existsSync(path11.join(nodeModulesDirectory, pkg)))
|
|
3988
3988
|
return pkg;
|
|
3989
3989
|
} catch {}
|
|
3990
3990
|
}
|
|
3991
3991
|
for (const windowsKey in knownWindowsPackages) {
|
|
3992
3992
|
try {
|
|
3993
3993
|
const pkg = knownWindowsPackages[windowsKey];
|
|
3994
|
-
if (fs8.existsSync(
|
|
3994
|
+
if (fs8.existsSync(path11.join(nodeModulesDirectory, pkg)))
|
|
3995
3995
|
return pkg;
|
|
3996
3996
|
} catch {}
|
|
3997
3997
|
}
|
|
@@ -3999,8 +3999,8 @@ ${file}:${line}:${column}: ERROR: ${pluginText}${e.text}`;
|
|
|
3999
3999
|
return null;
|
|
4000
4000
|
}
|
|
4001
4001
|
function downloadedBinPath(pkg, subpath) {
|
|
4002
|
-
const esbuildLibDir =
|
|
4003
|
-
return
|
|
4002
|
+
const esbuildLibDir = path11.dirname(__require.resolve("esbuild"));
|
|
4003
|
+
return path11.join(esbuildLibDir, `downloaded-${pkg.replace("/", "-")}-${path11.basename(subpath)}`);
|
|
4004
4004
|
}
|
|
4005
4005
|
function generateBinPath() {
|
|
4006
4006
|
if (isValidBinaryPath(ESBUILD_BINARY_PATH)) {
|
|
@@ -4089,9 +4089,9 @@ for your current platform.`);
|
|
|
4089
4089
|
} catch (e) {}
|
|
4090
4090
|
if (pnpapi) {
|
|
4091
4091
|
const root = pnpapi.getPackageInformation(pnpapi.topLevel).packageLocation;
|
|
4092
|
-
const binTargetPath =
|
|
4092
|
+
const binTargetPath = path11.join(root, "node_modules", ".cache", "esbuild", `pnpapi-${pkg.replace("/", "-")}-${"0.24.2"}-${path11.basename(subpath)}`);
|
|
4093
4093
|
if (!fs8.existsSync(binTargetPath)) {
|
|
4094
|
-
fs8.mkdirSync(
|
|
4094
|
+
fs8.mkdirSync(path11.dirname(binTargetPath), { recursive: true });
|
|
4095
4095
|
fs8.copyFileSync(binPath, binTargetPath);
|
|
4096
4096
|
fs8.chmodSync(binTargetPath, 493);
|
|
4097
4097
|
}
|
|
@@ -4757,7 +4757,7 @@ async function loadAppDefinition(configPath, parentComponentPath, entries, visit
|
|
|
4757
4757
|
for (const child of childComponents) {
|
|
4758
4758
|
const componentPath = joinComponentPath(parentComponentPath, child.name);
|
|
4759
4759
|
const definitionPath = resolveChildDefinitionPath(configPath, child.path);
|
|
4760
|
-
const modulesDir =
|
|
4760
|
+
const modulesDir = await resolveComponentModulesDir(definitionPath);
|
|
4761
4761
|
entries.push({
|
|
4762
4762
|
componentPath,
|
|
4763
4763
|
modulesDir,
|
|
@@ -4780,7 +4780,7 @@ async function loadComponentDefinition(configPath, componentPath, entries, visit
|
|
|
4780
4780
|
for (const child of childComponents) {
|
|
4781
4781
|
const nestedComponentPath = joinComponentPath(componentPath, child.name);
|
|
4782
4782
|
const definitionPath = resolveChildDefinitionPath(configPath, child.path);
|
|
4783
|
-
const modulesDir =
|
|
4783
|
+
const modulesDir = await resolveComponentModulesDir(definitionPath);
|
|
4784
4784
|
entries.push({
|
|
4785
4785
|
componentPath: nestedComponentPath,
|
|
4786
4786
|
modulesDir,
|
|
@@ -4806,6 +4806,17 @@ function resolveChildDefinitionPath(parentConfigPath, childPath) {
|
|
|
4806
4806
|
const parentDir = path.dirname(parentConfigPath);
|
|
4807
4807
|
return path.resolve(parentDir, childPath);
|
|
4808
4808
|
}
|
|
4809
|
+
async function resolveComponentModulesDir(definitionPath) {
|
|
4810
|
+
const definitionDir = path.dirname(definitionPath);
|
|
4811
|
+
const nestedConvexDir = path.join(definitionDir, "convex");
|
|
4812
|
+
try {
|
|
4813
|
+
const stats = await fs.stat(nestedConvexDir);
|
|
4814
|
+
if (stats.isDirectory()) {
|
|
4815
|
+
return nestedConvexDir;
|
|
4816
|
+
}
|
|
4817
|
+
} catch {}
|
|
4818
|
+
return definitionDir;
|
|
4819
|
+
}
|
|
4809
4820
|
function joinComponentPath(parent, child) {
|
|
4810
4821
|
if (!parent) {
|
|
4811
4822
|
return child;
|
|
@@ -5006,6 +5017,7 @@ for (const { componentPath, loader } of componentLoaders) {
|
|
|
5006
5017
|
const runtime = defineConcaveRuntime(${runtimeOptions});
|
|
5007
5018
|
export const ConcaveDO = runtime.ConcaveDO;
|
|
5008
5019
|
export const SyncDO = runtime.SyncDO;
|
|
5020
|
+
export const SyncCoordinatorDO = runtime.SyncCoordinatorDO;
|
|
5009
5021
|
export { UdfExecutorRpc };
|
|
5010
5022
|
export default runtime.worker;
|
|
5011
5023
|
`;
|
|
@@ -5146,6 +5158,7 @@ async function generateUserEntry(projectRoot, outDir) {
|
|
|
5146
5158
|
const componentManifest = await scanComponents(projectRoot);
|
|
5147
5159
|
await writeComponentManifest(targetDir, componentManifest.entries);
|
|
5148
5160
|
await copyComponentModules(targetDir, componentManifest.entries);
|
|
5161
|
+
const componentLoaderBlocks = await buildComponentLoaderBlocks(targetDir, componentManifest.entries);
|
|
5149
5162
|
const fallbackEntries = files.map((filePath) => {
|
|
5150
5163
|
const importPath = formatImportPath(targetDir, filePath);
|
|
5151
5164
|
return ` '${importPath}': () => import('${importPath}'),`;
|
|
@@ -5154,10 +5167,20 @@ async function generateUserEntry(projectRoot, outDir) {
|
|
|
5154
5167
|
const content = `// Generated by concave CLI
|
|
5155
5168
|
// Do not edit this file manually
|
|
5156
5169
|
|
|
5170
|
+
import { createModuleLoaderFromGlob, setConcaveModuleLoader } from "@concavejs/core/udf";
|
|
5171
|
+
|
|
5157
5172
|
const modules = import.meta?.glob?.(["../convex/**/*.*s", "!../**/*.*.*s"]) ?? {
|
|
5158
5173
|
${fallbackEntries}
|
|
5159
5174
|
};
|
|
5160
5175
|
|
|
5176
|
+
const componentLoaders = [];
|
|
5177
|
+
${componentLoaderBlocks.join(`
|
|
5178
|
+
|
|
5179
|
+
`)}
|
|
5180
|
+
for (const { componentPath, loader } of componentLoaders) {
|
|
5181
|
+
setConcaveModuleLoader(loader, { componentPath });
|
|
5182
|
+
}
|
|
5183
|
+
|
|
5161
5184
|
export { modules };
|
|
5162
5185
|
`;
|
|
5163
5186
|
const contentWithFunctionsPath = content.replace('const modules = import.meta?.glob?.(["../convex/**/*.*s", "!../**/*.*.*s"]) ?? {', `const modules = import.meta?.glob?.([${JSON.stringify(functionsGlobPattern)}, "!../**/*.*.*s"]) ?? {`);
|
|
@@ -5462,7 +5485,7 @@ function getProjectName(state, projectRoot) {
|
|
|
5462
5485
|
// src/cli/deploy/cloudflare.ts
|
|
5463
5486
|
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
5464
5487
|
import { promises as fs7 } from "node:fs";
|
|
5465
|
-
import
|
|
5488
|
+
import path10 from "node:path";
|
|
5466
5489
|
|
|
5467
5490
|
// src/cli/artifacts.ts
|
|
5468
5491
|
import { cp, copyFile, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -5573,7 +5596,147 @@ async function copyIfDifferent(source, destination) {
|
|
|
5573
5596
|
}
|
|
5574
5597
|
|
|
5575
5598
|
// src/cli/deploy/resources.ts
|
|
5576
|
-
import {
|
|
5599
|
+
import {
|
|
5600
|
+
spawn
|
|
5601
|
+
} from "node:child_process";
|
|
5602
|
+
|
|
5603
|
+
// src/cli/deploy/wrangler-launcher.ts
|
|
5604
|
+
import { accessSync, constants as fsConstants } from "node:fs";
|
|
5605
|
+
import path8 from "node:path";
|
|
5606
|
+
var WRANGLER_LAUNCHERS = [
|
|
5607
|
+
{ command: "wrangler", argsPrefix: [], description: "wrangler" },
|
|
5608
|
+
{ command: "bunx", argsPrefix: ["wrangler"], description: "bunx wrangler" },
|
|
5609
|
+
{ command: "npx", argsPrefix: ["wrangler"], description: "npx wrangler" },
|
|
5610
|
+
{ command: "npm", argsPrefix: ["exec", "--", "wrangler"], description: "npm exec -- wrangler" },
|
|
5611
|
+
{ command: "pnpm", argsPrefix: ["exec", "wrangler"], description: "pnpm exec wrangler" }
|
|
5612
|
+
];
|
|
5613
|
+
var WRANGLER_BIN_NOT_FOUND_MESSAGE = "Wrangler CLI is not available. Install it with `bun add -d wrangler` or `npm install -D wrangler`, or install `wrangler` globally.";
|
|
5614
|
+
|
|
5615
|
+
class WranglerNotFoundError extends Error {
|
|
5616
|
+
constructor(message = WRANGLER_BIN_NOT_FOUND_MESSAGE) {
|
|
5617
|
+
super(message);
|
|
5618
|
+
this.name = "WranglerNotFoundError";
|
|
5619
|
+
}
|
|
5620
|
+
}
|
|
5621
|
+
function resolveWranglerLauncher(options = {}) {
|
|
5622
|
+
const cwd = options.cwd || process.cwd();
|
|
5623
|
+
const env = options.env || process.env;
|
|
5624
|
+
const localBin = findLocalWranglerBin(cwd);
|
|
5625
|
+
if (localBin) {
|
|
5626
|
+
return {
|
|
5627
|
+
command: localBin,
|
|
5628
|
+
argsPrefix: [],
|
|
5629
|
+
description: "local node_modules/.bin/wrangler"
|
|
5630
|
+
};
|
|
5631
|
+
}
|
|
5632
|
+
for (const launcher of WRANGLER_LAUNCHERS) {
|
|
5633
|
+
if (isCommandAvailable(launcher.command, env)) {
|
|
5634
|
+
return launcher;
|
|
5635
|
+
}
|
|
5636
|
+
}
|
|
5637
|
+
const attempted = WRANGLER_LAUNCHERS.map((launcher) => launcher.description).join(", ");
|
|
5638
|
+
throw new WranglerNotFoundError(`${WRANGLER_BIN_NOT_FOUND_MESSAGE} Tried: ${attempted}.`);
|
|
5639
|
+
}
|
|
5640
|
+
function findLocalWranglerBin(cwd) {
|
|
5641
|
+
const candidates = process.platform === "win32" ? ["wrangler.cmd", "wrangler.exe", "wrangler"] : ["wrangler"];
|
|
5642
|
+
for (const dir of walkUpDirectories(cwd)) {
|
|
5643
|
+
const binDir = path8.join(dir, "node_modules", ".bin");
|
|
5644
|
+
for (const candidate of candidates) {
|
|
5645
|
+
const fullPath = path8.join(binDir, candidate);
|
|
5646
|
+
if (isExecutable(fullPath)) {
|
|
5647
|
+
return fullPath;
|
|
5648
|
+
}
|
|
5649
|
+
}
|
|
5650
|
+
}
|
|
5651
|
+
return null;
|
|
5652
|
+
}
|
|
5653
|
+
function isCommandAvailable(command, env) {
|
|
5654
|
+
return resolveOnPath(command, env) !== null;
|
|
5655
|
+
}
|
|
5656
|
+
function resolveOnPath(command, env) {
|
|
5657
|
+
if (hasPathSeparator(command)) {
|
|
5658
|
+
return isExecutable(command) ? command : null;
|
|
5659
|
+
}
|
|
5660
|
+
const pathValue = getEnvVar(env, "PATH") || "";
|
|
5661
|
+
const pathEntries = pathValue.split(path8.delimiter).filter((entry) => entry.length > 0);
|
|
5662
|
+
const commandNames = getCommandNamesForPlatform(command, env);
|
|
5663
|
+
for (const entry of pathEntries) {
|
|
5664
|
+
for (const commandName of commandNames) {
|
|
5665
|
+
const candidate = path8.join(entry, commandName);
|
|
5666
|
+
if (isExecutable(candidate)) {
|
|
5667
|
+
return candidate;
|
|
5668
|
+
}
|
|
5669
|
+
}
|
|
5670
|
+
}
|
|
5671
|
+
return null;
|
|
5672
|
+
}
|
|
5673
|
+
function getCommandNamesForPlatform(command, env) {
|
|
5674
|
+
if (process.platform !== "win32") {
|
|
5675
|
+
return [command];
|
|
5676
|
+
}
|
|
5677
|
+
if (path8.extname(command)) {
|
|
5678
|
+
return [command];
|
|
5679
|
+
}
|
|
5680
|
+
const pathExt = getEnvVar(env, "PATHEXT") || ".COM;.EXE;.BAT;.CMD";
|
|
5681
|
+
const extensions = pathExt.split(";").map((ext) => ext.trim()).filter((ext) => ext.length > 0);
|
|
5682
|
+
return [command, ...extensions.map((ext) => `${command}${ext}`)];
|
|
5683
|
+
}
|
|
5684
|
+
function hasPathSeparator(command) {
|
|
5685
|
+
return command.includes("/") || command.includes("\\");
|
|
5686
|
+
}
|
|
5687
|
+
function walkUpDirectories(startDir) {
|
|
5688
|
+
const directories = [];
|
|
5689
|
+
let current = path8.resolve(startDir);
|
|
5690
|
+
while (true) {
|
|
5691
|
+
directories.push(current);
|
|
5692
|
+
const parent = path8.dirname(current);
|
|
5693
|
+
if (parent === current) {
|
|
5694
|
+
break;
|
|
5695
|
+
}
|
|
5696
|
+
current = parent;
|
|
5697
|
+
}
|
|
5698
|
+
return directories;
|
|
5699
|
+
}
|
|
5700
|
+
function getEnvVar(env, key) {
|
|
5701
|
+
const direct = env[key];
|
|
5702
|
+
if (typeof direct === "string") {
|
|
5703
|
+
return direct;
|
|
5704
|
+
}
|
|
5705
|
+
const lowerKey = key.toLowerCase();
|
|
5706
|
+
for (const [envKey, envValue] of Object.entries(env)) {
|
|
5707
|
+
if (envKey.toLowerCase() === lowerKey && typeof envValue === "string") {
|
|
5708
|
+
return envValue;
|
|
5709
|
+
}
|
|
5710
|
+
}
|
|
5711
|
+
return;
|
|
5712
|
+
}
|
|
5713
|
+
function isExecutable(filePath) {
|
|
5714
|
+
try {
|
|
5715
|
+
const mode = process.platform === "win32" ? fsConstants.F_OK : fsConstants.X_OK;
|
|
5716
|
+
accessSync(filePath, mode);
|
|
5717
|
+
return true;
|
|
5718
|
+
} catch {
|
|
5719
|
+
return false;
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
|
|
5723
|
+
// src/cli/deploy/resources.ts
|
|
5724
|
+
function spawnWrangler(args, options) {
|
|
5725
|
+
const cwd = typeof options.cwd === "string" ? options.cwd : process.cwd();
|
|
5726
|
+
const env = options.env || process.env;
|
|
5727
|
+
const launcher = resolveWranglerLauncher({ cwd, env });
|
|
5728
|
+
return spawn(launcher.command, [...launcher.argsPrefix, ...args], {
|
|
5729
|
+
cwd,
|
|
5730
|
+
env,
|
|
5731
|
+
stdio: options.stdio
|
|
5732
|
+
});
|
|
5733
|
+
}
|
|
5734
|
+
function toWranglerRunError(prefix, error) {
|
|
5735
|
+
if (error.code === "ENOENT") {
|
|
5736
|
+
return new WranglerNotFoundError;
|
|
5737
|
+
}
|
|
5738
|
+
return new Error(`${prefix}: ${error.message}`);
|
|
5739
|
+
}
|
|
5577
5740
|
async function runWrangler(args, options = {}) {
|
|
5578
5741
|
return new Promise((resolve, reject) => {
|
|
5579
5742
|
const chunks = [];
|
|
@@ -5585,11 +5748,17 @@ async function runWrangler(args, options = {}) {
|
|
|
5585
5748
|
if (options.accountId) {
|
|
5586
5749
|
env.CLOUDFLARE_ACCOUNT_ID = options.accountId;
|
|
5587
5750
|
}
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5751
|
+
let proc;
|
|
5752
|
+
try {
|
|
5753
|
+
proc = spawnWrangler(args, {
|
|
5754
|
+
cwd: options.cwd || process.cwd(),
|
|
5755
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
5756
|
+
env
|
|
5757
|
+
});
|
|
5758
|
+
} catch (error) {
|
|
5759
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
5760
|
+
return;
|
|
5761
|
+
}
|
|
5593
5762
|
proc.stdout.on("data", (chunk) => chunks.push(chunk));
|
|
5594
5763
|
proc.stderr.on("data", (chunk) => errorChunks.push(chunk));
|
|
5595
5764
|
proc.on("close", (code) => {
|
|
@@ -5607,16 +5776,22 @@ ${stderr}`);
|
|
|
5607
5776
|
}
|
|
5608
5777
|
});
|
|
5609
5778
|
proc.on("error", (error) => {
|
|
5610
|
-
reject(
|
|
5779
|
+
reject(toWranglerRunError("Failed to run wrangler", error));
|
|
5611
5780
|
});
|
|
5612
5781
|
});
|
|
5613
5782
|
}
|
|
5614
5783
|
async function runWranglerDeploy(configPath, options = {}) {
|
|
5615
5784
|
return new Promise((resolve, reject) => {
|
|
5616
|
-
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5785
|
+
let proc;
|
|
5786
|
+
try {
|
|
5787
|
+
proc = spawnWrangler(["deploy", "--config", configPath], {
|
|
5788
|
+
cwd: options.cwd || process.cwd(),
|
|
5789
|
+
stdio: "inherit"
|
|
5790
|
+
});
|
|
5791
|
+
} catch (error) {
|
|
5792
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
5793
|
+
return;
|
|
5794
|
+
}
|
|
5620
5795
|
proc.on("close", (code) => {
|
|
5621
5796
|
if (code === 0) {
|
|
5622
5797
|
resolve();
|
|
@@ -5625,7 +5800,7 @@ async function runWranglerDeploy(configPath, options = {}) {
|
|
|
5625
5800
|
}
|
|
5626
5801
|
});
|
|
5627
5802
|
proc.on("error", (error) => {
|
|
5628
|
-
reject(
|
|
5803
|
+
reject(toWranglerRunError("Failed to run wrangler deploy", error));
|
|
5629
5804
|
});
|
|
5630
5805
|
});
|
|
5631
5806
|
}
|
|
@@ -5644,18 +5819,25 @@ async function checkWranglerAuth() {
|
|
|
5644
5819
|
email: emailMatch?.[1]
|
|
5645
5820
|
};
|
|
5646
5821
|
} catch (error) {
|
|
5822
|
+
if (error instanceof WranglerNotFoundError) {
|
|
5823
|
+
throw error;
|
|
5824
|
+
}
|
|
5647
5825
|
const errorText = (error.stderr || "") + (error.stdout || "");
|
|
5648
5826
|
if (errorText.includes("not logged in") || errorText.includes("You are not authenticated")) {
|
|
5649
5827
|
return null;
|
|
5650
5828
|
}
|
|
5651
|
-
|
|
5829
|
+
throw new Error(`Failed to check Cloudflare authentication: ${error.message}`);
|
|
5652
5830
|
}
|
|
5653
5831
|
}
|
|
5654
5832
|
async function wranglerLogin() {
|
|
5655
5833
|
return new Promise((resolve, reject) => {
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5834
|
+
let proc;
|
|
5835
|
+
try {
|
|
5836
|
+
proc = spawnWrangler(["login"], { stdio: "inherit" });
|
|
5837
|
+
} catch (error) {
|
|
5838
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
5839
|
+
return;
|
|
5840
|
+
}
|
|
5659
5841
|
proc.on("close", async (code) => {
|
|
5660
5842
|
if (code === 0) {
|
|
5661
5843
|
const auth = await checkWranglerAuth();
|
|
@@ -5669,7 +5851,7 @@ async function wranglerLogin() {
|
|
|
5669
5851
|
}
|
|
5670
5852
|
});
|
|
5671
5853
|
proc.on("error", (error) => {
|
|
5672
|
-
reject(
|
|
5854
|
+
reject(toWranglerRunError("Failed to run wrangler login", error));
|
|
5673
5855
|
});
|
|
5674
5856
|
});
|
|
5675
5857
|
}
|
|
@@ -5769,13 +5951,19 @@ async function ensureR2Bucket(name, accountId) {
|
|
|
5769
5951
|
}
|
|
5770
5952
|
async function setWorkerSecret(workerName, secretName, secretValue) {
|
|
5771
5953
|
return new Promise((resolve, reject) => {
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5954
|
+
let proc;
|
|
5955
|
+
try {
|
|
5956
|
+
proc = spawnWrangler(["secret", "put", secretName, "--name", workerName], {
|
|
5957
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
5958
|
+
env: {
|
|
5959
|
+
...process.env,
|
|
5960
|
+
CI: "true"
|
|
5961
|
+
}
|
|
5962
|
+
});
|
|
5963
|
+
} catch (error) {
|
|
5964
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
5965
|
+
return;
|
|
5966
|
+
}
|
|
5779
5967
|
proc.stdin.write(secretValue);
|
|
5780
5968
|
proc.stdin.end();
|
|
5781
5969
|
let stderr = "";
|
|
@@ -5790,7 +5978,7 @@ async function setWorkerSecret(workerName, secretName, secretValue) {
|
|
|
5790
5978
|
}
|
|
5791
5979
|
});
|
|
5792
5980
|
proc.on("error", (error) => {
|
|
5793
|
-
reject(
|
|
5981
|
+
reject(toWranglerRunError("Failed to run wrangler secret", error));
|
|
5794
5982
|
});
|
|
5795
5983
|
});
|
|
5796
5984
|
}
|
|
@@ -5815,7 +6003,7 @@ function getWorkerUrl(workerName, accountSubdomain) {
|
|
|
5815
6003
|
|
|
5816
6004
|
// src/cli/deploy/secrets.ts
|
|
5817
6005
|
import { promises as fs6 } from "node:fs";
|
|
5818
|
-
import
|
|
6006
|
+
import path9 from "node:path";
|
|
5819
6007
|
var EXCLUDED_VARS = new Set([
|
|
5820
6008
|
"NODE_ENV",
|
|
5821
6009
|
"PATH",
|
|
@@ -5913,7 +6101,7 @@ async function detectEnvFiles(projectRoot) {
|
|
|
5913
6101
|
];
|
|
5914
6102
|
const envFiles = [];
|
|
5915
6103
|
for (const name of envFileNames) {
|
|
5916
|
-
const filePath =
|
|
6104
|
+
const filePath = path9.join(projectRoot, name);
|
|
5917
6105
|
const envFile = await loadEnvFile(filePath);
|
|
5918
6106
|
if (envFile) {
|
|
5919
6107
|
envFiles.push(envFile);
|
|
@@ -6182,7 +6370,13 @@ async function runFirstTimeSetup(projectRoot, _existingState, options) {
|
|
|
6182
6370
|
printDryRunNotice();
|
|
6183
6371
|
}
|
|
6184
6372
|
const spinner = createSpinner("Checking Cloudflare authentication...");
|
|
6185
|
-
let auth
|
|
6373
|
+
let auth;
|
|
6374
|
+
try {
|
|
6375
|
+
auth = await checkWranglerAuth();
|
|
6376
|
+
} catch (error) {
|
|
6377
|
+
spinner.stop();
|
|
6378
|
+
throw error;
|
|
6379
|
+
}
|
|
6186
6380
|
if (!auth || !auth.accountId) {
|
|
6187
6381
|
spinner.stop();
|
|
6188
6382
|
console.log(import_picocolors2.default.dim(` Not logged in. Opening browser to authenticate...
|
|
@@ -6392,7 +6586,7 @@ async function buildAndDeploy(projectRoot, workerName, config) {
|
|
|
6392
6586
|
}
|
|
6393
6587
|
async function generateWranglerConfig(projectRoot, workerName, config) {
|
|
6394
6588
|
const concaveDir = getConcaveProjectPaths(projectRoot).concaveDir;
|
|
6395
|
-
const configPath =
|
|
6589
|
+
const configPath = path10.join(concaveDir, "wrangler.jsonc");
|
|
6396
6590
|
const wranglerConfig = {
|
|
6397
6591
|
$schema: "https://json.schemastore.org/wrangler.json",
|
|
6398
6592
|
name: workerName,
|
|
@@ -6441,7 +6635,7 @@ async function generateWranglerConfig(projectRoot, workerName, config) {
|
|
|
6441
6635
|
];
|
|
6442
6636
|
}
|
|
6443
6637
|
await fs7.mkdir(concaveDir, { recursive: true });
|
|
6444
|
-
await fs7.mkdir(
|
|
6638
|
+
await fs7.mkdir(path10.join(concaveDir, "static"), { recursive: true });
|
|
6445
6639
|
await fs7.writeFile(configPath, JSON.stringify(wranglerConfig, null, 2), "utf8");
|
|
6446
6640
|
return configPath;
|
|
6447
6641
|
}
|
|
@@ -6489,7 +6683,7 @@ async function handleSecrets(projectRoot, workerName, previousHashes, options) {
|
|
|
6489
6683
|
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
6490
6684
|
var import_esbuild = __toESM(require_main(), 1);
|
|
6491
6685
|
import { promises as fs8 } from "node:fs";
|
|
6492
|
-
import
|
|
6686
|
+
import path11 from "node:path";
|
|
6493
6687
|
function componentDefinitionPlugin() {
|
|
6494
6688
|
return {
|
|
6495
6689
|
name: "concave-component-definition",
|
|
@@ -6521,14 +6715,14 @@ export default __componentDef;
|
|
|
6521
6715
|
}
|
|
6522
6716
|
async function deploy(projectRoot, options) {
|
|
6523
6717
|
const { cloudUrl, environment = "development", verbose = false } = options;
|
|
6524
|
-
const convexDir =
|
|
6718
|
+
const convexDir = path11.join(projectRoot, "convex");
|
|
6525
6719
|
try {
|
|
6526
6720
|
await fs8.access(convexDir);
|
|
6527
6721
|
} catch {
|
|
6528
6722
|
throw new Error(`No convex/ directory found at ${convexDir}`);
|
|
6529
6723
|
}
|
|
6530
6724
|
let projectId = options.projectId;
|
|
6531
|
-
const projectSlug = options.projectSlug ||
|
|
6725
|
+
const projectSlug = options.projectSlug || path11.basename(projectRoot);
|
|
6532
6726
|
if (!projectId) {
|
|
6533
6727
|
projectId = generateProjectId(projectSlug);
|
|
6534
6728
|
if (verbose) {
|
|
@@ -6594,7 +6788,7 @@ async function ensureProject(cloudUrl, projectId, projectSlug) {
|
|
|
6594
6788
|
}
|
|
6595
6789
|
}
|
|
6596
6790
|
async function bundleProject(projectRoot, _verbose) {
|
|
6597
|
-
const buildDir =
|
|
6791
|
+
const buildDir = path11.join(getConcaveProjectPaths(projectRoot).concaveDir, "cloud");
|
|
6598
6792
|
try {
|
|
6599
6793
|
await fs8.rm(buildDir, { recursive: true, force: true });
|
|
6600
6794
|
} catch {}
|
|
@@ -6658,8 +6852,8 @@ async function getRouting(cloudUrl, projectId, environment) {
|
|
|
6658
6852
|
method: "GET"
|
|
6659
6853
|
});
|
|
6660
6854
|
}
|
|
6661
|
-
async function cloudRequest(cloudUrl,
|
|
6662
|
-
const url = `${cloudUrl}${
|
|
6855
|
+
async function cloudRequest(cloudUrl, path12, init) {
|
|
6856
|
+
const url = `${cloudUrl}${path12}`;
|
|
6663
6857
|
const response = await fetch(url, {
|
|
6664
6858
|
...init,
|
|
6665
6859
|
headers: {
|
|
@@ -6787,7 +6981,7 @@ var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
|
6787
6981
|
|
|
6788
6982
|
// src/cli/url-utils.ts
|
|
6789
6983
|
import { existsSync, readFileSync } from "node:fs";
|
|
6790
|
-
import
|
|
6984
|
+
import path12 from "node:path";
|
|
6791
6985
|
var URL_ENV_KEYS = [
|
|
6792
6986
|
"CONCAVE_URL",
|
|
6793
6987
|
"CONVEX_URL",
|
|
@@ -6835,7 +7029,7 @@ function resolveBaseUrl(options, cwd = process.cwd()) {
|
|
|
6835
7029
|
return {
|
|
6836
7030
|
baseUrl: normalizeUrl(fromFiles.value),
|
|
6837
7031
|
source: "environment-file",
|
|
6838
|
-
sourceDetail: `${fromFiles.key} from ${
|
|
7032
|
+
sourceDetail: `${fromFiles.key} from ${path12.relative(cwd, fromFiles.filePath) || path12.basename(fromFiles.filePath)}`
|
|
6839
7033
|
};
|
|
6840
7034
|
}
|
|
6841
7035
|
const port = options.port || "3000";
|
|
@@ -6922,16 +7116,16 @@ function getUrlFromEnvFiles(cwd) {
|
|
|
6922
7116
|
function getEnvFileCandidates(cwd) {
|
|
6923
7117
|
const convexRoot = detectConvexRoot(cwd);
|
|
6924
7118
|
const candidates = [
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
7119
|
+
path12.join(convexRoot, ".env.local"),
|
|
7120
|
+
path12.join(convexRoot, ".env"),
|
|
7121
|
+
path12.join(cwd, ".env.local"),
|
|
7122
|
+
path12.join(cwd, ".env")
|
|
6929
7123
|
];
|
|
6930
7124
|
return [...new Set(candidates)];
|
|
6931
7125
|
}
|
|
6932
7126
|
function detectConvexRoot(cwd) {
|
|
6933
|
-
const convexJsonPath =
|
|
6934
|
-
const fallback =
|
|
7127
|
+
const convexJsonPath = path12.join(cwd, "convex.json");
|
|
7128
|
+
const fallback = path12.join(cwd, "convex");
|
|
6935
7129
|
if (!existsSync(convexJsonPath)) {
|
|
6936
7130
|
return fallback;
|
|
6937
7131
|
}
|
|
@@ -6944,11 +7138,11 @@ function detectConvexRoot(cwd) {
|
|
|
6944
7138
|
if (!normalized) {
|
|
6945
7139
|
return fallback;
|
|
6946
7140
|
}
|
|
6947
|
-
const root = normalized.includes("/") ?
|
|
7141
|
+
const root = normalized.includes("/") ? path12.posix.dirname(normalized) : normalized;
|
|
6948
7142
|
if (!root || root === ".") {
|
|
6949
7143
|
return fallback;
|
|
6950
7144
|
}
|
|
6951
|
-
return
|
|
7145
|
+
return path12.resolve(cwd, root);
|
|
6952
7146
|
} catch {
|
|
6953
7147
|
return fallback;
|
|
6954
7148
|
}
|
|
@@ -7301,11 +7495,11 @@ function formatValue(value) {
|
|
|
7301
7495
|
// src/cli/type-codegen.ts
|
|
7302
7496
|
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
7303
7497
|
import { promises as fs9 } from "node:fs";
|
|
7304
|
-
import
|
|
7498
|
+
import path13 from "node:path";
|
|
7305
7499
|
async function generateTypes(projectRoot, options = {}) {
|
|
7306
7500
|
const layout = await resolveProjectLayout(projectRoot);
|
|
7307
7501
|
const convexDir = layout.functionsDir;
|
|
7308
|
-
const generatedDir =
|
|
7502
|
+
const generatedDir = path13.join(convexDir, "_generated");
|
|
7309
7503
|
try {
|
|
7310
7504
|
await fs9.access(convexDir);
|
|
7311
7505
|
} catch {
|
|
@@ -7334,7 +7528,7 @@ async function discoverModules(convexDir) {
|
|
|
7334
7528
|
if (entry.name.startsWith(".") || entry.name === "_generated" || entry.name === "node_modules") {
|
|
7335
7529
|
continue;
|
|
7336
7530
|
}
|
|
7337
|
-
const fullPath =
|
|
7531
|
+
const fullPath = path13.join(dir, entry.name);
|
|
7338
7532
|
const entryRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
7339
7533
|
if (entry.isDirectory()) {
|
|
7340
7534
|
await walk(fullPath, entryRelativePath);
|
|
@@ -7387,6 +7581,8 @@ import {
|
|
|
7387
7581
|
} from "convex/server";
|
|
7388
7582
|
import type { DataModel } from "./dataModel.js";
|
|
7389
7583
|
|
|
7584
|
+
export { defineSchema, defineTable } from "convex/server";
|
|
7585
|
+
|
|
7390
7586
|
/**
|
|
7391
7587
|
* Define a query in this Convex app's public API.
|
|
7392
7588
|
*
|
|
@@ -7507,7 +7703,7 @@ export type DatabaseReader = GenericDatabaseReader<DataModel>;
|
|
|
7507
7703
|
*/
|
|
7508
7704
|
export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
|
|
7509
7705
|
`;
|
|
7510
|
-
await fs9.writeFile(
|
|
7706
|
+
await fs9.writeFile(path13.join(generatedDir, "server.d.ts"), content, "utf8");
|
|
7511
7707
|
}
|
|
7512
7708
|
async function generateServerJs(generatedDir) {
|
|
7513
7709
|
const content = `/* eslint-disable */
|
|
@@ -7528,6 +7724,8 @@ import {
|
|
|
7528
7724
|
internalActionGeneric,
|
|
7529
7725
|
internalMutationGeneric,
|
|
7530
7726
|
internalQueryGeneric,
|
|
7727
|
+
defineSchema,
|
|
7728
|
+
defineTable,
|
|
7531
7729
|
} from "convex/server";
|
|
7532
7730
|
|
|
7533
7731
|
/**
|
|
@@ -7599,8 +7797,13 @@ export const internalAction = internalActionGeneric;
|
|
|
7599
7797
|
* @returns The wrapped endpoint function. Route a URL path to this function in \`convex/http.js\`.
|
|
7600
7798
|
*/
|
|
7601
7799
|
export const httpAction = httpActionGeneric;
|
|
7800
|
+
|
|
7801
|
+
/**
|
|
7802
|
+
* Define a table in this Convex app's schema.
|
|
7803
|
+
*/
|
|
7804
|
+
export { defineTable, defineSchema };
|
|
7602
7805
|
`;
|
|
7603
|
-
await fs9.writeFile(
|
|
7806
|
+
await fs9.writeFile(path13.join(generatedDir, "server.js"), content, "utf8");
|
|
7604
7807
|
}
|
|
7605
7808
|
async function generateDataModelTypes(generatedDir, hasSchema) {
|
|
7606
7809
|
const content = `/* eslint-disable */
|
|
@@ -7664,7 +7867,7 @@ export type Id<TableName extends TableNames | SystemTableNames> =
|
|
|
7664
7867
|
*/
|
|
7665
7868
|
${hasSchema ? "export type DataModel = DataModelFromSchemaDefinition<typeof schema>;" : "export type DataModel = any;"}
|
|
7666
7869
|
`;
|
|
7667
|
-
await fs9.writeFile(
|
|
7870
|
+
await fs9.writeFile(path13.join(generatedDir, "dataModel.d.ts"), content, "utf8");
|
|
7668
7871
|
}
|
|
7669
7872
|
async function generateApiTypes(generatedDir, modules, _hasSchema) {
|
|
7670
7873
|
const apiModules = modules.filter((m) => m.name !== "schema" && !m.name.startsWith("_") && m.name !== "http");
|
|
@@ -7722,7 +7925,7 @@ export declare const internal: FilterApi<
|
|
|
7722
7925
|
|
|
7723
7926
|
export declare const components: AnyComponents;
|
|
7724
7927
|
`;
|
|
7725
|
-
await fs9.writeFile(
|
|
7928
|
+
await fs9.writeFile(path13.join(generatedDir, "api.d.ts"), content, "utf8");
|
|
7726
7929
|
}
|
|
7727
7930
|
async function generateApiJs(generatedDir) {
|
|
7728
7931
|
const content = `/* eslint-disable */
|
|
@@ -7735,8 +7938,59 @@ async function generateApiJs(generatedDir) {
|
|
|
7735
7938
|
* @module
|
|
7736
7939
|
*/
|
|
7737
7940
|
|
|
7738
|
-
|
|
7739
|
-
|
|
7941
|
+
const functionName = Symbol.for("functionName");
|
|
7942
|
+
const toReferencePath = Symbol.for("toReferencePath");
|
|
7943
|
+
|
|
7944
|
+
function createApi(pathParts = []) {
|
|
7945
|
+
return new Proxy(
|
|
7946
|
+
{},
|
|
7947
|
+
{
|
|
7948
|
+
get(_target, prop) {
|
|
7949
|
+
if (typeof prop === "string") {
|
|
7950
|
+
return createApi([...pathParts, prop]);
|
|
7951
|
+
}
|
|
7952
|
+
if (prop === functionName) {
|
|
7953
|
+
if (pathParts.length < 2) {
|
|
7954
|
+
const found = ["api", ...pathParts].join(".");
|
|
7955
|
+
throw new Error(
|
|
7956
|
+
"API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`" + found + "\`",
|
|
7957
|
+
);
|
|
7958
|
+
}
|
|
7959
|
+
const modulePath = pathParts.slice(0, -1).join("/");
|
|
7960
|
+
const exportName = pathParts[pathParts.length - 1];
|
|
7961
|
+
return exportName === "default" ? modulePath : modulePath + ":" + exportName;
|
|
7962
|
+
}
|
|
7963
|
+
if (prop === Symbol.toStringTag) {
|
|
7964
|
+
return "FunctionReference";
|
|
7965
|
+
}
|
|
7966
|
+
return undefined;
|
|
7967
|
+
},
|
|
7968
|
+
},
|
|
7969
|
+
);
|
|
7970
|
+
}
|
|
7971
|
+
|
|
7972
|
+
function createComponents(pathParts = []) {
|
|
7973
|
+
return new Proxy(
|
|
7974
|
+
{},
|
|
7975
|
+
{
|
|
7976
|
+
get(_target, prop) {
|
|
7977
|
+
if (typeof prop === "string") {
|
|
7978
|
+
return createComponents([...pathParts, prop]);
|
|
7979
|
+
}
|
|
7980
|
+
if (prop === toReferencePath) {
|
|
7981
|
+
if (pathParts.length < 1) {
|
|
7982
|
+
const found = ["components", ...pathParts].join(".");
|
|
7983
|
+
throw new Error(
|
|
7984
|
+
"API path is expected to be of the form \`components.childComponent.functionName\`. Found: \`" + found + "\`",
|
|
7985
|
+
);
|
|
7986
|
+
}
|
|
7987
|
+
return "_reference/childComponent/" + pathParts.join("/");
|
|
7988
|
+
}
|
|
7989
|
+
return undefined;
|
|
7990
|
+
},
|
|
7991
|
+
},
|
|
7992
|
+
);
|
|
7993
|
+
}
|
|
7740
7994
|
|
|
7741
7995
|
/**
|
|
7742
7996
|
* A utility for referencing Convex functions in your app's API.
|
|
@@ -7746,17 +8000,17 @@ import { componentsGeneric } from "convex/server";
|
|
|
7746
8000
|
* const myFunctionReference = api.myModule.myFunction;
|
|
7747
8001
|
* \`\`\`
|
|
7748
8002
|
*/
|
|
7749
|
-
export const api =
|
|
7750
|
-
export const internal =
|
|
7751
|
-
export const components =
|
|
8003
|
+
export const api = createApi();
|
|
8004
|
+
export const internal = createApi();
|
|
8005
|
+
export const components = createComponents();
|
|
7752
8006
|
`;
|
|
7753
|
-
await fs9.writeFile(
|
|
8007
|
+
await fs9.writeFile(path13.join(generatedDir, "api.js"), content, "utf8");
|
|
7754
8008
|
}
|
|
7755
8009
|
|
|
7756
8010
|
// src/cli/type-codegen-runtime.ts
|
|
7757
8011
|
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
7758
8012
|
import { promises as fs10 } from "node:fs";
|
|
7759
|
-
import
|
|
8013
|
+
import path14 from "node:path";
|
|
7760
8014
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
7761
8015
|
|
|
7762
8016
|
// src/cli/validator-to-typescript.ts
|
|
@@ -7873,7 +8127,7 @@ function returnsValidatorToTypeScript(returns, options = {}) {
|
|
|
7873
8127
|
async function generateTypesWithRuntime(projectRoot, options = {}) {
|
|
7874
8128
|
const layout = await resolveProjectLayout(projectRoot);
|
|
7875
8129
|
const convexDir = layout.functionsDir;
|
|
7876
|
-
const generatedDir =
|
|
8130
|
+
const generatedDir = path14.join(convexDir, "_generated");
|
|
7877
8131
|
console.log(import_picocolors8.default.cyan("\uD83D\uDD27 Generating TypeScript types (runtime analysis)"));
|
|
7878
8132
|
console.log(import_picocolors8.default.dim(` Output: ${generatedDir}
|
|
7879
8133
|
`));
|
|
@@ -7946,7 +8200,7 @@ async function discoverAndAnalyzeModules(convexDir, options) {
|
|
|
7946
8200
|
const failed = [];
|
|
7947
8201
|
const moduleFiles = await collectConvexModules2(convexDir);
|
|
7948
8202
|
for (const filePath of moduleFiles) {
|
|
7949
|
-
const relativePath =
|
|
8203
|
+
const relativePath = path14.relative(convexDir, filePath);
|
|
7950
8204
|
const moduleName = relativePath.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, "").replace(/\\/g, "/");
|
|
7951
8205
|
if (moduleName === "schema" || moduleName === "http" || moduleName === "crons") {
|
|
7952
8206
|
continue;
|
|
@@ -8076,7 +8330,7 @@ async function collectConvexModules2(convexDir) {
|
|
|
8076
8330
|
if (entry.name.startsWith(".") || entry.name === "_generated" || entry.name === "node_modules") {
|
|
8077
8331
|
continue;
|
|
8078
8332
|
}
|
|
8079
|
-
const fullPath =
|
|
8333
|
+
const fullPath = path14.join(dir, entry.name);
|
|
8080
8334
|
if (entry.isDirectory()) {
|
|
8081
8335
|
await walk(fullPath);
|
|
8082
8336
|
} else if (isConvexSourceFile3(entry.name)) {
|
|
@@ -8257,7 +8511,7 @@ export declare const internal: FilterApi<
|
|
|
8257
8511
|
|
|
8258
8512
|
export declare const components: AnyComponents;
|
|
8259
8513
|
`;
|
|
8260
|
-
await fs10.writeFile(
|
|
8514
|
+
await fs10.writeFile(path14.join(generatedDir, "api.d.ts"), content, "utf8");
|
|
8261
8515
|
}
|
|
8262
8516
|
async function generatePackageJson(generatedDir) {
|
|
8263
8517
|
const content = {
|
|
@@ -8271,7 +8525,7 @@ async function generatePackageJson(generatedDir) {
|
|
|
8271
8525
|
"./dataModel.d.ts": "./dataModel.d.ts"
|
|
8272
8526
|
}
|
|
8273
8527
|
};
|
|
8274
|
-
await fs10.writeFile(
|
|
8528
|
+
await fs10.writeFile(path14.join(generatedDir, "package.json"), JSON.stringify(content, null, 2), "utf8");
|
|
8275
8529
|
}
|
|
8276
8530
|
async function generateServerTypes2(generatedDir, _hasSchema) {
|
|
8277
8531
|
const content = `/* eslint-disable */
|
|
@@ -8297,6 +8551,8 @@ import {
|
|
|
8297
8551
|
} from "convex/server";
|
|
8298
8552
|
import type { DataModel } from "./dataModel.js";
|
|
8299
8553
|
|
|
8554
|
+
export { defineSchema, defineTable } from "convex/server";
|
|
8555
|
+
|
|
8300
8556
|
export declare const query: QueryBuilder<DataModel, "public">;
|
|
8301
8557
|
export declare const internalQuery: QueryBuilder<DataModel, "internal">;
|
|
8302
8558
|
export declare const mutation: MutationBuilder<DataModel, "public">;
|
|
@@ -8311,7 +8567,7 @@ export type ActionCtx = GenericActionCtx<DataModel>;
|
|
|
8311
8567
|
export type DatabaseReader = GenericDatabaseReader<DataModel>;
|
|
8312
8568
|
export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
|
|
8313
8569
|
`;
|
|
8314
|
-
await fs10.writeFile(
|
|
8570
|
+
await fs10.writeFile(path14.join(generatedDir, "server.d.ts"), content, "utf8");
|
|
8315
8571
|
}
|
|
8316
8572
|
async function generateServerJs2(generatedDir) {
|
|
8317
8573
|
const content = `/* eslint-disable */
|
|
@@ -8332,17 +8588,86 @@ import {
|
|
|
8332
8588
|
internalActionGeneric,
|
|
8333
8589
|
internalMutationGeneric,
|
|
8334
8590
|
internalQueryGeneric,
|
|
8591
|
+
defineSchema,
|
|
8592
|
+
defineTable,
|
|
8335
8593
|
} from "convex/server";
|
|
8336
8594
|
|
|
8595
|
+
/**
|
|
8596
|
+
* Define a query in this Convex app's public API.
|
|
8597
|
+
*
|
|
8598
|
+
* This function will be allowed to read your Convex database and will be accessible from the client.
|
|
8599
|
+
*
|
|
8600
|
+
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
8601
|
+
* @returns The wrapped query. Include this as an \`export\` to name it and make it accessible.
|
|
8602
|
+
*/
|
|
8337
8603
|
export const query = queryGeneric;
|
|
8604
|
+
|
|
8605
|
+
/**
|
|
8606
|
+
* Define a query that is only accessible from other Convex functions (but not from the client).
|
|
8607
|
+
*
|
|
8608
|
+
* This function will be allowed to read from your Convex database. It will not be accessible from the client.
|
|
8609
|
+
*
|
|
8610
|
+
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
|
|
8611
|
+
* @returns The wrapped query. Include this as an \`export\` to name it and make it accessible.
|
|
8612
|
+
*/
|
|
8338
8613
|
export const internalQuery = internalQueryGeneric;
|
|
8614
|
+
|
|
8615
|
+
/**
|
|
8616
|
+
* Define a mutation in this Convex app's public API.
|
|
8617
|
+
*
|
|
8618
|
+
* This function will be allowed to modify your Convex database and will be accessible from the client.
|
|
8619
|
+
*
|
|
8620
|
+
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
8621
|
+
* @returns The wrapped mutation. Include this as an \`export\` to name it and make it accessible.
|
|
8622
|
+
*/
|
|
8339
8623
|
export const mutation = mutationGeneric;
|
|
8624
|
+
|
|
8625
|
+
/**
|
|
8626
|
+
* Define a mutation that is only accessible from other Convex functions (but not from the client).
|
|
8627
|
+
*
|
|
8628
|
+
* This function will be allowed to modify your Convex database. It will not be accessible from the client.
|
|
8629
|
+
*
|
|
8630
|
+
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
|
|
8631
|
+
* @returns The wrapped mutation. Include this as an \`export\` to name it and make it accessible.
|
|
8632
|
+
*/
|
|
8340
8633
|
export const internalMutation = internalMutationGeneric;
|
|
8634
|
+
|
|
8635
|
+
/**
|
|
8636
|
+
* Define an action in this Convex app's public API.
|
|
8637
|
+
*
|
|
8638
|
+
* An action is a function which can execute any JavaScript code, including non-deterministic
|
|
8639
|
+
* code and code with side-effects, like calling third-party services.
|
|
8640
|
+
* They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive.
|
|
8641
|
+
* They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.
|
|
8642
|
+
*
|
|
8643
|
+
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
|
|
8644
|
+
* @returns The wrapped action. Include this as an \`export\` to name it and make it accessible.
|
|
8645
|
+
*/
|
|
8341
8646
|
export const action = actionGeneric;
|
|
8647
|
+
|
|
8648
|
+
/**
|
|
8649
|
+
* Define an action that is only accessible from other Convex functions (but not from the client).
|
|
8650
|
+
*
|
|
8651
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
|
|
8652
|
+
* @returns The wrapped function. Include this as an \`export\` to name it and make it accessible.
|
|
8653
|
+
*/
|
|
8342
8654
|
export const internalAction = internalActionGeneric;
|
|
8655
|
+
|
|
8656
|
+
/**
|
|
8657
|
+
* Define a Convex HTTP action.
|
|
8658
|
+
*
|
|
8659
|
+
* @param func - The function. It receives an {@link ActionCtx} as its first argument, and a \`Request\` object
|
|
8660
|
+
* as its second.
|
|
8661
|
+
* @returns The wrapped endpoint function. Route a URL path to this function in \`convex/http.js\`.
|
|
8662
|
+
*/
|
|
8343
8663
|
export const httpAction = httpActionGeneric;
|
|
8664
|
+
|
|
8665
|
+
/**
|
|
8666
|
+
* Define a table in this Convex app's schema.
|
|
8667
|
+
*/
|
|
8668
|
+
export { defineTable, defineSchema };
|
|
8344
8669
|
`;
|
|
8345
|
-
await fs10.writeFile(
|
|
8670
|
+
await fs10.writeFile(path14.join(generatedDir, "server.js"), content, "utf8");
|
|
8346
8671
|
}
|
|
8347
8672
|
async function generateDataModelTypes2(generatedDir, hasSchema) {
|
|
8348
8673
|
const content = `/* eslint-disable */
|
|
@@ -8370,7 +8695,7 @@ export type Id<TableName extends TableNames | SystemTableNames> = GenericId<Tabl
|
|
|
8370
8695
|
|
|
8371
8696
|
${hasSchema ? "export type DataModel = DataModelFromSchemaDefinition<typeof schema>;" : "export type DataModel = any;"}
|
|
8372
8697
|
`;
|
|
8373
|
-
await fs10.writeFile(
|
|
8698
|
+
await fs10.writeFile(path14.join(generatedDir, "dataModel.d.ts"), content, "utf8");
|
|
8374
8699
|
}
|
|
8375
8700
|
async function generateApiJs2(generatedDir) {
|
|
8376
8701
|
const content = `/* eslint-disable */
|
|
@@ -8383,7 +8708,59 @@ async function generateApiJs2(generatedDir) {
|
|
|
8383
8708
|
* @module
|
|
8384
8709
|
*/
|
|
8385
8710
|
|
|
8386
|
-
|
|
8711
|
+
const functionName = Symbol.for("functionName");
|
|
8712
|
+
const toReferencePath = Symbol.for("toReferencePath");
|
|
8713
|
+
|
|
8714
|
+
function createApi(pathParts = []) {
|
|
8715
|
+
return new Proxy(
|
|
8716
|
+
{},
|
|
8717
|
+
{
|
|
8718
|
+
get(_target, prop) {
|
|
8719
|
+
if (typeof prop === "string") {
|
|
8720
|
+
return createApi([...pathParts, prop]);
|
|
8721
|
+
}
|
|
8722
|
+
if (prop === functionName) {
|
|
8723
|
+
if (pathParts.length < 2) {
|
|
8724
|
+
const found = ["api", ...pathParts].join(".");
|
|
8725
|
+
throw new Error(
|
|
8726
|
+
"API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`" + found + "\`",
|
|
8727
|
+
);
|
|
8728
|
+
}
|
|
8729
|
+
const modulePath = pathParts.slice(0, -1).join("/");
|
|
8730
|
+
const exportName = pathParts[pathParts.length - 1];
|
|
8731
|
+
return exportName === "default" ? modulePath : modulePath + ":" + exportName;
|
|
8732
|
+
}
|
|
8733
|
+
if (prop === Symbol.toStringTag) {
|
|
8734
|
+
return "FunctionReference";
|
|
8735
|
+
}
|
|
8736
|
+
return undefined;
|
|
8737
|
+
},
|
|
8738
|
+
},
|
|
8739
|
+
);
|
|
8740
|
+
}
|
|
8741
|
+
|
|
8742
|
+
function createComponents(pathParts = []) {
|
|
8743
|
+
return new Proxy(
|
|
8744
|
+
{},
|
|
8745
|
+
{
|
|
8746
|
+
get(_target, prop) {
|
|
8747
|
+
if (typeof prop === "string") {
|
|
8748
|
+
return createComponents([...pathParts, prop]);
|
|
8749
|
+
}
|
|
8750
|
+
if (prop === toReferencePath) {
|
|
8751
|
+
if (pathParts.length < 1) {
|
|
8752
|
+
const found = ["components", ...pathParts].join(".");
|
|
8753
|
+
throw new Error(
|
|
8754
|
+
"API path is expected to be of the form \`components.childComponent.functionName\`. Found: \`" + found + "\`",
|
|
8755
|
+
);
|
|
8756
|
+
}
|
|
8757
|
+
return "_reference/childComponent/" + pathParts.join("/");
|
|
8758
|
+
}
|
|
8759
|
+
return undefined;
|
|
8760
|
+
},
|
|
8761
|
+
},
|
|
8762
|
+
);
|
|
8763
|
+
}
|
|
8387
8764
|
|
|
8388
8765
|
/**
|
|
8389
8766
|
* A utility for referencing Convex functions in your app's API.
|
|
@@ -8393,11 +8770,11 @@ import { anyApi, componentsGeneric } from "convex/server";
|
|
|
8393
8770
|
* const myFunctionReference = api.myModule.myFunction;
|
|
8394
8771
|
* \`\`\`
|
|
8395
8772
|
*/
|
|
8396
|
-
export const api =
|
|
8397
|
-
export const internal =
|
|
8398
|
-
export const components =
|
|
8773
|
+
export const api = createApi();
|
|
8774
|
+
export const internal = createApi();
|
|
8775
|
+
export const components = createComponents();
|
|
8399
8776
|
`;
|
|
8400
|
-
await fs10.writeFile(
|
|
8777
|
+
await fs10.writeFile(path14.join(generatedDir, "api.js"), content, "utf8");
|
|
8401
8778
|
}
|
|
8402
8779
|
|
|
8403
8780
|
// ../../node_modules/chokidar/esm/index.js
|
|
@@ -8477,7 +8854,7 @@ class ReaddirpStream extends Readable {
|
|
|
8477
8854
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
8478
8855
|
const statMethod = opts.lstat ? lstat : stat2;
|
|
8479
8856
|
if (wantBigintFsStats) {
|
|
8480
|
-
this._stat = (
|
|
8857
|
+
this._stat = (path15) => statMethod(path15, { bigint: true });
|
|
8481
8858
|
} else {
|
|
8482
8859
|
this._stat = statMethod;
|
|
8483
8860
|
}
|
|
@@ -8502,8 +8879,8 @@ class ReaddirpStream extends Readable {
|
|
|
8502
8879
|
const par = this.parent;
|
|
8503
8880
|
const fil = par && par.files;
|
|
8504
8881
|
if (fil && fil.length > 0) {
|
|
8505
|
-
const { path:
|
|
8506
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
8882
|
+
const { path: path15, depth } = par;
|
|
8883
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path15));
|
|
8507
8884
|
const awaited = await Promise.all(slice);
|
|
8508
8885
|
for (const entry of awaited) {
|
|
8509
8886
|
if (!entry)
|
|
@@ -8543,20 +8920,20 @@ class ReaddirpStream extends Readable {
|
|
|
8543
8920
|
this.reading = false;
|
|
8544
8921
|
}
|
|
8545
8922
|
}
|
|
8546
|
-
async _exploreDir(
|
|
8923
|
+
async _exploreDir(path15, depth) {
|
|
8547
8924
|
let files;
|
|
8548
8925
|
try {
|
|
8549
|
-
files = await readdir(
|
|
8926
|
+
files = await readdir(path15, this._rdOptions);
|
|
8550
8927
|
} catch (error) {
|
|
8551
8928
|
this._onError(error);
|
|
8552
8929
|
}
|
|
8553
|
-
return { files, depth, path:
|
|
8930
|
+
return { files, depth, path: path15 };
|
|
8554
8931
|
}
|
|
8555
|
-
async _formatEntry(dirent,
|
|
8932
|
+
async _formatEntry(dirent, path15) {
|
|
8556
8933
|
let entry;
|
|
8557
8934
|
const basename = this._isDirent ? dirent.name : dirent;
|
|
8558
8935
|
try {
|
|
8559
|
-
const fullPath = presolve(pjoin(
|
|
8936
|
+
const fullPath = presolve(pjoin(path15, basename));
|
|
8560
8937
|
entry = { path: prelative(this._root, fullPath), fullPath, basename };
|
|
8561
8938
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
8562
8939
|
} catch (err) {
|
|
@@ -8955,16 +9332,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
8955
9332
|
};
|
|
8956
9333
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
8957
9334
|
var FsWatchInstances = new Map;
|
|
8958
|
-
function createFsWatchInstance(
|
|
9335
|
+
function createFsWatchInstance(path15, options, listener, errHandler, emitRaw) {
|
|
8959
9336
|
const handleEvent = (rawEvent, evPath) => {
|
|
8960
|
-
listener(
|
|
8961
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
8962
|
-
if (evPath &&
|
|
8963
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
9337
|
+
listener(path15);
|
|
9338
|
+
emitRaw(rawEvent, evPath, { watchedPath: path15 });
|
|
9339
|
+
if (evPath && path15 !== evPath) {
|
|
9340
|
+
fsWatchBroadcast(sysPath.resolve(path15, evPath), KEY_LISTENERS, sysPath.join(path15, evPath));
|
|
8964
9341
|
}
|
|
8965
9342
|
};
|
|
8966
9343
|
try {
|
|
8967
|
-
return fs_watch(
|
|
9344
|
+
return fs_watch(path15, {
|
|
8968
9345
|
persistent: options.persistent
|
|
8969
9346
|
}, handleEvent);
|
|
8970
9347
|
} catch (error) {
|
|
@@ -8980,12 +9357,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
8980
9357
|
listener(val1, val2, val3);
|
|
8981
9358
|
});
|
|
8982
9359
|
};
|
|
8983
|
-
var setFsWatchListener = (
|
|
9360
|
+
var setFsWatchListener = (path15, fullPath, options, handlers) => {
|
|
8984
9361
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
8985
9362
|
let cont = FsWatchInstances.get(fullPath);
|
|
8986
9363
|
let watcher;
|
|
8987
9364
|
if (!options.persistent) {
|
|
8988
|
-
watcher = createFsWatchInstance(
|
|
9365
|
+
watcher = createFsWatchInstance(path15, options, listener, errHandler, rawEmitter);
|
|
8989
9366
|
if (!watcher)
|
|
8990
9367
|
return;
|
|
8991
9368
|
return watcher.close.bind(watcher);
|
|
@@ -8995,7 +9372,7 @@ var setFsWatchListener = (path14, fullPath, options, handlers) => {
|
|
|
8995
9372
|
addAndConvert(cont, KEY_ERR, errHandler);
|
|
8996
9373
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
8997
9374
|
} else {
|
|
8998
|
-
watcher = createFsWatchInstance(
|
|
9375
|
+
watcher = createFsWatchInstance(path15, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
|
|
8999
9376
|
if (!watcher)
|
|
9000
9377
|
return;
|
|
9001
9378
|
watcher.on(EV.ERROR, async (error) => {
|
|
@@ -9004,7 +9381,7 @@ var setFsWatchListener = (path14, fullPath, options, handlers) => {
|
|
|
9004
9381
|
cont.watcherUnusable = true;
|
|
9005
9382
|
if (isWindows && error.code === "EPERM") {
|
|
9006
9383
|
try {
|
|
9007
|
-
const fd = await open(
|
|
9384
|
+
const fd = await open(path15, "r");
|
|
9008
9385
|
await fd.close();
|
|
9009
9386
|
broadcastErr(error);
|
|
9010
9387
|
} catch (err) {}
|
|
@@ -9034,7 +9411,7 @@ var setFsWatchListener = (path14, fullPath, options, handlers) => {
|
|
|
9034
9411
|
};
|
|
9035
9412
|
};
|
|
9036
9413
|
var FsWatchFileInstances = new Map;
|
|
9037
|
-
var setFsWatchFileListener = (
|
|
9414
|
+
var setFsWatchFileListener = (path15, fullPath, options, handlers) => {
|
|
9038
9415
|
const { listener, rawEmitter } = handlers;
|
|
9039
9416
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
9040
9417
|
const copts = cont && cont.options;
|
|
@@ -9056,7 +9433,7 @@ var setFsWatchFileListener = (path14, fullPath, options, handlers) => {
|
|
|
9056
9433
|
});
|
|
9057
9434
|
const currmtime = curr.mtimeMs;
|
|
9058
9435
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
9059
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
9436
|
+
foreach(cont.listeners, (listener2) => listener2(path15, curr));
|
|
9060
9437
|
}
|
|
9061
9438
|
})
|
|
9062
9439
|
};
|
|
@@ -9079,13 +9456,13 @@ class NodeFsHandler {
|
|
|
9079
9456
|
this.fsw = fsW;
|
|
9080
9457
|
this._boundHandleError = (error) => fsW._handleError(error);
|
|
9081
9458
|
}
|
|
9082
|
-
_watchWithNodeFs(
|
|
9459
|
+
_watchWithNodeFs(path15, listener) {
|
|
9083
9460
|
const opts = this.fsw.options;
|
|
9084
|
-
const directory = sysPath.dirname(
|
|
9085
|
-
const basename2 = sysPath.basename(
|
|
9461
|
+
const directory = sysPath.dirname(path15);
|
|
9462
|
+
const basename2 = sysPath.basename(path15);
|
|
9086
9463
|
const parent = this.fsw._getWatchedDir(directory);
|
|
9087
9464
|
parent.add(basename2);
|
|
9088
|
-
const absolutePath = sysPath.resolve(
|
|
9465
|
+
const absolutePath = sysPath.resolve(path15);
|
|
9089
9466
|
const options = {
|
|
9090
9467
|
persistent: opts.persistent
|
|
9091
9468
|
};
|
|
@@ -9095,12 +9472,12 @@ class NodeFsHandler {
|
|
|
9095
9472
|
if (opts.usePolling) {
|
|
9096
9473
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
9097
9474
|
options.interval = enableBin && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
|
|
9098
|
-
closer = setFsWatchFileListener(
|
|
9475
|
+
closer = setFsWatchFileListener(path15, absolutePath, options, {
|
|
9099
9476
|
listener,
|
|
9100
9477
|
rawEmitter: this.fsw._emitRaw
|
|
9101
9478
|
});
|
|
9102
9479
|
} else {
|
|
9103
|
-
closer = setFsWatchListener(
|
|
9480
|
+
closer = setFsWatchListener(path15, absolutePath, options, {
|
|
9104
9481
|
listener,
|
|
9105
9482
|
errHandler: this._boundHandleError,
|
|
9106
9483
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -9118,7 +9495,7 @@ class NodeFsHandler {
|
|
|
9118
9495
|
let prevStats = stats;
|
|
9119
9496
|
if (parent.has(basename2))
|
|
9120
9497
|
return;
|
|
9121
|
-
const listener = async (
|
|
9498
|
+
const listener = async (path15, newStats) => {
|
|
9122
9499
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
9123
9500
|
return;
|
|
9124
9501
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -9132,11 +9509,11 @@ class NodeFsHandler {
|
|
|
9132
9509
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
9133
9510
|
}
|
|
9134
9511
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
9135
|
-
this.fsw._closeFile(
|
|
9512
|
+
this.fsw._closeFile(path15);
|
|
9136
9513
|
prevStats = newStats2;
|
|
9137
9514
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
9138
9515
|
if (closer2)
|
|
9139
|
-
this.fsw._addPathCloser(
|
|
9516
|
+
this.fsw._addPathCloser(path15, closer2);
|
|
9140
9517
|
} else {
|
|
9141
9518
|
prevStats = newStats2;
|
|
9142
9519
|
}
|
|
@@ -9160,7 +9537,7 @@ class NodeFsHandler {
|
|
|
9160
9537
|
}
|
|
9161
9538
|
return closer;
|
|
9162
9539
|
}
|
|
9163
|
-
async _handleSymlink(entry, directory,
|
|
9540
|
+
async _handleSymlink(entry, directory, path15, item) {
|
|
9164
9541
|
if (this.fsw.closed) {
|
|
9165
9542
|
return;
|
|
9166
9543
|
}
|
|
@@ -9170,7 +9547,7 @@ class NodeFsHandler {
|
|
|
9170
9547
|
this.fsw._incrReadyCount();
|
|
9171
9548
|
let linkPath;
|
|
9172
9549
|
try {
|
|
9173
|
-
linkPath = await fsrealpath(
|
|
9550
|
+
linkPath = await fsrealpath(path15);
|
|
9174
9551
|
} catch (e) {
|
|
9175
9552
|
this.fsw._emitReady();
|
|
9176
9553
|
return true;
|
|
@@ -9180,12 +9557,12 @@ class NodeFsHandler {
|
|
|
9180
9557
|
if (dir.has(item)) {
|
|
9181
9558
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
9182
9559
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
9183
|
-
this.fsw._emit(EV.CHANGE,
|
|
9560
|
+
this.fsw._emit(EV.CHANGE, path15, entry.stats);
|
|
9184
9561
|
}
|
|
9185
9562
|
} else {
|
|
9186
9563
|
dir.add(item);
|
|
9187
9564
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
9188
|
-
this.fsw._emit(EV.ADD,
|
|
9565
|
+
this.fsw._emit(EV.ADD, path15, entry.stats);
|
|
9189
9566
|
}
|
|
9190
9567
|
this.fsw._emitReady();
|
|
9191
9568
|
return true;
|
|
@@ -9214,9 +9591,9 @@ class NodeFsHandler {
|
|
|
9214
9591
|
return;
|
|
9215
9592
|
}
|
|
9216
9593
|
const item = entry.path;
|
|
9217
|
-
let
|
|
9594
|
+
let path15 = sysPath.join(directory, item);
|
|
9218
9595
|
current.add(item);
|
|
9219
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
9596
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path15, item)) {
|
|
9220
9597
|
return;
|
|
9221
9598
|
}
|
|
9222
9599
|
if (this.fsw.closed) {
|
|
@@ -9225,8 +9602,8 @@ class NodeFsHandler {
|
|
|
9225
9602
|
}
|
|
9226
9603
|
if (item === target || !target && !previous.has(item)) {
|
|
9227
9604
|
this.fsw._incrReadyCount();
|
|
9228
|
-
|
|
9229
|
-
this._addToNodeFs(
|
|
9605
|
+
path15 = sysPath.join(dir, sysPath.relative(dir, path15));
|
|
9606
|
+
this._addToNodeFs(path15, initialAdd, wh, depth + 1);
|
|
9230
9607
|
}
|
|
9231
9608
|
}).on(EV.ERROR, this._boundHandleError);
|
|
9232
9609
|
return new Promise((resolve2, reject) => {
|
|
@@ -9275,13 +9652,13 @@ class NodeFsHandler {
|
|
|
9275
9652
|
}
|
|
9276
9653
|
return closer;
|
|
9277
9654
|
}
|
|
9278
|
-
async _addToNodeFs(
|
|
9655
|
+
async _addToNodeFs(path15, initialAdd, priorWh, depth, target) {
|
|
9279
9656
|
const ready = this.fsw._emitReady;
|
|
9280
|
-
if (this.fsw._isIgnored(
|
|
9657
|
+
if (this.fsw._isIgnored(path15) || this.fsw.closed) {
|
|
9281
9658
|
ready();
|
|
9282
9659
|
return false;
|
|
9283
9660
|
}
|
|
9284
|
-
const wh = this.fsw._getWatchHelpers(
|
|
9661
|
+
const wh = this.fsw._getWatchHelpers(path15);
|
|
9285
9662
|
if (priorWh) {
|
|
9286
9663
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
9287
9664
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -9297,8 +9674,8 @@ class NodeFsHandler {
|
|
|
9297
9674
|
const follow = this.fsw.options.followSymlinks;
|
|
9298
9675
|
let closer;
|
|
9299
9676
|
if (stats.isDirectory()) {
|
|
9300
|
-
const absPath = sysPath.resolve(
|
|
9301
|
-
const targetPath = follow ? await fsrealpath(
|
|
9677
|
+
const absPath = sysPath.resolve(path15);
|
|
9678
|
+
const targetPath = follow ? await fsrealpath(path15) : path15;
|
|
9302
9679
|
if (this.fsw.closed)
|
|
9303
9680
|
return;
|
|
9304
9681
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -9308,29 +9685,29 @@ class NodeFsHandler {
|
|
|
9308
9685
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
9309
9686
|
}
|
|
9310
9687
|
} else if (stats.isSymbolicLink()) {
|
|
9311
|
-
const targetPath = follow ? await fsrealpath(
|
|
9688
|
+
const targetPath = follow ? await fsrealpath(path15) : path15;
|
|
9312
9689
|
if (this.fsw.closed)
|
|
9313
9690
|
return;
|
|
9314
9691
|
const parent = sysPath.dirname(wh.watchPath);
|
|
9315
9692
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
9316
9693
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
9317
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
9694
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path15, wh, targetPath);
|
|
9318
9695
|
if (this.fsw.closed)
|
|
9319
9696
|
return;
|
|
9320
9697
|
if (targetPath !== undefined) {
|
|
9321
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
9698
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path15), targetPath);
|
|
9322
9699
|
}
|
|
9323
9700
|
} else {
|
|
9324
9701
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
9325
9702
|
}
|
|
9326
9703
|
ready();
|
|
9327
9704
|
if (closer)
|
|
9328
|
-
this.fsw._addPathCloser(
|
|
9705
|
+
this.fsw._addPathCloser(path15, closer);
|
|
9329
9706
|
return false;
|
|
9330
9707
|
} catch (error) {
|
|
9331
9708
|
if (this.fsw._handleError(error)) {
|
|
9332
9709
|
ready();
|
|
9333
|
-
return
|
|
9710
|
+
return path15;
|
|
9334
9711
|
}
|
|
9335
9712
|
}
|
|
9336
9713
|
}
|
|
@@ -9374,26 +9751,26 @@ function createPattern(matcher) {
|
|
|
9374
9751
|
}
|
|
9375
9752
|
return () => false;
|
|
9376
9753
|
}
|
|
9377
|
-
function normalizePath(
|
|
9378
|
-
if (typeof
|
|
9754
|
+
function normalizePath(path15) {
|
|
9755
|
+
if (typeof path15 !== "string")
|
|
9379
9756
|
throw new Error("string expected");
|
|
9380
|
-
|
|
9381
|
-
|
|
9757
|
+
path15 = sysPath2.normalize(path15);
|
|
9758
|
+
path15 = path15.replace(/\\/g, "/");
|
|
9382
9759
|
let prepend = false;
|
|
9383
|
-
if (
|
|
9760
|
+
if (path15.startsWith("//"))
|
|
9384
9761
|
prepend = true;
|
|
9385
9762
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
9386
|
-
while (
|
|
9387
|
-
|
|
9763
|
+
while (path15.match(DOUBLE_SLASH_RE2))
|
|
9764
|
+
path15 = path15.replace(DOUBLE_SLASH_RE2, "/");
|
|
9388
9765
|
if (prepend)
|
|
9389
|
-
|
|
9390
|
-
return
|
|
9766
|
+
path15 = "/" + path15;
|
|
9767
|
+
return path15;
|
|
9391
9768
|
}
|
|
9392
9769
|
function matchPatterns(patterns, testString, stats) {
|
|
9393
|
-
const
|
|
9770
|
+
const path15 = normalizePath(testString);
|
|
9394
9771
|
for (let index = 0;index < patterns.length; index++) {
|
|
9395
9772
|
const pattern = patterns[index];
|
|
9396
|
-
if (pattern(
|
|
9773
|
+
if (pattern(path15, stats)) {
|
|
9397
9774
|
return true;
|
|
9398
9775
|
}
|
|
9399
9776
|
}
|
|
@@ -9433,19 +9810,19 @@ var toUnix = (string) => {
|
|
|
9433
9810
|
}
|
|
9434
9811
|
return str;
|
|
9435
9812
|
};
|
|
9436
|
-
var normalizePathToUnix = (
|
|
9437
|
-
var normalizeIgnored = (cwd = "") => (
|
|
9438
|
-
if (typeof
|
|
9439
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
9813
|
+
var normalizePathToUnix = (path15) => toUnix(sysPath2.normalize(toUnix(path15)));
|
|
9814
|
+
var normalizeIgnored = (cwd = "") => (path15) => {
|
|
9815
|
+
if (typeof path15 === "string") {
|
|
9816
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path15) ? path15 : sysPath2.join(cwd, path15));
|
|
9440
9817
|
} else {
|
|
9441
|
-
return
|
|
9818
|
+
return path15;
|
|
9442
9819
|
}
|
|
9443
9820
|
};
|
|
9444
|
-
var getAbsolutePath = (
|
|
9445
|
-
if (sysPath2.isAbsolute(
|
|
9446
|
-
return
|
|
9821
|
+
var getAbsolutePath = (path15, cwd) => {
|
|
9822
|
+
if (sysPath2.isAbsolute(path15)) {
|
|
9823
|
+
return path15;
|
|
9447
9824
|
}
|
|
9448
|
-
return sysPath2.join(cwd,
|
|
9825
|
+
return sysPath2.join(cwd, path15);
|
|
9449
9826
|
};
|
|
9450
9827
|
var EMPTY_SET = Object.freeze(new Set);
|
|
9451
9828
|
|
|
@@ -9502,10 +9879,10 @@ var STAT_METHOD_F = "stat";
|
|
|
9502
9879
|
var STAT_METHOD_L = "lstat";
|
|
9503
9880
|
|
|
9504
9881
|
class WatchHelper {
|
|
9505
|
-
constructor(
|
|
9882
|
+
constructor(path15, follow, fsw) {
|
|
9506
9883
|
this.fsw = fsw;
|
|
9507
|
-
const watchPath =
|
|
9508
|
-
this.path =
|
|
9884
|
+
const watchPath = path15;
|
|
9885
|
+
this.path = path15 = path15.replace(REPLACER_RE, "");
|
|
9509
9886
|
this.watchPath = watchPath;
|
|
9510
9887
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
9511
9888
|
this.dirParts = [];
|
|
@@ -9618,20 +9995,20 @@ class FSWatcher extends EventEmitter {
|
|
|
9618
9995
|
this._closePromise = undefined;
|
|
9619
9996
|
let paths = unifyPaths(paths_);
|
|
9620
9997
|
if (cwd) {
|
|
9621
|
-
paths = paths.map((
|
|
9622
|
-
const absPath = getAbsolutePath(
|
|
9998
|
+
paths = paths.map((path15) => {
|
|
9999
|
+
const absPath = getAbsolutePath(path15, cwd);
|
|
9623
10000
|
return absPath;
|
|
9624
10001
|
});
|
|
9625
10002
|
}
|
|
9626
|
-
paths.forEach((
|
|
9627
|
-
this._removeIgnoredPath(
|
|
10003
|
+
paths.forEach((path15) => {
|
|
10004
|
+
this._removeIgnoredPath(path15);
|
|
9628
10005
|
});
|
|
9629
10006
|
this._userIgnored = undefined;
|
|
9630
10007
|
if (!this._readyCount)
|
|
9631
10008
|
this._readyCount = 0;
|
|
9632
10009
|
this._readyCount += paths.length;
|
|
9633
|
-
Promise.all(paths.map(async (
|
|
9634
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
10010
|
+
Promise.all(paths.map(async (path15) => {
|
|
10011
|
+
const res = await this._nodeFsHandler._addToNodeFs(path15, !_internal, undefined, 0, _origAdd);
|
|
9635
10012
|
if (res)
|
|
9636
10013
|
this._emitReady();
|
|
9637
10014
|
return res;
|
|
@@ -9650,17 +10027,17 @@ class FSWatcher extends EventEmitter {
|
|
|
9650
10027
|
return this;
|
|
9651
10028
|
const paths = unifyPaths(paths_);
|
|
9652
10029
|
const { cwd } = this.options;
|
|
9653
|
-
paths.forEach((
|
|
9654
|
-
if (!sysPath2.isAbsolute(
|
|
10030
|
+
paths.forEach((path15) => {
|
|
10031
|
+
if (!sysPath2.isAbsolute(path15) && !this._closers.has(path15)) {
|
|
9655
10032
|
if (cwd)
|
|
9656
|
-
|
|
9657
|
-
|
|
10033
|
+
path15 = sysPath2.join(cwd, path15);
|
|
10034
|
+
path15 = sysPath2.resolve(path15);
|
|
9658
10035
|
}
|
|
9659
|
-
this._closePath(
|
|
9660
|
-
this._addIgnoredPath(
|
|
9661
|
-
if (this._watched.has(
|
|
10036
|
+
this._closePath(path15);
|
|
10037
|
+
this._addIgnoredPath(path15);
|
|
10038
|
+
if (this._watched.has(path15)) {
|
|
9662
10039
|
this._addIgnoredPath({
|
|
9663
|
-
path:
|
|
10040
|
+
path: path15,
|
|
9664
10041
|
recursive: true
|
|
9665
10042
|
});
|
|
9666
10043
|
}
|
|
@@ -9709,38 +10086,38 @@ class FSWatcher extends EventEmitter {
|
|
|
9709
10086
|
if (event !== EVENTS.ERROR)
|
|
9710
10087
|
this.emit(EVENTS.ALL, event, ...args);
|
|
9711
10088
|
}
|
|
9712
|
-
async _emit(event,
|
|
10089
|
+
async _emit(event, path15, stats) {
|
|
9713
10090
|
if (this.closed)
|
|
9714
10091
|
return;
|
|
9715
10092
|
const opts = this.options;
|
|
9716
10093
|
if (isWindows)
|
|
9717
|
-
|
|
10094
|
+
path15 = sysPath2.normalize(path15);
|
|
9718
10095
|
if (opts.cwd)
|
|
9719
|
-
|
|
9720
|
-
const args = [
|
|
10096
|
+
path15 = sysPath2.relative(opts.cwd, path15);
|
|
10097
|
+
const args = [path15];
|
|
9721
10098
|
if (stats != null)
|
|
9722
10099
|
args.push(stats);
|
|
9723
10100
|
const awf = opts.awaitWriteFinish;
|
|
9724
10101
|
let pw;
|
|
9725
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
10102
|
+
if (awf && (pw = this._pendingWrites.get(path15))) {
|
|
9726
10103
|
pw.lastChange = new Date;
|
|
9727
10104
|
return this;
|
|
9728
10105
|
}
|
|
9729
10106
|
if (opts.atomic) {
|
|
9730
10107
|
if (event === EVENTS.UNLINK) {
|
|
9731
|
-
this._pendingUnlinks.set(
|
|
10108
|
+
this._pendingUnlinks.set(path15, [event, ...args]);
|
|
9732
10109
|
setTimeout(() => {
|
|
9733
|
-
this._pendingUnlinks.forEach((entry,
|
|
10110
|
+
this._pendingUnlinks.forEach((entry, path16) => {
|
|
9734
10111
|
this.emit(...entry);
|
|
9735
10112
|
this.emit(EVENTS.ALL, ...entry);
|
|
9736
|
-
this._pendingUnlinks.delete(
|
|
10113
|
+
this._pendingUnlinks.delete(path16);
|
|
9737
10114
|
});
|
|
9738
10115
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
9739
10116
|
return this;
|
|
9740
10117
|
}
|
|
9741
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
10118
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path15)) {
|
|
9742
10119
|
event = EVENTS.CHANGE;
|
|
9743
|
-
this._pendingUnlinks.delete(
|
|
10120
|
+
this._pendingUnlinks.delete(path15);
|
|
9744
10121
|
}
|
|
9745
10122
|
}
|
|
9746
10123
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -9758,16 +10135,16 @@ class FSWatcher extends EventEmitter {
|
|
|
9758
10135
|
this.emitWithAll(event, args);
|
|
9759
10136
|
}
|
|
9760
10137
|
};
|
|
9761
|
-
this._awaitWriteFinish(
|
|
10138
|
+
this._awaitWriteFinish(path15, awf.stabilityThreshold, event, awfEmit);
|
|
9762
10139
|
return this;
|
|
9763
10140
|
}
|
|
9764
10141
|
if (event === EVENTS.CHANGE) {
|
|
9765
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
10142
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path15, 50);
|
|
9766
10143
|
if (isThrottled)
|
|
9767
10144
|
return this;
|
|
9768
10145
|
}
|
|
9769
10146
|
if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
9770
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
10147
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path15) : path15;
|
|
9771
10148
|
let stats2;
|
|
9772
10149
|
try {
|
|
9773
10150
|
stats2 = await stat4(fullPath);
|
|
@@ -9786,23 +10163,23 @@ class FSWatcher extends EventEmitter {
|
|
|
9786
10163
|
}
|
|
9787
10164
|
return error || this.closed;
|
|
9788
10165
|
}
|
|
9789
|
-
_throttle(actionType,
|
|
10166
|
+
_throttle(actionType, path15, timeout) {
|
|
9790
10167
|
if (!this._throttled.has(actionType)) {
|
|
9791
10168
|
this._throttled.set(actionType, new Map);
|
|
9792
10169
|
}
|
|
9793
10170
|
const action = this._throttled.get(actionType);
|
|
9794
10171
|
if (!action)
|
|
9795
10172
|
throw new Error("invalid throttle");
|
|
9796
|
-
const actionPath = action.get(
|
|
10173
|
+
const actionPath = action.get(path15);
|
|
9797
10174
|
if (actionPath) {
|
|
9798
10175
|
actionPath.count++;
|
|
9799
10176
|
return false;
|
|
9800
10177
|
}
|
|
9801
10178
|
let timeoutObject;
|
|
9802
10179
|
const clear = () => {
|
|
9803
|
-
const item = action.get(
|
|
10180
|
+
const item = action.get(path15);
|
|
9804
10181
|
const count = item ? item.count : 0;
|
|
9805
|
-
action.delete(
|
|
10182
|
+
action.delete(path15);
|
|
9806
10183
|
clearTimeout(timeoutObject);
|
|
9807
10184
|
if (item)
|
|
9808
10185
|
clearTimeout(item.timeoutObject);
|
|
@@ -9810,50 +10187,50 @@ class FSWatcher extends EventEmitter {
|
|
|
9810
10187
|
};
|
|
9811
10188
|
timeoutObject = setTimeout(clear, timeout);
|
|
9812
10189
|
const thr = { timeoutObject, clear, count: 0 };
|
|
9813
|
-
action.set(
|
|
10190
|
+
action.set(path15, thr);
|
|
9814
10191
|
return thr;
|
|
9815
10192
|
}
|
|
9816
10193
|
_incrReadyCount() {
|
|
9817
10194
|
return this._readyCount++;
|
|
9818
10195
|
}
|
|
9819
|
-
_awaitWriteFinish(
|
|
10196
|
+
_awaitWriteFinish(path15, threshold, event, awfEmit) {
|
|
9820
10197
|
const awf = this.options.awaitWriteFinish;
|
|
9821
10198
|
if (typeof awf !== "object")
|
|
9822
10199
|
return;
|
|
9823
10200
|
const pollInterval = awf.pollInterval;
|
|
9824
10201
|
let timeoutHandler;
|
|
9825
|
-
let fullPath =
|
|
9826
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
9827
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
10202
|
+
let fullPath = path15;
|
|
10203
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path15)) {
|
|
10204
|
+
fullPath = sysPath2.join(this.options.cwd, path15);
|
|
9828
10205
|
}
|
|
9829
10206
|
const now = new Date;
|
|
9830
10207
|
const writes = this._pendingWrites;
|
|
9831
10208
|
function awaitWriteFinishFn(prevStat) {
|
|
9832
10209
|
statcb(fullPath, (err, curStat) => {
|
|
9833
|
-
if (err || !writes.has(
|
|
10210
|
+
if (err || !writes.has(path15)) {
|
|
9834
10211
|
if (err && err.code !== "ENOENT")
|
|
9835
10212
|
awfEmit(err);
|
|
9836
10213
|
return;
|
|
9837
10214
|
}
|
|
9838
10215
|
const now2 = Number(new Date);
|
|
9839
10216
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
9840
|
-
writes.get(
|
|
10217
|
+
writes.get(path15).lastChange = now2;
|
|
9841
10218
|
}
|
|
9842
|
-
const pw = writes.get(
|
|
10219
|
+
const pw = writes.get(path15);
|
|
9843
10220
|
const df = now2 - pw.lastChange;
|
|
9844
10221
|
if (df >= threshold) {
|
|
9845
|
-
writes.delete(
|
|
10222
|
+
writes.delete(path15);
|
|
9846
10223
|
awfEmit(undefined, curStat);
|
|
9847
10224
|
} else {
|
|
9848
10225
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
9849
10226
|
}
|
|
9850
10227
|
});
|
|
9851
10228
|
}
|
|
9852
|
-
if (!writes.has(
|
|
9853
|
-
writes.set(
|
|
10229
|
+
if (!writes.has(path15)) {
|
|
10230
|
+
writes.set(path15, {
|
|
9854
10231
|
lastChange: now,
|
|
9855
10232
|
cancelWait: () => {
|
|
9856
|
-
writes.delete(
|
|
10233
|
+
writes.delete(path15);
|
|
9857
10234
|
clearTimeout(timeoutHandler);
|
|
9858
10235
|
return event;
|
|
9859
10236
|
}
|
|
@@ -9861,8 +10238,8 @@ class FSWatcher extends EventEmitter {
|
|
|
9861
10238
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
|
|
9862
10239
|
}
|
|
9863
10240
|
}
|
|
9864
|
-
_isIgnored(
|
|
9865
|
-
if (this.options.atomic && DOT_RE.test(
|
|
10241
|
+
_isIgnored(path15, stats) {
|
|
10242
|
+
if (this.options.atomic && DOT_RE.test(path15))
|
|
9866
10243
|
return true;
|
|
9867
10244
|
if (!this._userIgnored) {
|
|
9868
10245
|
const { cwd } = this.options;
|
|
@@ -9872,13 +10249,13 @@ class FSWatcher extends EventEmitter {
|
|
|
9872
10249
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
9873
10250
|
this._userIgnored = anymatch(list, undefined);
|
|
9874
10251
|
}
|
|
9875
|
-
return this._userIgnored(
|
|
10252
|
+
return this._userIgnored(path15, stats);
|
|
9876
10253
|
}
|
|
9877
|
-
_isntIgnored(
|
|
9878
|
-
return !this._isIgnored(
|
|
10254
|
+
_isntIgnored(path15, stat5) {
|
|
10255
|
+
return !this._isIgnored(path15, stat5);
|
|
9879
10256
|
}
|
|
9880
|
-
_getWatchHelpers(
|
|
9881
|
-
return new WatchHelper(
|
|
10257
|
+
_getWatchHelpers(path15) {
|
|
10258
|
+
return new WatchHelper(path15, this.options.followSymlinks, this);
|
|
9882
10259
|
}
|
|
9883
10260
|
_getWatchedDir(directory) {
|
|
9884
10261
|
const dir = sysPath2.resolve(directory);
|
|
@@ -9892,57 +10269,57 @@ class FSWatcher extends EventEmitter {
|
|
|
9892
10269
|
return Boolean(Number(stats.mode) & 256);
|
|
9893
10270
|
}
|
|
9894
10271
|
_remove(directory, item, isDirectory) {
|
|
9895
|
-
const
|
|
9896
|
-
const fullPath = sysPath2.resolve(
|
|
9897
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
9898
|
-
if (!this._throttle("remove",
|
|
10272
|
+
const path15 = sysPath2.join(directory, item);
|
|
10273
|
+
const fullPath = sysPath2.resolve(path15);
|
|
10274
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path15) || this._watched.has(fullPath);
|
|
10275
|
+
if (!this._throttle("remove", path15, 100))
|
|
9899
10276
|
return;
|
|
9900
10277
|
if (!isDirectory && this._watched.size === 1) {
|
|
9901
10278
|
this.add(directory, item, true);
|
|
9902
10279
|
}
|
|
9903
|
-
const wp = this._getWatchedDir(
|
|
10280
|
+
const wp = this._getWatchedDir(path15);
|
|
9904
10281
|
const nestedDirectoryChildren = wp.getChildren();
|
|
9905
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
10282
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path15, nested));
|
|
9906
10283
|
const parent = this._getWatchedDir(directory);
|
|
9907
10284
|
const wasTracked = parent.has(item);
|
|
9908
10285
|
parent.remove(item);
|
|
9909
10286
|
if (this._symlinkPaths.has(fullPath)) {
|
|
9910
10287
|
this._symlinkPaths.delete(fullPath);
|
|
9911
10288
|
}
|
|
9912
|
-
let relPath =
|
|
10289
|
+
let relPath = path15;
|
|
9913
10290
|
if (this.options.cwd)
|
|
9914
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
10291
|
+
relPath = sysPath2.relative(this.options.cwd, path15);
|
|
9915
10292
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
9916
10293
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
9917
10294
|
if (event === EVENTS.ADD)
|
|
9918
10295
|
return;
|
|
9919
10296
|
}
|
|
9920
|
-
this._watched.delete(
|
|
10297
|
+
this._watched.delete(path15);
|
|
9921
10298
|
this._watched.delete(fullPath);
|
|
9922
10299
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
9923
|
-
if (wasTracked && !this._isIgnored(
|
|
9924
|
-
this._emit(eventName,
|
|
9925
|
-
this._closePath(
|
|
10300
|
+
if (wasTracked && !this._isIgnored(path15))
|
|
10301
|
+
this._emit(eventName, path15);
|
|
10302
|
+
this._closePath(path15);
|
|
9926
10303
|
}
|
|
9927
|
-
_closePath(
|
|
9928
|
-
this._closeFile(
|
|
9929
|
-
const dir = sysPath2.dirname(
|
|
9930
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
10304
|
+
_closePath(path15) {
|
|
10305
|
+
this._closeFile(path15);
|
|
10306
|
+
const dir = sysPath2.dirname(path15);
|
|
10307
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path15));
|
|
9931
10308
|
}
|
|
9932
|
-
_closeFile(
|
|
9933
|
-
const closers = this._closers.get(
|
|
10309
|
+
_closeFile(path15) {
|
|
10310
|
+
const closers = this._closers.get(path15);
|
|
9934
10311
|
if (!closers)
|
|
9935
10312
|
return;
|
|
9936
10313
|
closers.forEach((closer) => closer());
|
|
9937
|
-
this._closers.delete(
|
|
10314
|
+
this._closers.delete(path15);
|
|
9938
10315
|
}
|
|
9939
|
-
_addPathCloser(
|
|
10316
|
+
_addPathCloser(path15, closer) {
|
|
9940
10317
|
if (!closer)
|
|
9941
10318
|
return;
|
|
9942
|
-
let list = this._closers.get(
|
|
10319
|
+
let list = this._closers.get(path15);
|
|
9943
10320
|
if (!list) {
|
|
9944
10321
|
list = [];
|
|
9945
|
-
this._closers.set(
|
|
10322
|
+
this._closers.set(path15, list);
|
|
9946
10323
|
}
|
|
9947
10324
|
list.push(closer);
|
|
9948
10325
|
}
|
|
@@ -9973,7 +10350,7 @@ var esm_default = { watch, FSWatcher };
|
|
|
9973
10350
|
|
|
9974
10351
|
// src/cli/cli.ts
|
|
9975
10352
|
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
9976
|
-
import
|
|
10353
|
+
import path16 from "node:path";
|
|
9977
10354
|
import { promises as fs12, existsSync as existsSync2 } from "node:fs";
|
|
9978
10355
|
import { spawn as spawn2, spawnSync } from "node:child_process";
|
|
9979
10356
|
import { pathToFileURL as pathToFileURL4 } from "node:url";
|
|
@@ -9982,7 +10359,7 @@ import { createRequire as createRequire3 } from "node:module";
|
|
|
9982
10359
|
// src/cli/auth-keys.ts
|
|
9983
10360
|
import * as crypto2 from "crypto";
|
|
9984
10361
|
import * as fs11 from "fs/promises";
|
|
9985
|
-
import * as
|
|
10362
|
+
import * as path15 from "path";
|
|
9986
10363
|
var AUTH_KEYS_FILENAME = "auth-keys.json";
|
|
9987
10364
|
async function generateAuthKeys() {
|
|
9988
10365
|
return new Promise((resolve3, reject) => {
|
|
@@ -10029,7 +10406,7 @@ function createJwksFromPublicKey(publicKeyPem, kid) {
|
|
|
10029
10406
|
};
|
|
10030
10407
|
}
|
|
10031
10408
|
async function loadOrGenerateAuthKeys(dataDir) {
|
|
10032
|
-
const keysPath =
|
|
10409
|
+
const keysPath = path15.join(dataDir, AUTH_KEYS_FILENAME);
|
|
10033
10410
|
try {
|
|
10034
10411
|
const data = await fs11.readFile(keysPath, "utf-8");
|
|
10035
10412
|
const stored = JSON.parse(data);
|
|
@@ -10056,7 +10433,7 @@ async function loadOrGenerateAuthKeys(dataDir) {
|
|
|
10056
10433
|
}
|
|
10057
10434
|
}
|
|
10058
10435
|
async function detectAuthProjectFlavor(projectRoot) {
|
|
10059
|
-
const packageJsonPath =
|
|
10436
|
+
const packageJsonPath = path15.join(projectRoot, "package.json");
|
|
10060
10437
|
try {
|
|
10061
10438
|
const raw = await fs11.readFile(packageJsonPath, "utf-8");
|
|
10062
10439
|
const parsed = JSON.parse(raw);
|
|
@@ -10098,7 +10475,7 @@ function setupAuthEnvironment(keys, siteUrl, options = {}) {
|
|
|
10098
10475
|
setEnv("AUTH_SKIP_VERIFICATION", "true");
|
|
10099
10476
|
}
|
|
10100
10477
|
// package.json
|
|
10101
|
-
var version = "0.0.1-alpha.
|
|
10478
|
+
var version = "0.0.1-alpha.9";
|
|
10102
10479
|
|
|
10103
10480
|
// src/cli/cli.ts
|
|
10104
10481
|
var WATCH_IGNORE_PATTERNS = [
|
|
@@ -10138,16 +10515,16 @@ function detectPreferredRuntime() {
|
|
|
10138
10515
|
return "node";
|
|
10139
10516
|
}
|
|
10140
10517
|
function detectPackageManager(projectRoot) {
|
|
10141
|
-
if (existsSync2(
|
|
10518
|
+
if (existsSync2(path16.join(projectRoot, "bun.lock")) || existsSync2(path16.join(projectRoot, "bun.lockb"))) {
|
|
10142
10519
|
return "bun";
|
|
10143
10520
|
}
|
|
10144
|
-
if (existsSync2(
|
|
10521
|
+
if (existsSync2(path16.join(projectRoot, "pnpm-lock.yaml"))) {
|
|
10145
10522
|
return "pnpm";
|
|
10146
10523
|
}
|
|
10147
|
-
if (existsSync2(
|
|
10524
|
+
if (existsSync2(path16.join(projectRoot, "yarn.lock"))) {
|
|
10148
10525
|
return "yarn";
|
|
10149
10526
|
}
|
|
10150
|
-
if (existsSync2(
|
|
10527
|
+
if (existsSync2(path16.join(projectRoot, "package-lock.json")) || existsSync2(path16.join(projectRoot, "npm-shrinkwrap.json"))) {
|
|
10151
10528
|
return "npm";
|
|
10152
10529
|
}
|
|
10153
10530
|
return isBunAvailable() ? "bun" : "npm";
|
|
@@ -10184,11 +10561,11 @@ function sanitizePackageName(input) {
|
|
|
10184
10561
|
return normalized.length > 0 ? normalized : "concave-app";
|
|
10185
10562
|
}
|
|
10186
10563
|
function formatPathForDisplay(fromDir, targetPath) {
|
|
10187
|
-
const relative3 =
|
|
10564
|
+
const relative3 = path16.relative(fromDir, targetPath);
|
|
10188
10565
|
if (!relative3 || relative3 === ".") {
|
|
10189
10566
|
return ".";
|
|
10190
10567
|
}
|
|
10191
|
-
if (!relative3.startsWith("..") && !
|
|
10568
|
+
if (!relative3.startsWith("..") && !path16.isAbsolute(relative3)) {
|
|
10192
10569
|
return relative3;
|
|
10193
10570
|
}
|
|
10194
10571
|
return targetPath;
|
|
@@ -10198,7 +10575,7 @@ function hasConvexDependency(packageJson) {
|
|
|
10198
10575
|
}
|
|
10199
10576
|
function createDefaultPackageJson(projectRoot) {
|
|
10200
10577
|
return {
|
|
10201
|
-
name: sanitizePackageName(
|
|
10578
|
+
name: sanitizePackageName(path16.basename(projectRoot)),
|
|
10202
10579
|
private: true,
|
|
10203
10580
|
type: "module"
|
|
10204
10581
|
};
|
|
@@ -10227,7 +10604,7 @@ async function writePackageJson(packageJsonPath, packageJson) {
|
|
|
10227
10604
|
`, "utf8");
|
|
10228
10605
|
}
|
|
10229
10606
|
async function ensurePackageJsonWithConvexDependency(projectRoot) {
|
|
10230
|
-
const packageJsonPath =
|
|
10607
|
+
const packageJsonPath = path16.join(projectRoot, "package.json");
|
|
10231
10608
|
const existing = await readPackageJson(packageJsonPath);
|
|
10232
10609
|
const packageJson = existing ?? createDefaultPackageJson(projectRoot);
|
|
10233
10610
|
const createdPackageJson = existing === null;
|
|
@@ -10249,7 +10626,7 @@ async function ensurePackageJsonWithConvexDependency(projectRoot) {
|
|
|
10249
10626
|
};
|
|
10250
10627
|
}
|
|
10251
10628
|
async function canResolveConvexRuntime(projectRoot) {
|
|
10252
|
-
const requireFromProject = createRequire3(
|
|
10629
|
+
const requireFromProject = createRequire3(path16.join(projectRoot, "__concave__.js"));
|
|
10253
10630
|
try {
|
|
10254
10631
|
requireFromProject.resolve("convex/values");
|
|
10255
10632
|
requireFromProject.resolve("convex/server");
|
|
@@ -10274,7 +10651,7 @@ async function ensureConvexDependencyReady(projectRoot, commandName) {
|
|
|
10274
10651
|
const packageManager = detectPackageManager(projectRoot);
|
|
10275
10652
|
const addCommand = getAddConvexCommand(packageManager);
|
|
10276
10653
|
const installCommand = getInstallCommand(packageManager);
|
|
10277
|
-
const packageJsonPath =
|
|
10654
|
+
const packageJsonPath = path16.join(projectRoot, "package.json");
|
|
10278
10655
|
const packageJson = await readPackageJson(packageJsonPath);
|
|
10279
10656
|
if (!packageJson) {
|
|
10280
10657
|
console.error(import_picocolors9.default.red("✗ Missing package.json"));
|
|
@@ -10284,7 +10661,7 @@ async function ensureConvexDependencyReady(projectRoot, commandName) {
|
|
|
10284
10661
|
}
|
|
10285
10662
|
if (!hasConvexDependency(packageJson)) {
|
|
10286
10663
|
console.error(import_picocolors9.default.red("✗ Missing dependency: convex"));
|
|
10287
|
-
console.error(import_picocolors9.default.dim(" Concave function files import `convex/values` and generated
|
|
10664
|
+
console.error(import_picocolors9.default.dim(" Concave function files import `convex/values` and generated types depend on `convex/server`."));
|
|
10288
10665
|
console.error(import_picocolors9.default.dim(` Run: ${addCommand.display}`));
|
|
10289
10666
|
process.exit(1);
|
|
10290
10667
|
}
|
|
@@ -10328,10 +10705,10 @@ function parseDotEnv2(content) {
|
|
|
10328
10705
|
}
|
|
10329
10706
|
async function loadDevEnvironment(cwd, layout) {
|
|
10330
10707
|
const candidates = [
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10708
|
+
path16.join(layout.convexRootDir, ".env.local"),
|
|
10709
|
+
path16.join(layout.convexRootDir, ".env"),
|
|
10710
|
+
path16.join(cwd, ".env.local"),
|
|
10711
|
+
path16.join(cwd, ".env")
|
|
10335
10712
|
];
|
|
10336
10713
|
const loaded = [];
|
|
10337
10714
|
for (const filePath of candidates) {
|
|
@@ -10345,7 +10722,7 @@ async function loadDevEnvironment(cwd, layout) {
|
|
|
10345
10722
|
process.env[key] = value;
|
|
10346
10723
|
}
|
|
10347
10724
|
}
|
|
10348
|
-
loaded.push(
|
|
10725
|
+
loaded.push(path16.relative(cwd, filePath));
|
|
10349
10726
|
}
|
|
10350
10727
|
return loaded;
|
|
10351
10728
|
}
|
|
@@ -10358,11 +10735,11 @@ Examples:
|
|
|
10358
10735
|
$ concave init my-app --force Overwrite starter files
|
|
10359
10736
|
`).action(async (dir, opts) => {
|
|
10360
10737
|
const cwd = process.cwd();
|
|
10361
|
-
const projectRoot =
|
|
10738
|
+
const projectRoot = path16.resolve(cwd, dir ?? ".");
|
|
10362
10739
|
const displayRoot = formatPathForDisplay(cwd, projectRoot);
|
|
10363
10740
|
const layout = await resolveProjectLayout(projectRoot);
|
|
10364
10741
|
const convexDir = layout.functionsDir;
|
|
10365
|
-
const starterPath =
|
|
10742
|
+
const starterPath = path16.join(convexDir, "messages.ts");
|
|
10366
10743
|
await fs12.mkdir(projectRoot, { recursive: true });
|
|
10367
10744
|
await fs12.mkdir(convexDir, { recursive: true });
|
|
10368
10745
|
const starterExists = existsSync2(starterPath);
|
|
@@ -10486,16 +10863,17 @@ Examples:
|
|
|
10486
10863
|
});
|
|
10487
10864
|
console.log(import_picocolors9.default.green(`✓ Generated worker entry (${result.moduleCount} module${result.moduleCount === 1 ? "" : "s"})`));
|
|
10488
10865
|
const configPath = await ensureWranglerConfig(cwd);
|
|
10489
|
-
console.log(import_picocolors9.default.green(`✓ Using config: ${
|
|
10490
|
-
const relativeConfigPath =
|
|
10491
|
-
const wranglerArgs = ["
|
|
10866
|
+
console.log(import_picocolors9.default.green(`✓ Using config: ${path16.basename(configPath)}`));
|
|
10867
|
+
const relativeConfigPath = path16.relative(cwd, configPath);
|
|
10868
|
+
const wranglerArgs = ["dev", "--config", relativeConfigPath];
|
|
10492
10869
|
if (opts.port) {
|
|
10493
10870
|
wranglerArgs.push("--port", opts.port);
|
|
10494
10871
|
}
|
|
10495
10872
|
console.log(import_picocolors9.default.cyan(`
|
|
10496
10873
|
\uD83D\uDE80 Starting wrangler dev...
|
|
10497
10874
|
`));
|
|
10498
|
-
|
|
10875
|
+
const wranglerLauncher = resolveWranglerLauncher({ cwd });
|
|
10876
|
+
wranglerProcess = spawn2(wranglerLauncher.command, [...wranglerLauncher.argsPrefix, ...wranglerArgs], {
|
|
10499
10877
|
cwd,
|
|
10500
10878
|
stdio: "inherit"
|
|
10501
10879
|
});
|
|
@@ -10518,7 +10896,7 @@ Examples:
|
|
|
10518
10896
|
try {
|
|
10519
10897
|
await generateTypes(cwd, { silent: true });
|
|
10520
10898
|
} catch {}
|
|
10521
|
-
const relPath =
|
|
10899
|
+
const relPath = path16.relative(cwd, filePath);
|
|
10522
10900
|
console.log(import_picocolors9.default.dim(` Updated worker entry (${event}: ${relPath || "convex/"}, ${regenResult.moduleCount} module${regenResult.moduleCount === 1 ? "" : "s"})`));
|
|
10523
10901
|
} catch (error) {
|
|
10524
10902
|
console.error(import_picocolors9.default.red("✗ Failed to update worker entry:"), error.message ?? error);
|
|
@@ -10700,10 +11078,10 @@ Examples:
|
|
|
10700
11078
|
console.log(import_picocolors9.default.green(`✓ Generated standalone entry (${result.moduleCount} module${result.moduleCount === 1 ? "" : "s"})`));
|
|
10701
11079
|
if (opts.verbose) {
|
|
10702
11080
|
for (const file of result.sourceFiles) {
|
|
10703
|
-
console.log(import_picocolors9.default.dim(` ${
|
|
11081
|
+
console.log(import_picocolors9.default.dim(` ${path16.relative(cwd, file)}`));
|
|
10704
11082
|
}
|
|
10705
11083
|
}
|
|
10706
|
-
const outfile =
|
|
11084
|
+
const outfile = path16.resolve(cwd, opts.outfile);
|
|
10707
11085
|
const buildArgs = ["build", "--compile", result.entryFile, "--outfile", outfile];
|
|
10708
11086
|
if (opts.target) {
|
|
10709
11087
|
buildArgs.push("--target", `bun-${opts.target}`);
|
|
@@ -10733,13 +11111,13 @@ Examples:
|
|
|
10733
11111
|
sizeStr = ` (${sizeMB} MB)`;
|
|
10734
11112
|
} catch {}
|
|
10735
11113
|
console.log(import_picocolors9.default.green(`
|
|
10736
|
-
✓ Built: ${
|
|
11114
|
+
✓ Built: ${path16.relative(cwd, outfile)}${sizeStr}`));
|
|
10737
11115
|
if (opts.target) {
|
|
10738
11116
|
console.log(import_picocolors9.default.dim(` Target: bun-${opts.target}`));
|
|
10739
11117
|
}
|
|
10740
11118
|
console.log(import_picocolors9.default.dim(`
|
|
10741
11119
|
Run it:`));
|
|
10742
|
-
console.log(import_picocolors9.default.dim(` ./${
|
|
11120
|
+
console.log(import_picocolors9.default.dim(` ./${path16.relative(cwd, outfile)} --port 3000`));
|
|
10743
11121
|
} catch (error) {
|
|
10744
11122
|
console.error(import_picocolors9.default.red("✗ Build failed:"), error.message);
|
|
10745
11123
|
if (opts.verbose && error.stack) {
|
|
@@ -10821,7 +11199,7 @@ async function listFunctionSpecs(options) {
|
|
|
10821
11199
|
const result = await response.json();
|
|
10822
11200
|
const functions = result.value || result.result || [];
|
|
10823
11201
|
if (options.file) {
|
|
10824
|
-
const outPath =
|
|
11202
|
+
const outPath = path16.resolve("function-spec.json");
|
|
10825
11203
|
await fs12.writeFile(outPath, JSON.stringify(functions, null, 2) + `
|
|
10826
11204
|
`);
|
|
10827
11205
|
console.log(import_picocolors9.default.green(`✓ Wrote ${functions.length} function specs to ${outPath}`));
|
|
@@ -10934,7 +11312,7 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
|
|
|
10934
11312
|
console.log(import_picocolors9.default.cyan(`
|
|
10935
11313
|
\uD83D\uDE80 Server ready at ${import_picocolors9.default.bold(displayUrl)}`));
|
|
10936
11314
|
console.log(import_picocolors9.default.dim(` Dashboard: ${displayUrl}/_dashboard`));
|
|
10937
|
-
console.log(import_picocolors9.default.dim(` Functions: ${
|
|
11315
|
+
console.log(import_picocolors9.default.dim(` Functions: ${path16.relative(cwd, functionsDir)}/`));
|
|
10938
11316
|
console.log(import_picocolors9.default.dim(`
|
|
10939
11317
|
Press Ctrl+C to stop
|
|
10940
11318
|
`));
|
|
@@ -10947,17 +11325,15 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
|
|
|
10947
11325
|
throw error;
|
|
10948
11326
|
}
|
|
10949
11327
|
};
|
|
10950
|
-
const
|
|
11328
|
+
const reloadServer = async (reason) => {
|
|
10951
11329
|
if (isRestarting)
|
|
10952
11330
|
return;
|
|
10953
11331
|
isRestarting = true;
|
|
10954
11332
|
try {
|
|
10955
|
-
console.log(import_picocolors9.default.
|
|
10956
|
-
⟳ ${reason}`));
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
}
|
|
10960
|
-
await startServer();
|
|
11333
|
+
console.log(import_picocolors9.default.dim(`
|
|
11334
|
+
⟳ ${reason}`));
|
|
11335
|
+
await server.reload();
|
|
11336
|
+
console.log(import_picocolors9.default.dim(` ✓ Reloaded`));
|
|
10961
11337
|
} catch (error) {
|
|
10962
11338
|
console.error(import_picocolors9.default.red("✗ Failed to reload server:"), error.message);
|
|
10963
11339
|
} finally {
|
|
@@ -10977,11 +11353,11 @@ async function runBunDevServer(cwd, opts, artifacts, layout) {
|
|
|
10977
11353
|
}
|
|
10978
11354
|
reloadTimer = setTimeout(async () => {
|
|
10979
11355
|
reloadTimer = undefined;
|
|
10980
|
-
const relPath =
|
|
11356
|
+
const relPath = path16.relative(cwd, filePath);
|
|
10981
11357
|
try {
|
|
10982
11358
|
await generateTypes(cwd, { silent: true });
|
|
10983
11359
|
} catch {}
|
|
10984
|
-
|
|
11360
|
+
reloadServer(`File changed: ${relPath}`);
|
|
10985
11361
|
}, 300);
|
|
10986
11362
|
};
|
|
10987
11363
|
watcher.on("add", (filePath) => scheduleReload("added", filePath)).on("change", (filePath) => scheduleReload("changed", filePath)).on("unlink", (filePath) => scheduleReload("deleted", filePath));
|
|
@@ -11045,7 +11421,7 @@ async function runBunDevServerForked(cwd, opts, artifacts, layout) {
|
|
|
11045
11421
|
} catch (error) {
|
|
11046
11422
|
console.warn(import_picocolors9.default.yellow(`⚠️ Auth keys setup failed: ${error.message}`));
|
|
11047
11423
|
}
|
|
11048
|
-
const tempScriptPath =
|
|
11424
|
+
const tempScriptPath = path16.join(localData.dataDir, ".bun-dev-server.js");
|
|
11049
11425
|
const dashboardModulePath = artifacts.dashboardHtmlPath.replace(/\\/g, "/");
|
|
11050
11426
|
const scriptContent = `import { BunServer } from "${artifacts.bunRuntime.serverEntryPath.replace(/\\/g, "/")}";
|
|
11051
11427
|
import { DASHBOARD_HTML } from ${JSON.stringify(dashboardModulePath)};
|
|
@@ -11062,7 +11438,7 @@ const displayUrl = server.url.replace(/127\\.0\\.0\\.1|0\\.0\\.0\\.0/, "localhos
|
|
|
11062
11438
|
|
|
11063
11439
|
console.log("\\n\uD83D\uDE80 Server ready at " + displayUrl);
|
|
11064
11440
|
console.log(" Dashboard: " + displayUrl + "/_dashboard");
|
|
11065
|
-
console.log(" Functions: ${
|
|
11441
|
+
console.log(" Functions: ${path16.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
|
|
11066
11442
|
console.log("\\n Press Ctrl+C to stop\\n");
|
|
11067
11443
|
|
|
11068
11444
|
// Handle graceful shutdown
|
|
@@ -11088,20 +11464,136 @@ process.on("SIGTERM", async () => {
|
|
|
11088
11464
|
`;
|
|
11089
11465
|
await fs12.writeFile(tempScriptPath, scriptContent, "utf8");
|
|
11090
11466
|
const bunArgs = [tempScriptPath];
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
|
|
11096
|
-
|
|
11097
|
-
|
|
11098
|
-
|
|
11099
|
-
|
|
11100
|
-
|
|
11101
|
-
|
|
11102
|
-
|
|
11103
|
-
|
|
11467
|
+
let watcher;
|
|
11468
|
+
let bunProcess;
|
|
11469
|
+
let reloadTimer;
|
|
11470
|
+
let isRestarting = false;
|
|
11471
|
+
let isShuttingDown = false;
|
|
11472
|
+
const stopBunProcess = async () => {
|
|
11473
|
+
const activeProcess = bunProcess;
|
|
11474
|
+
if (!activeProcess || activeProcess.exitCode !== null) {
|
|
11475
|
+
return;
|
|
11476
|
+
}
|
|
11477
|
+
await new Promise((resolve3) => {
|
|
11478
|
+
let settled = false;
|
|
11479
|
+
let forceKillTimer;
|
|
11480
|
+
const finish = () => {
|
|
11481
|
+
if (settled) {
|
|
11482
|
+
return;
|
|
11483
|
+
}
|
|
11484
|
+
settled = true;
|
|
11485
|
+
if (forceKillTimer) {
|
|
11486
|
+
clearTimeout(forceKillTimer);
|
|
11487
|
+
forceKillTimer = undefined;
|
|
11488
|
+
}
|
|
11489
|
+
activeProcess.off("exit", onExit);
|
|
11490
|
+
resolve3();
|
|
11491
|
+
};
|
|
11492
|
+
const onExit = () => finish();
|
|
11493
|
+
activeProcess.once("exit", onExit);
|
|
11494
|
+
try {
|
|
11495
|
+
activeProcess.kill("SIGTERM");
|
|
11496
|
+
} catch {
|
|
11497
|
+
finish();
|
|
11498
|
+
return;
|
|
11499
|
+
}
|
|
11500
|
+
forceKillTimer = setTimeout(() => {
|
|
11501
|
+
if (settled) {
|
|
11502
|
+
return;
|
|
11503
|
+
}
|
|
11504
|
+
try {
|
|
11505
|
+
activeProcess.kill("SIGKILL");
|
|
11506
|
+
} catch {
|
|
11507
|
+
finish();
|
|
11508
|
+
}
|
|
11509
|
+
}, 2000);
|
|
11510
|
+
});
|
|
11511
|
+
};
|
|
11512
|
+
const cleanup = async () => {
|
|
11513
|
+
if (reloadTimer) {
|
|
11514
|
+
clearTimeout(reloadTimer);
|
|
11515
|
+
reloadTimer = undefined;
|
|
11516
|
+
}
|
|
11517
|
+
if (watcher) {
|
|
11518
|
+
await watcher.close();
|
|
11519
|
+
watcher = undefined;
|
|
11520
|
+
}
|
|
11521
|
+
await stopBunProcess();
|
|
11522
|
+
await fs12.unlink(tempScriptPath).catch(() => {});
|
|
11523
|
+
};
|
|
11524
|
+
const spawnBunProcess = () => {
|
|
11525
|
+
const child = spawn2("bun", bunArgs, {
|
|
11526
|
+
cwd,
|
|
11527
|
+
stdio: "inherit"
|
|
11528
|
+
});
|
|
11529
|
+
child.on("exit", (code) => {
|
|
11530
|
+
if (isRestarting || isShuttingDown) {
|
|
11531
|
+
return;
|
|
11532
|
+
}
|
|
11533
|
+
cleanup().catch(() => {}).finally(() => {
|
|
11534
|
+
process.exit(code ?? 0);
|
|
11535
|
+
});
|
|
11536
|
+
});
|
|
11537
|
+
return child;
|
|
11538
|
+
};
|
|
11539
|
+
const reloadServerViaHttp = async (reason) => {
|
|
11540
|
+
if (isRestarting || isShuttingDown) {
|
|
11541
|
+
return;
|
|
11542
|
+
}
|
|
11543
|
+
isRestarting = true;
|
|
11544
|
+
try {
|
|
11545
|
+
console.log(import_picocolors9.default.dim(`
|
|
11546
|
+
⟳ ${reason}`));
|
|
11547
|
+
const response = await fetch(`http://127.0.0.1:${port}/_dev/reload`, {
|
|
11548
|
+
method: "POST",
|
|
11549
|
+
signal: AbortSignal.timeout(5000)
|
|
11550
|
+
});
|
|
11551
|
+
if (response.ok) {
|
|
11552
|
+
console.log(import_picocolors9.default.dim(` ✓ Reloaded`));
|
|
11553
|
+
} else {
|
|
11554
|
+
throw new Error(`HTTP ${response.status}`);
|
|
11555
|
+
}
|
|
11556
|
+
} catch (error) {
|
|
11557
|
+
console.warn(import_picocolors9.default.dim(` HTTP reload failed (${error.message}), restarting process...`));
|
|
11558
|
+
await stopBunProcess();
|
|
11559
|
+
bunProcess = spawnBunProcess();
|
|
11560
|
+
} finally {
|
|
11561
|
+
isRestarting = false;
|
|
11562
|
+
}
|
|
11563
|
+
};
|
|
11564
|
+
bunProcess = spawnBunProcess();
|
|
11565
|
+
watcher = esm_default.watch(convexDir, {
|
|
11566
|
+
ignoreInitial: true,
|
|
11567
|
+
ignored: WATCH_IGNORE_PATTERNS,
|
|
11568
|
+
persistent: true
|
|
11104
11569
|
});
|
|
11570
|
+
const scheduleReload = (_event, filePath) => {
|
|
11571
|
+
if (reloadTimer) {
|
|
11572
|
+
clearTimeout(reloadTimer);
|
|
11573
|
+
}
|
|
11574
|
+
reloadTimer = setTimeout(async () => {
|
|
11575
|
+
reloadTimer = undefined;
|
|
11576
|
+
const relPath = path16.relative(cwd, filePath);
|
|
11577
|
+
try {
|
|
11578
|
+
await generateTypes(cwd, { silent: true });
|
|
11579
|
+
} catch {}
|
|
11580
|
+
await reloadServerViaHttp(`File changed: ${relPath}`);
|
|
11581
|
+
}, 300);
|
|
11582
|
+
};
|
|
11583
|
+
watcher.on("add", (filePath) => scheduleReload("added", filePath)).on("change", (filePath) => scheduleReload("changed", filePath)).on("unlink", (filePath) => scheduleReload("deleted", filePath));
|
|
11584
|
+
const shutdown = async () => {
|
|
11585
|
+
if (isShuttingDown) {
|
|
11586
|
+
return;
|
|
11587
|
+
}
|
|
11588
|
+
isShuttingDown = true;
|
|
11589
|
+
console.log(import_picocolors9.default.cyan(`
|
|
11590
|
+
|
|
11591
|
+
\uD83C\uDF0A Shutting down Concave dev server...`));
|
|
11592
|
+
await cleanup();
|
|
11593
|
+
process.exit(0);
|
|
11594
|
+
};
|
|
11595
|
+
process.on("SIGINT", shutdown);
|
|
11596
|
+
process.on("SIGTERM", shutdown);
|
|
11105
11597
|
}
|
|
11106
11598
|
async function ensureNodeSqliteReady() {
|
|
11107
11599
|
const hasFlag = process.execArgv.includes("--experimental-sqlite");
|
|
@@ -11153,7 +11645,7 @@ function resolveTsxLoaderPath() {
|
|
|
11153
11645
|
let tsxLoaderPath = "tsx";
|
|
11154
11646
|
try {
|
|
11155
11647
|
const tsxPackagePath = require2.resolve("tsx/package.json");
|
|
11156
|
-
tsxLoaderPath =
|
|
11648
|
+
tsxLoaderPath = path16.join(path16.dirname(tsxPackagePath), "dist/loader.mjs");
|
|
11157
11649
|
} catch {
|
|
11158
11650
|
tsxLoaderPath = "tsx";
|
|
11159
11651
|
}
|
|
@@ -11241,7 +11733,7 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
|
|
|
11241
11733
|
console.log(import_picocolors9.default.cyan(`
|
|
11242
11734
|
\uD83D\uDE80 Server ready at ${import_picocolors9.default.bold(displayUrl)}`));
|
|
11243
11735
|
console.log(import_picocolors9.default.dim(` Dashboard: ${displayUrl}/_dashboard`));
|
|
11244
|
-
console.log(import_picocolors9.default.dim(` Functions: ${
|
|
11736
|
+
console.log(import_picocolors9.default.dim(` Functions: ${path16.relative(cwd, functionsDir)}/`));
|
|
11245
11737
|
console.log(import_picocolors9.default.dim(`
|
|
11246
11738
|
Press Ctrl+C to stop
|
|
11247
11739
|
`));
|
|
@@ -11254,17 +11746,15 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
|
|
|
11254
11746
|
throw error;
|
|
11255
11747
|
}
|
|
11256
11748
|
};
|
|
11257
|
-
const
|
|
11749
|
+
const reloadServer = async (reason) => {
|
|
11258
11750
|
if (isRestarting)
|
|
11259
11751
|
return;
|
|
11260
11752
|
isRestarting = true;
|
|
11261
11753
|
try {
|
|
11262
|
-
console.log(import_picocolors9.default.
|
|
11263
|
-
⟳ ${reason}`));
|
|
11264
|
-
|
|
11265
|
-
|
|
11266
|
-
}
|
|
11267
|
-
await startServer();
|
|
11754
|
+
console.log(import_picocolors9.default.dim(`
|
|
11755
|
+
⟳ ${reason}`));
|
|
11756
|
+
await server.reload();
|
|
11757
|
+
console.log(import_picocolors9.default.dim(` ✓ Reloaded`));
|
|
11268
11758
|
} catch (error) {
|
|
11269
11759
|
console.error(import_picocolors9.default.red("✗ Failed to reload server:"), error.message);
|
|
11270
11760
|
} finally {
|
|
@@ -11284,11 +11774,11 @@ async function runNodeDevServer(cwd, opts, artifacts, layout) {
|
|
|
11284
11774
|
}
|
|
11285
11775
|
reloadTimer = setTimeout(async () => {
|
|
11286
11776
|
reloadTimer = undefined;
|
|
11287
|
-
const relPath =
|
|
11777
|
+
const relPath = path16.relative(cwd, filePath);
|
|
11288
11778
|
try {
|
|
11289
11779
|
await generateTypes(cwd, { silent: true });
|
|
11290
11780
|
} catch {}
|
|
11291
|
-
|
|
11781
|
+
reloadServer(`File changed: ${relPath}`);
|
|
11292
11782
|
}, 300);
|
|
11293
11783
|
};
|
|
11294
11784
|
watcher.on("add", (filePath) => scheduleReload("added", filePath)).on("change", (filePath) => scheduleReload("changed", filePath)).on("unlink", (filePath) => scheduleReload("deleted", filePath));
|
|
@@ -11356,11 +11846,11 @@ async function runNodeDevServerForked(cwd, opts, artifacts, layout) {
|
|
|
11356
11846
|
let tsxLoaderPath;
|
|
11357
11847
|
try {
|
|
11358
11848
|
const tsxPackagePath = require2.resolve("tsx/package.json");
|
|
11359
|
-
tsxLoaderPath =
|
|
11849
|
+
tsxLoaderPath = path16.join(path16.dirname(tsxPackagePath), "dist/loader.mjs");
|
|
11360
11850
|
} catch {
|
|
11361
11851
|
tsxLoaderPath = "tsx";
|
|
11362
11852
|
}
|
|
11363
|
-
const tempScriptPath =
|
|
11853
|
+
const tempScriptPath = path16.join(localData.dataDir, ".node-dev-server.mjs");
|
|
11364
11854
|
const nodeDashboardModulePath = artifacts.dashboardHtmlPath.replace(/\\/g, "/");
|
|
11365
11855
|
const scriptContent = `import { NodeServer } from "${artifacts.nodeRuntime.serverEntryPath.replace(/\\/g, "/")}";
|
|
11366
11856
|
import { DASHBOARD_HTML } from ${JSON.stringify(nodeDashboardModulePath)};
|
|
@@ -11377,7 +11867,7 @@ const displayUrl = server.url.replace(/127\\.0\\.0\\.1|0\\.0\\.0\\.0/, "localhos
|
|
|
11377
11867
|
|
|
11378
11868
|
console.log("\\n\uD83D\uDE80 Server ready at " + displayUrl);
|
|
11379
11869
|
console.log(" Dashboard: " + displayUrl + "/_dashboard");
|
|
11380
|
-
console.log(" Functions: ${
|
|
11870
|
+
console.log(" Functions: ${path16.relative(cwd, functionsDir).replace(/\\/g, "/")}/");
|
|
11381
11871
|
console.log("\\n Press Ctrl+C to stop\\n");
|
|
11382
11872
|
|
|
11383
11873
|
// Handle graceful shutdown
|
|
@@ -11404,26 +11894,142 @@ process.on("SIGTERM", async () => {
|
|
|
11404
11894
|
await fs12.writeFile(tempScriptPath, scriptContent, "utf8");
|
|
11405
11895
|
const nodeArgs = ["--experimental-sqlite", "--import", tsxLoaderPath, tempScriptPath];
|
|
11406
11896
|
const executable = detectHostRuntime() === "node" ? process.execPath : "node";
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
|
|
11410
|
-
|
|
11411
|
-
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11897
|
+
let watcher;
|
|
11898
|
+
let nodeProcess;
|
|
11899
|
+
let reloadTimer;
|
|
11900
|
+
let isRestarting = false;
|
|
11901
|
+
let isShuttingDown = false;
|
|
11902
|
+
const stopNodeProcess = async () => {
|
|
11903
|
+
const activeProcess = nodeProcess;
|
|
11904
|
+
if (!activeProcess || activeProcess.exitCode !== null) {
|
|
11905
|
+
return;
|
|
11906
|
+
}
|
|
11907
|
+
await new Promise((resolve3) => {
|
|
11908
|
+
let settled = false;
|
|
11909
|
+
let forceKillTimer;
|
|
11910
|
+
const finish = () => {
|
|
11911
|
+
if (settled) {
|
|
11912
|
+
return;
|
|
11913
|
+
}
|
|
11914
|
+
settled = true;
|
|
11915
|
+
if (forceKillTimer) {
|
|
11916
|
+
clearTimeout(forceKillTimer);
|
|
11917
|
+
forceKillTimer = undefined;
|
|
11918
|
+
}
|
|
11919
|
+
activeProcess.off("exit", onExit);
|
|
11920
|
+
resolve3();
|
|
11921
|
+
};
|
|
11922
|
+
const onExit = () => finish();
|
|
11923
|
+
activeProcess.once("exit", onExit);
|
|
11924
|
+
try {
|
|
11925
|
+
activeProcess.kill("SIGTERM");
|
|
11926
|
+
} catch {
|
|
11927
|
+
finish();
|
|
11928
|
+
return;
|
|
11929
|
+
}
|
|
11930
|
+
forceKillTimer = setTimeout(() => {
|
|
11931
|
+
if (settled) {
|
|
11932
|
+
return;
|
|
11933
|
+
}
|
|
11934
|
+
try {
|
|
11935
|
+
activeProcess.kill("SIGKILL");
|
|
11936
|
+
} catch {
|
|
11937
|
+
finish();
|
|
11938
|
+
}
|
|
11939
|
+
}, 2000);
|
|
11940
|
+
});
|
|
11941
|
+
};
|
|
11942
|
+
const cleanup = async () => {
|
|
11943
|
+
if (reloadTimer) {
|
|
11944
|
+
clearTimeout(reloadTimer);
|
|
11945
|
+
reloadTimer = undefined;
|
|
11946
|
+
}
|
|
11947
|
+
if (watcher) {
|
|
11948
|
+
await watcher.close();
|
|
11949
|
+
watcher = undefined;
|
|
11950
|
+
}
|
|
11951
|
+
await stopNodeProcess();
|
|
11952
|
+
await fs12.unlink(tempScriptPath).catch(() => {});
|
|
11953
|
+
};
|
|
11954
|
+
const spawnNodeProcess = () => {
|
|
11955
|
+
const child = spawn2(executable, nodeArgs, {
|
|
11956
|
+
cwd,
|
|
11957
|
+
stdio: "inherit"
|
|
11958
|
+
});
|
|
11959
|
+
child.on("exit", (code) => {
|
|
11960
|
+
if (isRestarting || isShuttingDown) {
|
|
11961
|
+
return;
|
|
11962
|
+
}
|
|
11963
|
+
cleanup().catch(() => {}).finally(() => {
|
|
11964
|
+
process.exit(code ?? 0);
|
|
11965
|
+
});
|
|
11966
|
+
});
|
|
11967
|
+
return child;
|
|
11968
|
+
};
|
|
11969
|
+
const reloadServerViaHttp = async (reason) => {
|
|
11970
|
+
if (isRestarting || isShuttingDown) {
|
|
11971
|
+
return;
|
|
11972
|
+
}
|
|
11973
|
+
isRestarting = true;
|
|
11974
|
+
try {
|
|
11975
|
+
console.log(import_picocolors9.default.dim(`
|
|
11976
|
+
⟳ ${reason}`));
|
|
11977
|
+
const response = await fetch(`http://127.0.0.1:${port}/_dev/reload`, {
|
|
11978
|
+
method: "POST",
|
|
11979
|
+
signal: AbortSignal.timeout(5000)
|
|
11980
|
+
});
|
|
11981
|
+
if (response.ok) {
|
|
11982
|
+
console.log(import_picocolors9.default.dim(` ✓ Reloaded`));
|
|
11983
|
+
} else {
|
|
11984
|
+
throw new Error(`HTTP ${response.status}`);
|
|
11985
|
+
}
|
|
11986
|
+
} catch (error) {
|
|
11987
|
+
console.warn(import_picocolors9.default.dim(` HTTP reload failed (${error.message}), restarting process...`));
|
|
11988
|
+
await stopNodeProcess();
|
|
11989
|
+
nodeProcess = spawnNodeProcess();
|
|
11990
|
+
} finally {
|
|
11991
|
+
isRestarting = false;
|
|
11992
|
+
}
|
|
11993
|
+
};
|
|
11994
|
+
nodeProcess = spawnNodeProcess();
|
|
11995
|
+
watcher = esm_default.watch(convexDir, {
|
|
11996
|
+
ignoreInitial: true,
|
|
11997
|
+
ignored: WATCH_IGNORE_PATTERNS,
|
|
11998
|
+
persistent: true
|
|
11420
11999
|
});
|
|
12000
|
+
const scheduleReload = (_event, filePath) => {
|
|
12001
|
+
if (reloadTimer) {
|
|
12002
|
+
clearTimeout(reloadTimer);
|
|
12003
|
+
}
|
|
12004
|
+
reloadTimer = setTimeout(async () => {
|
|
12005
|
+
reloadTimer = undefined;
|
|
12006
|
+
const relPath = path16.relative(cwd, filePath);
|
|
12007
|
+
try {
|
|
12008
|
+
await generateTypes(cwd, { silent: true });
|
|
12009
|
+
} catch {}
|
|
12010
|
+
await reloadServerViaHttp(`File changed: ${relPath}`);
|
|
12011
|
+
}, 300);
|
|
12012
|
+
};
|
|
12013
|
+
watcher.on("add", (filePath) => scheduleReload("added", filePath)).on("change", (filePath) => scheduleReload("changed", filePath)).on("unlink", (filePath) => scheduleReload("deleted", filePath));
|
|
12014
|
+
const shutdown = async () => {
|
|
12015
|
+
if (isShuttingDown) {
|
|
12016
|
+
return;
|
|
12017
|
+
}
|
|
12018
|
+
isShuttingDown = true;
|
|
12019
|
+
console.log(import_picocolors9.default.cyan(`
|
|
12020
|
+
|
|
12021
|
+
\uD83C\uDF0A Shutting down Concave dev server...`));
|
|
12022
|
+
await cleanup();
|
|
12023
|
+
process.exit(0);
|
|
12024
|
+
};
|
|
12025
|
+
process.on("SIGINT", shutdown);
|
|
12026
|
+
process.on("SIGTERM", shutdown);
|
|
11421
12027
|
}
|
|
11422
12028
|
async function ensureWranglerConfig(cwd) {
|
|
11423
12029
|
const userConfigs = [
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
12030
|
+
path16.join(cwd, "wrangler.jsonc"),
|
|
12031
|
+
path16.join(cwd, "wrangler.json"),
|
|
12032
|
+
path16.join(cwd, "wrangler.toml")
|
|
11427
12033
|
];
|
|
11428
12034
|
for (const configPath of userConfigs) {
|
|
11429
12035
|
try {
|
|
@@ -11432,8 +12038,8 @@ async function ensureWranglerConfig(cwd) {
|
|
|
11432
12038
|
} catch {}
|
|
11433
12039
|
}
|
|
11434
12040
|
const concavePaths = getConcaveProjectPaths(cwd);
|
|
11435
|
-
const generatedConfigPath =
|
|
11436
|
-
const assetsDirectory =
|
|
12041
|
+
const generatedConfigPath = path16.join(concavePaths.concaveDir, "wrangler.jsonc");
|
|
12042
|
+
const assetsDirectory = path16.join(concavePaths.concaveDir, "static");
|
|
11437
12043
|
await fs12.mkdir(assetsDirectory, { recursive: true });
|
|
11438
12044
|
const config = {
|
|
11439
12045
|
name: "concave-app",
|
|
@@ -11456,7 +12062,7 @@ async function ensureWranglerConfig(cwd) {
|
|
|
11456
12062
|
}
|
|
11457
12063
|
]
|
|
11458
12064
|
};
|
|
11459
|
-
await fs12.mkdir(
|
|
12065
|
+
await fs12.mkdir(path16.dirname(generatedConfigPath), { recursive: true });
|
|
11460
12066
|
await fs12.writeFile(generatedConfigPath, JSON.stringify(config, null, 2), "utf8");
|
|
11461
12067
|
return generatedConfigPath;
|
|
11462
12068
|
}
|