@lunora/cli 1.0.0-alpha.101 → 1.0.0-alpha.102

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.
Files changed (83) hide show
  1. package/dist/bin.mjs +2 -10
  2. package/dist/index.mjs +1 -18
  3. package/dist/packem_chunks/handler.mjs +1 -160
  4. package/dist/packem_chunks/handler10.mjs +1 -16
  5. package/dist/packem_chunks/handler11.mjs +1 -23
  6. package/dist/packem_chunks/handler12.mjs +2 -192
  7. package/dist/packem_chunks/handler13.mjs +2 -131
  8. package/dist/packem_chunks/handler14.mjs +1 -65
  9. package/dist/packem_chunks/handler15.mjs +1 -100
  10. package/dist/packem_chunks/handler16.mjs +1 -44
  11. package/dist/packem_chunks/handler17.mjs +1 -105
  12. package/dist/packem_chunks/handler18.mjs +3 -170
  13. package/dist/packem_chunks/handler19.mjs +1 -128
  14. package/dist/packem_chunks/handler2.mjs +2 -116
  15. package/dist/packem_chunks/handler20.mjs +1 -94
  16. package/dist/packem_chunks/handler21.mjs +2 -202
  17. package/dist/packem_chunks/handler3.mjs +2 -208
  18. package/dist/packem_chunks/handler4.mjs +1 -33
  19. package/dist/packem_chunks/handler5.mjs +1 -52
  20. package/dist/packem_chunks/handler6.mjs +1 -94
  21. package/dist/packem_chunks/handler7.mjs +1 -42
  22. package/dist/packem_chunks/handler8.mjs +1 -174
  23. package/dist/packem_chunks/handler9.mjs +8 -334
  24. package/dist/packem_chunks/planDevCommand.mjs +7 -1181
  25. package/dist/packem_chunks/runCodegenCommand.mjs +4 -53
  26. package/dist/packem_chunks/runDeployCommand.mjs +1 -619
  27. package/dist/packem_chunks/runInitCommand.mjs +51 -1411
  28. package/dist/packem_chunks/runMigrateGenerateCommand.mjs +9 -442
  29. package/dist/packem_chunks/runResetCommand.mjs +1 -41
  30. package/dist/packem_chunks/runRpcCommand.mjs +1 -69
  31. package/dist/packem_shared/COMMANDS-DRqlsGT2.mjs +3 -0
  32. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-DL87PIEl.mjs +8 -0
  33. package/dist/packem_shared/admin-url-DfVehV3e.mjs +1 -0
  34. package/dist/packem_shared/api-spec-BENwiyUa.mjs +1 -0
  35. package/dist/packem_shared/buildRegistryIndex-DwySASBu.mjs +1 -0
  36. package/dist/packem_shared/codegen-error-DJN6pTH5.mjs +3 -0
  37. package/dist/packem_shared/command-Bjv4VmYA.mjs +1 -0
  38. package/dist/packem_shared/commands-BhX2Bo9B.mjs +19 -0
  39. package/dist/packem_shared/createLogger--C3x1FNE.mjs +2 -0
  40. package/dist/packem_shared/createRecordingSpawner-C8_7nffs.mjs +1 -0
  41. package/dist/packem_shared/detect-package-manager-B2eIuAiP.mjs +1 -0
  42. package/dist/packem_shared/diffSnapshots-9bDd9nOK.mjs +5 -0
  43. package/dist/packem_shared/docker-CKvYE9YF.mjs +1 -0
  44. package/dist/packem_shared/insertSchemaExtension-DZReBZ4_.mjs +8 -0
  45. package/dist/packem_shared/open-url-CTU_g9gr.mjs +1 -0
  46. package/dist/packem_shared/output-format-D7cKB-O5.mjs +2 -0
  47. package/dist/packem_shared/parseManifest-x3WsxKHz.mjs +1 -0
  48. package/dist/packem_shared/prompt-cancelled-C8Sj7OqI.mjs +1 -0
  49. package/dist/packem_shared/resolve-target-vxaXHmvg.mjs +1 -0
  50. package/dist/packem_shared/runAddCommand--TBYJQYi.mjs +1 -0
  51. package/dist/packem_shared/schema-drift-gate-CpqG-xP4.mjs +1 -0
  52. package/dist/packem_shared/schemaIrToSnapshot-Clwd2A8e.mjs +1 -0
  53. package/dist/packem_shared/storage-DOvAKGi4.mjs +1 -0
  54. package/dist/packem_shared/tui-prompts-CCt3jm1k.mjs +4 -0
  55. package/dist/packem_shared/wrangler-name-HIl0Z6yx.mjs +1 -0
  56. package/dist/packem_shared/wrangler-secrets-BMRJwKQU.mjs +1 -0
  57. package/package.json +6 -6
  58. package/dist/packem_shared/COMMANDS-BOJIDoVY.mjs +0 -1031
  59. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-D0VOTerB.mjs +0 -249
  60. package/dist/packem_shared/admin-url-4UzT-CI4.mjs +0 -19
  61. package/dist/packem_shared/api-spec-Bx0iKbxA.mjs +0 -15
  62. package/dist/packem_shared/buildRegistryIndex-BS5ig822.mjs +0 -38
  63. package/dist/packem_shared/codegen-error-DJG-ghs_.mjs +0 -31
  64. package/dist/packem_shared/command-lYnl4QyF.mjs +0 -19
  65. package/dist/packem_shared/commands-D5Yxt9VY.mjs +0 -991
  66. package/dist/packem_shared/createLogger-CIWSHrTL.mjs +0 -105
  67. package/dist/packem_shared/createRecordingSpawner-WuSn20kb.mjs +0 -64
  68. package/dist/packem_shared/detect-package-manager-v4hHpQd0.mjs +0 -62
  69. package/dist/packem_shared/diffSnapshots-BeDvvNiF.mjs +0 -161
  70. package/dist/packem_shared/docker-hMQ97KSQ.mjs +0 -21
  71. package/dist/packem_shared/insertSchemaExtension-DAqbfr9Z.mjs +0 -64
  72. package/dist/packem_shared/open-url-4PBLY9X0.mjs +0 -42
  73. package/dist/packem_shared/output-format-B4642rjE.mjs +0 -17
  74. package/dist/packem_shared/parseManifest-Dbp-Q2q3.mjs +0 -121
  75. package/dist/packem_shared/prompt-cancelled-APzX1Im-.mjs +0 -9
  76. package/dist/packem_shared/resolve-target-qbsJ_5sF.mjs +0 -16
  77. package/dist/packem_shared/runAddCommand-D1hgfqFQ.mjs +0 -4
  78. package/dist/packem_shared/schema-drift-gate-BtBt0as0.mjs +0 -79
  79. package/dist/packem_shared/schemaIrToSnapshot-DdsljJT-.mjs +0 -43
  80. package/dist/packem_shared/storage-BXU4ax4O.mjs +0 -84
  81. package/dist/packem_shared/tui-prompts-BjEN8XgP.mjs +0 -658
  82. package/dist/packem_shared/wrangler-name-cy4yhm9j.mjs +0 -12
  83. package/dist/packem_shared/wrangler-secrets-Coni-mER.mjs +0 -49
