@percher/core 0.4.0 → 0.4.2
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/commands/account.d.ts +24 -14
- package/dist/commands/account.d.ts.map +1 -1
- package/dist/commands/account.js +17 -4
- package/dist/commands/account.js.map +1 -1
- package/dist/commands/admin-reconcile-routes.d.ts +18 -0
- package/dist/commands/admin-reconcile-routes.d.ts.map +1 -0
- package/dist/commands/admin-reconcile-routes.js +22 -0
- package/dist/commands/admin-reconcile-routes.js.map +1 -0
- package/dist/commands/ai-files.d.ts +5 -17
- package/dist/commands/ai-files.d.ts.map +1 -1
- package/dist/commands/ai-files.js +3 -4
- package/dist/commands/ai-files.js.map +1 -1
- package/dist/commands/alerts.d.ts +70 -0
- package/dist/commands/alerts.d.ts.map +1 -0
- package/dist/commands/alerts.js +82 -0
- package/dist/commands/alerts.js.map +1 -0
- package/dist/commands/app-resources.d.ts +30 -0
- package/dist/commands/app-resources.d.ts.map +1 -0
- package/dist/commands/app-resources.js +34 -0
- package/dist/commands/app-resources.js.map +1 -0
- package/dist/commands/app-topology.d.ts +18 -0
- package/dist/commands/app-topology.d.ts.map +1 -0
- package/dist/commands/app-topology.js +25 -0
- package/dist/commands/app-topology.js.map +1 -0
- package/dist/commands/billing.d.ts +8 -8
- package/dist/commands/billing.d.ts.map +1 -1
- package/dist/commands/billing.js +1 -1
- package/dist/commands/billing.js.map +1 -1
- package/dist/commands/continue.d.ts +1 -1
- package/dist/commands/create.d.ts +2 -12
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +1 -1
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/dashboard.d.ts +2 -8
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/data-export.d.ts +2 -8
- package/dist/commands/data-export.d.ts.map +1 -1
- package/dist/commands/data-export.js +1 -1
- package/dist/commands/data-export.js.map +1 -1
- package/dist/commands/data.d.ts +2 -8
- package/dist/commands/data.d.ts.map +1 -1
- package/dist/commands/data.js +1 -1
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/delete.d.ts +2 -8
- package/dist/commands/delete.d.ts.map +1 -1
- package/dist/commands/delete.js +1 -1
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/deploys.d.ts +4 -28
- package/dist/commands/deploys.d.ts.map +1 -1
- package/dist/commands/deploys.js +1 -1
- package/dist/commands/deploys.js.map +1 -1
- package/dist/commands/dev.d.ts +2 -6
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +1 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/diagnose.d.ts +2 -22
- package/dist/commands/diagnose.d.ts.map +1 -1
- package/dist/commands/diagnose.js +1 -1
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/doctor.d.ts +10 -35
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +12 -4
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/domains.d.ts +5 -27
- package/dist/commands/domains.d.ts.map +1 -1
- package/dist/commands/domains.js +1 -1
- package/dist/commands/domains.js.map +1 -1
- package/dist/commands/env-scan.js +1 -1
- package/dist/commands/env-scan.js.map +1 -1
- package/dist/commands/env.d.ts +4 -20
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +1 -1
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/export.d.ts +6 -15
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +1 -1
- package/dist/commands/forgejo.d.ts +45 -0
- package/dist/commands/forgejo.d.ts.map +1 -0
- package/dist/commands/forgejo.js +125 -0
- package/dist/commands/forgejo.js.map +1 -0
- package/dist/commands/generate.d.ts +2 -6
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +1 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/github.d.ts +4 -15
- package/dist/commands/github.d.ts.map +1 -1
- package/dist/commands/github.js +17 -1
- package/dist/commands/github.js.map +1 -1
- package/dist/commands/import-project.d.ts +13 -9
- package/dist/commands/import-project.d.ts.map +1 -1
- package/dist/commands/import-project.js +73 -22
- package/dist/commands/import-project.js.map +1 -1
- package/dist/commands/init.d.ts +26 -11
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +103 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/insights.d.ts +2 -6
- package/dist/commands/insights.d.ts.map +1 -1
- package/dist/commands/insights.js +1 -1
- package/dist/commands/insights.js.map +1 -1
- package/dist/commands/login.d.ts +2 -8
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +22 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logs.d.ts +25 -10
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +65 -5
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/mcp.d.ts +2 -2
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +1 -1
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/migrate-supabase-map.d.ts +171 -0
- package/dist/commands/migrate-supabase-map.d.ts.map +1 -0
- package/dist/commands/migrate-supabase-map.js +452 -0
- package/dist/commands/migrate-supabase-map.js.map +1 -0
- package/dist/commands/migrate-supabase-schema.d.ts +67 -0
- package/dist/commands/migrate-supabase-schema.d.ts.map +1 -0
- package/dist/commands/migrate-supabase-schema.js +321 -0
- package/dist/commands/migrate-supabase-schema.js.map +1 -0
- package/dist/commands/migrate-supabase-scripts.d.ts +64 -0
- package/dist/commands/migrate-supabase-scripts.d.ts.map +1 -0
- package/dist/commands/migrate-supabase-scripts.js +564 -0
- package/dist/commands/migrate-supabase-scripts.js.map +1 -0
- package/dist/commands/migrate-supabase-sdk.d.ts +133 -0
- package/dist/commands/migrate-supabase-sdk.d.ts.map +1 -0
- package/dist/commands/migrate-supabase-sdk.js +1119 -0
- package/dist/commands/migrate-supabase-sdk.js.map +1 -0
- package/dist/commands/migrate-supabase-walker.d.ts +93 -0
- package/dist/commands/migrate-supabase-walker.d.ts.map +1 -0
- package/dist/commands/migrate-supabase-walker.js +413 -0
- package/dist/commands/migrate-supabase-walker.js.map +1 -0
- package/dist/commands/migrate-supabase.d.ts +81 -0
- package/dist/commands/migrate-supabase.d.ts.map +1 -0
- package/dist/commands/migrate-supabase.js +579 -0
- package/dist/commands/migrate-supabase.js.map +1 -0
- package/dist/commands/open.d.ts +2 -6
- package/dist/commands/open.d.ts.map +1 -1
- package/dist/commands/open.js +1 -1
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/publish-api-error.d.ts +46 -0
- package/dist/commands/publish-api-error.d.ts.map +1 -0
- package/dist/commands/publish-api-error.js +358 -0
- package/dist/commands/publish-api-error.js.map +1 -0
- package/dist/commands/publish-failure.d.ts.map +1 -1
- package/dist/commands/publish-failure.js +11 -2
- package/dist/commands/publish-failure.js.map +1 -1
- package/dist/commands/publish.d.ts +40 -17
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +115 -8
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/push.d.ts +2 -12
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +2 -2
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/redeploy.d.ts +2 -8
- package/dist/commands/redeploy.d.ts.map +1 -1
- package/dist/commands/redeploy.js +2 -2
- package/dist/commands/redeploy.js.map +1 -1
- package/dist/commands/rename.d.ts +2 -8
- package/dist/commands/rename.d.ts.map +1 -1
- package/dist/commands/rename.js +1 -1
- package/dist/commands/rename.js.map +1 -1
- package/dist/commands/reproduce.d.ts +2 -8
- package/dist/commands/reproduce.d.ts.map +1 -1
- package/dist/commands/reproduce.js +1 -1
- package/dist/commands/reproduce.js.map +1 -1
- package/dist/commands/reset-superuser.d.ts +2 -16
- package/dist/commands/reset-superuser.d.ts.map +1 -1
- package/dist/commands/reset-superuser.js +1 -1
- package/dist/commands/reset-superuser.js.map +1 -1
- package/dist/commands/restore.d.ts +7 -22
- package/dist/commands/restore.d.ts.map +1 -1
- package/dist/commands/restore.js +1 -1
- package/dist/commands/restore.js.map +1 -1
- package/dist/commands/resume.d.ts +2 -6
- package/dist/commands/resume.d.ts.map +1 -1
- package/dist/commands/resume.js +1 -1
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/rollback.d.ts +2 -8
- package/dist/commands/rollback.d.ts.map +1 -1
- package/dist/commands/rollback.js +1 -1
- package/dist/commands/rollback.js.map +1 -1
- package/dist/commands/sharing.d.ts +48 -0
- package/dist/commands/sharing.d.ts.map +1 -0
- package/dist/commands/sharing.js +85 -0
- package/dist/commands/sharing.js.map +1 -0
- package/dist/commands/status.d.ts +2 -6
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/transfers.d.ts +34 -0
- package/dist/commands/transfers.d.ts.map +1 -0
- package/dist/commands/transfers.js +62 -0
- package/dist/commands/transfers.js.map +1 -0
- package/dist/commands/unsuspend.d.ts +2 -6
- package/dist/commands/unsuspend.d.ts.map +1 -1
- package/dist/commands/unsuspend.js +1 -1
- package/dist/commands/unsuspend.js.map +1 -1
- package/dist/commands/versions.d.ts +2 -6
- package/dist/commands/versions.d.ts.map +1 -1
- package/dist/commands/versions.js +1 -1
- package/dist/commands/versions.js.map +1 -1
- package/dist/commands/wait-deploy.d.ts +2 -12
- package/dist/commands/wait-deploy.d.ts.map +1 -1
- package/dist/commands/wait-deploy.js +1 -1
- package/dist/commands/wait-deploy.js.map +1 -1
- package/dist/context.d.ts +15 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/detect.d.ts +11 -0
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +31 -8
- package/dist/detect.js.map +1 -1
- package/dist/env-scan-source.d.ts +8 -1
- package/dist/env-scan-source.d.ts.map +1 -1
- package/dist/env-scan-source.js +100 -24
- package/dist/env-scan-source.js.map +1 -1
- package/dist/error-classifier.d.ts +18 -1
- package/dist/error-classifier.d.ts.map +1 -1
- package/dist/error-classifier.js +171 -9
- package/dist/error-classifier.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +64 -49
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -42
- package/dist/index.js.map +1 -1
- package/dist/plans.d.ts +86 -8
- package/dist/plans.d.ts.map +1 -1
- package/dist/plans.js +113 -24
- package/dist/plans.js.map +1 -1
- package/dist/recovery.d.ts +73 -3
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +36 -0
- package/dist/recovery.js.map +1 -1
- package/dist/static-docker.d.ts +77 -0
- package/dist/static-docker.d.ts.map +1 -0
- package/dist/static-docker.js +105 -0
- package/dist/static-docker.js.map +1 -0
- package/dist/tarball.js +1 -1
- package/dist/tarball.js.map +1 -1
- package/dist/templates/ai-files/cursor-percher-mdc.d.ts.map +1 -1
- package/dist/templates/ai-files/cursor-percher-mdc.js +12 -9
- package/dist/templates/ai-files/cursor-percher-mdc.js.map +1 -1
- package/dist/templates.js +11 -11
- package/dist/templates.js.map +1 -1
- package/dist/watcher.js +1 -1
- package/dist/watcher.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate the data-import scripts for a Phase B migration preview.
|
|
3
|
+
* Pure — no I/O. Deterministic — identical input gives byte-identical
|
|
4
|
+
* scripts.
|
|
5
|
+
*/
|
|
6
|
+
export function generateDataImportScripts(preview) {
|
|
7
|
+
const { tableOrder, cyclicTables } = topologicalSort(preview.collections);
|
|
8
|
+
const pbMigrate = renderPbMigrate({
|
|
9
|
+
collections: preview.collections,
|
|
10
|
+
tableOrder,
|
|
11
|
+
cyclicTables,
|
|
12
|
+
sourceProjectRef: preview.sourceProjectRef,
|
|
13
|
+
generatedAt: preview.generatedAt,
|
|
14
|
+
});
|
|
15
|
+
const pbMigrateStorage = preview.migrationNotes.storageMigration !== null
|
|
16
|
+
? renderPbMigrateStorage({
|
|
17
|
+
buckets: preview.migrationNotes.storageMigration.buckets,
|
|
18
|
+
sourceProjectRef: preview.sourceProjectRef,
|
|
19
|
+
generatedAt: preview.generatedAt,
|
|
20
|
+
})
|
|
21
|
+
: null;
|
|
22
|
+
return { pbMigrate, pbMigrateStorage, cyclicTables, tableOrder };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Kahn's algorithm over the FK graph. Edges point from dependent
|
|
26
|
+
* collection → target collection (i.e. `posts.author_id → users`
|
|
27
|
+
* adds the edge posts → users, so users must migrate before posts).
|
|
28
|
+
*
|
|
29
|
+
* Stable order: collections with the same in-degree are processed
|
|
30
|
+
* in input order, so the generated script's line layout matches the
|
|
31
|
+
* preview's collection layout when there are no FKs to disambiguate.
|
|
32
|
+
*
|
|
33
|
+
* Cycle handling: any collections remaining after Kahn's main loop
|
|
34
|
+
* are part of a cycle. They get appended to `tableOrder` in input
|
|
35
|
+
* order (so the script still tries to migrate them) AND reported in
|
|
36
|
+
* `cyclicTables`. The migration is best-effort for those — PB will
|
|
37
|
+
* reject the FK violation on the dependent insert; the user must
|
|
38
|
+
* break the cycle manually by either deferring one FK or splitting
|
|
39
|
+
* the migration into two passes.
|
|
40
|
+
*/
|
|
41
|
+
function topologicalSort(collections) {
|
|
42
|
+
// Map by collection name for O(1) FK target lookup.
|
|
43
|
+
const byName = new Map();
|
|
44
|
+
for (const c of collections)
|
|
45
|
+
byName.set(c.name, c);
|
|
46
|
+
// dependsOn[X] = set of collection names X has FKs into.
|
|
47
|
+
// dependents[X] = set of collection names that have FKs into X.
|
|
48
|
+
const dependsOn = new Map();
|
|
49
|
+
const dependents = new Map();
|
|
50
|
+
for (const c of collections) {
|
|
51
|
+
dependsOn.set(c.name, new Set());
|
|
52
|
+
dependents.set(c.name, new Set());
|
|
53
|
+
}
|
|
54
|
+
for (const c of collections) {
|
|
55
|
+
for (const field of c.schema) {
|
|
56
|
+
if (field.type !== "relation")
|
|
57
|
+
continue;
|
|
58
|
+
const target = field.options.collectionName;
|
|
59
|
+
// Self-references are valid PB but they'd create a 1-node
|
|
60
|
+
// cycle in Kahn's algorithm. Skip the self-edge — PB handles
|
|
61
|
+
// self-refs on insert as long as the row exists OR the field
|
|
62
|
+
// is nullable; we trust the schema and don't enforce ordering
|
|
63
|
+
// for self-FKs.
|
|
64
|
+
if (target === c.name)
|
|
65
|
+
continue;
|
|
66
|
+
// External FK targets (the FK pointed at a table that isn't in
|
|
67
|
+
// our user-schema set, e.g. PB built-in `users` from
|
|
68
|
+
// auth.users-reference). They have no node in our graph; skip
|
|
69
|
+
// the edge so Kahn doesn't treat them as a missing dep.
|
|
70
|
+
if (!byName.has(target))
|
|
71
|
+
continue;
|
|
72
|
+
dependsOn.get(c.name).add(target);
|
|
73
|
+
dependents.get(target).add(c.name);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Stable input order is critical — tests pin layout against it.
|
|
77
|
+
const inputOrder = collections.map((c) => c.name);
|
|
78
|
+
const inDegree = new Map();
|
|
79
|
+
for (const name of inputOrder)
|
|
80
|
+
inDegree.set(name, dependsOn.get(name).size);
|
|
81
|
+
const ready = [];
|
|
82
|
+
for (const name of inputOrder) {
|
|
83
|
+
if (inDegree.get(name) === 0)
|
|
84
|
+
ready.push(name);
|
|
85
|
+
}
|
|
86
|
+
const out = [];
|
|
87
|
+
while (ready.length > 0) {
|
|
88
|
+
// shift for FIFO — preserves input order among ready set.
|
|
89
|
+
const name = ready.shift();
|
|
90
|
+
out.push(name);
|
|
91
|
+
for (const dependent of dependents.get(name)) {
|
|
92
|
+
const next = (inDegree.get(dependent) ?? 0) - 1;
|
|
93
|
+
inDegree.set(dependent, next);
|
|
94
|
+
if (next === 0)
|
|
95
|
+
ready.push(dependent);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Anything left has an in-degree > 0 → part of a cycle.
|
|
99
|
+
const cyclicTables = [];
|
|
100
|
+
for (const name of inputOrder) {
|
|
101
|
+
if (!out.includes(name)) {
|
|
102
|
+
cyclicTables.push(name);
|
|
103
|
+
out.push(name);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return { tableOrder: out, cyclicTables };
|
|
107
|
+
}
|
|
108
|
+
function renderPbMigrate(input) {
|
|
109
|
+
const lines = [];
|
|
110
|
+
lines.push("#!/usr/bin/env bun");
|
|
111
|
+
lines.push("/**");
|
|
112
|
+
lines.push(" * pb_migrate.js — generated by `bunx percher migrate-from-supabase`.");
|
|
113
|
+
lines.push(` * Source project: ${input.sourceProjectRef}`);
|
|
114
|
+
lines.push(` * Generated at: ${input.generatedAt}`);
|
|
115
|
+
lines.push(" *");
|
|
116
|
+
lines.push(" * Copies rows from a Supabase project into a PocketBase instance,");
|
|
117
|
+
lines.push(" * batch by batch, in foreign-key-dependency order.");
|
|
118
|
+
lines.push(" *");
|
|
119
|
+
lines.push(" * Required env vars:");
|
|
120
|
+
lines.push(" * POCKETBASE_URL");
|
|
121
|
+
lines.push(" * POCKETBASE_ADMIN_EMAIL");
|
|
122
|
+
lines.push(" * POCKETBASE_ADMIN_PASSWORD");
|
|
123
|
+
lines.push(" * SUPABASE_URL");
|
|
124
|
+
lines.push(" * SUPABASE_SERVICE_ROLE_KEY (use service-role for full read — never bake it into source)");
|
|
125
|
+
lines.push(" * Optional:");
|
|
126
|
+
lines.push(" * SKIP_EXISTING=1 skip rows that already exist in PB instead of failing");
|
|
127
|
+
lines.push(" * BATCH_SIZE=500 rows per Supabase page");
|
|
128
|
+
lines.push(" *");
|
|
129
|
+
lines.push(" * Run with: bun pb_migrate.js");
|
|
130
|
+
lines.push(" *");
|
|
131
|
+
lines.push(" * NOTE: install the runtime deps first:");
|
|
132
|
+
lines.push(" * bun add pocketbase @supabase/supabase-js");
|
|
133
|
+
lines.push(" */");
|
|
134
|
+
lines.push("");
|
|
135
|
+
lines.push('import PocketBase from "pocketbase";');
|
|
136
|
+
lines.push('import { createClient } from "@supabase/supabase-js";');
|
|
137
|
+
lines.push('import { createHash } from "node:crypto";');
|
|
138
|
+
lines.push("");
|
|
139
|
+
lines.push("const REQUIRED_ENV = [");
|
|
140
|
+
lines.push(' "POCKETBASE_URL",');
|
|
141
|
+
lines.push(' "POCKETBASE_ADMIN_EMAIL",');
|
|
142
|
+
lines.push(' "POCKETBASE_ADMIN_PASSWORD",');
|
|
143
|
+
lines.push(' "SUPABASE_URL",');
|
|
144
|
+
lines.push(' "SUPABASE_SERVICE_ROLE_KEY",');
|
|
145
|
+
lines.push("];");
|
|
146
|
+
lines.push("");
|
|
147
|
+
lines.push("const missing = REQUIRED_ENV.filter((k) => !process.env[k]);");
|
|
148
|
+
lines.push("if (missing.length > 0) {");
|
|
149
|
+
lines.push(' console.error(`Missing required env vars: ${missing.join(", ")}`);');
|
|
150
|
+
lines.push(" process.exit(1);");
|
|
151
|
+
lines.push("}");
|
|
152
|
+
lines.push("");
|
|
153
|
+
lines.push('const SKIP_EXISTING = process.env.SKIP_EXISTING === "1";');
|
|
154
|
+
lines.push("const BATCH_SIZE = Number(process.env.BATCH_SIZE ?? 500);");
|
|
155
|
+
lines.push("if (!Number.isFinite(BATCH_SIZE) || BATCH_SIZE < 1 || BATCH_SIZE > 1000) {");
|
|
156
|
+
lines.push(" console.error(`BATCH_SIZE must be 1..1000 (got ${process.env.BATCH_SIZE})`);");
|
|
157
|
+
lines.push(" process.exit(1);");
|
|
158
|
+
lines.push("}");
|
|
159
|
+
lines.push("");
|
|
160
|
+
lines.push("const pb = new PocketBase(process.env.POCKETBASE_URL);");
|
|
161
|
+
lines.push("await pb.admins.authWithPassword(");
|
|
162
|
+
lines.push(" process.env.POCKETBASE_ADMIN_EMAIL,");
|
|
163
|
+
lines.push(" process.env.POCKETBASE_ADMIN_PASSWORD,");
|
|
164
|
+
lines.push(");");
|
|
165
|
+
lines.push("");
|
|
166
|
+
lines.push("const supabase = createClient(");
|
|
167
|
+
lines.push(" process.env.SUPABASE_URL,");
|
|
168
|
+
lines.push(" process.env.SUPABASE_SERVICE_ROLE_KEY,");
|
|
169
|
+
lines.push(");");
|
|
170
|
+
lines.push("");
|
|
171
|
+
lines.push("/** Per-collection map from source uuid → derived PB record id.");
|
|
172
|
+
lines.push(" * Populated as each table is migrated (in FK-dependency order)");
|
|
173
|
+
lines.push(" * so that downstream tables' FK columns can be rewritten from");
|
|
174
|
+
lines.push(" * raw Supabase UUIDs to the new PB ids before insert. Without");
|
|
175
|
+
lines.push(" * this remap, relations would point at PB ids that don't exist.");
|
|
176
|
+
lines.push(" * Codex P1 review 2026-05-17 (round 2).");
|
|
177
|
+
lines.push(" */");
|
|
178
|
+
lines.push("const idMaps = new Map();");
|
|
179
|
+
lines.push("function rememberId(collection, sourceUuid, newPbId) {");
|
|
180
|
+
lines.push(" if (!idMaps.has(collection)) idMaps.set(collection, new Map());");
|
|
181
|
+
lines.push(" idMaps.get(collection).set(String(sourceUuid), newPbId);");
|
|
182
|
+
lines.push("}");
|
|
183
|
+
lines.push("function lookupId(collection, sourceUuid) {");
|
|
184
|
+
lines.push(" const m = idMaps.get(collection);");
|
|
185
|
+
lines.push(" return m ? m.get(String(sourceUuid)) : undefined;");
|
|
186
|
+
lines.push("}");
|
|
187
|
+
lines.push("");
|
|
188
|
+
lines.push("/** Derive a stable, PB-compatible 15-char record id from a source");
|
|
189
|
+
lines.push(" * uuid (or any string). sha256 → hex → first 15 chars. The PB");
|
|
190
|
+
lines.push(" * docs spec record ids as a 15-char string; collisions are");
|
|
191
|
+
lines.push(" * astronomically unlikely (16^15 ≈ 10^18) for any realistic");
|
|
192
|
+
lines.push(" * dataset. Stable across re-runs so SKIP_EXISTING works. */");
|
|
193
|
+
lines.push("function pbIdFromSource(sourceValue) {");
|
|
194
|
+
lines.push(' return createHash("sha256").update(String(sourceValue)).digest("hex").slice(0, 15);');
|
|
195
|
+
lines.push("}");
|
|
196
|
+
lines.push("");
|
|
197
|
+
lines.push("/** Generic per-table migrator. Supabase paginates with .range();");
|
|
198
|
+
lines.push(" * we batch by BATCH_SIZE rows. Errors short-circuit unless");
|
|
199
|
+
lines.push(" * SKIP_EXISTING is set AND the error looks like a uniqueness");
|
|
200
|
+
lines.push(" * violation.");
|
|
201
|
+
lines.push(" *");
|
|
202
|
+
lines.push(' * `supabaseSchema` defaults to "public" — non-public sources');
|
|
203
|
+
lines.push(" * (e.g. `billing.invoices`) route through `supabase.schema(s)`");
|
|
204
|
+
lines.push(" * so the query hits the right Postgres schema. Requires");
|
|
205
|
+
lines.push(" * @supabase/supabase-js >= 2.21.0 (when .schema() shipped).");
|
|
206
|
+
lines.push(" *");
|
|
207
|
+
lines.push(" * ID remap (Codex P1 round 2): for tables whose source PK is a");
|
|
208
|
+
lines.push(" * single uuid, `sourcePrimaryKey` carries the source column");
|
|
209
|
+
lines.push(" * name. We derive a deterministic PB id from `row[sourcePrimaryKey]`,");
|
|
210
|
+
lines.push(" * store the mapping, and pass `{ id: <derived>, ...rest }` to");
|
|
211
|
+
lines.push(" * pb.create. The `transform` callback handles per-collection");
|
|
212
|
+
lines.push(" * column stripping AND FK rewrites (looking up upstream maps).");
|
|
213
|
+
lines.push(" */");
|
|
214
|
+
lines.push("async function migrateTable(");
|
|
215
|
+
lines.push(" supabaseSchema,");
|
|
216
|
+
lines.push(" supabaseTable,");
|
|
217
|
+
lines.push(" pbCollection,");
|
|
218
|
+
lines.push(" sourcePrimaryKey, // string | null");
|
|
219
|
+
lines.push(" transform = (r) => r,");
|
|
220
|
+
lines.push(") {");
|
|
221
|
+
lines.push(' const tableLabel = supabaseSchema === "public" ? supabaseTable : `${supabaseSchema}.${supabaseTable}`;');
|
|
222
|
+
lines.push(' const sbSource = supabaseSchema === "public"');
|
|
223
|
+
lines.push(" ? supabase");
|
|
224
|
+
lines.push(" : supabase.schema(supabaseSchema);");
|
|
225
|
+
lines.push(" let from = 0;");
|
|
226
|
+
lines.push(" let total = 0;");
|
|
227
|
+
lines.push(" while (true) {");
|
|
228
|
+
lines.push(" const { data, error } = await sbSource");
|
|
229
|
+
lines.push(" .from(supabaseTable)");
|
|
230
|
+
lines.push(' .select("*")');
|
|
231
|
+
lines.push(" .range(from, from + BATCH_SIZE - 1);");
|
|
232
|
+
lines.push(" if (error) {");
|
|
233
|
+
lines.push(" throw new Error(`[${tableLabel}] Supabase select failed: ${error.message}`);");
|
|
234
|
+
lines.push(" }");
|
|
235
|
+
lines.push(" if (!data || data.length === 0) break;");
|
|
236
|
+
lines.push(" for (const row of data) {");
|
|
237
|
+
lines.push(" let payload = transform(row);");
|
|
238
|
+
lines.push(" if (sourcePrimaryKey) {");
|
|
239
|
+
lines.push(" const sourceId = row[sourcePrimaryKey];");
|
|
240
|
+
lines.push(" if (sourceId === undefined || sourceId === null) {");
|
|
241
|
+
lines.push(" throw new Error(");
|
|
242
|
+
lines.push(" `[${tableLabel}] row has no ${sourcePrimaryKey} value — expected source PK to be present`,");
|
|
243
|
+
lines.push(" );");
|
|
244
|
+
lines.push(" }");
|
|
245
|
+
lines.push(" const pbId = pbIdFromSource(sourceId);");
|
|
246
|
+
lines.push(" rememberId(pbCollection, sourceId, pbId);");
|
|
247
|
+
lines.push(" payload = { id: pbId, ...payload };");
|
|
248
|
+
lines.push(" }");
|
|
249
|
+
lines.push(" try {");
|
|
250
|
+
lines.push(" await pb.collection(pbCollection).create(payload);");
|
|
251
|
+
lines.push(" total += 1;");
|
|
252
|
+
lines.push(" } catch (err) {");
|
|
253
|
+
lines.push(' const status = err && typeof err === "object" ? err.status : undefined;');
|
|
254
|
+
lines.push(" if (SKIP_EXISTING && (status === 400 || status === 409)) {");
|
|
255
|
+
lines.push(" continue;");
|
|
256
|
+
lines.push(" }");
|
|
257
|
+
lines.push(" throw new Error(");
|
|
258
|
+
lines.push(' `[${tableLabel} → ${pbCollection}] create failed (source row id=${row?.[sourcePrimaryKey ?? "id"] ?? "?"}): ${err && err.message ? err.message : String(err)}`,');
|
|
259
|
+
lines.push(" );");
|
|
260
|
+
lines.push(" }");
|
|
261
|
+
lines.push(" }");
|
|
262
|
+
lines.push(" from += BATCH_SIZE;");
|
|
263
|
+
lines.push(" if (data.length < BATCH_SIZE) break;");
|
|
264
|
+
lines.push(" }");
|
|
265
|
+
lines.push(" console.log(`[${tableLabel} → ${pbCollection}] DONE — ${total} rows`);");
|
|
266
|
+
lines.push("}");
|
|
267
|
+
lines.push("");
|
|
268
|
+
if (input.cyclicTables.length > 0) {
|
|
269
|
+
lines.push("// ⚠️ FK CYCLE DETECTED");
|
|
270
|
+
lines.push("// The following collections form a foreign-key cycle. Postgres allows");
|
|
271
|
+
lines.push("// deferred FKs at commit time; PocketBase doesn't. The script still");
|
|
272
|
+
lines.push("// attempts them last, but PB will reject the FK-dependent inserts");
|
|
273
|
+
lines.push("// until the cycle is broken. Options:");
|
|
274
|
+
lines.push("// 1. Make one of the FKs nullable in PB and patch it in a second");
|
|
275
|
+
lines.push("// pass after the initial migrate.");
|
|
276
|
+
lines.push("// 2. Split the migration manually: import rows without the FK,");
|
|
277
|
+
lines.push("// then update them with the FK once the targets exist.");
|
|
278
|
+
for (const name of input.cyclicTables) {
|
|
279
|
+
lines.push(`// - ${name}`);
|
|
280
|
+
}
|
|
281
|
+
lines.push("");
|
|
282
|
+
}
|
|
283
|
+
if (input.collections.length === 0) {
|
|
284
|
+
lines.push("// No collections to migrate — the source project had no user-schema tables.");
|
|
285
|
+
lines.push('console.log("Nothing to migrate.");');
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
lines.push("// Generated migrate calls — in FK-dependency order.");
|
|
289
|
+
const byName = new Map(input.collections.map((c) => [c.name, c]));
|
|
290
|
+
for (const name of input.tableOrder) {
|
|
291
|
+
const collection = byName.get(name);
|
|
292
|
+
if (!collection)
|
|
293
|
+
continue;
|
|
294
|
+
const { schema: supabaseSchema, table: supabaseTable } = splitSourceTable(collection.sourceTable);
|
|
295
|
+
const transformBody = renderRowTransform(collection);
|
|
296
|
+
lines.push(`await migrateTable(${JSON.stringify(supabaseSchema)}, ${JSON.stringify(supabaseTable)}, ${JSON.stringify(collection.name)}, ${JSON.stringify(collection.sourcePrimaryKey)}, ${transformBody});`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
lines.push("");
|
|
300
|
+
lines.push('console.log("All collections processed.");');
|
|
301
|
+
lines.push("");
|
|
302
|
+
return lines.join("\n");
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Per-row transform for the generated migrate call. Always emits a
|
|
306
|
+
* function (no `null` shortcut) because:
|
|
307
|
+
*
|
|
308
|
+
* - The migrateTable runtime needs a callable; passing `null`
|
|
309
|
+
* would require a guard at the call site.
|
|
310
|
+
* - Even when nothing is dropped AND there are no relations, we
|
|
311
|
+
* return an identity arrow so the call signature stays stable.
|
|
312
|
+
*
|
|
313
|
+
* Two concerns combine inside the transform:
|
|
314
|
+
*
|
|
315
|
+
* 1. Strip every column in `droppedSourceColumns` so PB doesn't
|
|
316
|
+
* reject the create() with "unknown field" errors. This
|
|
317
|
+
* includes uuid PKs (PB's built-in id covers them — the
|
|
318
|
+
* remap happens via `sourcePrimaryKey` in migrateTable) and
|
|
319
|
+
* `created_at` / `updated_at` (PB built-ins).
|
|
320
|
+
*
|
|
321
|
+
* 2. Rewrite every relation field's value from the source UUID
|
|
322
|
+
* to the derived PB id via `lookupId(targetCollection,
|
|
323
|
+
* sourceUuid)`. This is the FK-integrity piece — without it,
|
|
324
|
+
* relations point at raw Supabase UUIDs that PB doesn't know.
|
|
325
|
+
*
|
|
326
|
+
* Edge cases:
|
|
327
|
+
*
|
|
328
|
+
* - Auth.users-flagged relations (FK pointed at Supabase's
|
|
329
|
+
* `auth.users`, mapped to PB's built-in `users` collection
|
|
330
|
+
* which we DON'T import here): we have no id-map for them, so
|
|
331
|
+
* the rewrite falls through with the original value and the
|
|
332
|
+
* transform logs a one-time warning per row that this field
|
|
333
|
+
* needs manual remapping. The import still succeeds — but the
|
|
334
|
+
* `users` relation will point at a non-existent PB id until
|
|
335
|
+
* the user wires auth migration themselves.
|
|
336
|
+
*
|
|
337
|
+
* - Nullable relation columns: a NULL value passes through
|
|
338
|
+
* unchanged (`lookupId` of `null` is undefined; we keep null).
|
|
339
|
+
*/
|
|
340
|
+
function renderRowTransform(collection) {
|
|
341
|
+
const stripKeys = collection.droppedSourceColumns;
|
|
342
|
+
const relations = collection.schema.filter((f) => f.type === "relation");
|
|
343
|
+
// Fast path: nothing to do.
|
|
344
|
+
if (stripKeys.length === 0 && relations.length === 0) {
|
|
345
|
+
return "(row) => row";
|
|
346
|
+
}
|
|
347
|
+
// Build the transform body as a series of small steps for
|
|
348
|
+
// readability in the generated script.
|
|
349
|
+
//
|
|
350
|
+
// Why `{ ...row }` + delete instead of destructure:
|
|
351
|
+
// earlier versions used `const { id, created_at, ...rest } = row;`
|
|
352
|
+
// which is more compact but breaks for Postgres quoted-identifier
|
|
353
|
+
// column names that aren't valid JS identifiers — e.g. a PK named
|
|
354
|
+
// `"order-id"` or `"123_id"` would emit
|
|
355
|
+
// `const { order-id, ...rest } = row;` (syntax error). After the
|
|
356
|
+
// round-3 PK-universalisation, ANY single-column PK column name
|
|
357
|
+
// reaches this code path, so the regression surface widened.
|
|
358
|
+
// Computed property destructure (`{ ["order-id"]: _d0, ...rest }`)
|
|
359
|
+
// also works but `delete rest[key]` reads cleaner in the generated
|
|
360
|
+
// script. Codex P2 finding 2026-05-17 (round 4).
|
|
361
|
+
const parts = [];
|
|
362
|
+
parts.push("(row) => {");
|
|
363
|
+
parts.push(" const rest = { ...row };");
|
|
364
|
+
for (const key of stripKeys) {
|
|
365
|
+
parts.push(` delete rest[${JSON.stringify(key)}];`);
|
|
366
|
+
}
|
|
367
|
+
for (const rel of relations) {
|
|
368
|
+
const fieldName = rel.name;
|
|
369
|
+
const target = rel.options.collectionName;
|
|
370
|
+
const isAuthUsersRef = rel.source.flag === "auth_users_reference";
|
|
371
|
+
if (isAuthUsersRef) {
|
|
372
|
+
// PB built-in `users` collection isn't part of this import,
|
|
373
|
+
// so there's no id-map. Keeping the raw Supabase UUID would
|
|
374
|
+
// make PB reject the row (PB validates relation fields
|
|
375
|
+
// against existing records in the target collection). NULL
|
|
376
|
+
// the field instead — the PB schema is forced nullable for
|
|
377
|
+
// auth-ref columns specifically to allow this. The user
|
|
378
|
+
// back-fills after wiring auth migration. Codex P1 round 3
|
|
379
|
+
// (2026-05-17).
|
|
380
|
+
parts.push(` if (rest[${JSON.stringify(fieldName)}] != null) {`);
|
|
381
|
+
parts.push(` console.warn(\`[${collection.name}.${fieldName}] auth.users FK cleared (raw source value '\${rest[${JSON.stringify(fieldName)}]}' kept aside) — back-fill after wiring auth migration\`);`);
|
|
382
|
+
parts.push(` rest[${JSON.stringify(fieldName)}] = null;`);
|
|
383
|
+
parts.push(" }");
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
parts.push(` if (rest[${JSON.stringify(fieldName)}] != null) {`);
|
|
387
|
+
parts.push(` const mapped = lookupId(${JSON.stringify(target)}, rest[${JSON.stringify(fieldName)}]);`);
|
|
388
|
+
parts.push(" if (mapped === undefined) {");
|
|
389
|
+
parts.push(` throw new Error(\`[${collection.name}.${fieldName}] no PB id for source value '\${rest[${JSON.stringify(fieldName)}]}' in ${target} map — was ${target} migrated first?\`);`);
|
|
390
|
+
parts.push(" }");
|
|
391
|
+
parts.push(` rest[${JSON.stringify(fieldName)}] = mapped;`);
|
|
392
|
+
parts.push(" }");
|
|
393
|
+
}
|
|
394
|
+
parts.push(" return rest;");
|
|
395
|
+
parts.push("}");
|
|
396
|
+
return parts.join(" ");
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Split the authoritative `<schema>.<table>` source-table identifier
|
|
400
|
+
* into its parts. The Supabase JS SDK's `from(name)` does NOT accept
|
|
401
|
+
* a dotted schema-qualified name — it routes through PostgREST which
|
|
402
|
+
* scopes by Accept-Profile. So we emit `supabase.schema(s).from(t)`
|
|
403
|
+
* for non-public schemas, falling back to bare `supabase.from(t)`
|
|
404
|
+
* for the common public-schema case. Codex P2 finding 2026-05-16:
|
|
405
|
+
* the previous version silently routed `billing.invoices` to
|
|
406
|
+
* `supabase.from("invoices")`, which queries the default (public)
|
|
407
|
+
* schema and either fails or grabs the wrong table.
|
|
408
|
+
*
|
|
409
|
+
* Defensive: when sourceTable has no dot at all, treat it as a
|
|
410
|
+
* public-schema table. Phase A should always produce a dotted form,
|
|
411
|
+
* but a malformed input shouldn't crash the generator.
|
|
412
|
+
*/
|
|
413
|
+
function splitSourceTable(sourceTable) {
|
|
414
|
+
const dotIdx = sourceTable.indexOf(".");
|
|
415
|
+
if (dotIdx === -1)
|
|
416
|
+
return { schema: "public", table: sourceTable };
|
|
417
|
+
return {
|
|
418
|
+
schema: sourceTable.slice(0, dotIdx),
|
|
419
|
+
table: sourceTable.slice(dotIdx + 1),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function renderPbMigrateStorage(input) {
|
|
423
|
+
const lines = [];
|
|
424
|
+
lines.push("#!/usr/bin/env bun");
|
|
425
|
+
lines.push("/**");
|
|
426
|
+
lines.push(" * pb_migrate_storage.js — generated by `bunx percher migrate-from-supabase`.");
|
|
427
|
+
lines.push(` * Source project: ${input.sourceProjectRef}`);
|
|
428
|
+
lines.push(` * Generated at: ${input.generatedAt}`);
|
|
429
|
+
lines.push(" *");
|
|
430
|
+
lines.push(" * Lists + downloads files from each Supabase storage bucket.");
|
|
431
|
+
lines.push(" * The upload side is MANUAL — see the loop body. Supabase's");
|
|
432
|
+
lines.push(" * bucket-shape doesn't map cleanly to PocketBase's");
|
|
433
|
+
lines.push(" * record-attached-file model, so you need to decide how each");
|
|
434
|
+
lines.push(" * bucket lands in PB (typically a collection that wraps each");
|
|
435
|
+
lines.push(" * file as a record with a `file` field).");
|
|
436
|
+
lines.push(" *");
|
|
437
|
+
lines.push(" * Required env vars:");
|
|
438
|
+
lines.push(" * SUPABASE_URL");
|
|
439
|
+
lines.push(" * SUPABASE_SERVICE_ROLE_KEY");
|
|
440
|
+
lines.push(" * POCKETBASE_URL (only needed once you wire the upload step)");
|
|
441
|
+
lines.push(" * POCKETBASE_ADMIN_EMAIL");
|
|
442
|
+
lines.push(" * POCKETBASE_ADMIN_PASSWORD");
|
|
443
|
+
lines.push(" *");
|
|
444
|
+
lines.push(" * Optional:");
|
|
445
|
+
lines.push(" * DOWNLOAD_DIR=./bucket-downloads where to save the downloaded files");
|
|
446
|
+
lines.push(" * LIST_LIMIT=1000 max files per bucket list page");
|
|
447
|
+
lines.push(" *");
|
|
448
|
+
lines.push(" * Run with: bun pb_migrate_storage.js");
|
|
449
|
+
lines.push(" *");
|
|
450
|
+
lines.push(" * NOTE: install the runtime deps first:");
|
|
451
|
+
lines.push(" * bun add pocketbase @supabase/supabase-js");
|
|
452
|
+
lines.push(" */");
|
|
453
|
+
lines.push("");
|
|
454
|
+
lines.push('import { mkdir, writeFile } from "node:fs/promises";');
|
|
455
|
+
lines.push('import { dirname, join } from "node:path";');
|
|
456
|
+
lines.push('import { createClient } from "@supabase/supabase-js";');
|
|
457
|
+
lines.push("");
|
|
458
|
+
lines.push('const REQUIRED_ENV = ["SUPABASE_URL", "SUPABASE_SERVICE_ROLE_KEY"];');
|
|
459
|
+
lines.push("const missing = REQUIRED_ENV.filter((k) => !process.env[k]);");
|
|
460
|
+
lines.push("if (missing.length > 0) {");
|
|
461
|
+
lines.push(' console.error(`Missing required env vars: ${missing.join(", ")}`);');
|
|
462
|
+
lines.push(" process.exit(1);");
|
|
463
|
+
lines.push("}");
|
|
464
|
+
lines.push("");
|
|
465
|
+
lines.push('const DOWNLOAD_DIR = process.env.DOWNLOAD_DIR ?? "./bucket-downloads";');
|
|
466
|
+
lines.push("const LIST_LIMIT = Number(process.env.LIST_LIMIT ?? 1000);");
|
|
467
|
+
lines.push("");
|
|
468
|
+
lines.push("const supabase = createClient(");
|
|
469
|
+
lines.push(" process.env.SUPABASE_URL,");
|
|
470
|
+
lines.push(" process.env.SUPABASE_SERVICE_ROLE_KEY,");
|
|
471
|
+
lines.push(");");
|
|
472
|
+
lines.push("");
|
|
473
|
+
lines.push("const BUCKETS = [");
|
|
474
|
+
for (const name of input.buckets) {
|
|
475
|
+
lines.push(` ${JSON.stringify(name)},`);
|
|
476
|
+
}
|
|
477
|
+
lines.push("];");
|
|
478
|
+
lines.push("");
|
|
479
|
+
lines.push("/** Recursively list every file under a bucket prefix.");
|
|
480
|
+
lines.push(" * Supabase Storage's .list(prefix) returns one page of the");
|
|
481
|
+
lines.push(" * IMMEDIATE children of that prefix — files AND subfolders.");
|
|
482
|
+
lines.push(" * Folders are entries with id=null (the storage metadata row");
|
|
483
|
+
lines.push(" * for a directory placeholder). Without recursion we'd skip");
|
|
484
|
+
lines.push(" * every nested path silently. Codex P2 finding 2026-05-16.");
|
|
485
|
+
lines.push(" *");
|
|
486
|
+
lines.push(" * Also pages within each prefix so buckets with >LIST_LIMIT");
|
|
487
|
+
lines.push(" * immediate entries don't get truncated. */");
|
|
488
|
+
lines.push('async function* walkBucket(bucket, prefix = "") {');
|
|
489
|
+
lines.push(" let offset = 0;");
|
|
490
|
+
lines.push(" while (true) {");
|
|
491
|
+
lines.push(" const { data: entries, error } = await supabase.storage");
|
|
492
|
+
lines.push(" .from(bucket)");
|
|
493
|
+
lines.push(" .list(prefix, {");
|
|
494
|
+
lines.push(" limit: LIST_LIMIT,");
|
|
495
|
+
lines.push(" offset,");
|
|
496
|
+
lines.push(' sortBy: { column: "name", order: "asc" },');
|
|
497
|
+
lines.push(" });");
|
|
498
|
+
lines.push(" if (error) {");
|
|
499
|
+
lines.push(" const where = prefix ? `${bucket}/${prefix}` : bucket;");
|
|
500
|
+
lines.push(" throw new Error(`[${where}] list failed: ${error.message}`);");
|
|
501
|
+
lines.push(" }");
|
|
502
|
+
lines.push(" if (!entries || entries.length === 0) return;");
|
|
503
|
+
lines.push(" for (const entry of entries) {");
|
|
504
|
+
lines.push(" if (!entry.name) continue;");
|
|
505
|
+
lines.push(" const fullPath = prefix ? `${prefix}/${entry.name}` : entry.name;");
|
|
506
|
+
lines.push(" // Folder placeholder: id is null in Supabase Storage's");
|
|
507
|
+
lines.push(" // list response. Recurse — don't try to download.");
|
|
508
|
+
lines.push(" if (entry.id === null || entry.id === undefined) {");
|
|
509
|
+
lines.push(" yield* walkBucket(bucket, fullPath);");
|
|
510
|
+
lines.push(" continue;");
|
|
511
|
+
lines.push(" }");
|
|
512
|
+
lines.push(" yield { name: fullPath, metadata: entry.metadata };");
|
|
513
|
+
lines.push(" }");
|
|
514
|
+
lines.push(" if (entries.length < LIST_LIMIT) return;");
|
|
515
|
+
lines.push(" offset += entries.length;");
|
|
516
|
+
lines.push(" }");
|
|
517
|
+
lines.push("}");
|
|
518
|
+
lines.push("");
|
|
519
|
+
lines.push("for (const bucket of BUCKETS) {");
|
|
520
|
+
lines.push(" console.log(`[${bucket}] walking files (recursive, limit=${LIST_LIMIT}/page)...`);");
|
|
521
|
+
lines.push(" let count = 0;");
|
|
522
|
+
lines.push(" for await (const file of walkBucket(bucket)) {");
|
|
523
|
+
lines.push(" const { data: blob, error: dlErr } = await supabase.storage");
|
|
524
|
+
lines.push(" .from(bucket)");
|
|
525
|
+
lines.push(" .download(file.name);");
|
|
526
|
+
lines.push(" if (dlErr) {");
|
|
527
|
+
lines.push(" throw new Error(`[${bucket}/${file.name}] download failed: ${dlErr.message}`);");
|
|
528
|
+
lines.push(" }");
|
|
529
|
+
lines.push(" const localPath = join(DOWNLOAD_DIR, bucket, file.name);");
|
|
530
|
+
lines.push(" await mkdir(dirname(localPath), { recursive: true });");
|
|
531
|
+
lines.push(" const buf = Buffer.from(await blob.arrayBuffer());");
|
|
532
|
+
lines.push(" await writeFile(localPath, buf);");
|
|
533
|
+
lines.push(" console.log(`[${bucket}/${file.name}] downloaded ${buf.length} bytes → ${localPath}`);");
|
|
534
|
+
lines.push(" count += 1;");
|
|
535
|
+
lines.push(" // TODO (MANUAL): upload to PocketBase. Typical pattern:");
|
|
536
|
+
lines.push(" // const form = new FormData();");
|
|
537
|
+
lines.push(' // form.append("file", new Blob([buf]), file.name);');
|
|
538
|
+
lines.push(' // await pb.collection("<your-file-collection>").create(form);');
|
|
539
|
+
lines.push(" // Pick the target collection + field name based on how you want PB");
|
|
540
|
+
lines.push(" // to model this bucket (one record per file? one record per source row");
|
|
541
|
+
lines.push(" // that references the file? etc.).");
|
|
542
|
+
lines.push(" }");
|
|
543
|
+
lines.push(" console.log(`[${bucket}] DONE — ${count} files`);");
|
|
544
|
+
lines.push("}");
|
|
545
|
+
lines.push("");
|
|
546
|
+
lines.push('console.log("All buckets processed (download phase). Wire the upload step manually.");');
|
|
547
|
+
lines.push("");
|
|
548
|
+
return lines.join("\n");
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Convenience exposed for the Phase B Markdown renderer. Returns the
|
|
552
|
+
* env-var names the generated `pb_migrate.js` requires — kept in
|
|
553
|
+
* sync with `REQUIRED_ENV` inside the script by reading the same
|
|
554
|
+
* source-of-truth array.
|
|
555
|
+
*/
|
|
556
|
+
export const PB_MIGRATE_REQUIRED_ENV = [
|
|
557
|
+
"POCKETBASE_URL",
|
|
558
|
+
"POCKETBASE_ADMIN_EMAIL",
|
|
559
|
+
"POCKETBASE_ADMIN_PASSWORD",
|
|
560
|
+
"SUPABASE_URL",
|
|
561
|
+
"SUPABASE_SERVICE_ROLE_KEY",
|
|
562
|
+
];
|
|
563
|
+
export const PB_MIGRATE_OPTIONAL_ENV = ["SKIP_EXISTING", "BATCH_SIZE"];
|
|
564
|
+
//# sourceMappingURL=migrate-supabase-scripts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-supabase-scripts.js","sourceRoot":"","sources":["../../src/commands/migrate-supabase-scripts.ts"],"names":[],"mappings":"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"}
|