@edge-base/cli 0.1.1

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 (234) hide show
  1. package/README.md +182 -0
  2. package/dist/commands/admin.d.ts +10 -0
  3. package/dist/commands/admin.d.ts.map +1 -0
  4. package/dist/commands/admin.js +307 -0
  5. package/dist/commands/admin.js.map +1 -0
  6. package/dist/commands/backup.d.ts +148 -0
  7. package/dist/commands/backup.d.ts.map +1 -0
  8. package/dist/commands/backup.js +1247 -0
  9. package/dist/commands/backup.js.map +1 -0
  10. package/dist/commands/completion.d.ts +3 -0
  11. package/dist/commands/completion.d.ts.map +1 -0
  12. package/dist/commands/completion.js +168 -0
  13. package/dist/commands/completion.js.map +1 -0
  14. package/dist/commands/create-plugin.d.ts +3 -0
  15. package/dist/commands/create-plugin.d.ts.map +1 -0
  16. package/dist/commands/create-plugin.js +208 -0
  17. package/dist/commands/create-plugin.js.map +1 -0
  18. package/dist/commands/deploy.d.ts +146 -0
  19. package/dist/commands/deploy.d.ts.map +1 -0
  20. package/dist/commands/deploy.js +1823 -0
  21. package/dist/commands/deploy.js.map +1 -0
  22. package/dist/commands/describe.d.ts +45 -0
  23. package/dist/commands/describe.d.ts.map +1 -0
  24. package/dist/commands/describe.js +114 -0
  25. package/dist/commands/describe.js.map +1 -0
  26. package/dist/commands/destroy.d.ts +13 -0
  27. package/dist/commands/destroy.d.ts.map +1 -0
  28. package/dist/commands/destroy.js +642 -0
  29. package/dist/commands/destroy.js.map +1 -0
  30. package/dist/commands/dev.d.ts +80 -0
  31. package/dist/commands/dev.d.ts.map +1 -0
  32. package/dist/commands/dev.js +1131 -0
  33. package/dist/commands/dev.js.map +1 -0
  34. package/dist/commands/docker.d.ts +22 -0
  35. package/dist/commands/docker.d.ts.map +1 -0
  36. package/dist/commands/docker.js +373 -0
  37. package/dist/commands/docker.js.map +1 -0
  38. package/dist/commands/export.d.ts +15 -0
  39. package/dist/commands/export.d.ts.map +1 -0
  40. package/dist/commands/export.js +142 -0
  41. package/dist/commands/export.js.map +1 -0
  42. package/dist/commands/init.d.ts +7 -0
  43. package/dist/commands/init.d.ts.map +1 -0
  44. package/dist/commands/init.js +506 -0
  45. package/dist/commands/init.js.map +1 -0
  46. package/dist/commands/keys.d.ts +23 -0
  47. package/dist/commands/keys.d.ts.map +1 -0
  48. package/dist/commands/keys.js +347 -0
  49. package/dist/commands/keys.js.map +1 -0
  50. package/dist/commands/logs.d.ts +17 -0
  51. package/dist/commands/logs.d.ts.map +1 -0
  52. package/dist/commands/logs.js +104 -0
  53. package/dist/commands/logs.js.map +1 -0
  54. package/dist/commands/migrate.d.ts +29 -0
  55. package/dist/commands/migrate.d.ts.map +1 -0
  56. package/dist/commands/migrate.js +302 -0
  57. package/dist/commands/migrate.js.map +1 -0
  58. package/dist/commands/migration.d.ts +18 -0
  59. package/dist/commands/migration.d.ts.map +1 -0
  60. package/dist/commands/migration.js +114 -0
  61. package/dist/commands/migration.js.map +1 -0
  62. package/dist/commands/neon.d.ts +66 -0
  63. package/dist/commands/neon.d.ts.map +1 -0
  64. package/dist/commands/neon.js +600 -0
  65. package/dist/commands/neon.js.map +1 -0
  66. package/dist/commands/plugins.d.ts +9 -0
  67. package/dist/commands/plugins.d.ts.map +1 -0
  68. package/dist/commands/plugins.js +295 -0
  69. package/dist/commands/plugins.js.map +1 -0
  70. package/dist/commands/realtime.d.ts +3 -0
  71. package/dist/commands/realtime.d.ts.map +1 -0
  72. package/dist/commands/realtime.js +71 -0
  73. package/dist/commands/realtime.js.map +1 -0
  74. package/dist/commands/secret.d.ts +7 -0
  75. package/dist/commands/secret.d.ts.map +1 -0
  76. package/dist/commands/secret.js +180 -0
  77. package/dist/commands/secret.js.map +1 -0
  78. package/dist/commands/seed.d.ts +21 -0
  79. package/dist/commands/seed.d.ts.map +1 -0
  80. package/dist/commands/seed.js +325 -0
  81. package/dist/commands/seed.js.map +1 -0
  82. package/dist/commands/telemetry.d.ts +12 -0
  83. package/dist/commands/telemetry.d.ts.map +1 -0
  84. package/dist/commands/telemetry.js +57 -0
  85. package/dist/commands/telemetry.js.map +1 -0
  86. package/dist/commands/typegen.d.ts +26 -0
  87. package/dist/commands/typegen.d.ts.map +1 -0
  88. package/dist/commands/typegen.js +212 -0
  89. package/dist/commands/typegen.js.map +1 -0
  90. package/dist/commands/upgrade.d.ts +29 -0
  91. package/dist/commands/upgrade.d.ts.map +1 -0
  92. package/dist/commands/upgrade.js +265 -0
  93. package/dist/commands/upgrade.js.map +1 -0
  94. package/dist/commands/webhook-test.d.ts +3 -0
  95. package/dist/commands/webhook-test.d.ts.map +1 -0
  96. package/dist/commands/webhook-test.js +133 -0
  97. package/dist/commands/webhook-test.js.map +1 -0
  98. package/dist/index.d.ts +3 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +183 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/lib/agent-contract.d.ts +36 -0
  103. package/dist/lib/agent-contract.d.ts.map +1 -0
  104. package/dist/lib/agent-contract.js +78 -0
  105. package/dist/lib/agent-contract.js.map +1 -0
  106. package/dist/lib/cf-auth.d.ts +76 -0
  107. package/dist/lib/cf-auth.d.ts.map +1 -0
  108. package/dist/lib/cf-auth.js +321 -0
  109. package/dist/lib/cf-auth.js.map +1 -0
  110. package/dist/lib/cli-context.d.ts +23 -0
  111. package/dist/lib/cli-context.d.ts.map +1 -0
  112. package/dist/lib/cli-context.js +40 -0
  113. package/dist/lib/cli-context.js.map +1 -0
  114. package/dist/lib/cloudflare-deploy-manifest.d.ts +26 -0
  115. package/dist/lib/cloudflare-deploy-manifest.d.ts.map +1 -0
  116. package/dist/lib/cloudflare-deploy-manifest.js +107 -0
  117. package/dist/lib/cloudflare-deploy-manifest.js.map +1 -0
  118. package/dist/lib/cloudflare-wrangler-resources.d.ts +32 -0
  119. package/dist/lib/cloudflare-wrangler-resources.d.ts.map +1 -0
  120. package/dist/lib/cloudflare-wrangler-resources.js +59 -0
  121. package/dist/lib/cloudflare-wrangler-resources.js.map +1 -0
  122. package/dist/lib/config-editor.d.ts +139 -0
  123. package/dist/lib/config-editor.d.ts.map +1 -0
  124. package/dist/lib/config-editor.js +1188 -0
  125. package/dist/lib/config-editor.js.map +1 -0
  126. package/dist/lib/deploy-shared.d.ts +55 -0
  127. package/dist/lib/deploy-shared.d.ts.map +1 -0
  128. package/dist/lib/deploy-shared.js +183 -0
  129. package/dist/lib/deploy-shared.js.map +1 -0
  130. package/dist/lib/dev-sidecar.d.ts +31 -0
  131. package/dist/lib/dev-sidecar.d.ts.map +1 -0
  132. package/dist/lib/dev-sidecar.js +1058 -0
  133. package/dist/lib/dev-sidecar.js.map +1 -0
  134. package/dist/lib/fetch-with-timeout.d.ts +14 -0
  135. package/dist/lib/fetch-with-timeout.d.ts.map +1 -0
  136. package/dist/lib/fetch-with-timeout.js +29 -0
  137. package/dist/lib/fetch-with-timeout.js.map +1 -0
  138. package/dist/lib/function-registry.d.ts +56 -0
  139. package/dist/lib/function-registry.d.ts.map +1 -0
  140. package/dist/lib/function-registry.js +210 -0
  141. package/dist/lib/function-registry.js.map +1 -0
  142. package/dist/lib/load-config.d.ts +24 -0
  143. package/dist/lib/load-config.d.ts.map +1 -0
  144. package/dist/lib/load-config.js +263 -0
  145. package/dist/lib/load-config.js.map +1 -0
  146. package/dist/lib/local-secrets.d.ts +2 -0
  147. package/dist/lib/local-secrets.d.ts.map +1 -0
  148. package/dist/lib/local-secrets.js +60 -0
  149. package/dist/lib/local-secrets.js.map +1 -0
  150. package/dist/lib/managed-resource-names.d.ts +4 -0
  151. package/dist/lib/managed-resource-names.d.ts.map +1 -0
  152. package/dist/lib/managed-resource-names.js +19 -0
  153. package/dist/lib/managed-resource-names.js.map +1 -0
  154. package/dist/lib/migrator.d.ts +57 -0
  155. package/dist/lib/migrator.d.ts.map +1 -0
  156. package/dist/lib/migrator.js +321 -0
  157. package/dist/lib/migrator.js.map +1 -0
  158. package/dist/lib/neon.d.ts +41 -0
  159. package/dist/lib/neon.d.ts.map +1 -0
  160. package/dist/lib/neon.js +325 -0
  161. package/dist/lib/neon.js.map +1 -0
  162. package/dist/lib/node-tools.d.ts +10 -0
  163. package/dist/lib/node-tools.d.ts.map +1 -0
  164. package/dist/lib/node-tools.js +32 -0
  165. package/dist/lib/node-tools.js.map +1 -0
  166. package/dist/lib/npm.d.ts +8 -0
  167. package/dist/lib/npm.d.ts.map +1 -0
  168. package/dist/lib/npm.js +10 -0
  169. package/dist/lib/npm.js.map +1 -0
  170. package/dist/lib/npx.d.ts +9 -0
  171. package/dist/lib/npx.d.ts.map +1 -0
  172. package/dist/lib/npx.js +11 -0
  173. package/dist/lib/npx.js.map +1 -0
  174. package/dist/lib/project-runtime.d.ts +38 -0
  175. package/dist/lib/project-runtime.d.ts.map +1 -0
  176. package/dist/lib/project-runtime.js +122 -0
  177. package/dist/lib/project-runtime.js.map +1 -0
  178. package/dist/lib/prompts.d.ts +28 -0
  179. package/dist/lib/prompts.d.ts.map +1 -0
  180. package/dist/lib/prompts.js +85 -0
  181. package/dist/lib/prompts.js.map +1 -0
  182. package/dist/lib/rate-limit-bindings.d.ts +11 -0
  183. package/dist/lib/rate-limit-bindings.d.ts.map +1 -0
  184. package/dist/lib/rate-limit-bindings.js +52 -0
  185. package/dist/lib/rate-limit-bindings.js.map +1 -0
  186. package/dist/lib/realtime-provision.d.ts +22 -0
  187. package/dist/lib/realtime-provision.d.ts.map +1 -0
  188. package/dist/lib/realtime-provision.js +246 -0
  189. package/dist/lib/realtime-provision.js.map +1 -0
  190. package/dist/lib/resolve-options.d.ts +42 -0
  191. package/dist/lib/resolve-options.d.ts.map +1 -0
  192. package/dist/lib/resolve-options.js +98 -0
  193. package/dist/lib/resolve-options.js.map +1 -0
  194. package/dist/lib/runtime-scaffold.d.ts +17 -0
  195. package/dist/lib/runtime-scaffold.d.ts.map +1 -0
  196. package/dist/lib/runtime-scaffold.js +366 -0
  197. package/dist/lib/runtime-scaffold.js.map +1 -0
  198. package/dist/lib/schema-check.d.ts +79 -0
  199. package/dist/lib/schema-check.d.ts.map +1 -0
  200. package/dist/lib/schema-check.js +347 -0
  201. package/dist/lib/schema-check.js.map +1 -0
  202. package/dist/lib/spinner.d.ts +20 -0
  203. package/dist/lib/spinner.d.ts.map +1 -0
  204. package/dist/lib/spinner.js +42 -0
  205. package/dist/lib/spinner.js.map +1 -0
  206. package/dist/lib/telemetry.d.ts +37 -0
  207. package/dist/lib/telemetry.d.ts.map +1 -0
  208. package/dist/lib/telemetry.js +98 -0
  209. package/dist/lib/telemetry.js.map +1 -0
  210. package/dist/lib/turnstile-provision.d.ts +27 -0
  211. package/dist/lib/turnstile-provision.d.ts.map +1 -0
  212. package/dist/lib/turnstile-provision.js +144 -0
  213. package/dist/lib/turnstile-provision.js.map +1 -0
  214. package/dist/lib/update-check.d.ts +13 -0
  215. package/dist/lib/update-check.d.ts.map +1 -0
  216. package/dist/lib/update-check.js +110 -0
  217. package/dist/lib/update-check.js.map +1 -0
  218. package/dist/lib/wrangler-secrets.d.ts +3 -0
  219. package/dist/lib/wrangler-secrets.d.ts.map +1 -0
  220. package/dist/lib/wrangler-secrets.js +32 -0
  221. package/dist/lib/wrangler-secrets.js.map +1 -0
  222. package/dist/lib/wrangler.d.ts +9 -0
  223. package/dist/lib/wrangler.d.ts.map +1 -0
  224. package/dist/lib/wrangler.js +84 -0
  225. package/dist/lib/wrangler.js.map +1 -0
  226. package/dist/templates/plugin/README.md.tmpl +91 -0
  227. package/dist/templates/plugin/client/js/package.json.tmpl +23 -0
  228. package/dist/templates/plugin/client/js/src/index.ts.tmpl +68 -0
  229. package/dist/templates/plugin/client/js/tsconfig.json.tmpl +14 -0
  230. package/dist/templates/plugin/server/package.json.tmpl +19 -0
  231. package/dist/templates/plugin/server/src/index.ts.tmpl +59 -0
  232. package/dist/templates/plugin/server/tsconfig.json.tmpl +14 -0
  233. package/llms.txt +94 -0
  234. package/package.json +60 -0