package/dist/bin.mjs CHANGED
@@ -1,11 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { runCli } from './packem_shared/COMMANDS-BOJIDoVY.mjs';
3
-
4
- try {
5
- const code = await runCli();
6
- process.exit(code);
7
- } catch (error) {
8
- process.stderr.write(`${error instanceof Error ? error.message : String(error)}
9
- `);
10
- process.exit(1);
11
- }
2
+ import{runCli as s}from"./packem_shared/COMMANDS-DRqlsGT2.mjs";try{const r=await s();process.exit(r)}catch(r){process.stderr.write(`${r instanceof Error?r.message:String(r)}
3
+ `),process.exit(1)}
package/dist/index.mjs CHANGED
@@ -1,18 +1 @@
1
- export { COMMANDS, VERSION, runCli } from './packem_shared/COMMANDS-BOJIDoVY.mjs';
2
- export { runCodegenCommand } from './packem_chunks/runCodegenCommand.mjs';
3
- export { DEFAULT_IMPORT_BATCH_SIZE, runExportCommand, runImportCommand } from './packem_shared/DEFAULT_IMPORT_BATCH_SIZE-D0VOTerB.mjs';
4
- export { runDeployCommand } from './packem_chunks/runDeployCommand.mjs';
5
- export { planDevCommand, runDevCommand } from './packem_chunks/planDevCommand.mjs';
6
- export { runInitCommand } from './packem_chunks/runInitCommand.mjs';
7
- export { runMigrateGenerateCommand } from './packem_chunks/runMigrateGenerateCommand.mjs';
8
- export { runResetCommand } from './packem_chunks/runResetCommand.mjs';
9
- export { runRpcCommand } from './packem_chunks/runRpcCommand.mjs';
10
- export { insertSchemaExtension } from './packem_shared/insertSchemaExtension-DAqbfr9Z.mjs';
11
- export { createLogger, pail } from './packem_shared/createLogger-CIWSHrTL.mjs';
12
- export { diffSnapshots, renderAddColumn, renderCreateIndex, renderCreateTable, renderDropIndex, renderDropTable, renderMigrationFile, validatorKindToSqlType } from './packem_shared/diffSnapshots-BeDvvNiF.mjs';
13
- export { default as schemaIrToSnapshot } from './packem_shared/schemaIrToSnapshot-DdsljJT-.mjs';
14
- export { createRecordingSpawner, defaultSpawner } from './packem_shared/createRecordingSpawner-WuSn20kb.mjs';
15
- export { default as parseManifest } from './packem_shared/parseManifest-Dbp-Q2q3.mjs';
16
- export { REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, validateWranglerProject as validateWrangler, validateWranglerConfig } from '@lunora/config';
17
- export { buildRegistryIndex } from './packem_shared/buildRegistryIndex-BS5ig822.mjs';
18
- export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-D5Yxt9VY.mjs';
1
+ import{COMMANDS as o,VERSION as n,runCli as a}from"./packem_shared/COMMANDS-DRqlsGT2.mjs";import{runCodegenCommand as t}from"./packem_chunks/runCodegenCommand.mjs";import{DEFAULT_IMPORT_BATCH_SIZE as p,runExportCommand as f,runImportCommand as x}from"./packem_shared/DEFAULT_IMPORT_BATCH_SIZE-DL87PIEl.mjs";import{runDeployCommand as C}from"./packem_chunks/runDeployCommand.mjs";import{planDevCommand as u,runDevCommand as s}from"./packem_chunks/planDevCommand.mjs";import{runInitCommand as g}from"./packem_chunks/runInitCommand.mjs";import{runMigrateGenerateCommand as T}from"./packem_chunks/runMigrateGenerateCommand.mjs";import{runResetCommand as E}from"./packem_chunks/runResetCommand.mjs";import{runRpcCommand as A}from"./packem_chunks/runRpcCommand.mjs";import{insertSchemaExtension as c}from"./packem_shared/insertSchemaExtension-DZReBZ4_.mjs";import{createLogger as _,pail as h}from"./packem_shared/createLogger--C3x1FNE.mjs";import{diffSnapshots as L,renderAddColumn as O,renderCreateIndex as b,renderCreateTable as w,renderDropIndex as B,renderDropTable as F,renderMigrationFile as P,validatorKindToSqlType as U}from"./packem_shared/diffSnapshots-9bDd9nOK.mjs";import{default as q}from"./packem_shared/schemaIrToSnapshot-Clwd2A8e.mjs";import{createRecordingSpawner as N,defaultSpawner as Q}from"./packem_shared/createRecordingSpawner-C8_7nffs.mjs";import{default as j}from"./packem_shared/parseManifest-x3WsxKHz.mjs";import{REQUIRED_COMPATIBILITY_DATE as H,REQUIRED_FLAG as K,validateWranglerProject as Y,validateWranglerConfig as Z}from"@lunora/config";import{buildRegistryIndex as J}from"./packem_shared/buildRegistryIndex-DwySASBu.mjs";import{M as $,q as rr,k as er}from"./packem_shared/commands-BhX2Bo9B.mjs";export{o as COMMANDS,p as DEFAULT_IMPORT_BATCH_SIZE,H as REQUIRED_COMPATIBILITY_DATE,K as REQUIRED_FLAG,n as VERSION,J as buildRegistryIndex,_ as createLogger,N as createRecordingSpawner,Q as defaultSpawner,L as diffSnapshots,c as insertSchemaExtension,h as pail,j as parseManifest,u as planDevCommand,O as renderAddColumn,b as renderCreateIndex,w as renderCreateTable,B as renderDropIndex,F as renderDropTable,P as renderMigrationFile,$ as runAddCommand,rr as runBuildIndexCommand,a as runCli,t as runCodegenCommand,C as runDeployCommand,s as runDevCommand,f as runExportCommand,x as runImportCommand,g as runInitCommand,T as runMigrateGenerateCommand,er as runRegistryViewCommand,E as runResetCommand,A as runRpcCommand,q as schemaIrToSnapshot,Y as validateWrangler,Z as validateWranglerConfig,U as validatorKindToSqlType};
@@ -1,160 +1 @@
1
- import { existsSync } from 'node:fs';
2
- import { findWranglerFile } from '@lunora/config';
3
- import { join, basename } from '@visulima/path';
4
- import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
5
- import { v as validateOutputFormat, i as isJsonFormat, p as printJson, l as loggerForFormat } from '../packem_shared/output-format-B4642rjE.mjs';
6
- import { t as tuiText, a as tuiSelect } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
7
- import { n as normalizeFeature, E as EMAIL_ITEM, s as sanitizeBucketName, d as deriveBucketName, p as promptBucketName, r as resolveTypedDestination, M as MAIL_DESTINATION_PROMPT, a as sanitizeDatabaseName, b as deriveDatabaseName, c as promptDatabaseName, D as DEFAULT_AUTH_ITEM, e as promptAuthProvider, A as AUTH_PROVIDER_OPTIONS, w as withStorageBucketName, f as withMailDestination, g as withAuthDatabaseName } from '../packem_shared/storage-BXU4ax4O.mjs';
8
- import { r as runAddCommand } from '../packem_shared/commands-D5Yxt9VY.mjs';
9
-
10
- const providerToItem = (provider) => {
11
- const value = provider.trim().toLowerCase();
12
- const match = AUTH_PROVIDER_OPTIONS.find(
13
- (option) => option.value === value || option.label.toLowerCase() === value || value === "auth0" && option.value === "auth-auth0" || value === "clerk" && option.value === "auth-clerk"
14
- );
15
- return match?.value;
16
- };
17
- const resolveAuthItem = async (options) => {
18
- if (options.provider !== void 0 && options.provider !== "") {
19
- const item = providerToItem(options.provider);
20
- if (item === void 0) {
21
- options.logger.warn(`add: unknown --provider "${options.provider}" — using "${DEFAULT_AUTH_ITEM}" (email & password).`);
22
- return DEFAULT_AUTH_ITEM;
23
- }
24
- return item;
25
- }
26
- if (options.yes === true) {
27
- return DEFAULT_AUTH_ITEM;
28
- }
29
- const select = options.promptSelect ?? ((message, choices, settings) => tuiSelect(message, choices, settings));
30
- return promptAuthProvider(select);
31
- };
32
- const textPrompt = (options) => options.promptText ?? ((message, settings) => tuiText(message, settings));
33
- const resolveStorageBucketName = async (options) => {
34
- const projectName = basename(options.cwd ?? process.cwd());
35
- if (options.bucket !== void 0 && options.bucket !== "") {
36
- const sanitized = sanitizeBucketName(options.bucket);
37
- if (sanitized !== void 0) {
38
- return sanitized;
39
- }
40
- const fallback = deriveBucketName(projectName);
41
- options.logger.warn(`add: "${options.bucket}" isn't a valid R2 bucket name (lowercase alphanumeric + hyphens, 3–63 chars) — using "${fallback}".`);
42
- return fallback;
43
- }
44
- if (options.yes === true) {
45
- return deriveBucketName(projectName);
46
- }
47
- return promptBucketName(textPrompt(options), projectName);
48
- };
49
- const resolveMailDestination = async (options) => {
50
- const warn = (message) => {
51
- options.logger.warn(`add: ${message}`);
52
- };
53
- if (options.mailTo !== void 0 && options.mailTo !== "") {
54
- return resolveTypedDestination(options.mailTo, warn);
55
- }
56
- if (options.yes === true) {
57
- return void 0;
58
- }
59
- return resolveTypedDestination(await textPrompt(options)(MAIL_DESTINATION_PROMPT, { placeholder: "you@yourdomain.com" }), warn);
60
- };
61
- const resolveAuthDatabaseName = async (options) => {
62
- const projectName = basename(options.cwd ?? process.cwd());
63
- if (options.db !== void 0 && options.db !== "") {
64
- const sanitized = sanitizeDatabaseName(options.db);
65
- if (sanitized !== void 0) {
66
- return sanitized;
67
- }
68
- const fallback = deriveDatabaseName(projectName);
69
- options.logger.warn(`add: "${options.db}" isn't a usable D1 database name — using "${fallback}".`);
70
- return fallback;
71
- }
72
- if (options.yes === true) {
73
- return deriveDatabaseName(projectName);
74
- }
75
- return promptDatabaseName(textPrompt(options), projectName);
76
- };
77
- const resolveFeatureItems = async (feature, options) => {
78
- if (feature.kind === "auth") {
79
- return [await resolveAuthItem(options)];
80
- }
81
- if (feature.kind === "email") {
82
- return [EMAIL_ITEM];
83
- }
84
- return [feature.item];
85
- };
86
- const runAddFeature = async (options) => {
87
- const cwd = options.cwd ?? process.cwd();
88
- const feature = options.feature === void 0 ? void 0 : normalizeFeature(options.feature);
89
- if (feature === void 0) {
90
- options.logger.error("add requires a feature or registry item. Usage: lunora add <auth|email|storage|crons|presence|…>");
91
- return { code: 1, items: [] };
92
- }
93
- if (!existsSync(join(cwd, "lunora")) || findWranglerFile(cwd) === void 0) {
94
- options.logger.error("add: not a Lunora project here (need a lunora/ directory and a wrangler.jsonc). Run `lunora init` first.");
95
- return { code: 1, items: [] };
96
- }
97
- const items = await resolveFeatureItems(feature, options);
98
- const transforms = [];
99
- if (items.includes("storage")) {
100
- const bucketName = await resolveStorageBucketName(options);
101
- transforms.push((manifest) => withStorageBucketName(manifest, bucketName));
102
- }
103
- if (items.includes("mail")) {
104
- const destination = await resolveMailDestination(options);
105
- if (destination !== void 0) {
106
- transforms.push((manifest) => withMailDestination(manifest, destination));
107
- }
108
- }
109
- if (items.some((name) => name === "auth" || name.startsWith("auth-"))) {
110
- const databaseName = await resolveAuthDatabaseName(options);
111
- transforms.push((manifest) => withAuthDatabaseName(manifest, databaseName));
112
- }
113
- const transformManifest = transforms.length > 0 ? (manifest) => {
114
- let result2 = manifest;
115
- for (const transform of transforms) {
116
- result2 = transform(result2);
117
- }
118
- return result2;
119
- } : void 0;
120
- const result = await runAddCommand({
121
- allowUnsafeSource: options.allowUnsafeSource,
122
- cwd,
123
- from: options.from,
124
- logger: options.logger,
125
- names: [...items],
126
- ref: options.ref,
127
- source: options.source,
128
- transformManifest,
129
- yes: true
130
- });
131
- return { code: result.code, items };
132
- };
133
- const execute = defineHandler(async ({ argument, cwd, logger, options }) => {
134
- const formatError = validateOutputFormat("add", options.format);
135
- if (formatError !== void 0) {
136
- logger.error(formatError);
137
- return { code: 1 };
138
- }
139
- const effectiveLogger = loggerForFormat(options.format, logger);
140
- const result = await runAddFeature({
141
- allowUnsafeSource: options.allowUnsafeSource === true,
142
- bucket: options.bucket,
143
- cwd,
144
- db: options.db,
145
- feature: argument[0],
146
- from: options.from,
147
- logger: effectiveLogger,
148
- mailTo: options.mailTo,
149
- provider: options.provider,
150
- ref: options.ref,
151
- source: options.source,
152
- yes: options.yes === true
153
- });
154
- if (isJsonFormat(options.format)) {
155
- printJson({ code: result.code, items: result.items });
156
- }
157
- return { code: result.code };
158
- });
159
-
160
- export { execute, runAddFeature };
1
+ import{existsSync as g}from"node:fs";import{findWranglerFile as w}from"@lunora/config";import{join as v,basename as f}from"@visulima/path";import{i as y}from"../packem_shared/command-Bjv4VmYA.mjs";import{i as h,r as b,d as k,s as $}from"../packem_shared/output-format-D7cKB-O5.mjs";import{C as S,B as T}from"../packem_shared/tui-prompts-CCt3jm1k.mjs";import{o as j,n as C,i as U,a as c,u as x,d as l,b as B,r as L,c as m,e as W,f as u,g as q,h as F,p as M,l as R,j as A}from"../packem_shared/storage-DOvAKGi4.mjs";import{M as D}from"../packem_shared/commands-BhX2Bo9B.mjs";const H=r=>{const o=r.trim().toLowerCase();return F.find(e=>e.value===o||e.label.toLowerCase()===o||o==="auth0"&&e.value==="auth-auth0"||o==="clerk"&&e.value==="auth-clerk")?.value},J=async r=>{if(r.provider!==void 0&&r.provider!==""){const e=H(r.provider);return e===void 0?(r.logger.warn(`add: unknown --provider "${r.provider}" — using "${u}" (email & password).`),u):e}if(r.yes===!0)return u;const o=r.promptSelect??((e,a,s)=>T(e,a,s));return q(o)},d=r=>r.promptText??((o,e)=>S(o,e)),z=async r=>{const o=f(r.cwd??process.cwd());if(r.bucket!==void 0&&r.bucket!==""){const e=U(r.bucket);if(e!==void 0)return e;const a=c(o);return r.logger.warn(`add: "${r.bucket}" isn't a valid R2 bucket name (lowercase alphanumeric + hyphens, 3–63 chars) — using "${a}".`),a}return r.yes===!0?c(o):x(d(r),o)},E=async r=>{const o=e=>{r.logger.warn(`add: ${e}`)};if(r.mailTo!==void 0&&r.mailTo!=="")return l(r.mailTo,o);if(r.yes!==!0)return l(await d(r)(B,{placeholder:"you@yourdomain.com"}),o)},G=async r=>{const o=f(r.cwd??process.cwd());if(r.db!==void 0&&r.db!==""){const e=L(r.db);if(e!==void 0)return e;const a=m(o);return r.logger.warn(`add: "${r.db}" isn't a usable D1 database name — using "${a}".`),a}return r.yes===!0?m(o):W(d(r),o)},I=async(r,o)=>r.kind==="auth"?[await J(o)]:r.kind==="email"?[C]:[r.item],K=async r=>{const o=r.cwd??process.cwd(),e=r.feature===void 0?void 0:j(r.feature);if(e===void 0)return r.logger.error("add requires a feature or registry item. Usage: lunora add <auth|email|storage|crons|presence|…>"),{code:1,items:[]};if(!g(v(o,"lunora"))||w(o)===void 0)return r.logger.error("add: not a Lunora project here (need a lunora/ directory and a wrangler.jsonc). Run `lunora init` first."),{code:1,items:[]};const a=await I(e,r),s=[];if(a.includes("storage")){const t=await z(r);s.push(i=>M(i,t))}if(a.includes("mail")){const t=await E(r);t!==void 0&&s.push(i=>R(i,t))}if(a.some(t=>t==="auth"||t.startsWith("auth-"))){const t=await G(r);s.push(i=>A(i,t))}const n=s.length>0?t=>{let i=t;for(const p of s)i=p(i);return i}:void 0;return{code:(await D({allowUnsafeSource:r.allowUnsafeSource,cwd:o,from:r.from,logger:r.logger,names:[...a],ref:r.ref,source:r.source,transformManifest:n,yes:!0})).code,items:a}},_=y(async({argument:r,cwd:o,logger:e,options:a})=>{const s=h("add",a.format);if(s!==void 0)return e.error(s),{code:1};const n=$(a.format,e),t=await K({allowUnsafeSource:a.allowUnsafeSource===!0,bucket:a.bucket,cwd:o,db:a.db,feature:r[0],from:a.from,logger:n,mailTo:a.mailTo,provider:a.provider,ref:a.ref,source:a.source,yes:a.yes===!0});return b(a.format)&&k({code:t.code,items:t.items}),{code:t.code}});export{_ as execute,K as runAddFeature};
@@ -1,16 +1 @@
1
- import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
2
- import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
3
- import { runExportCommand } from '../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-D0VOTerB.mjs';
4
-
5
- const execute = defineHandler(
6
- ({ argument, cwd, logger, options }) => runExportCommand({
7
- logger,
8
- out: argument[0] ?? options.out,
9
- prod: options.prod === true,
10
- tables: options.tables,
11
- token: options.token,
12
- url: resolveProductionWorkerUrl({ cwd, prod: options.prod === true, url: options.url })
13
- })
14
- );
15
-
16
- export { execute };
1
+ import{i as p}from"../packem_shared/command-Bjv4VmYA.mjs";import{s as u}from"../packem_shared/resolve-target-vxaXHmvg.mjs";import{runExportCommand as m}from"../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-DL87PIEl.mjs";const s=p(({argument:t,cwd:r,logger:e,options:o})=>m({logger:e,out:t[0]??o.out,prod:o.prod===!0,tables:o.tables,token:o.token,url:u({cwd:r,prod:o.prod===!0,url:o.url})}));export{s as execute};
@@ -1,23 +1 @@
1
- import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
2
- import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
3
- import { runImportCommand } from '../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-D0VOTerB.mjs';
4
-
5
- const execute = defineHandler(({ argument, cwd, logger, options }) => {
6
- const file = argument[0];
7
- if (!file) {
8
- logger.error("import requires a file. Usage: lunora import <path> [--table <name>]");
9
- return { code: 1 };
10
- }
11
- return runImportCommand({
12
- batchSize: options.batchSize,
13
- file,
14
- logger,
15
- prod: options.prod === true,
16
- table: options.table,
17
- token: options.token,
18
- url: resolveProductionWorkerUrl({ cwd, prod: options.prod === true, url: options.url }),
19
- yes: options.yes === true
20
- });
21
- });
22
-
23
- export { execute };
1
+ import{i as m}from"../packem_shared/command-Bjv4VmYA.mjs";import{s as p}from"../packem_shared/resolve-target-vxaXHmvg.mjs";import{runImportCommand as i}from"../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-DL87PIEl.mjs";const s=m(({argument:t,cwd:a,logger:o,options:e})=>{const r=t[0];return r?i({batchSize:e.batchSize,file:r,logger:o,prod:e.prod===!0,table:e.table,token:e.token,url:p({cwd:a,prod:e.prod===!0,url:e.url}),yes:e.yes===!0}):(o.error("import requires a file. Usage: lunora import <path> [--table <name>]"),{code:1})});export{s as execute};
@@ -1,192 +1,2 @@
1
- import { readFileSync, existsSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { discoverSchema } from '@lunora/codegen';
4
- import { readLinkedProject } from '@lunora/config';
5
- import { parse } from 'jsonc-parser';
6
- import { Project } from 'ts-morph';
7
- import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
8
-
9
- const findWranglerFile = (projectRoot) => {
10
- for (const candidate of ["wrangler.jsonc", "wrangler.json"]) {
11
- const fullPath = join(projectRoot, candidate);
12
- if (existsSync(fullPath)) {
13
- return fullPath;
14
- }
15
- }
16
- return void 0;
17
- };
18
- const stringField = (record, key) => {
19
- if (record === null || typeof record !== "object") {
20
- return void 0;
21
- }
22
- const value = record[key];
23
- return typeof value === "string" && value.length > 0 ? value : void 0;
24
- };
25
- const arrayField = (record, key) => {
26
- if (record === null || typeof record !== "object") {
27
- return [];
28
- }
29
- const value = record[key];
30
- return Array.isArray(value) ? value : [];
31
- };
32
- const summariseWrangler = (raw) => {
33
- const durableObjectBindings = arrayField(raw.durable_objects ?? {}, "bindings");
34
- const d1 = arrayField(raw, "d1_databases");
35
- const vectorize = arrayField(raw, "vectorize");
36
- return {
37
- bindings: {
38
- d1: d1.map((entry) => stringField(entry, "binding") ?? "<unnamed>"),
39
- durableObjects: durableObjectBindings.map((entry) => stringField(entry, "name") ?? "<unnamed>"),
40
- vectorize: vectorize.map((entry) => stringField(entry, "binding") ?? "<unnamed>")
41
- },
42
- compatibilityDate: stringField(raw, "compatibility_date"),
43
- compatibilityFlags: arrayField(raw, "compatibility_flags").filter((entry) => typeof entry === "string"),
44
- main: stringField(raw, "main"),
45
- name: stringField(raw, "name")
46
- };
47
- };
48
- const summariseSchema = (schema) => {
49
- return {
50
- tables: schema.tables.map((table) => {
51
- let shard = "root";
52
- if (table.shardMode === "global") {
53
- shard = "global";
54
- } else if (typeof table.shardMode === "object") {
55
- shard = `shardBy(${table.shardMode.field})`;
56
- }
57
- return {
58
- indexes: table.indexes.length,
59
- name: table.name,
60
- shard
61
- };
62
- }),
63
- vectorIndexes: schema.vectorIndexes.length
64
- };
65
- };
66
- const collectLunoraPackages = (projectRoot) => {
67
- const pkgPath = join(projectRoot, "package.json");
68
- if (!existsSync(pkgPath)) {
69
- return [];
70
- }
71
- let pkg;
72
- try {
73
- pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
74
- } catch {
75
- return [];
76
- }
77
- if (pkg === null || typeof pkg !== "object") {
78
- return [];
79
- }
80
- const sections = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
81
- const seen = /* @__PURE__ */ new Map();
82
- for (const section of sections) {
83
- const block = pkg[section];
84
- if (block === null || typeof block !== "object") {
85
- continue;
86
- }
87
- for (const [name, version] of Object.entries(block)) {
88
- if (!name.startsWith("@lunora/")) {
89
- continue;
90
- }
91
- if (typeof version === "string" && !seen.has(name)) {
92
- seen.set(name, version);
93
- }
94
- }
95
- }
96
- return [...seen.entries()].toSorted(([a], [b]) => a.localeCompare(b)).map(([name, version]) => {
97
- return { name, version };
98
- });
99
- };
100
- const collectInfo = (projectRoot) => {
101
- const lunoraPackages = collectLunoraPackages(projectRoot);
102
- const wranglerPath = findWranglerFile(projectRoot);
103
- let wrangler;
104
- if (wranglerPath) {
105
- try {
106
- wrangler = summariseWrangler(parse(readFileSync(wranglerPath, "utf8")));
107
- } catch {
108
- wrangler = void 0;
109
- }
110
- }
111
- const schemaPath = join(projectRoot, "lunora", "schema.ts");
112
- let schema;
113
- let schemaError;
114
- if (existsSync(schemaPath)) {
115
- try {
116
- const project = new Project({ skipAddingFilesFromTsConfig: true, useInMemoryFileSystem: false });
117
- schema = summariseSchema(discoverSchema(project, schemaPath));
118
- } catch (error) {
119
- schemaError = error instanceof Error ? error.message : String(error);
120
- }
121
- }
122
- return {
123
- link: readLinkedProject(projectRoot),
124
- lunoraPackages,
125
- projectRoot,
126
- schema,
127
- schemaError,
128
- wrangler,
129
- wranglerPath
130
- };
131
- };
132
- const renderText = (snapshot, logger) => {
133
- logger.info(`project: ${snapshot.projectRoot}`);
134
- logger.info("");
135
- logger.info("@lunora/* packages:");
136
- if (snapshot.lunoraPackages.length === 0) {
137
- logger.info(" (none found in package.json)");
138
- } else {
139
- for (const pkg of snapshot.lunoraPackages) {
140
- logger.info(` ${pkg.name}@${pkg.version}`);
141
- }
142
- }
143
- logger.info("");
144
- if (snapshot.wrangler) {
145
- logger.info(`wrangler: ${snapshot.wranglerPath ?? ""}`);
146
- logger.info(` name: ${snapshot.wrangler.name ?? "<unset>"}`);
147
- logger.info(` main: ${snapshot.wrangler.main ?? "<unset>"}`);
148
- logger.info(` compatibility_date: ${snapshot.wrangler.compatibilityDate ?? "<unset>"}`);
149
- logger.info(` compatibility_flags: ${snapshot.wrangler.compatibilityFlags.join(", ") || "<none>"}`);
150
- logger.info(` durable objects: ${snapshot.wrangler.bindings.durableObjects.join(", ") || "<none>"}`);
151
- logger.info(` d1 databases: ${snapshot.wrangler.bindings.d1.join(", ") || "<none>"}`);
152
- logger.info(` vectorize indexes: ${snapshot.wrangler.bindings.vectorize.join(", ") || "<none>"}`);
153
- } else {
154
- logger.info("wrangler: (not found)");
155
- }
156
- logger.info("");
157
- if (snapshot.link) {
158
- logger.info(`link: ${snapshot.link.workerName ?? "(unnamed)"} -> ${snapshot.link.workerUrl ?? "<no url>"}`);
159
- if (snapshot.link.env !== void 0) {
160
- logger.info(` env: ${snapshot.link.env}`);
161
- }
162
- } else {
163
- logger.info("link: (not linked — run `lunora link --url <https://your-worker>`)");
164
- }
165
- logger.info("");
166
- if (snapshot.schemaError !== void 0) {
167
- logger.warn(`schema: parse error — ${snapshot.schemaError}`);
168
- } else if (snapshot.schema) {
169
- logger.info(`schema: ${String(snapshot.schema.tables.length)} table(s), ${String(snapshot.schema.vectorIndexes)} vector index(es)`);
170
- for (const table of snapshot.schema.tables) {
171
- logger.info(` ${table.name} [${table.shard}, ${String(table.indexes)} index(es)]`);
172
- }
173
- } else {
174
- logger.info("schema: (no lunora/schema.ts)");
175
- }
176
- };
177
- const runInfoCommand = (options) => {
178
- const cwd = options.cwd ?? process.cwd();
179
- const snapshot = collectInfo(cwd);
180
- if (options.json) {
181
- process.stdout.write(`${JSON.stringify(snapshot, void 0, 2)}
182
- `);
183
- } else {
184
- renderText(snapshot, options.logger);
185
- }
186
- return { code: 0, snapshot };
187
- };
188
- const execute = defineHandler(
189
- ({ cwd, logger, options }) => runInfoCommand({ cwd, json: options.json === true, logger })
190
- );
191
-
192
- export { collectInfo, execute, runInfoCommand };
1
+ import{readFileSync as g,existsSync as f}from"node:fs";import{join as d}from"node:path";import{discoverSchema as p}from"@lunora/codegen";import{readLinkedProject as u}from"@lunora/config";import{parse as b}from"jsonc-parser";import{Project as h}from"ts-morph";import{i as y}from"../packem_shared/command-Bjv4VmYA.mjs";const j=e=>{for(const o of["wrangler.jsonc","wrangler.json"]){const r=d(e,o);if(f(r))return r}},l=(e,o)=>{if(e===null||typeof e!="object")return;const r=e[o];return typeof r=="string"&&r.length>0?r:void 0},c=(e,o)=>{if(e===null||typeof e!="object")return[];const r=e[o];return Array.isArray(r)?r:[]},w=e=>{const o=c(e.durable_objects??{},"bindings"),r=c(e,"d1_databases"),s=c(e,"vectorize");return{bindings:{d1:r.map(n=>l(n,"binding")??"<unnamed>"),durableObjects:o.map(n=>l(n,"name")??"<unnamed>"),vectorize:s.map(n=>l(n,"binding")??"<unnamed>")},compatibilityDate:l(e,"compatibility_date"),compatibilityFlags:c(e,"compatibility_flags").filter(n=>typeof n=="string"),main:l(e,"main"),name:l(e,"name")}},$=e=>({tables:e.tables.map(o=>{let r="root";return o.shardMode==="global"?r="global":typeof o.shardMode=="object"&&(r=`shardBy(${o.shardMode.field})`),{indexes:o.indexes.length,name:o.name,shard:r}}),vectorIndexes:e.vectorIndexes.length}),k=e=>{const o=d(e,"package.json");if(!f(o))return[];let r;try{r=JSON.parse(g(o,"utf8"))}catch{return[]}if(r===null||typeof r!="object")return[];const s=["dependencies","devDependencies","peerDependencies","optionalDependencies"],n=new Map;for(const a of s){const t=r[a];if(!(t===null||typeof t!="object"))for(const[i,m]of Object.entries(t))i.startsWith("@lunora/")&&typeof m=="string"&&!n.has(i)&&n.set(i,m)}return[...n.entries()].toSorted(([a],[t])=>a.localeCompare(t)).map(([a,t])=>({name:a,version:t}))},v=e=>{const o=k(e),r=j(e);let s;if(r)try{s=w(b(g(r,"utf8")))}catch{s=void 0}const n=d(e,"lunora","schema.ts");let a,t;if(f(n))try{const i=new h({skipAddingFilesFromTsConfig:!0,useInMemoryFileSystem:!1});a=$(p(i,n))}catch(i){t=i instanceof Error?i.message:String(i)}return{link:u(e),lunoraPackages:o,projectRoot:e,schema:a,schemaError:t,wrangler:s,wranglerPath:r}},x=(e,o)=>{if(o.info(`project: ${e.projectRoot}`),o.info(""),o.info("@lunora/* packages:"),e.lunoraPackages.length===0)o.info(" (none found in package.json)");else for(const r of e.lunoraPackages)o.info(` ${r.name}@${r.version}`);if(o.info(""),e.wrangler?(o.info(`wrangler: ${e.wranglerPath??""}`),o.info(` name: ${e.wrangler.name??"<unset>"}`),o.info(` main: ${e.wrangler.main??"<unset>"}`),o.info(` compatibility_date: ${e.wrangler.compatibilityDate??"<unset>"}`),o.info(` compatibility_flags: ${e.wrangler.compatibilityFlags.join(", ")||"<none>"}`),o.info(` durable objects: ${e.wrangler.bindings.durableObjects.join(", ")||"<none>"}`),o.info(` d1 databases: ${e.wrangler.bindings.d1.join(", ")||"<none>"}`),o.info(` vectorize indexes: ${e.wrangler.bindings.vectorize.join(", ")||"<none>"}`)):o.info("wrangler: (not found)"),o.info(""),e.link?(o.info(`link: ${e.link.workerName??"(unnamed)"} -> ${e.link.workerUrl??"<no url>"}`),e.link.env!==void 0&&o.info(` env: ${e.link.env}`)):o.info("link: (not linked — run `lunora link --url <https://your-worker>`)"),o.info(""),e.schemaError!==void 0)o.warn(`schema: parse error — ${e.schemaError}`);else if(e.schema){o.info(`schema: ${String(e.schema.tables.length)} table(s), ${String(e.schema.vectorIndexes)} vector index(es)`);for(const r of e.schema.tables)o.info(` ${r.name} [${r.shard}, ${String(r.indexes)} index(es)]`)}else o.info("schema: (no lunora/schema.ts)")},S=e=>{const o=e.cwd??process.cwd(),r=v(o);return e.json?process.stdout.write(`${JSON.stringify(r,void 0,2)}
2
+ `):x(r,e.logger),{code:0,snapshot:r}},z=y(({cwd:e,logger:o,options:r})=>S({cwd:e,json:r.json===!0,logger:o}));export{v as collectInfo,z as execute,S as runInfoCommand};
@@ -1,131 +1,2 @@
1
- import { r as resolveAdminBaseUrl } from '../packem_shared/admin-url-4UzT-CI4.mjs';
2
- import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
3
- import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
4
-
5
- const GET_FUNCTION_STATS_OP = "__lunora_admin__:getFunctionStats";
6
- const DEFAULT_LIMIT = 10;
7
- const TRAILING_SLASH = /\/$/u;
8
- const toInsightRow = (stat, rate) => {
9
- return {
10
- calls: stat.calls,
11
- conflicts: stat.conflicts ?? 0,
12
- errors: stat.errors,
13
- lastErrorMessage: stat.lastErrorMessage,
14
- maxDurationMs: stat.maxDurationMs,
15
- meanDurationMs: stat.calls === 0 ? 0 : stat.totalDurationMs / stat.calls,
16
- path: stat.path,
17
- rate
18
- };
19
- };
20
- const buildInsightsReport = (functions, limit) => {
21
- const writeContention = functions.filter((stat) => (stat.conflicts ?? 0) > 0).map((stat) => toInsightRow(stat, stat.calls === 0 ? 0 : (stat.conflicts ?? 0) / stat.calls)).toSorted((a, b) => b.rate - a.rate || b.conflicts - a.conflicts).slice(0, limit);
22
- const errorHotspots = functions.filter((stat) => stat.errors > 0).map((stat) => toInsightRow(stat, stat.calls === 0 ? 0 : stat.errors / stat.calls)).toSorted((a, b) => b.rate - a.rate || b.errors - a.errors).slice(0, limit);
23
- const latencyOutliers = functions.map((stat) => toInsightRow(stat, 0)).toSorted((a, b) => b.maxDurationMs - a.maxDurationMs).slice(0, limit);
24
- return { errorHotspots, latencyOutliers, totalFunctions: functions.length, writeContention };
25
- };
26
- const percent = (rate) => `${(rate * 100).toFixed(1)}%`;
27
- const formatMs = (ms) => ms < 1e3 ? `${Math.round(ms).toString()}ms` : `${(ms / 1e3).toFixed(2)}s`;
28
- const formatSection = (heading, rows, emptyNote, renderRow) => [
29
- heading,
30
- ...rows.length === 0 ? [` ${emptyNote}`] : rows.map((row) => ` ${renderRow(row)}`)
31
- ];
32
- const formatInsightsReport = (report) => {
33
- const errorTail = (row) => row.lastErrorMessage ? ` — ${row.lastErrorMessage}` : "";
34
- return [
35
- `Insights over ${report.totalFunctions.toString()} function${report.totalFunctions === 1 ? "" : "s"}`,
36
- "",
37
- ...formatSection(
38
- "Write-conflict hot-spots (OCC contention — candidates for sharding):",
39
- report.writeContention,
40
- "none — no write conflicts observed",
41
- (row) => `${row.path} ${row.conflicts.toString()}/${row.calls.toString()} calls (${percent(row.rate)})`
42
- ),
43
- "",
44
- ...formatSection(
45
- "Error hot-spots:",
46
- report.errorHotspots,
47
- "none — no errors observed",
48
- (row) => `${row.path} ${row.errors.toString()}/${row.calls.toString()} calls (${percent(row.rate)})${errorTail(row)}`
49
- ),
50
- "",
51
- ...formatSection(
52
- "Latency outliers (slowest single call):",
53
- report.latencyOutliers,
54
- "none — no functions have run",
55
- (row) => `${row.path} max ${formatMs(row.maxDurationMs)}, mean ${formatMs(row.meanDurationMs)} over ${row.calls.toString()} calls`
56
- )
57
- ].join("\n");
58
- };
59
- const resolveLimit = (raw) => {
60
- if (raw === void 0 || !Number.isFinite(raw) || raw <= 0) {
61
- return DEFAULT_LIMIT;
62
- }
63
- return Math.floor(raw);
64
- };
65
- const runInsightsCommand = async (options) => {
66
- if (options.prod && options.url === void 0) {
67
- options.logger.error("--prod requires an explicit --url (refusing to report from the implicit localhost worker)");
68
- return { code: 1 };
69
- }
70
- const token = options.token ?? process.env.LUNORA_ADMIN_TOKEN;
71
- if (!token) {
72
- options.logger.error("admin token required — pass --token or set LUNORA_ADMIN_TOKEN");
73
- return { code: 1 };
74
- }
75
- const baseUrl = resolveAdminBaseUrl(options.url, options.logger);
76
- if (baseUrl === void 0) {
77
- return { code: 1 };
78
- }
79
- const requestUrl = `${baseUrl.replace(TRAILING_SLASH, "")}/_lunora/rpc`;
80
- const fetchImpl = globalThis.fetch;
81
- if (typeof fetchImpl !== "function") {
82
- throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");
83
- }
84
- const payload = { args: {}, functionPath: GET_FUNCTION_STATS_OP };
85
- if (options.shard !== void 0) {
86
- payload.shardKey = options.shard;
87
- }
88
- options.logger.info(`POST ${requestUrl} -> insights`);
89
- const response = await fetchImpl(requestUrl, {
90
- body: JSON.stringify(payload),
91
- headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
92
- method: "POST"
93
- });
94
- const text = await response.text();
95
- if (!response.ok) {
96
- options.logger.error(`insights failed: HTTP ${String(response.status)}: ${text}`);
97
- return { code: 1 };
98
- }
99
- let parsed;
100
- try {
101
- parsed = JSON.parse(text);
102
- } catch {
103
- options.logger.error(`insights failed: worker returned non-JSON: ${text}`);
104
- return { code: 1 };
105
- }
106
- const result = parsed.result ?? parsed;
107
- const { functions } = result;
108
- if (!Array.isArray(functions)) {
109
- options.logger.error("insights failed: response carried no `functions` array");
110
- return { code: 1 };
111
- }
112
- const report = buildInsightsReport(functions, resolveLimit(options.limit));
113
- options.logger.info(options.json ? JSON.stringify(report, void 0, 2) : formatInsightsReport(report));
114
- return { code: 0, report };
115
- };
116
- const execute = defineHandler(({ cwd, logger, options }) => {
117
- const limit = options.limit === void 0 ? void 0 : Number.parseInt(options.limit, 10);
118
- return runInsightsCommand({
119
- json: options.json,
120
- limit,
121
- logger,
122
- prod: options.prod,
123
- shard: options.shard,
124
- token: options.token,
125
- // Fall back to the `.lunora/project.json` link when `--prod` is set, so a
126
- // linked checkout doesn't need --url repeated for prod insights.
127
- url: resolveProductionWorkerUrl({ cwd, prod: options.prod === true, url: options.url })
128
- });
129
- });
130
-
131
- export { buildInsightsReport, execute, formatInsightsReport, runInsightsCommand };
1
+ import{a as m}from"../packem_shared/admin-url-DfVehV3e.mjs";import{i as $}from"../packem_shared/command-Bjv4VmYA.mjs";import{s as S}from"../packem_shared/resolve-target-vxaXHmvg.mjs";const M="__lunora_admin__:getFunctionStats",y=10,v=/\/$/u,u=(o,e)=>({calls:o.calls,conflicts:o.conflicts??0,errors:o.errors,lastErrorMessage:o.lastErrorMessage,maxDurationMs:o.maxDurationMs,meanDurationMs:o.calls===0?0:o.totalDurationMs/o.calls,path:o.path,rate:e}),O=(o,e)=>{const t=o.filter(r=>(r.conflicts??0)>0).map(r=>u(r,r.calls===0?0:(r.conflicts??0)/r.calls)).toSorted((r,s)=>s.rate-r.rate||s.conflicts-r.conflicts).slice(0,e),i=o.filter(r=>r.errors>0).map(r=>u(r,r.calls===0?0:r.errors/r.calls)).toSorted((r,s)=>s.rate-r.rate||s.errors-r.errors).slice(0,e),n=o.map(r=>u(r,0)).toSorted((r,s)=>s.maxDurationMs-r.maxDurationMs).slice(0,e);return{errorHotspots:i,latencyOutliers:n,totalFunctions:o.length,writeContention:t}},p=o=>`${(o*100).toFixed(1)}%`,f=o=>o<1e3?`${Math.round(o).toString()}ms`:`${(o/1e3).toFixed(2)}s`,d=(o,e,t,i)=>[o,...e.length===0?[` ${t}`]:e.map(n=>` ${i(n)}`)],N=o=>{const e=t=>t.lastErrorMessage?` — ${t.lastErrorMessage}`:"";return[`Insights over ${o.totalFunctions.toString()} function${o.totalFunctions===1?"":"s"}`,"",...d("Write-conflict hot-spots (OCC contention — candidates for sharding):",o.writeContention,"none — no write conflicts observed",t=>`${t.path} ${t.conflicts.toString()}/${t.calls.toString()} calls (${p(t.rate)})`),"",...d("Error hot-spots:",o.errorHotspots,"none — no errors observed",t=>`${t.path} ${t.errors.toString()}/${t.calls.toString()} calls (${p(t.rate)})${e(t)}`),"",...d("Latency outliers (slowest single call):",o.latencyOutliers,"none — no functions have run",t=>`${t.path} max ${f(t.maxDurationMs)}, mean ${f(t.meanDurationMs)} over ${t.calls.toString()} calls`)].join(`
2
+ `)},w=o=>o===void 0||!Number.isFinite(o)||o<=0?y:Math.floor(o),x=async o=>{if(o.prod&&o.url===void 0)return o.logger.error("--prod requires an explicit --url (refusing to report from the implicit localhost worker)"),{code:1};const e=o.token??process.env.LUNORA_ADMIN_TOKEN;if(!e)return o.logger.error("admin token required — pass --token or set LUNORA_ADMIN_TOKEN"),{code:1};const t=m(o.url,o.logger);if(t===void 0)return{code:1};const i=`${t.replace(v,"")}/_lunora/rpc`,n=globalThis.fetch;if(typeof n!="function")throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");const r={args:{},functionPath:M};o.shard!==void 0&&(r.shardKey=o.shard),o.logger.info(`POST ${i} -> insights`);const s=await n(i,{body:JSON.stringify(r),headers:{authorization:`Bearer ${e}`,"content-type":"application/json"},method:"POST"}),a=await s.text();if(!s.ok)return o.logger.error(`insights failed: HTTP ${String(s.status)}: ${a}`),{code:1};let l;try{l=JSON.parse(a)}catch{return o.logger.error(`insights failed: worker returned non-JSON: ${a}`),{code:1}}const h=l.result??l,{functions:g}=h;if(!Array.isArray(g))return o.logger.error("insights failed: response carried no `functions` array"),{code:1};const c=O(g,w(o.limit));return o.logger.info(o.json?JSON.stringify(c,void 0,2):N(c)),{code:0,report:c}},k=$(({cwd:o,logger:e,options:t})=>{const i=t.limit===void 0?void 0:Number.parseInt(t.limit,10);return x({json:t.json,limit:i,logger:e,prod:t.prod,shard:t.shard,token:t.token,url:S({cwd:o,prod:t.prod===!0,url:t.url})})});export{O as buildInsightsReport,k as execute,N as formatInsightsReport,x as runInsightsCommand};
@@ -1,65 +1 @@
1
- import { existsSync, rmSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { writeLinkedProject, LINKED_PROJECT_FILE } from '@lunora/config';
4
- import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
5
- import { r as readWranglerName } from '../packem_shared/wrangler-name-cy4yhm9j.mjs';
6
-
7
- const isValidWorkerUrl = (value) => {
8
- try {
9
- const { protocol } = new URL(value);
10
- return protocol === "http:" || protocol === "https:";
11
- } catch {
12
- return false;
13
- }
14
- };
15
- const runLinkRemove = (cwd, logger) => {
16
- const path = join(cwd, LINKED_PROJECT_FILE);
17
- if (!existsSync(path)) {
18
- logger.warn(`link: no ${LINKED_PROJECT_FILE} to remove`);
19
- return { code: 0 };
20
- }
21
- rmSync(path);
22
- logger.success(`link: removed ${LINKED_PROJECT_FILE}`);
23
- return { code: 0 };
24
- };
25
- const runLinkCommand = (options) => {
26
- const cwd = options.cwd ?? process.cwd();
27
- const { logger } = options;
28
- if (options.remove) {
29
- return runLinkRemove(cwd, logger);
30
- }
31
- if (options.url === void 0 || options.url === "") {
32
- logger.error("link requires a deployed Worker URL. Usage: lunora link --url <https://your-worker>");
33
- return { code: 1 };
34
- }
35
- if (!isValidWorkerUrl(options.url)) {
36
- logger.error(`link: invalid --url "${options.url}" — expected an http(s) URL`);
37
- return { code: 1 };
38
- }
39
- const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
40
- const link = {
41
- env: options.env,
42
- linkedAt: now(),
43
- workerName: options.name ?? readWranglerName(cwd),
44
- workerUrl: options.url
45
- };
46
- const path = writeLinkedProject(cwd, link);
47
- logger.success(`link: ${link.workerName ?? "(unnamed worker)"} -> ${options.url}`);
48
- logger.info(`link: wrote ${path}`);
49
- if (link.env !== void 0) {
50
- logger.info(`link: environment "${link.env}"`);
51
- }
52
- return { code: 0, link };
53
- };
54
- const execute = defineHandler(
55
- ({ cwd, logger, options }) => runLinkCommand({
56
- cwd,
57
- env: options.env,
58
- logger,
59
- name: options.name,
60
- remove: options.remove === true,
61
- url: options.url
62
- })
63
- );
64
-
65
- export { execute, runLinkCommand };
1
+ import{existsSync as c,rmSync as m}from"node:fs";import{join as u}from"node:path";import{writeLinkedProject as s,LINKED_PROJECT_FILE as t}from"@lunora/config";import{i as d}from"../packem_shared/command-Bjv4VmYA.mjs";import{d as a}from"../packem_shared/wrangler-name-HIl0Z6yx.mjs";const k=r=>{try{const{protocol:o}=new URL(r);return o==="http:"||o==="https:"}catch{return!1}},p=(r,o)=>{const e=u(r,t);return c(e)?(m(e),o.success(`link: removed ${t}`),{code:0}):(o.warn(`link: no ${t} to remove`),{code:0})},v=r=>{const o=r.cwd??process.cwd(),{logger:e}=r;if(r.remove)return p(o,e);if(r.url===void 0||r.url==="")return e.error("link requires a deployed Worker URL. Usage: lunora link --url <https://your-worker>"),{code:1};if(!k(r.url))return e.error(`link: invalid --url "${r.url}" — expected an http(s) URL`),{code:1};const i=r.now??(()=>new Date().toISOString()),n={env:r.env,linkedAt:i(),workerName:r.name??a(o),workerUrl:r.url},l=s(o,n);return e.success(`link: ${n.workerName??"(unnamed worker)"} -> ${r.url}`),e.info(`link: wrote ${l}`),n.env!==void 0&&e.info(`link: environment "${n.env}"`),{code:0,link:n}},h=d(({cwd:r,logger:o,options:e})=>v({cwd:r,env:e.env,logger:o,name:e.name,remove:e.remove===!0,url:e.url}));export{h as execute,v as runLinkCommand};