doomain 0.1.4 → 0.1.5
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/wizard.js +45 -23
- package/dist/lib/errors.d.ts +1 -1
- package/dist/lib/vercel.js +10 -0
- package/oclif.manifest.json +69 -69
- package/package.json +1 -1
package/dist/commands/wizard.js
CHANGED
|
@@ -110,6 +110,9 @@ function teamLabel(team) {
|
|
|
110
110
|
function globalTokenLabel(token) {
|
|
111
111
|
return token.source === 'environment' ? `Use ${token.label}` : `Use ${token.label} token`;
|
|
112
112
|
}
|
|
113
|
+
function isVercelAuthError(error) {
|
|
114
|
+
return error instanceof DoomainError && error.code === 'VERCEL_AUTH_FAILED';
|
|
115
|
+
}
|
|
113
116
|
async function promptVercelToken(globalTokens) {
|
|
114
117
|
if (globalTokens.length > 0) {
|
|
115
118
|
const selected = await p.select({
|
|
@@ -154,35 +157,54 @@ export default class Wizard extends Command {
|
|
|
154
157
|
let vercelTeamId = process.env.VERCEL_TEAM_ID || localProject?.orgId || config.vercel?.teamId;
|
|
155
158
|
const defaultProvider = process.env.DOOMAIN_PROVIDER || config.defaults?.provider;
|
|
156
159
|
const defaultDomain = process.env.DOOMAIN_DOMAIN || config.defaults?.domain;
|
|
160
|
+
let globalVercelTokens = [];
|
|
157
161
|
if (!vercelToken) {
|
|
158
|
-
|
|
162
|
+
globalVercelTokens = await listGlobalVercelTokens();
|
|
159
163
|
vercelToken = (await promptVercelToken(globalVercelTokens)) ?? undefined;
|
|
160
164
|
if (!vercelToken)
|
|
161
165
|
return;
|
|
162
166
|
}
|
|
163
|
-
const teamSpinner = p.spinner();
|
|
164
167
|
let teams = [];
|
|
165
|
-
|
|
166
|
-
p.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
168
|
+
while (true) {
|
|
169
|
+
const teamSpinner = p.spinner();
|
|
170
|
+
try {
|
|
171
|
+
if (process.env.VERCEL_TEAM_ID) {
|
|
172
|
+
p.log.info(`Using Vercel team ${vercelTeamId} from VERCEL_TEAM_ID.`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
activeSpinner = teamSpinner;
|
|
176
|
+
teamSpinner.start('Loading Vercel teams');
|
|
177
|
+
teams = await createVercelClient({ token: vercelToken }).listTeams();
|
|
178
|
+
teamSpinner.stop(`Loaded ${teams.length} Vercel team${teams.length === 1 ? '' : 's'}`);
|
|
179
|
+
activeSpinner = undefined;
|
|
180
|
+
const selected = await p.select({
|
|
181
|
+
message: 'Select Vercel account/team',
|
|
182
|
+
initialValue: vercelTeamId ?? localProject?.orgId ?? PERSONAL_ACCOUNT,
|
|
183
|
+
options: [
|
|
184
|
+
{ label: 'Personal account', value: PERSONAL_ACCOUNT, hint: 'No team id' },
|
|
185
|
+
...teams.map((team) => ({ label: teamLabel(team), value: team.id, hint: team.role ?? team.slug })),
|
|
186
|
+
],
|
|
187
|
+
});
|
|
188
|
+
const resolved = cancelIfNeeded(selected);
|
|
189
|
+
if (resolved === null)
|
|
190
|
+
return;
|
|
191
|
+
vercelTeamId = resolved === PERSONAL_ACCOUNT ? undefined : resolved;
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
if (!isVercelAuthError(error) || process.env.VERCEL_TOKEN)
|
|
197
|
+
throw error;
|
|
198
|
+
activeSpinner?.error('Vercel authorization failed');
|
|
199
|
+
activeSpinner = undefined;
|
|
200
|
+
p.log.warning(error instanceof Error ? error.message : String(error));
|
|
201
|
+
if (globalVercelTokens.length === 0)
|
|
202
|
+
globalVercelTokens = await listGlobalVercelTokens();
|
|
203
|
+
globalVercelTokens = globalVercelTokens.filter((token) => token.token !== vercelToken);
|
|
204
|
+
vercelToken = (await promptVercelToken(globalVercelTokens)) ?? undefined;
|
|
205
|
+
if (!vercelToken)
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
186
208
|
}
|
|
187
209
|
const selectedTeam = teams.find((team) => team.id === vercelTeamId);
|
|
188
210
|
const teamDisplay = vercelTeamId ? teamLabel(selectedTeam ?? { id: vercelTeamId, name: null, role: null, slug: vercelTeamId }) : 'Personal account';
|
package/dist/lib/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type DoomainErrorCode = 'CONFIG_NOT_FOUND' | 'DOMAIN_LINK_FAILED' | 'DOMAIN_ALREADY_ASSIGNED' | 'DOMAIN_VERIFY_FAILED' | 'INVALID_INPUT' | 'MISSING_ARGUMENT' | 'MISSING_CREDENTIALS' | 'PROVIDER_API_ERROR' | 'PROVIDER_AUTH_FAILED' | 'PROVIDER_PERMISSION_DENIED' | 'PROVIDER_NOT_FOUND' | 'PROVIDER_RATE_LIMITED' | 'PROVIDER_RECORD_CONFLICT' | 'PROVIDER_UNSUPPORTED_RECORD' | 'PROVIDER_ZONE_AMBIGUOUS' | 'PROVIDER_ZONE_NOT_FOUND' | 'PROJECT_NOT_FOUND' | 'VERCEL_PROJECT_NOT_LINKED';
|
|
1
|
+
export type DoomainErrorCode = 'CONFIG_NOT_FOUND' | 'DOMAIN_LINK_FAILED' | 'DOMAIN_ALREADY_ASSIGNED' | 'DOMAIN_VERIFY_FAILED' | 'INVALID_INPUT' | 'MISSING_ARGUMENT' | 'MISSING_CREDENTIALS' | 'PROVIDER_API_ERROR' | 'PROVIDER_AUTH_FAILED' | 'PROVIDER_PERMISSION_DENIED' | 'PROVIDER_NOT_FOUND' | 'PROVIDER_RATE_LIMITED' | 'PROVIDER_RECORD_CONFLICT' | 'PROVIDER_UNSUPPORTED_RECORD' | 'PROVIDER_ZONE_AMBIGUOUS' | 'PROVIDER_ZONE_NOT_FOUND' | 'PROJECT_NOT_FOUND' | 'VERCEL_AUTH_FAILED' | 'VERCEL_PROJECT_NOT_LINKED';
|
|
2
2
|
export declare class DoomainError extends Error {
|
|
3
3
|
readonly code: DoomainErrorCode;
|
|
4
4
|
readonly details?: unknown;
|
package/dist/lib/vercel.js
CHANGED
|
@@ -22,6 +22,13 @@ function appendTeam(path, teamId) {
|
|
|
22
22
|
function apiErrorMessage(status, body) {
|
|
23
23
|
return body?.error?.message ?? `Vercel API error (${status}).`;
|
|
24
24
|
}
|
|
25
|
+
function vercelAuthErrorMessage(body) {
|
|
26
|
+
const message = body?.error?.message;
|
|
27
|
+
if (!message || message.toLowerCase() === 'not authorized') {
|
|
28
|
+
return 'Vercel token is not authorized. Run `vercel login` again or enter a token from https://vercel.com/account/tokens.';
|
|
29
|
+
}
|
|
30
|
+
return `Vercel authorization failed: ${message}`;
|
|
31
|
+
}
|
|
25
32
|
function isDomainConflictError(error) {
|
|
26
33
|
if (!(error instanceof DoomainError))
|
|
27
34
|
return false;
|
|
@@ -52,6 +59,9 @@ export function createVercelClient(config) {
|
|
|
52
59
|
});
|
|
53
60
|
if (!response.ok) {
|
|
54
61
|
const body = (await response.json().catch(() => undefined));
|
|
62
|
+
if (response.status === 401 || response.status === 403) {
|
|
63
|
+
throw new DoomainError('VERCEL_AUTH_FAILED', vercelAuthErrorMessage(body), body);
|
|
64
|
+
}
|
|
55
65
|
throw new DoomainError('DOMAIN_LINK_FAILED', apiErrorMessage(response.status, body), body);
|
|
56
66
|
}
|
|
57
67
|
if (response.status === 204)
|
package/oclif.manifest.json
CHANGED
|
@@ -300,6 +300,74 @@
|
|
|
300
300
|
"list.js"
|
|
301
301
|
]
|
|
302
302
|
},
|
|
303
|
+
"projects:list": {
|
|
304
|
+
"aliases": [],
|
|
305
|
+
"args": {},
|
|
306
|
+
"description": "List Vercel projects.",
|
|
307
|
+
"flags": {
|
|
308
|
+
"json": {
|
|
309
|
+
"description": "Output a single JSON object and never prompt.",
|
|
310
|
+
"name": "json",
|
|
311
|
+
"allowNo": false,
|
|
312
|
+
"type": "boolean"
|
|
313
|
+
},
|
|
314
|
+
"search": {
|
|
315
|
+
"description": "Filter projects by search term.",
|
|
316
|
+
"name": "search",
|
|
317
|
+
"hasDynamicHelp": false,
|
|
318
|
+
"multiple": false,
|
|
319
|
+
"type": "option"
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
"hasDynamicHelp": false,
|
|
323
|
+
"hiddenAliases": [],
|
|
324
|
+
"id": "projects:list",
|
|
325
|
+
"pluginAlias": "doomain",
|
|
326
|
+
"pluginName": "doomain",
|
|
327
|
+
"pluginType": "core",
|
|
328
|
+
"strict": true,
|
|
329
|
+
"enableJsonFlag": false,
|
|
330
|
+
"isESM": true,
|
|
331
|
+
"relativePath": [
|
|
332
|
+
"dist",
|
|
333
|
+
"commands",
|
|
334
|
+
"projects",
|
|
335
|
+
"list.js"
|
|
336
|
+
]
|
|
337
|
+
},
|
|
338
|
+
"auth:logout:vercel": {
|
|
339
|
+
"aliases": [],
|
|
340
|
+
"args": {},
|
|
341
|
+
"description": "Remove saved Vercel credentials locally.",
|
|
342
|
+
"examples": [
|
|
343
|
+
"<%= config.bin %> <%= command.id %>",
|
|
344
|
+
"<%= config.bin %> <%= command.id %> --json"
|
|
345
|
+
],
|
|
346
|
+
"flags": {
|
|
347
|
+
"json": {
|
|
348
|
+
"description": "Output a single JSON object and never prompt.",
|
|
349
|
+
"name": "json",
|
|
350
|
+
"allowNo": false,
|
|
351
|
+
"type": "boolean"
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
"hasDynamicHelp": false,
|
|
355
|
+
"hiddenAliases": [],
|
|
356
|
+
"id": "auth:logout:vercel",
|
|
357
|
+
"pluginAlias": "doomain",
|
|
358
|
+
"pluginName": "doomain",
|
|
359
|
+
"pluginType": "core",
|
|
360
|
+
"strict": true,
|
|
361
|
+
"enableJsonFlag": false,
|
|
362
|
+
"isESM": true,
|
|
363
|
+
"relativePath": [
|
|
364
|
+
"dist",
|
|
365
|
+
"commands",
|
|
366
|
+
"auth",
|
|
367
|
+
"logout",
|
|
368
|
+
"vercel.js"
|
|
369
|
+
]
|
|
370
|
+
},
|
|
303
371
|
"providers:add": {
|
|
304
372
|
"aliases": [],
|
|
305
373
|
"args": {
|
|
@@ -559,75 +627,7 @@
|
|
|
559
627
|
"providers",
|
|
560
628
|
"verify.js"
|
|
561
629
|
]
|
|
562
|
-
},
|
|
563
|
-
"projects:list": {
|
|
564
|
-
"aliases": [],
|
|
565
|
-
"args": {},
|
|
566
|
-
"description": "List Vercel projects.",
|
|
567
|
-
"flags": {
|
|
568
|
-
"json": {
|
|
569
|
-
"description": "Output a single JSON object and never prompt.",
|
|
570
|
-
"name": "json",
|
|
571
|
-
"allowNo": false,
|
|
572
|
-
"type": "boolean"
|
|
573
|
-
},
|
|
574
|
-
"search": {
|
|
575
|
-
"description": "Filter projects by search term.",
|
|
576
|
-
"name": "search",
|
|
577
|
-
"hasDynamicHelp": false,
|
|
578
|
-
"multiple": false,
|
|
579
|
-
"type": "option"
|
|
580
|
-
}
|
|
581
|
-
},
|
|
582
|
-
"hasDynamicHelp": false,
|
|
583
|
-
"hiddenAliases": [],
|
|
584
|
-
"id": "projects:list",
|
|
585
|
-
"pluginAlias": "doomain",
|
|
586
|
-
"pluginName": "doomain",
|
|
587
|
-
"pluginType": "core",
|
|
588
|
-
"strict": true,
|
|
589
|
-
"enableJsonFlag": false,
|
|
590
|
-
"isESM": true,
|
|
591
|
-
"relativePath": [
|
|
592
|
-
"dist",
|
|
593
|
-
"commands",
|
|
594
|
-
"projects",
|
|
595
|
-
"list.js"
|
|
596
|
-
]
|
|
597
|
-
},
|
|
598
|
-
"auth:logout:vercel": {
|
|
599
|
-
"aliases": [],
|
|
600
|
-
"args": {},
|
|
601
|
-
"description": "Remove saved Vercel credentials locally.",
|
|
602
|
-
"examples": [
|
|
603
|
-
"<%= config.bin %> <%= command.id %>",
|
|
604
|
-
"<%= config.bin %> <%= command.id %> --json"
|
|
605
|
-
],
|
|
606
|
-
"flags": {
|
|
607
|
-
"json": {
|
|
608
|
-
"description": "Output a single JSON object and never prompt.",
|
|
609
|
-
"name": "json",
|
|
610
|
-
"allowNo": false,
|
|
611
|
-
"type": "boolean"
|
|
612
|
-
}
|
|
613
|
-
},
|
|
614
|
-
"hasDynamicHelp": false,
|
|
615
|
-
"hiddenAliases": [],
|
|
616
|
-
"id": "auth:logout:vercel",
|
|
617
|
-
"pluginAlias": "doomain",
|
|
618
|
-
"pluginName": "doomain",
|
|
619
|
-
"pluginType": "core",
|
|
620
|
-
"strict": true,
|
|
621
|
-
"enableJsonFlag": false,
|
|
622
|
-
"isESM": true,
|
|
623
|
-
"relativePath": [
|
|
624
|
-
"dist",
|
|
625
|
-
"commands",
|
|
626
|
-
"auth",
|
|
627
|
-
"logout",
|
|
628
|
-
"vercel.js"
|
|
629
|
-
]
|
|
630
630
|
}
|
|
631
631
|
},
|
|
632
|
-
"version": "0.1.
|
|
632
|
+
"version": "0.1.5"
|
|
633
633
|
}
|