@lunora/cli 1.0.0-alpha.68 → 1.0.0-alpha.69
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/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/packem_chunks/handler15.mjs +1 -1
- package/dist/packem_chunks/handler2.mjs +1 -1
- package/dist/packem_chunks/handler20.mjs +1 -1
- package/dist/packem_chunks/handler5.mjs +1 -1
- package/dist/packem_chunks/handler6.mjs +1 -1
- package/dist/packem_chunks/handler9.mjs +2 -2
- package/dist/packem_chunks/planDevCommand.mjs +72 -8
- package/dist/packem_chunks/runDeployCommand.mjs +2 -2
- package/dist/packem_chunks/runInitCommand.mjs +4 -4
- package/dist/packem_shared/{detect-package-manager-Cxo6Tpyx.mjs → detect-package-manager-DvEthdCw.mjs} +15 -28
- package/dist/packem_shared/{wrangler-secrets-P2_ZUR-k.mjs → wrangler-secrets-Dq_Fkbm-.mjs} +6 -4
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -483,8 +483,12 @@ interface DevCommandOptions {
|
|
|
483
483
|
ensureExample?: typeof ensureDevVarsExample;
|
|
484
484
|
/** Injection seam for tests — defaults to the real empty-secret/admin-token filler. */
|
|
485
485
|
fillSecrets?: typeof fillDevSecrets;
|
|
486
|
+
/** Injection seam for tests — defaults to the real free-port probe ({@link findAvailablePort}). */
|
|
487
|
+
findFreePort?: (preferred: number) => Promise<number>;
|
|
486
488
|
/** Dev flavor override (tests / callers that already detected it) — defaults to {@link detectDevFlavor}. */
|
|
487
489
|
flavor?: DevFlavor;
|
|
490
|
+
/** Injection seam for tests — defaults to the real IPv6-loopback probe ({@link hasIpv6Loopback}). */
|
|
491
|
+
hasIpv6Loopback?: () => boolean;
|
|
488
492
|
logger: Logger;
|
|
489
493
|
/** Injection seam for tests — defaults to the real remote-config materializer. */
|
|
490
494
|
materializeRemote?: typeof materializeRemoteWranglerConfig;
|
|
@@ -531,6 +535,12 @@ interface DevCommandPlan {
|
|
|
531
535
|
* regardless.
|
|
532
536
|
*/
|
|
533
537
|
frameworkHint?: string;
|
|
538
|
+
/**
|
|
539
|
+
* True when `wrangler dev` was given `--ip 127.0.0.1` because the host has no
|
|
540
|
+
* IPv6 loopback (`::1`) — surfaced so the dev loop can note the rebind.
|
|
541
|
+
* Always `false` for the vite flavor (the plugin owns its own bind).
|
|
542
|
+
*/
|
|
543
|
+
ipv4LoopbackForced: boolean;
|
|
534
544
|
/** The remote-binding decision: which D1/KV/R2 bindings hit the deployed worker. */
|
|
535
545
|
remote: DevRemotePlan;
|
|
536
546
|
studioEnabled: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -483,8 +483,12 @@ interface DevCommandOptions {
|
|
|
483
483
|
ensureExample?: typeof ensureDevVarsExample;
|
|
484
484
|
/** Injection seam for tests — defaults to the real empty-secret/admin-token filler. */
|
|
485
485
|
fillSecrets?: typeof fillDevSecrets;
|
|
486
|
+
/** Injection seam for tests — defaults to the real free-port probe ({@link findAvailablePort}). */
|
|
487
|
+
findFreePort?: (preferred: number) => Promise<number>;
|
|
486
488
|
/** Dev flavor override (tests / callers that already detected it) — defaults to {@link detectDevFlavor}. */
|
|
487
489
|
flavor?: DevFlavor;
|
|
490
|
+
/** Injection seam for tests — defaults to the real IPv6-loopback probe ({@link hasIpv6Loopback}). */
|
|
491
|
+
hasIpv6Loopback?: () => boolean;
|
|
488
492
|
logger: Logger;
|
|
489
493
|
/** Injection seam for tests — defaults to the real remote-config materializer. */
|
|
490
494
|
materializeRemote?: typeof materializeRemoteWranglerConfig;
|
|
@@ -531,6 +535,12 @@ interface DevCommandPlan {
|
|
|
531
535
|
* regardless.
|
|
532
536
|
*/
|
|
533
537
|
frameworkHint?: string;
|
|
538
|
+
/**
|
|
539
|
+
* True when `wrangler dev` was given `--ip 127.0.0.1` because the host has no
|
|
540
|
+
* IPv6 loopback (`::1`) — surfaced so the dev loop can note the rebind.
|
|
541
|
+
* Always `false` for the vite flavor (the plugin owns its own bind).
|
|
542
|
+
*/
|
|
543
|
+
ipv4LoopbackForced: boolean;
|
|
534
544
|
/** The remote-binding decision: which D1/KV/R2 bindings hit the deployed worker. */
|
|
535
545
|
remote: DevRemotePlan;
|
|
536
546
|
studioEnabled: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readLinkedProject } from '@lunora/config';
|
|
2
2
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
3
|
-
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-
|
|
3
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
4
4
|
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
5
5
|
|
|
6
6
|
const LOG_FORMATS = /* @__PURE__ */ new Set(["json", "pretty"]);
|
|
@@ -2,7 +2,7 @@ import { mkdtempSync, rmSync, existsSync, readdirSync, statSync } from 'node:fs'
|
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import { join, relative } from 'node:path';
|
|
4
4
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
5
|
-
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-
|
|
5
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
6
6
|
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
7
7
|
|
|
8
8
|
const walk = (root) => {
|
|
@@ -4,7 +4,7 @@ import { runCodegen } from '@lunora/codegen';
|
|
|
4
4
|
import { p as parseApiSpec } from '../packem_shared/api-spec-Bx0iKbxA.mjs';
|
|
5
5
|
import { a as renderCodegenHint } from '../packem_shared/codegen-error-DJG-ghs_.mjs';
|
|
6
6
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
7
|
-
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-
|
|
7
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
8
8
|
import { v as validateOutputFormat, i as isJsonFormat, p as printJson, l as loggerForFormat } from '../packem_shared/output-format-B4642rjE.mjs';
|
|
9
9
|
import { r as runSchemaDriftGate } from '../packem_shared/schema-drift-gate-BtBt0as0.mjs';
|
|
10
10
|
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
|
-
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-
|
|
2
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
3
3
|
import { i as isDockerAvailable } from '../packem_shared/docker-hMQ97KSQ.mjs';
|
|
4
4
|
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
|
-
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-
|
|
2
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
3
3
|
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
4
4
|
|
|
5
5
|
const withEnv = (args, env) => {
|
|
@@ -2,9 +2,9 @@ import { writeFileSync, existsSync, readFileSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { DEV_VARS_FILE, DEV_VARS_KEY_PATTERN, generateSecretValue, DEV_VARS_EXAMPLE_FILE, parseDevVariableEntries, isPlaceholderValue, packageNamesFromBindings, inferLunoraBindings, requiredSecrets, isMintableSecretKey } from '@lunora/config';
|
|
4
4
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
5
|
-
import { d as detectPackageManager, e as execArgsFor } from '../packem_shared/detect-package-manager-
|
|
5
|
+
import { d as detectPackageManager, e as execArgsFor } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
6
6
|
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
7
|
-
import { l as listRemoteSecrets } from '../packem_shared/wrangler-secrets-
|
|
7
|
+
import { l as listRemoteSecrets } from '../packem_shared/wrangler-secrets-Dq_Fkbm-.mjs';
|
|
8
8
|
|
|
9
9
|
const NEWLINE_PRESENT = /[\r\n]/u;
|
|
10
10
|
const UNREPRESENTABLE_PRESENT = /["\\]/u;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { spawnSync, spawn } from 'node:child_process';
|
|
2
|
-
import { detectAgentRules, claimDevServerState, clearDevServerState, readDevServerState, readLiveDevServerState, readProjectDependencyNames, DEV_HANDOFF_ENV, isRecordedProcessCurrent, DEV_LOG_FILE, DEV_LOG_FILE_ENV, DEV_DAEMON_ENV, updateDevServerState, detectAiAgent, resolveRemoteEnabled, readProjectRemotePreference,
|
|
2
|
+
import { detectAgentRules, claimDevServerState, clearDevServerState, readDevServerState, readLiveDevServerState, readProjectDependencyNames, DEV_HANDOFF_ENV, isRecordedProcessCurrent, DEV_LOG_FILE, DEV_LOG_FILE_ENV, DEV_DAEMON_ENV, updateDevServerState, detectAiAgent, resolveRemoteEnabled, readProjectRemotePreference, inferLunoraBindings, packageNamesFromBindings, ensureDevVarsExample, ensureDevVariables, isInteractive, DEV_VARS_FILE, DEV_VARS_EXAMPLE_FILE, fillDevSecrets, claimAgentRulesHint, AGENT_RULES_HINT, findWranglerFile, readWranglerJsonc, detectFramework, discoverContainerInfo, streamContainerLogs, materializeRemoteWranglerConfig, formatLunoraEvent } from '@lunora/config';
|
|
3
3
|
import { p as parseApiSpec } from '../packem_shared/api-spec-Bx0iKbxA.mjs';
|
|
4
4
|
import { existsSync, watch, readFileSync, statSync, openSync, readSync, closeSync, mkdirSync } from 'node:fs';
|
|
5
5
|
import { join, dirname } from 'node:path';
|
|
6
6
|
import { runCodegen } from '@lunora/codegen';
|
|
7
7
|
import { r as renderCodegenFailure } from '../packem_shared/codegen-error-DJG-ghs_.mjs';
|
|
8
8
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
9
|
-
import { d as detectPackageManager, e as execArgsFor, r as runScriptCommand } from '../packem_shared/detect-package-manager-
|
|
9
|
+
import { d as detectPackageManager, e as execArgsFor, r as runScriptCommand } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
10
|
+
import { createServer, connect } from 'node:net';
|
|
10
11
|
import { forceJsonLogging } from '../packem_shared/createLogger-CIWSHrTL.mjs';
|
|
12
|
+
import { networkInterfaces } from 'node:os';
|
|
11
13
|
import { spawnShellCompat } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
12
|
-
import { createServer, request } from 'node:http';
|
|
13
|
-
import { connect } from 'node:net';
|
|
14
|
+
import { createServer as createServer$1, request } from 'node:http';
|
|
14
15
|
import { loadStudioAssets, studioAssetsStamp, renderStudioHtml, resolveAdminToken, SCHEMA_EDIT_ENDPOINT, POLICY_SCAFFOLD_ENDPOINT, SEED_ENDPOINT, serveJsonHandler, isStandaloneModulePath, readStandaloneAsset, assetContentType, handleSchemaEditRequest, handlePolicyScaffoldRequest, handleSeedRequest } from '@lunora/config/studio-host';
|
|
15
16
|
import { c as createTuiConfirm } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
|
|
16
17
|
import { p as printJson } from '../packem_shared/output-format-B4642rjE.mjs';
|
|
@@ -75,6 +76,32 @@ const startCodegenWatch = (options) => {
|
|
|
75
76
|
};
|
|
76
77
|
};
|
|
77
78
|
|
|
79
|
+
const DEFAULT_PROBE_ATTEMPTS = 64;
|
|
80
|
+
const LOOPBACK_HOST = "127.0.0.1";
|
|
81
|
+
const MAX_PORT = 65535;
|
|
82
|
+
const isPortFree = (port, host = LOOPBACK_HOST) => new Promise((resolve) => {
|
|
83
|
+
const server = createServer();
|
|
84
|
+
server.once("error", () => {
|
|
85
|
+
resolve(false);
|
|
86
|
+
});
|
|
87
|
+
server.once("listening", () => {
|
|
88
|
+
server.close(() => {
|
|
89
|
+
resolve(true);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
server.listen(port, host);
|
|
93
|
+
});
|
|
94
|
+
const findAvailablePort = async (preferred, host = LOOPBACK_HOST, attempts = DEFAULT_PROBE_ATTEMPTS) => {
|
|
95
|
+
for (let port = preferred; port < preferred + attempts && port <= MAX_PORT; port += 1) {
|
|
96
|
+
if (await isPortFree(port, host)) {
|
|
97
|
+
return port;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return preferred;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const hasIpv6Loopback = (readInterfaces = networkInterfaces) => Object.values(readInterfaces()).some((addresses) => addresses?.some((address) => address.internal && address.address === "::1"));
|
|
104
|
+
|
|
78
105
|
const PROXY_PREFIX = "/_lunora";
|
|
79
106
|
const pathnameOf = (url) => {
|
|
80
107
|
const queryIndex = url.indexOf("?");
|
|
@@ -201,7 +228,7 @@ const startStudioServer = async (options) => {
|
|
|
201
228
|
return true;
|
|
202
229
|
};
|
|
203
230
|
const document = Buffer.from(html);
|
|
204
|
-
const server = createServer((request, response) => {
|
|
231
|
+
const server = createServer$1((request, response) => {
|
|
205
232
|
const pathname = pathnameOf(request.url ?? "/");
|
|
206
233
|
if (isLoopback && !isLoopbackHost(request.headers.host)) {
|
|
207
234
|
response.statusCode = 403;
|
|
@@ -692,6 +719,29 @@ const resolveRemotePlan = (options, cwd) => {
|
|
|
692
719
|
}
|
|
693
720
|
return { args: ["--config", result.configPath], plan: { bindings, cleanup, enabled: true } };
|
|
694
721
|
};
|
|
722
|
+
const resolveLoopbackArgs = (cwd, hasLoopback) => {
|
|
723
|
+
const wranglerPath = findWranglerFile(cwd);
|
|
724
|
+
if (wranglerPath !== void 0) {
|
|
725
|
+
const { parsed } = readWranglerJsonc(wranglerPath);
|
|
726
|
+
if (parsed?.dev?.ip !== void 0) {
|
|
727
|
+
return [];
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
return hasLoopback() ? [] : ["--ip", "127.0.0.1"];
|
|
731
|
+
};
|
|
732
|
+
const resolveWorkerPort = async (options, cwd) => {
|
|
733
|
+
if (options.workerPort !== void 0) {
|
|
734
|
+
return options.workerPort;
|
|
735
|
+
}
|
|
736
|
+
const wranglerPath = findWranglerFile(cwd);
|
|
737
|
+
if (wranglerPath !== void 0) {
|
|
738
|
+
const { parsed } = readWranglerJsonc(wranglerPath);
|
|
739
|
+
if (typeof parsed?.dev?.port === "number") {
|
|
740
|
+
return parsed.dev.port;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return (options.findFreePort ?? findAvailablePort)(DEFAULT_WORKER_PORT);
|
|
744
|
+
};
|
|
695
745
|
const planDevCommand = (options) => {
|
|
696
746
|
const cwd = options.cwd ?? process.cwd();
|
|
697
747
|
const manager = detectPackageManager(cwd);
|
|
@@ -701,6 +751,7 @@ const planDevCommand = (options) => {
|
|
|
701
751
|
return {
|
|
702
752
|
codegenEnabled: false,
|
|
703
753
|
flavor,
|
|
754
|
+
ipv4LoopbackForced: false,
|
|
704
755
|
remote: { bindings: [], cleanup: () => {
|
|
705
756
|
}, enabled: options.remote === true },
|
|
706
757
|
studioEnabled: false,
|
|
@@ -720,11 +771,13 @@ const planDevCommand = (options) => {
|
|
|
720
771
|
const frameworkHint = detection.framework === "none" ? void 0 : `this project uses ${detection.framework} — the worker runs inside Vite there. run \`${runScriptCommand(manager, "dev")}\` for the full app (frontend + HMR); \`lunora dev\` starts only the worker.`;
|
|
721
772
|
const workerPort = options.workerPort ?? DEFAULT_WORKER_PORT;
|
|
722
773
|
const remote = resolveRemotePlan(options, cwd);
|
|
723
|
-
const
|
|
774
|
+
const loopbackArgs = resolveLoopbackArgs(cwd, options.hasIpv6Loopback ?? hasIpv6Loopback);
|
|
775
|
+
const exec = execArgsFor(manager, "wrangler", ["dev", "--port", String(workerPort), ...loopbackArgs, "--var", "WORKER_ENV:development", ...remote.args]);
|
|
724
776
|
return {
|
|
725
777
|
codegenEnabled: options.codegen !== false,
|
|
726
778
|
flavor,
|
|
727
779
|
frameworkHint,
|
|
780
|
+
ipv4LoopbackForced: loopbackArgs.length > 0,
|
|
728
781
|
remote: remote.plan,
|
|
729
782
|
studioEnabled: options.studio !== false,
|
|
730
783
|
studioPort: options.port ?? DEFAULT_STUDIO_PORT,
|
|
@@ -922,8 +975,14 @@ const claimStartRecord = (plan, cwd) => {
|
|
|
922
975
|
);
|
|
923
976
|
return claim.ok ? void 0 : claim.existing;
|
|
924
977
|
};
|
|
978
|
+
const buildDevPlan = async (options) => {
|
|
979
|
+
const cwd = options.cwd ?? process.cwd();
|
|
980
|
+
const flavor = options.flavor ?? detectDevFlavor(cwd);
|
|
981
|
+
const workerPort = flavor === "wrangler" ? await resolveWorkerPort(options, cwd) : options.workerPort;
|
|
982
|
+
return planDevCommand({ ...options, cwd, flavor, workerPort });
|
|
983
|
+
};
|
|
925
984
|
const runDevCommand = async (options) => {
|
|
926
|
-
const plan =
|
|
985
|
+
const plan = await buildDevPlan(options);
|
|
927
986
|
const { logger } = options;
|
|
928
987
|
const cwd = plan.wrangler.cwd ?? process.cwd();
|
|
929
988
|
const handles = { remoteCleanup: plan.remote.cleanup };
|
|
@@ -945,6 +1004,11 @@ const runDevCommand = async (options) => {
|
|
|
945
1004
|
logger.info(
|
|
946
1005
|
plan.flavor === "vite" ? "starting vite dev (worker + studio + codegen run inside Vite via @lunora/vite)" : "starting wrangler dev + studio"
|
|
947
1006
|
);
|
|
1007
|
+
if (plan.ipv4LoopbackForced) {
|
|
1008
|
+
logger.info(
|
|
1009
|
+
"no IPv6 loopback (::1) on this host — binding the worker to 127.0.0.1 (--ip) so wrangler dev doesn't crash. Pin `dev.ip` in wrangler.jsonc to override."
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
948
1012
|
if (plan.codegenEnabled) {
|
|
949
1013
|
handles.codegen = (options.startCodegen ?? startCodegenWatch)({ apiSpec: options.apiSpec, logger, projectRoot: cwd });
|
|
950
1014
|
}
|
|
@@ -1049,4 +1113,4 @@ const execute = defineHandler(async ({ argument, cwd, logger, options }) => {
|
|
|
1049
1113
|
});
|
|
1050
1114
|
});
|
|
1051
1115
|
|
|
1052
|
-
export { detectDevFlavor, execute, planDevCommand, resolveRemotePlan, runDevCommand };
|
|
1116
|
+
export { detectDevFlavor, execute, planDevCommand, resolveRemotePlan, resolveWorkerPort, runDevCommand };
|
|
@@ -7,7 +7,7 @@ import { Project } from 'ts-morph';
|
|
|
7
7
|
import { p as parseApiSpec } from '../packem_shared/api-spec-Bx0iKbxA.mjs';
|
|
8
8
|
import { r as readWranglerName } from '../packem_shared/wrangler-name-cy4yhm9j.mjs';
|
|
9
9
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
10
|
-
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-
|
|
10
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
11
11
|
import { a as isRailpackAvailable, i as isDockerAvailable } from '../packem_shared/docker-hMQ97KSQ.mjs';
|
|
12
12
|
import { v as validateOutputFormat, i as isJsonFormat, p as printJson, l as loggerForFormat } from '../packem_shared/output-format-B4642rjE.mjs';
|
|
13
13
|
import { containerBuildTag } from '@lunora/container';
|
|
@@ -15,7 +15,7 @@ import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G
|
|
|
15
15
|
import { r as resolveWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
|
|
16
16
|
import { r as runSchemaDriftGate } from '../packem_shared/schema-drift-gate-BtBt0as0.mjs';
|
|
17
17
|
import { c as createTuiConfirm } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
|
|
18
|
-
import { l as listRemoteSecrets } from '../packem_shared/wrangler-secrets-
|
|
18
|
+
import { l as listRemoteSecrets } from '../packem_shared/wrangler-secrets-Dq_Fkbm-.mjs';
|
|
19
19
|
import { runMigrateDataCommand } from './runMigrateGenerateCommand.mjs';
|
|
20
20
|
|
|
21
21
|
const WORKERS_DEV_URL = /https?:\/\/[^\s"'<>]+\.workers\.dev[^\s"'<>]*/u;
|
|
@@ -7,7 +7,7 @@ import { downloadTemplate } from 'giget';
|
|
|
7
7
|
import { modify, applyEdits } from 'jsonc-parser';
|
|
8
8
|
import { join, dirname } from 'node:path';
|
|
9
9
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
10
|
-
import { d as detectPackageManager, a as detectInstalledManagers, i as installArgsFor, r as runScriptCommand } from '../packem_shared/detect-package-manager-
|
|
10
|
+
import { d as detectPackageManager, a as detectInstalledManagers, i as installArgsFor, r as runScriptCommand } from '../packem_shared/detect-package-manager-DvEthdCw.mjs';
|
|
11
11
|
import MagicString from 'magic-string';
|
|
12
12
|
import { Project, SyntaxKind } from 'ts-morph';
|
|
13
13
|
import { P as PromptCancelledError } from '../packem_shared/prompt-cancelled-APzX1Im-.mjs';
|
|
@@ -1940,8 +1940,7 @@ const maybeOfferGit = async (options, target) => {
|
|
|
1940
1940
|
options.logger.warn("`git init` failed — initialize it yourself later with `git init`.");
|
|
1941
1941
|
}
|
|
1942
1942
|
};
|
|
1943
|
-
const printNextSteps = async (name, installed, insideMonorepo) => {
|
|
1944
|
-
const manager = installed ?? "pnpm";
|
|
1943
|
+
const printNextSteps = async (name, installed, manager, insideMonorepo) => {
|
|
1945
1944
|
const steps = [{ code: `cd ./${name}`, lead: "Enter your project directory using" }];
|
|
1946
1945
|
if (installed === void 0) {
|
|
1947
1946
|
steps.push({ code: `${manager} install`, lead: "Install dependencies with", tail: insideMonorepo ? " from the workspace root" : void 0 });
|
|
@@ -2462,7 +2461,8 @@ const runPostScaffold = async (options, result, cwd) => {
|
|
|
2462
2461
|
const installedManager = options.inPlace === true ? void 0 : await maybeOfferInstall(options, result.target);
|
|
2463
2462
|
if (options.inPlace !== true) {
|
|
2464
2463
|
await maybeOfferGit(options, result.target);
|
|
2465
|
-
|
|
2464
|
+
const manager = installedManager ?? detectPackageManager(result.target);
|
|
2465
|
+
await printNextSteps(basename(result.target), installedManager, manager, isInsideMonorepo(cwd));
|
|
2466
2466
|
await emitMascot(options.logger);
|
|
2467
2467
|
}
|
|
2468
2468
|
};
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { LunoraError } from '@lunora/errors';
|
|
3
|
+
import { findPackageManagerSync, identifyInitiatingPackageManager } from '@visulima/package/package-manager';
|
|
4
4
|
|
|
5
|
-
const FALLBACK = "pnpm";
|
|
6
|
-
const KNOWN_MANAGERS = ["pnpm", "yarn", "npm", "bun"];
|
|
7
5
|
const INSTALL_PREFERENCE = ["pnpm", "bun", "yarn", "npm"];
|
|
8
6
|
const isManagerInstalled = (manager) => {
|
|
9
7
|
try {
|
|
@@ -16,34 +14,23 @@ const detectInstalledManagers = (probe = isManagerInstalled) => INSTALL_PREFEREN
|
|
|
16
14
|
const installArgsFor = (manager) => {
|
|
17
15
|
return { args: ["install"], command: manager };
|
|
18
16
|
};
|
|
19
|
-
const
|
|
20
|
-
if (typeof declared !== "string") {
|
|
21
|
-
return void 0;
|
|
22
|
-
}
|
|
23
|
-
return KNOWN_MANAGERS.find((manager) => declared.startsWith(`${manager}@`));
|
|
24
|
-
};
|
|
25
|
-
const readDeclaredManager = (directory) => {
|
|
26
|
-
const candidate = join(directory, "package.json");
|
|
27
|
-
if (!existsSync(candidate)) {
|
|
28
|
-
return void 0;
|
|
29
|
-
}
|
|
17
|
+
const detectPackageManager = (startDirectory) => {
|
|
30
18
|
try {
|
|
31
|
-
|
|
32
|
-
return parseDeclaredManager(parsed.packageManager);
|
|
19
|
+
return findPackageManagerSync(startDirectory).packageManager;
|
|
33
20
|
} catch {
|
|
34
|
-
return void 0;
|
|
35
21
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
directory = dirname(directory);
|
|
22
|
+
const initiating = identifyInitiatingPackageManager();
|
|
23
|
+
if (initiating !== void 0) {
|
|
24
|
+
return initiating.name === "cnpm" ? "npm" : initiating.name;
|
|
25
|
+
}
|
|
26
|
+
const [installed] = detectInstalledManagers();
|
|
27
|
+
if (installed !== void 0) {
|
|
28
|
+
return installed;
|
|
45
29
|
}
|
|
46
|
-
|
|
30
|
+
throw new LunoraError(
|
|
31
|
+
"INTERNAL",
|
|
32
|
+
"Could not detect a package manager: no lock file or `packageManager` field was found, and none (pnpm, bun, yarn, npm) is installed on PATH."
|
|
33
|
+
);
|
|
47
34
|
};
|
|
48
35
|
const execArgsFor = (manager, command, args) => {
|
|
49
36
|
if (manager === "yarn") {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { execFile } from 'node:child_process';
|
|
2
|
+
import { e as execArgsFor, d as detectPackageManager } from './detect-package-manager-DvEthdCw.mjs';
|
|
2
3
|
|
|
3
4
|
const execCode = (error) => {
|
|
4
5
|
if (!error) {
|
|
@@ -25,15 +26,16 @@ const parseSecretNames = (stdout) => {
|
|
|
25
26
|
return [...names].toSorted((a, b) => a.localeCompare(b));
|
|
26
27
|
};
|
|
27
28
|
const listRemoteSecrets = async (inputs) => {
|
|
28
|
-
const
|
|
29
|
+
const wranglerArgs = ["secret", "list", "--format", "json"];
|
|
29
30
|
if (inputs.env !== void 0) {
|
|
30
|
-
|
|
31
|
+
wranglerArgs.push("--env", inputs.env);
|
|
31
32
|
}
|
|
32
33
|
if (inputs.temporary) {
|
|
33
|
-
|
|
34
|
+
wranglerArgs.push("--temporary");
|
|
34
35
|
}
|
|
36
|
+
const { args, command } = execArgsFor(detectPackageManager(inputs.cwd), "wrangler", wranglerArgs);
|
|
35
37
|
const runner = inputs.runner ?? defaultRunner;
|
|
36
|
-
const result = await runner(
|
|
38
|
+
const result = await runner(command, args, inputs.cwd);
|
|
37
39
|
if (result.code !== 0) {
|
|
38
40
|
return { error: result.stderr.trim() || `wrangler secret list exited ${String(result.code)}`, names: [], ok: false };
|
|
39
41
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/cli",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.69",
|
|
4
4
|
"description": "The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"@visulima/cerebro": "3.0.0-alpha.32",
|
|
62
62
|
"@visulima/error": "6.0.0-alpha.34",
|
|
63
63
|
"@visulima/fs": "5.0.0-alpha.32",
|
|
64
|
+
"@visulima/package": "5.0.0-alpha.23",
|
|
64
65
|
"@visulima/pail": "4.0.0-alpha.22",
|
|
65
66
|
"@visulima/path": "3.0.0-alpha.13",
|
|
66
67
|
"@visulima/spinner": "1.0.0-alpha.4",
|