@@ -0,0 +1,347 @@
1
+ /**
2
+ * Schema Destructive Change Detection — Build-time snapshot diff.
3
+ *
4
+ * Compares the current config schema against a saved snapshot to detect
5
+ * destructive changes (column delete, rename, type change) and forces
6
+ * the developer to choose: DB reset or migration.
7
+ */
8
+ import { existsSync, readFileSync, writeFileSync, rmSync } from 'node:fs';
9
+ import { resolve } from 'node:path';
10
+ import chalk from 'chalk';
11
+ import { raiseCliError, raiseNeedsInput } from './agent-contract.js';
12
+ import { isNonInteractive } from './cli-context.js';
13
+ // ─── Auto-Fields (mirrors server AUTO_FIELDS —) ───
14
+ const AUTO_FIELDS = {
15
+ id: { type: 'string', primaryKey: true },
16
+ createdAt: { type: 'datetime' },
17
+ updatedAt: { type: 'datetime' },
18
+ };
19
+ // ─── Snapshot Build ───
20
+ /**
21
+ * Build effective schema for snapshot purposes.
22
+ * Mirrors server's buildEffectiveSchema() but only extracts type/primaryKey for diffing.
23
+ * Accepts loosely-typed schema from parsed JSON config.
24
+ */
25
+ function buildSnapshotSchema(userSchema) {
26
+ const effective = {};
27
+ // Inject auto-fields (disabled by `false`, type override blocked by §1a)
28
+ for (const [name, field] of Object.entries(AUTO_FIELDS)) {
29
+ if (userSchema?.[name] === false)
30
+ continue;
31
+ effective[name] = { ...field };
32
+ }
33
+ // Add user-defined fields
34
+ if (userSchema) {
35
+ for (const [name, field] of Object.entries(userSchema)) {
36
+ if (name in AUTO_FIELDS)
37
+ continue;
38
+ if (field === false)
39
+ continue;
40
+ if (typeof field === 'object' && field !== null && 'type' in field) {
41
+ const f = field;
42
+ effective[name] = { type: f.type, ...(f.primaryKey ? { primaryKey: true } : {}) };
43
+ }
44
+ }
45
+ }
46
+ return effective;
47
+ }
48
+ /**
49
+ * Build a full snapshot from the current config's databases block.
50
+ */
51
+ export function buildSnapshot(databases, authProvider) {
52
+ const snapshot = { version: 2, databases: {}, ...(authProvider ? { authProvider } : {}) };
53
+ for (const [dbKey, dbBlock] of Object.entries(databases)) {
54
+ const tables = {};
55
+ for (const [tableName, tableConfig] of Object.entries(dbBlock.tables ?? {})) {
56
+ const migrations = tableConfig.migrations ?? [];
57
+ const latestVersion = migrations.length > 0
58
+ ? Math.max(...migrations.map(m => m.version))
59
+ : 0;
60
+ tables[tableName] = {
61
+ schema: buildSnapshotSchema(tableConfig.schema),
62
+ latestMigrationVersion: latestVersion,
63
+ };
64
+ }
65
+ snapshot.databases[dbKey] = {
66
+ tables,
67
+ ...(dbBlock.provider ? { provider: dbBlock.provider } : {}),
68
+ };
69
+ }
70
+ return snapshot;
71
+ }
72
+ // ─── Snapshot I/O ───
73
+ const SNAPSHOT_FILENAME = 'edgebase-schema.lock.json';
74
+ export function getSnapshotPath(projectDir) {
75
+ return resolve(projectDir, SNAPSHOT_FILENAME);
76
+ }
77
+ export function loadSnapshot(projectDir) {
78
+ const path = getSnapshotPath(projectDir);
79
+ if (!existsSync(path))
80
+ return null;
81
+ try {
82
+ const raw = readFileSync(path, 'utf-8');
83
+ return JSON.parse(raw);
84
+ }
85
+ catch {
86
+ return null;
87
+ }
88
+ }
89
+ export function saveSnapshot(projectDir, snapshot) {
90
+ const path = getSnapshotPath(projectDir);
91
+ writeFileSync(path, JSON.stringify(snapshot, null, 2) + '\n', 'utf-8');
92
+ }
93
+ /**
94
+ * Detect provider changes between snapshots.
95
+ * Returns list of namespaces whose provider changed.
96
+ */
97
+ export function detectProviderChanges(saved, current) {
98
+ const changes = [];
99
+ for (const [ns, currentDb] of Object.entries(current.databases)) {
100
+ const savedDb = saved.databases[ns];
101
+ if (!savedDb)
102
+ continue; // new namespace — no change to detect
103
+ const oldProvider = savedDb.provider ?? 'do';
104
+ const newProvider = currentDb.provider ?? 'do';
105
+ if (oldProvider !== newProvider) {
106
+ changes.push({ namespace: ns, oldProvider, newProvider });
107
+ }
108
+ }
109
+ return changes;
110
+ }
111
+ /**
112
+ * Detect auth provider change between snapshots.
113
+ * Returns a ProviderChange for namespace '_auth' if auth.provider changed.
114
+ */
115
+ export function detectAuthProviderChange(saved, current) {
116
+ const oldProvider = saved.authProvider ?? 'd1';
117
+ const newProvider = current.authProvider ?? 'd1';
118
+ if (oldProvider !== newProvider) {
119
+ return { namespace: '_auth', oldProvider, newProvider };
120
+ }
121
+ return null;
122
+ }
123
+ // ─── Destructive Change Detection (§2) ───
124
+ /**
125
+ * Compare saved snapshot against current config and return destructive changes.
126
+ */
127
+ export function detectDestructiveChanges(saved, current) {
128
+ const changes = [];
129
+ for (const [dbKey, savedDb] of Object.entries(saved.databases)) {
130
+ const currentDb = current.databases[dbKey];
131
+ // Entire DB block removed
132
+ if (!currentDb) {
133
+ for (const tableName of Object.keys(savedDb.tables)) {
134
+ changes.push({
135
+ dbKey,
136
+ table: tableName,
137
+ type: 'table_deleted',
138
+ detail: `Table '${dbKey}.${tableName}' removed (entire DB block '${dbKey}' deleted)`,
139
+ });
140
+ }
141
+ continue;
142
+ }
143
+ for (const [tableName, savedTable] of Object.entries(savedDb.tables)) {
144
+ const currentTable = currentDb.tables[tableName];
145
+ // Table removed
146
+ if (!currentTable) {
147
+ changes.push({
148
+ dbKey,
149
+ table: tableName,
150
+ type: 'table_deleted',
151
+ detail: `Table '${dbKey}.${tableName}' removed`,
152
+ });
153
+ continue;
154
+ }
155
+ // Column-level diff
156
+ for (const [colName, savedCol] of Object.entries(savedTable.schema)) {
157
+ const currentCol = currentTable.schema[colName];
158
+ if (!currentCol) {
159
+ changes.push({
160
+ dbKey,
161
+ table: tableName,
162
+ type: 'column_deleted',
163
+ detail: `Column '${dbKey}.${tableName}.${colName}' removed`,
164
+ });
165
+ continue;
166
+ }
167
+ if (savedCol.type !== currentCol.type) {
168
+ changes.push({
169
+ dbKey,
170
+ table: tableName,
171
+ type: 'column_type_changed',
172
+ detail: `Column '${dbKey}.${tableName}.${colName}' type: ${savedCol.type} → ${currentCol.type}`,
173
+ });
174
+ }
175
+ }
176
+ }
177
+ }
178
+ return changes;
179
+ }
180
+ // ─── Per-table Migration Auto-Pass (§4) ───
181
+ /**
182
+ * Filter out destructive changes for tables that have new migrations covering them.
183
+ */
184
+ export function filterAutoPassChanges(changes, saved, current) {
185
+ return changes.filter(change => {
186
+ const savedDb = saved.databases[change.dbKey];
187
+ const currentDb = current.databases[change.dbKey];
188
+ if (!savedDb || !currentDb)
189
+ return true; // Keep — can't auto-pass
190
+ const savedTable = savedDb.tables[change.table];
191
+ const currentTable = currentDb.tables[change.table];
192
+ if (!savedTable || !currentTable)
193
+ return true; // Keep — table deleted, no migration possible
194
+ const savedVersion = savedTable.latestMigrationVersion;
195
+ const currentVersion = currentTable.latestMigrationVersion;
196
+ // Auto-pass: new migration version > saved version for THIS table
197
+ return currentVersion <= savedVersion;
198
+ });
199
+ }
200
+ /**
201
+ * Display destructive changes and prompt for action.
202
+ * Returns the user's choice.
203
+ */
204
+ export async function handleDestructiveChanges(changes, isRelease, isTTY, ifDestructiveFlag) {
205
+ // Display changes
206
+ console.log();
207
+ console.log(chalk.yellow('⚠ Destructive schema changes detected:'));
208
+ for (const c of changes) {
209
+ console.log(chalk.yellow(` • ${c.detail}`));
210
+ }
211
+ console.log();
212
+ // Non-interactive (CI/CD) — §5a
213
+ if (!isTTY || isNonInteractive()) {
214
+ if (ifDestructiveFlag === 'reset') {
215
+ if (isRelease) {
216
+ raiseCliError({
217
+ code: 'destructive_reset_not_allowed',
218
+ field: 'ifDestructive',
219
+ message: '--if-destructive=reset is not allowed when release: true.',
220
+ hint: 'Use --if-destructive=reject and add a migration for the destructive schema change.',
221
+ });
222
+ }
223
+ return { action: 'reset' };
224
+ }
225
+ raiseNeedsInput({
226
+ code: 'destructive_schema_confirmation_required',
227
+ field: 'ifDestructive',
228
+ message: 'Destructive schema changes require an explicit strategy in non-interactive mode.',
229
+ hint: 'Rerun with --if-destructive=reset for local development, or add migrations before retrying.',
230
+ choices: isRelease
231
+ ? [{
232
+ label: 'Reject and add migrations',
233
+ value: 'reject',
234
+ args: ['--if-destructive', 'reject'],
235
+ hint: 'Release mode cannot reset the database.',
236
+ }]
237
+ : [
238
+ {
239
+ label: 'Reject and add migrations',
240
+ value: 'reject',
241
+ args: ['--if-destructive', 'reject'],
242
+ },
243
+ {
244
+ label: 'Reset local DB and continue',
245
+ value: 'reset',
246
+ args: ['--if-destructive', 'reset'],
247
+ hint: 'Development only. This deletes local data.',
248
+ },
249
+ ],
250
+ });
251
+ }
252
+ // Release mode: no reset option (§3)
253
+ if (isRelease) {
254
+ raiseCliError({
255
+ code: 'destructive_reset_not_allowed',
256
+ field: 'ifDestructive',
257
+ message: 'DB reset is not supported in release mode.',
258
+ hint: 'Write a migration instead of using --if-destructive reset in release mode.',
259
+ details: {
260
+ changes: changes.map((change) => ({
261
+ dbKey: change.dbKey,
262
+ table: change.table,
263
+ type: change.type,
264
+ })),
265
+ },
266
+ });
267
+ }
268
+ // Interactive dev mode: prompt for choice
269
+ const readline = await import('node:readline');
270
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
271
+ return new Promise((resolve) => {
272
+ console.log(chalk.cyan('[r]'), 'Reset DB and continue (all data will be deleted)');
273
+ console.log(chalk.cyan('[m]'), 'Show migration guide');
274
+ console.log();
275
+ rl.question(chalk.cyan('Choose: '), (answer) => {
276
+ rl.close();
277
+ const choice = answer.trim().toLowerCase();
278
+ if (choice === 'r') {
279
+ resolve({ action: 'reset' });
280
+ }
281
+ else {
282
+ printMigrationGuide(changes);
283
+ resolve({ action: 'migration_guide' });
284
+ }
285
+ });
286
+ });
287
+ }
288
+ /**
289
+ * Print migration guide for each affected table.
290
+ */
291
+ function printMigrationGuide(changes) {
292
+ // Group changes by table
293
+ const byTable = new Map();
294
+ for (const c of changes) {
295
+ const key = `${c.dbKey}.${c.table}`;
296
+ if (!byTable.has(key))
297
+ byTable.set(key, []);
298
+ byTable.get(key).push(c);
299
+ }
300
+ console.log();
301
+ for (const [tableKey, tableChanges] of byTable) {
302
+ const [_dbKey, tableName] = tableKey.split('.');
303
+ console.log(chalk.dim(` Add to ${tableKey}.migrations:`));
304
+ console.log();
305
+ // Suggest SQL hints based on change types
306
+ const hints = [];
307
+ for (const c of tableChanges) {
308
+ if (c.type === 'column_deleted') {
309
+ const colName = c.detail.match(/Column '.*?\.(\w+)' removed/)?.[1] ?? '?';
310
+ hints.push(`ALTER TABLE ${tableName} DROP COLUMN ${colName}`);
311
+ }
312
+ else if (c.type === 'column_type_changed') {
313
+ const match = c.detail.match(/Column '.*?\.(\w+)' type: (\w+) → (\w+)/);
314
+ if (match) {
315
+ hints.push(`-- Type change: ${match[1]} ${match[2]} → ${match[3]} (manual SQL required)`);
316
+ }
317
+ }
318
+ else if (c.type === 'table_deleted') {
319
+ hints.push(`DROP TABLE IF EXISTS ${tableName}`);
320
+ }
321
+ }
322
+ console.log(chalk.dim(' {'));
323
+ console.log(chalk.dim(` version: <next>,`));
324
+ console.log(chalk.dim(` description: '...',`));
325
+ console.log(chalk.dim(` up: '${hints.join('; ')}'`));
326
+ console.log(chalk.dim(' }'));
327
+ console.log();
328
+ }
329
+ console.log(chalk.dim(' Add the migration and run again.'));
330
+ }
331
+ // ─── Dev Mode Reset Helper ───
332
+ /**
333
+ * Reset local Miniflare DO state for dev mode.
334
+ */
335
+ export function resetLocalDoState(projectDir, persistTo) {
336
+ const statePath = persistTo
337
+ ? resolve(persistTo, 'v3', 'do')
338
+ : resolve(projectDir, '.wrangler', 'state', 'v3', 'do');
339
+ try {
340
+ rmSync(statePath, { recursive: true, force: true });
341
+ console.log(chalk.green('✓'), `Local DO state cleared (${statePath})`);
342
+ }
343
+ catch {
344
+ console.log(chalk.yellow('⚠'), 'Could not clear local DO state — manual cleanup may be needed');
345
+ }
346
+ }
347
+ //# sourceMappingURL=schema-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-check.js","sourceRoot":"","sources":["../../src/lib/schema-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Spinner utility — wraps `ora` with automatic quiet/json mode detection.
3
+ *
4
+ * When --quiet or --json flags are active, returns a no-op stub
5
+ * so commands don't need conditional logic around spinners.
6
+ */
7
+ import { type Ora } from 'ora';
8
+ /**
9
+ * Start a spinner with the given text.
10
+ * Returns a no-op stub in quiet/json mode.
11
+ *
12
+ * Usage:
13
+ * ```typescript
14
+ * const s = spin('Deploying...');
15
+ * // ... long operation ...
16
+ * s.succeed('Deployed!');
17
+ * ```
18
+ */
19
+ export declare function spin(text: string): Ora;
20
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAqBpC;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAGtC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Spinner utility — wraps `ora` with automatic quiet/json mode detection.
3
+ *
4
+ * When --quiet or --json flags are active, returns a no-op stub
5
+ * so commands don't need conditional logic around spinners.
6
+ */
7
+ import ora from 'ora';
8
+ import { isQuiet } from './cli-context.js';
9
+ /** No-op spinner stub returned in quiet/json mode. */
10
+ const noop = () => { };
11
+ const noopSpinner = {
12
+ start: function () { return this; },
13
+ stop: noop,
14
+ succeed: noop,
15
+ fail: noop,
16
+ warn: noop,
17
+ info: noop,
18
+ stopAndPersist: noop,
19
+ clear: noop,
20
+ render: noop,
21
+ frame: noop,
22
+ get text() { return ''; },
23
+ set text(_v) { },
24
+ get isSpinning() { return false; },
25
+ };
26
+ /**
27
+ * Start a spinner with the given text.
28
+ * Returns a no-op stub in quiet/json mode.
29
+ *
30
+ * Usage:
31
+ * ```typescript
32
+ * const s = spin('Deploying...');
33
+ * // ... long operation ...
34
+ * s.succeed('Deployed!');
35
+ * ```
36
+ */
37
+ export function spin(text) {
38
+ if (isQuiet())
39
+ return noopSpinner;
40
+ return ora({ text, color: 'blue' }).start();
41
+ }
42
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,GAAiB,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,sDAAsD;AACtD,MAAM,IAAI,GAAG,GAAS,EAAE,GAAE,CAAC,CAAC;AAC5B,MAAM,WAAW,GAAQ;IACvB,KAAK,EAAE,cAAc,OAAO,IAAI,CAAC,CAAC,CAAC;IACnC,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,cAAc,EAAE,IAAI;IACpB,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IACzB,IAAI,IAAI,CAAC,EAAU,IAAG,CAAC;IACvB,IAAI,UAAU,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC;CACjB,CAAC;AAEpB;;;;;;;;;;GAUG;AACH,MAAM,UAAU,IAAI,CAAC,IAAY;IAC/B,IAAI,OAAO,EAAE;QAAE,OAAO,WAAW,CAAC;IAClC,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Telemetry — opt-in local usage statistics.
3
+ *
4
+ * Currently stores events locally in ~/.edgebase/telemetry.json.
5
+ * No remote transmission — reserved for future analytics endpoint.
6
+ *
7
+ * Data collected (when enabled):
8
+ * - Command name (e.g., "deploy", "backup create")
9
+ * - Success/failure boolean
10
+ * - Duration in milliseconds
11
+ * - Timestamp
12
+ *
13
+ * No PII, no code content, no file paths.
14
+ */
15
+ /** Check if telemetry is enabled. */
16
+ export declare function isTelemetryEnabled(): boolean;
17
+ /** Record a command execution event (no-op if disabled). */
18
+ export declare function recordEvent(command: string, success: boolean, durationMs: number): void;
19
+ /** Enable telemetry collection. */
20
+ export declare function enableTelemetry(): void;
21
+ /** Disable telemetry collection. Preserves existing events. */
22
+ export declare function disableTelemetry(): void;
23
+ interface TelemetryNoticeOptions {
24
+ suppressOutput?: boolean;
25
+ }
26
+ /**
27
+ * Show a one-time privacy notice on first CLI run.
28
+ * No-op if the notice has already been shown.
29
+ */
30
+ export declare function showTelemetryNoticeOnce(options?: TelemetryNoticeOptions): void;
31
+ /** Get telemetry status for display. */
32
+ export declare function getTelemetryStatus(): {
33
+ enabled: boolean;
34
+ eventCount: number;
35
+ };
36
+ export {};
37
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/lib/telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAuCH,qCAAqC;AACrC,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,GACjB,IAAI,CAmBN;AAED,mCAAmC;AACnC,wBAAgB,eAAe,IAAI,IAAI,CAItC;AAED,+DAA+D;AAC/D,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED,UAAU,sBAAsB;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAe9E;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAG7E"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Telemetry — opt-in local usage statistics.
3
+ *
4
+ * Currently stores events locally in ~/.edgebase/telemetry.json.
5
+ * No remote transmission — reserved for future analytics endpoint.
6
+ *
7
+ * Data collected (when enabled):
8
+ * - Command name (e.g., "deploy", "backup create")
9
+ * - Success/failure boolean
10
+ * - Duration in milliseconds
11
+ * - Timestamp
12
+ *
13
+ * No PII, no code content, no file paths.
14
+ */
15
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
16
+ import { join } from 'node:path';
17
+ import { homedir } from 'node:os';
18
+ const MAX_EVENTS = 1000;
19
+ // Lazy path resolution — allows tests to mock homedir()
20
+ function telemetryDir() { return join(homedir(), '.edgebase'); }
21
+ function telemetryFile() { return join(telemetryDir(), 'telemetry.json'); }
22
+ function loadData() {
23
+ try {
24
+ if (existsSync(telemetryFile())) {
25
+ return JSON.parse(readFileSync(telemetryFile(), 'utf-8'));
26
+ }
27
+ }
28
+ catch { /* corrupted file — treat as disabled */ }
29
+ return { enabled: false, events: [] };
30
+ }
31
+ function saveData(data) {
32
+ if (!existsSync(telemetryDir()))
33
+ mkdirSync(telemetryDir(), { recursive: true });
34
+ writeFileSync(telemetryFile(), JSON.stringify(data, null, 2));
35
+ }
36
+ /** Check if telemetry is enabled. */
37
+ export function isTelemetryEnabled() {
38
+ return loadData().enabled;
39
+ }
40
+ /** Record a command execution event (no-op if disabled). */
41
+ export function recordEvent(command, success, durationMs) {
42
+ const data = loadData();
43
+ if (!data.enabled)
44
+ return;
45
+ data.events.push({
46
+ command,
47
+ success,
48
+ durationMs,
49
+ timestamp: new Date().toISOString(),
50
+ });
51
+ // Keep only the most recent events
52
+ if (data.events.length > MAX_EVENTS) {
53
+ data.events = data.events.slice(-MAX_EVENTS);
54
+ }
55
+ try {
56
+ saveData(data);
57
+ }
58
+ catch { /* non-fatal */ }
59
+ }
60
+ /** Enable telemetry collection. */
61
+ export function enableTelemetry() {
62
+ const data = loadData();
63
+ data.enabled = true;
64
+ saveData(data);
65
+ }
66
+ /** Disable telemetry collection. Preserves existing events. */
67
+ export function disableTelemetry() {
68
+ const data = loadData();
69
+ data.enabled = false;
70
+ saveData(data);
71
+ }
72
+ /**
73
+ * Show a one-time privacy notice on first CLI run.
74
+ * No-op if the notice has already been shown.
75
+ */
76
+ export function showTelemetryNoticeOnce(options) {
77
+ const data = loadData();
78
+ if (data.noticeShown)
79
+ return;
80
+ if (options?.suppressOutput)
81
+ return;
82
+ console.log();
83
+ console.log('\u{1F4CA} EdgeBase supports optional anonymous CLI telemetry.');
84
+ console.log(' Telemetry is disabled by default.');
85
+ console.log(' Run \'npx edgebase telemetry enable\' to opt in.');
86
+ console.log();
87
+ data.noticeShown = true;
88
+ try {
89
+ saveData(data);
90
+ }
91
+ catch { /* non-fatal */ }
92
+ }
93
+ /** Get telemetry status for display. */
94
+ export function getTelemetryStatus() {
95
+ const data = loadData();
96
+ return { enabled: data.enabled, eventCount: data.events.length };
97
+ }
98
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/lib/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface TurnstileProvisionResult {
2
+ siteKey: string;
3
+ secretKey: string;
4
+ widgetName?: string;
5
+ managed: boolean;
6
+ source: 'manual' | 'created' | 'existing';
7
+ }
8
+ /**
9
+ * Provision Cloudflare Turnstile widget via Management API.
10
+ * If config.captcha === true: auto-create widget, store secret.
11
+ * If config.captcha is CaptchaConfig: use provided keys.
12
+ *
13
+ * @returns { siteKey, secretKey } or null if captcha not configured.
14
+ */
15
+ export declare function provisionTurnstile(captchaConfig: boolean | {
16
+ siteKey: string;
17
+ secretKey: string;
18
+ } | undefined, projectDir: string, _configJson: Record<string, unknown>, knownAccountId?: string): Promise<TurnstileProvisionResult | null>;
19
+ /**
20
+ * Store a Workers secret if not already set.
21
+ */
22
+ export declare function storeSecretIfMissing(projectDir: string, secretName: string, secretValue: string): void;
23
+ /**
24
+ * Inject captcha siteKey as a standalone CAPTCHA_SITE_KEY variable in wrangler.toml [vars].
25
+ */
26
+ export declare function injectCaptchaSiteKey(wranglerPath: string, siteKey: string): void;
27
+ //# sourceMappingURL=turnstile-provision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turnstile-provision.d.ts","sourceRoot":"","sources":["../../src/lib/turnstile-provision.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EAC3E,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CA0H1C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,IAAI,CAiBN;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAqBhF"}