@payload-auth-link/migrate 0.0.0-stage → 0.2.0
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/README.md +49 -2
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +257 -0
- package/dist/cli.js.map +1 -0
- package/dist/doctor/bands.d.ts +16 -0
- package/dist/doctor/bands.d.ts.map +1 -0
- package/dist/doctor/bands.js +49 -0
- package/dist/doctor/bands.js.map +1 -0
- package/dist/doctor/database.d.ts +3 -0
- package/dist/doctor/database.d.ts.map +1 -0
- package/dist/doctor/database.js +110 -0
- package/dist/doctor/database.js.map +1 -0
- package/dist/doctor/plugins.d.ts +12 -0
- package/dist/doctor/plugins.d.ts.map +1 -0
- package/dist/doctor/plugins.js +202 -0
- package/dist/doctor/plugins.js.map +1 -0
- package/dist/doctor/run-doctor.d.ts +48 -0
- package/dist/doctor/run-doctor.d.ts.map +1 -0
- package/dist/doctor/run-doctor.js +236 -0
- package/dist/doctor/run-doctor.js.map +1 -0
- package/dist/doctor/source-scan.d.ts +10 -0
- package/dist/doctor/source-scan.d.ts.map +1 -0
- package/dist/doctor/source-scan.js +142 -0
- package/dist/doctor/source-scan.js.map +1 -0
- package/dist/doctor/types.d.ts +86 -0
- package/dist/doctor/types.d.ts.map +1 -0
- package/dist/doctor/types.js +7 -0
- package/dist/doctor/types.js.map +1 -0
- package/dist/doctor/users.d.ts +10 -0
- package/dist/doctor/users.d.ts.map +1 -0
- package/dist/doctor/users.js +176 -0
- package/dist/doctor/users.js.map +1 -0
- package/dist/importer/apply.d.ts +39 -0
- package/dist/importer/apply.d.ts.map +1 -0
- package/dist/importer/apply.js +588 -0
- package/dist/importer/apply.js.map +1 -0
- package/dist/importer/lifecycle.d.ts +52 -0
- package/dist/importer/lifecycle.d.ts.map +1 -0
- package/dist/importer/lifecycle.js +265 -0
- package/dist/importer/lifecycle.js.map +1 -0
- package/dist/importer/run-import.d.ts +40 -0
- package/dist/importer/run-import.d.ts.map +1 -0
- package/dist/importer/run-import.js +176 -0
- package/dist/importer/run-import.js.map +1 -0
- package/dist/importer/source.d.ts +49 -0
- package/dist/importer/source.d.ts.map +1 -0
- package/dist/importer/source.js +147 -0
- package/dist/importer/source.js.map +1 -0
- package/dist/importer/types.d.ts +69 -0
- package/dist/importer/types.d.ts.map +1 -0
- package/dist/importer/types.js +13 -0
- package/dist/importer/types.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/package.json +70 -4
- package/src/cli.ts +287 -0
- package/src/doctor/bands.ts +66 -0
- package/src/doctor/database.ts +130 -0
- package/src/doctor/plugins.ts +216 -0
- package/src/doctor/run-doctor.ts +278 -0
- package/src/doctor/source-scan.ts +148 -0
- package/src/doctor/types.ts +92 -0
- package/src/doctor/users.ts +207 -0
- package/src/importer/apply.ts +731 -0
- package/src/importer/lifecycle.ts +328 -0
- package/src/importer/run-import.ts +237 -0
- package/src/importer/source.ts +211 -0
- package/src/importer/types.ts +96 -0
- package/src/index.ts +53 -0
package/README.md
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @payload-auth-link/migrate
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The payload-auth → payload-auth-link migration kit
|
|
4
|
+
([issues #49–#59](https://github.com/jellologic/payload-auth-link/issues/59)):
|
|
5
|
+
a read-only **doctor/preflight** today, with the runnable importer and
|
|
6
|
+
exporters riding the same CLI as they land (#50, #58).
|
|
7
|
+
|
|
8
|
+
## Doctor (read-only preflight)
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
bunx @payload-auth-link/migrate doctor --config ./src/payload.config.ts --src ./src
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Reports, without writing anything:
|
|
15
|
+
|
|
16
|
+
- **Version bands** — payload, better-auth, next against the supported
|
|
17
|
+
bands (better-auth 1.6 → 1.7 removed `oidcProvider`, so apps using it
|
|
18
|
+
are flagged).
|
|
19
|
+
- **Better Auth plugins** — supported, auto-declarable, unprobed, or
|
|
20
|
+
removed upstream, derived from the collections payload-auth built and
|
|
21
|
+
the plugin calls in the config source.
|
|
22
|
+
- **The users collection** — field collisions with the plugin's
|
|
23
|
+
injected fields, the existing role field and its values
|
|
24
|
+
(non-canonical values such as `frontPlugin`), and whether Payload's
|
|
25
|
+
local strategy is on.
|
|
26
|
+
- **0.7.0 behaviour changes that will bite** — provider-owned
|
|
27
|
+
documents, suspension on every strategy, access defaults, the
|
|
28
|
+
`req.user` projection.
|
|
29
|
+
- **Source scan** — `payload-auth/*` imports, `payload.betterAuth` /
|
|
30
|
+
`getPayloadAuth` call sites, `$context` internals, and
|
|
31
|
+
`req.user.<field>` reads outside the session projection.
|
|
32
|
+
- **Database** (with `--database-url` or `DATABASE_URL`) — row counts
|
|
33
|
+
per auth table, unverified users (who will not JIT-link), and
|
|
34
|
+
orphans.
|
|
35
|
+
|
|
36
|
+
Output: human-readable text, or `--json` for tools. Exit codes:
|
|
37
|
+
`0` clean, `1` blockers, `2` warnings only, `3` usage errors.
|
|
38
|
+
|
|
39
|
+
Every finding carries a stable machine `code`, so CI (and the
|
|
40
|
+
migration guide) can assert exact blocker lists. The authoritative
|
|
41
|
+
exercise of the doctor lives in the repo's payload-auth fixture
|
|
42
|
+
(`fixtures/payload-auth-app`), where the CI job pins the exact
|
|
43
|
+
blockers it must report — and none it must not.
|
|
44
|
+
|
|
45
|
+
Requires Bun (`bunx`): the doctor loads the app's config module with
|
|
46
|
+
Bun's module loader, which tolerates the directory imports
|
|
47
|
+
payload-auth's dist uses.
|
|
48
|
+
|
|
49
|
+
Peers: `payload` ^3.83.0 || 4.0.0-beta.0 (the import commands boot the
|
|
50
|
+
app's own Payload instance; the doctor itself only reads).
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA6KA,KAAK,OAAO,GAAG;IACb,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC,CAAA;AAED,iBAAe,IAAI,CACjB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,GAAE,OAAwB,EAC7B,GAAG,GAAE,OAAwB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAwFjB;AAiBD,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,CAAA"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* The `@payload-auth-link/migrate` CLI (issues #49–#59). Today: the
|
|
4
|
+
* read-only `doctor` (#52). The importer and exporters ride the same
|
|
5
|
+
* entrypoint as they land (#50, #58).
|
|
6
|
+
*
|
|
7
|
+
* Exit codes: 0 clean, 1 blockers, 2 warnings only, 3 usage errors.
|
|
8
|
+
* Never logs credential material — connection strings print only in
|
|
9
|
+
* the `--json` echo of what the caller passed, and secrets inside them
|
|
10
|
+
* are the caller's own input.
|
|
11
|
+
*/
|
|
12
|
+
import { runDoctor } from './doctor/run-doctor.js';
|
|
13
|
+
import { runFinalize, runFromPayloadAuth, runRollback, runVerify, } from './importer/run-import.js';
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
const positional = [];
|
|
16
|
+
const flags = new Map();
|
|
17
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
18
|
+
const arg = argv[index];
|
|
19
|
+
if (arg === undefined) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (arg.startsWith('--')) {
|
|
23
|
+
const eq = arg.indexOf('=');
|
|
24
|
+
if (eq > 0) {
|
|
25
|
+
flags.set(arg.slice(2, eq), arg.slice(eq + 1));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const name = arg.slice(2);
|
|
29
|
+
const next = argv[index + 1];
|
|
30
|
+
if (next !== undefined && !next.startsWith('--')) {
|
|
31
|
+
flags.set(name, next);
|
|
32
|
+
index += 1;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
flags.set(name, true);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
positional.push(arg);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { command: positional[0] ?? null, flags };
|
|
44
|
+
}
|
|
45
|
+
function usage() {
|
|
46
|
+
return `@payload-auth-link/migrate — the payload-auth → payload-auth-link migration kit
|
|
47
|
+
|
|
48
|
+
Commands:
|
|
49
|
+
doctor --config ./src/payload.config.ts [--src ./src] [--json] [--database-url URL]
|
|
50
|
+
from-payload-auth --config ./src/payload.config.ts [--apply] [--sessions=carry|drop]
|
|
51
|
+
[--manifest ./payload-auth-link-migration.json] [--database-url URL] [--json]
|
|
52
|
+
verify --config ./src/payload.config.ts [--database-url URL] [--json]
|
|
53
|
+
rollback --config ./src/payload.config.ts [--manifest ...]
|
|
54
|
+
finalize [--manifest ...]
|
|
55
|
+
|
|
56
|
+
doctor is read-only: it loads the config, inspects the users
|
|
57
|
+
collection and Better Auth plugins, scans sources for call sites
|
|
58
|
+
that must migrate, and (with a database URL) reports row counts,
|
|
59
|
+
unverified users, and orphans.
|
|
60
|
+
|
|
61
|
+
from-payload-auth is a DRY RUN by default: it prints planned row
|
|
62
|
+
counts per model, collisions, and anything unmappable. --apply
|
|
63
|
+
writes the payload-auth-link collections through the Payload Local
|
|
64
|
+
API, records every created row and field change in the manifest,
|
|
65
|
+
and never modifies the source tables. verify checks both sides;
|
|
66
|
+
rollback undoes exactly the manifest; finalize marks it read-only
|
|
67
|
+
so the legacy tables may be dropped later, in their own migration.
|
|
68
|
+
|
|
69
|
+
Exit codes: 0 clean, 1 blockers/mismatch, 2 warnings only, 3 usage errors.
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
function formatReport(report) {
|
|
73
|
+
const lines = [];
|
|
74
|
+
lines.push('== versions ==');
|
|
75
|
+
for (const finding of report.versions) {
|
|
76
|
+
lines.push(`${finding.status === 'ok' ? ' ok ' : finding.status === 'unknown' ? ' ? ' : ' !! '} ${finding.name}: ${finding.installed ?? 'unresolved'} (band ${finding.band})`);
|
|
77
|
+
}
|
|
78
|
+
lines.push('');
|
|
79
|
+
lines.push('== Better Auth plugins ==');
|
|
80
|
+
if (report.plugins.length === 0) {
|
|
81
|
+
lines.push(' none declared');
|
|
82
|
+
}
|
|
83
|
+
for (const finding of report.plugins) {
|
|
84
|
+
lines.push(` - ${finding.id}: ${finding.status} — ${finding.detail}`);
|
|
85
|
+
}
|
|
86
|
+
lines.push('');
|
|
87
|
+
lines.push('== users collection ==');
|
|
88
|
+
if (report.users === null) {
|
|
89
|
+
lines.push(' not found');
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
lines.push(` slug: ${report.users.slug}`);
|
|
93
|
+
const role = report.users.roleField;
|
|
94
|
+
if (role !== null) {
|
|
95
|
+
lines.push(` role field '${role.name}': ${role.type}${role.hasMany ? ' (hasMany)' : ''} values [${role.values.join(', ')}]${role.nonCanonical.length > 0 ? ` — NON-CANONICAL: ${role.nonCanonical.join(', ')}` : ''}`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
lines.push(' role field: none found');
|
|
99
|
+
}
|
|
100
|
+
lines.push(` local strategy: ${report.users.localStrategy ? 'ON' : 'off'}`);
|
|
101
|
+
if (report.users.collisions.length > 0) {
|
|
102
|
+
lines.push(` collisions with injected fields: ${report.users.collisions.join(', ')}`);
|
|
103
|
+
}
|
|
104
|
+
for (const note of report.users.notes) {
|
|
105
|
+
lines.push(` note: ${note}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
lines.push('');
|
|
109
|
+
lines.push('== source scan ==');
|
|
110
|
+
if (report.source.length === 0) {
|
|
111
|
+
lines.push(' no migration call sites found');
|
|
112
|
+
}
|
|
113
|
+
for (const finding of report.source) {
|
|
114
|
+
lines.push(` - ${finding.kind}: ${finding.files.length} file(s)${finding.fields.length > 0 ? ` (fields: ${finding.fields.join(', ')})` : ''}`);
|
|
115
|
+
for (const file of finding.files.slice(0, 8)) {
|
|
116
|
+
lines.push(` ${file}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
lines.push('');
|
|
120
|
+
lines.push('== database ==');
|
|
121
|
+
if (report.database === null) {
|
|
122
|
+
lines.push(' not inspected');
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
for (const table of report.database.tables) {
|
|
126
|
+
lines.push(` ${table.name}: ${table.rows}`);
|
|
127
|
+
}
|
|
128
|
+
if (report.database.unverifiedUsers !== null) {
|
|
129
|
+
lines.push(` unverified users: ${report.database.unverifiedUsers}`);
|
|
130
|
+
}
|
|
131
|
+
for (const orphan of report.database.orphans) {
|
|
132
|
+
lines.push(` ORPHANS ${orphan.kind}: ${orphan.count}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
lines.push('');
|
|
136
|
+
lines.push('== behaviour changes that will bite (0.7.0) ==');
|
|
137
|
+
for (const change of report.behaviourChanges) {
|
|
138
|
+
lines.push(` * ${change.title}: ${change.detail}`);
|
|
139
|
+
}
|
|
140
|
+
lines.push('');
|
|
141
|
+
lines.push('== blockers ==');
|
|
142
|
+
if (report.blockers.length === 0) {
|
|
143
|
+
lines.push(' none');
|
|
144
|
+
}
|
|
145
|
+
for (const issue of report.blockers) {
|
|
146
|
+
lines.push(` [${issue.code}] ${issue.detail}`);
|
|
147
|
+
}
|
|
148
|
+
lines.push('');
|
|
149
|
+
lines.push('== warnings ==');
|
|
150
|
+
if (report.warnings.length === 0) {
|
|
151
|
+
lines.push(' none');
|
|
152
|
+
}
|
|
153
|
+
for (const issue of report.warnings) {
|
|
154
|
+
lines.push(` [${issue.code}] ${issue.detail}`);
|
|
155
|
+
}
|
|
156
|
+
return lines.join('\n');
|
|
157
|
+
}
|
|
158
|
+
async function main(argv, out = process.stdout, err = process.stderr) {
|
|
159
|
+
const { command, flags } = parseArgs(argv);
|
|
160
|
+
if (command === null || command === 'help' || flags.get('help') === true) {
|
|
161
|
+
out.write(usage());
|
|
162
|
+
return command === null && argv.length === 0 ? 3 : 0;
|
|
163
|
+
}
|
|
164
|
+
const importCommands = ['from-payload-auth', 'verify', 'rollback', 'finalize'];
|
|
165
|
+
if (command !== 'doctor' && !importCommands.includes(command)) {
|
|
166
|
+
err.write(`unknown command '${command}'\n\n${usage()}`);
|
|
167
|
+
return 3;
|
|
168
|
+
}
|
|
169
|
+
if (importCommands.includes(command)) {
|
|
170
|
+
const configFlag = flags.get('config');
|
|
171
|
+
if (typeof configFlag !== 'string' || configFlag === '') {
|
|
172
|
+
err.write(`${command} requires --config <path to payload.config.ts>\n`);
|
|
173
|
+
return 3;
|
|
174
|
+
}
|
|
175
|
+
const databaseUrl = typeof flags.get('database-url') === 'string'
|
|
176
|
+
? flags.get('database-url')
|
|
177
|
+
: (process.env.DATABASE_URL ?? '');
|
|
178
|
+
if ((command === 'from-payload-auth' || command === 'verify') && databaseUrl === '') {
|
|
179
|
+
err.write(`${command} requires --database-url or DATABASE_URL\n`);
|
|
180
|
+
return 3;
|
|
181
|
+
}
|
|
182
|
+
const sessionsFlag = flags.get('sessions');
|
|
183
|
+
const sessions = sessionsFlag === 'drop' ? 'drop' : 'carry';
|
|
184
|
+
const importOptions = {
|
|
185
|
+
configPath: new URL(configFlag, `file://${process.cwd()}/`).pathname,
|
|
186
|
+
databaseUrl,
|
|
187
|
+
apply: flags.get('apply') === true,
|
|
188
|
+
sessions,
|
|
189
|
+
...(typeof flags.get('manifest') === 'string'
|
|
190
|
+
? { manifestPath: flags.get('manifest') }
|
|
191
|
+
: {}),
|
|
192
|
+
...(typeof flags.get('slugs') === 'string'
|
|
193
|
+
? { slugsJson: flags.get('slugs') }
|
|
194
|
+
: {}),
|
|
195
|
+
json: flags.get('json') === true,
|
|
196
|
+
};
|
|
197
|
+
if (command === 'from-payload-auth') {
|
|
198
|
+
const outcome = await runFromPayloadAuth(importOptions);
|
|
199
|
+
if (outcome.plan.unmappable.length > 0) {
|
|
200
|
+
err.write(`ABORT: ${outcome.plan.unmappable.length} unmappable row(s); nothing was silently skipped\n`);
|
|
201
|
+
return 1;
|
|
202
|
+
}
|
|
203
|
+
return 0;
|
|
204
|
+
}
|
|
205
|
+
if (command === 'verify') {
|
|
206
|
+
const result = await runVerify(importOptions);
|
|
207
|
+
return result.ok ? 0 : 1;
|
|
208
|
+
}
|
|
209
|
+
if (command === 'rollback') {
|
|
210
|
+
await runRollback(importOptions);
|
|
211
|
+
return 0;
|
|
212
|
+
}
|
|
213
|
+
await runFinalize(importOptions);
|
|
214
|
+
return 0;
|
|
215
|
+
}
|
|
216
|
+
const configPath = flags.get('config');
|
|
217
|
+
if (typeof configPath !== 'string' || configPath === '') {
|
|
218
|
+
err.write('doctor requires --config <path to payload.config.ts>\n');
|
|
219
|
+
return 3;
|
|
220
|
+
}
|
|
221
|
+
const resolvedConfig = new URL(configPath, `file://${process.cwd()}/`).pathname;
|
|
222
|
+
const srcFlag = flags.get('src');
|
|
223
|
+
const dbFlag = flags.get('database-url');
|
|
224
|
+
const report = await runDoctor({
|
|
225
|
+
configPath: resolvedConfig,
|
|
226
|
+
...(typeof srcFlag === 'string'
|
|
227
|
+
? { srcDir: new URL(srcFlag, `file://${process.cwd()}/`).pathname }
|
|
228
|
+
: {}),
|
|
229
|
+
...(typeof dbFlag === 'string' ? { databaseUrl: dbFlag } : {}),
|
|
230
|
+
});
|
|
231
|
+
if (flags.get('json') === true) {
|
|
232
|
+
out.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
out.write(`${formatReport(report)}\n`);
|
|
236
|
+
}
|
|
237
|
+
if (report.blockers.length > 0) {
|
|
238
|
+
return 1;
|
|
239
|
+
}
|
|
240
|
+
if (report.warnings.length > 0) {
|
|
241
|
+
return 2;
|
|
242
|
+
}
|
|
243
|
+
return 0;
|
|
244
|
+
}
|
|
245
|
+
const invokedDirectly = process.argv[1]?.endsWith('cli.js') === true || process.argv[1]?.endsWith('cli.ts') === true;
|
|
246
|
+
if (invokedDirectly) {
|
|
247
|
+
main(process.argv.slice(2))
|
|
248
|
+
.then((code) => {
|
|
249
|
+
process.exitCode = code;
|
|
250
|
+
})
|
|
251
|
+
.catch((error) => {
|
|
252
|
+
process.stderr.write(`doctor failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
253
|
+
process.exitCode = 1;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
export { main as cliMain };
|
|
257
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type VersionRange } from '@payload-auth-link/core';
|
|
2
|
+
import type { VersionFinding } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The bands the doctor checks against. These mirror the authoritative
|
|
5
|
+
* constants — `supportedPayloadBand` (packages/plugin) and
|
|
6
|
+
* `supportedBetterAuthBand` (packages/provider-better-auth) — and a
|
|
7
|
+
* unit test asserts the copies never drift from them, so the doctor
|
|
8
|
+
* cannot promise a band the runtime would refuse.
|
|
9
|
+
*/
|
|
10
|
+
export declare const payloadBand: readonly VersionRange[];
|
|
11
|
+
export declare const betterAuthBand: readonly VersionRange[];
|
|
12
|
+
/** Next is a peer of the Next adapter; the doctor reports it informationally. */
|
|
13
|
+
export declare const nextBand: readonly VersionRange[];
|
|
14
|
+
/** Band checks for the three upstreams that gate a migration. */
|
|
15
|
+
export declare function checkVersions(fromUrl: string): VersionFinding[];
|
|
16
|
+
//# sourceMappingURL=bands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bands.d.ts","sourceRoot":"","sources":["../../src/doctor/bands.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,YAAY,EAG9C,CAAA;AACD,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAA8C,CAAA;AAChG,iFAAiF;AACjF,eAAO,MAAM,QAAQ,EAAE,SAAS,YAAY,EAAgD,CAAA;AAgC5F,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAW/D"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { describeBand, isSupportedVersion, readInstalledVersion, } from '@payload-auth-link/core';
|
|
2
|
+
/**
|
|
3
|
+
* The bands the doctor checks against. These mirror the authoritative
|
|
4
|
+
* constants — `supportedPayloadBand` (packages/plugin) and
|
|
5
|
+
* `supportedBetterAuthBand` (packages/provider-better-auth) — and a
|
|
6
|
+
* unit test asserts the copies never drift from them, so the doctor
|
|
7
|
+
* cannot promise a band the runtime would refuse.
|
|
8
|
+
*/
|
|
9
|
+
export const payloadBand = [
|
|
10
|
+
{ min: '3.83.0', maxExclusive: '4.0.0' },
|
|
11
|
+
{ exact: '4.0.0-beta.0' },
|
|
12
|
+
];
|
|
13
|
+
export const betterAuthBand = [{ min: '1.7.6', maxExclusive: '1.8.0' }];
|
|
14
|
+
/** Next is a peer of the Next adapter; the doctor reports it informationally. */
|
|
15
|
+
export const nextBand = [{ min: '15.0.0', maxExclusive: '17.0.0' }];
|
|
16
|
+
/**
|
|
17
|
+
* Better Auth minors this doctor knows the payload-auth app must move
|
|
18
|
+
* off: 1.6 removed `oidcProvider` in 1.7 and payload-auth's peer range
|
|
19
|
+
* still admits 1.4+, so an app can sit far below the supported band
|
|
20
|
+
* without anything telling it.
|
|
21
|
+
*/
|
|
22
|
+
function versionFinding(name, band, fromUrl, note) {
|
|
23
|
+
const installed = readInstalledVersion(name, fromUrl);
|
|
24
|
+
const status = installed === null ? 'unknown' : isSupportedVersion(installed, band) ? 'ok' : 'blocker';
|
|
25
|
+
const base = installed === null
|
|
26
|
+
? 'could not read the installed manifest; resolve the version manually'
|
|
27
|
+
: isSupportedVersion(installed, band)
|
|
28
|
+
? `installed ${installed} is inside the supported band`
|
|
29
|
+
: `installed ${installed} is OUTSIDE the supported band; upgrade before migrating`;
|
|
30
|
+
return {
|
|
31
|
+
name,
|
|
32
|
+
installed,
|
|
33
|
+
band: describeBand(band),
|
|
34
|
+
status,
|
|
35
|
+
detail: [base, note?.(installed)].filter((part) => part !== undefined).join(' — '),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Band checks for the three upstreams that gate a migration. */
|
|
39
|
+
export function checkVersions(fromUrl) {
|
|
40
|
+
return [
|
|
41
|
+
versionFinding('payload', payloadBand, fromUrl),
|
|
42
|
+
versionFinding('better-auth', betterAuthBand, fromUrl, (installed) => installed !== null &&
|
|
43
|
+
(installed.startsWith('1.4.') || installed.startsWith('1.5.') || installed.startsWith('1.6.'))
|
|
44
|
+
? 'better-auth 1.7 removed `oidcProvider` and the `mcp` plugin; an OAuth 2.1 server moves to @better-auth/oauth-provider (a schema migration — see the journey notes in issue #60)'
|
|
45
|
+
: undefined),
|
|
46
|
+
versionFinding('next', nextBand, fromUrl),
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=bands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bands.js","sourceRoot":"","sources":["../../src/doctor/bands.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,GAErB,MAAM,yBAAyB,CAAA;AAGhC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAA4B;IAClD,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE;IACxC,EAAE,KAAK,EAAE,cAAc,EAAE;CAC1B,CAAA;AACD,MAAM,CAAC,MAAM,cAAc,GAA4B,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAA;AAChG,iFAAiF;AACjF,MAAM,CAAC,MAAM,QAAQ,GAA4B,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAA;AAE5F;;;;;GAKG;AACH,SAAS,cAAc,CACrB,IAAY,EACZ,IAA6B,EAC7B,OAAe,EACf,IAAuD;IAEvD,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACrD,MAAM,MAAM,GACV,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;IACzF,MAAM,IAAI,GACR,SAAS,KAAK,IAAI;QAChB,CAAC,CAAC,qEAAqE;QACvE,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC;YACnC,CAAC,CAAC,aAAa,SAAS,+BAA+B;YACvD,CAAC,CAAC,aAAa,SAAS,0DAA0D,CAAA;IACxF,OAAO;QACL,IAAI;QACJ,SAAS;QACT,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC;QACxB,MAAM;QACN,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;KACnF,CAAA;AACH,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO;QACL,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC;QAC/C,cAAc,CAAC,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,EAAE,CACnE,SAAS,KAAK,IAAI;YAClB,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5F,CAAC,CAAC,iLAAiL;YACnL,CAAC,CAAC,SAAS,CACd;QACD,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC;KAC1C,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/doctor/database.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AA6DjD,wBAAsB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAmE3F"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Client } from 'pg';
|
|
2
|
+
/**
|
|
3
|
+
* Read-only database introspection (issue #52): row counts for the
|
|
4
|
+
* payload-auth layout's auth tables, unverified users (who will not
|
|
5
|
+
* JIT-link), and orphans. Only an honest SELECT — the doctor never
|
|
6
|
+
* writes.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The payload-auth 1.9.x Postgres layout (snake_case columns; Payload's
|
|
10
|
+
* drizzle adapter stores hasMany selects as child tables like
|
|
11
|
+
* `users_role`). Tables that don't exist are simply absent from the
|
|
12
|
+
* report — apps customize slugs and drop plugins.
|
|
13
|
+
*/
|
|
14
|
+
const knownTables = [
|
|
15
|
+
'users',
|
|
16
|
+
'accounts',
|
|
17
|
+
'sessions',
|
|
18
|
+
'verifications',
|
|
19
|
+
'api_keys',
|
|
20
|
+
'organizations',
|
|
21
|
+
'members',
|
|
22
|
+
'invitations',
|
|
23
|
+
'jwks',
|
|
24
|
+
'admin_invitations',
|
|
25
|
+
'users_role',
|
|
26
|
+
'two_factors',
|
|
27
|
+
'passkeys',
|
|
28
|
+
'oauth_applications',
|
|
29
|
+
'oauth_access_tokens',
|
|
30
|
+
'oauth_consents',
|
|
31
|
+
'teams',
|
|
32
|
+
'team_members',
|
|
33
|
+
'subscriptions',
|
|
34
|
+
'device_code',
|
|
35
|
+
'sso_providers',
|
|
36
|
+
];
|
|
37
|
+
async function tableExists(client, table) {
|
|
38
|
+
const result = await client.query(`SELECT 1 FROM information_schema.tables
|
|
39
|
+
WHERE table_schema = 'public' AND table_name = $1`, [table]);
|
|
40
|
+
return result.rows.length > 0;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Discover the columns a table actually has, so checks adapt to
|
|
44
|
+
* customized layouts instead of assuming.
|
|
45
|
+
*/
|
|
46
|
+
async function columnsOf(client, table) {
|
|
47
|
+
const result = await client.query(`SELECT column_name FROM information_schema.columns
|
|
48
|
+
WHERE table_schema = 'public' AND table_name = $1`, [table]);
|
|
49
|
+
return new Set(result.rows.map((row) => String(row.column_name)));
|
|
50
|
+
}
|
|
51
|
+
export async function introspectDatabase(connectionString) {
|
|
52
|
+
const client = new Client({ connectionString });
|
|
53
|
+
await client.connect();
|
|
54
|
+
try {
|
|
55
|
+
const tables = [];
|
|
56
|
+
for (const table of knownTables) {
|
|
57
|
+
if (!(await tableExists(client, table))) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const counted = await client.query(`SELECT count(*)::int AS n FROM ${table}`);
|
|
61
|
+
const first = counted.rows[0];
|
|
62
|
+
tables.push({ name: table, rows: first?.n ?? 0 });
|
|
63
|
+
}
|
|
64
|
+
let unverifiedUsers = null;
|
|
65
|
+
if (await tableExists(client, 'users')) {
|
|
66
|
+
const columns = await columnsOf(client, 'users');
|
|
67
|
+
if (columns.has('email_verified')) {
|
|
68
|
+
const counted = await client.query('SELECT count(*)::int AS n FROM users WHERE email_verified = false');
|
|
69
|
+
const first = counted.rows[0];
|
|
70
|
+
unverifiedUsers = first?.n ?? null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const orphans = [];
|
|
74
|
+
const orphanChecks = [
|
|
75
|
+
{ kind: 'accounts-without-user', table: 'accounts', column: 'user_id', target: 'users' },
|
|
76
|
+
{
|
|
77
|
+
kind: 'members-without-org',
|
|
78
|
+
table: 'members',
|
|
79
|
+
column: 'organization_id',
|
|
80
|
+
target: 'organizations',
|
|
81
|
+
},
|
|
82
|
+
{ kind: 'members-without-user', table: 'members', column: 'user_id', target: 'users' },
|
|
83
|
+
{
|
|
84
|
+
kind: 'invitations-without-org',
|
|
85
|
+
table: 'invitations',
|
|
86
|
+
column: 'organization_id',
|
|
87
|
+
target: 'organizations',
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
for (const check of orphanChecks) {
|
|
91
|
+
if ((await tableExists(client, check.table)) &&
|
|
92
|
+
(await tableExists(client, check.target)) &&
|
|
93
|
+
(await columnsOf(client, check.table)).has(check.column)) {
|
|
94
|
+
const counted = await client.query(`SELECT count(*)::int AS n FROM ${check.table}
|
|
95
|
+
WHERE ${check.column} IS NOT NULL
|
|
96
|
+
AND NOT EXISTS (SELECT 1 FROM ${check.target} t WHERE t.id = ${check.table}.${check.column})`);
|
|
97
|
+
const first = counted.rows[0];
|
|
98
|
+
const count = first?.n ?? 0;
|
|
99
|
+
if (count > 0) {
|
|
100
|
+
orphans.push({ kind: check.kind, count });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { tables, unverifiedUsers, orphans };
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
await client.end();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/doctor/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PluginFinding } from './types.js';
|
|
2
|
+
export declare function classifyPlugins(ids: readonly string[]): PluginFinding[];
|
|
3
|
+
/** Plugin ids proven live by the collections payload-auth built. */
|
|
4
|
+
export declare function pluginsFromCollectionSlugs(slugs: readonly string[]): string[];
|
|
5
|
+
/**
|
|
6
|
+
* Plugin ids found by scanning the config source for plugin factory
|
|
7
|
+
* calls. Regex on purpose: the loaded config cannot reveal these
|
|
8
|
+
* (closure-held options), and the doctor must not execute app code
|
|
9
|
+
* beyond loading its config module.
|
|
10
|
+
*/
|
|
11
|
+
export declare function pluginsFromConfigSource(configSource: string): string[];
|
|
12
|
+
//# sourceMappingURL=plugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/doctor/plugins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AA2E/C,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,aAAa,EAAE,CA8DvE;AA+BD,oEAAoE;AACpE,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAS7E;AAsBD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAStE"}
|