@wix/web50-cli 0.1.0 → 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.
- package/dist/cjs/auth/deviceFlow.js +99 -13
- package/dist/cjs/auth/deviceFlow.js.map +1 -1
- package/dist/cjs/auth/index.js +65 -12
- package/dist/cjs/auth/index.js.map +1 -1
- package/dist/cjs/auth/secretStore.js.map +1 -1
- package/dist/cjs/cli.js +29 -1
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/commands/bundle.js +95 -0
- package/dist/cjs/commands/bundle.js.map +1 -0
- package/dist/cjs/commands/conversation.js +50 -0
- package/dist/cjs/commands/conversation.js.map +1 -0
- package/dist/cjs/commands/conversationWizard.js +526 -0
- package/dist/cjs/commands/conversationWizard.js.map +1 -0
- package/dist/cjs/commands/deploy.js +192 -0
- package/dist/cjs/commands/deploy.js.map +1 -0
- package/dist/cjs/commands/embed.js +118 -0
- package/dist/cjs/commands/embed.js.map +1 -0
- package/dist/cjs/commands/getClientId.js +60 -0
- package/dist/cjs/commands/getClientId.js.map +1 -0
- package/dist/cjs/commands/init.js +31 -26
- package/dist/cjs/commands/init.js.map +1 -1
- package/dist/cjs/commands/instructions.js +360 -0
- package/dist/cjs/commands/instructions.js.map +1 -0
- package/dist/cjs/commands/login.js +59 -4
- package/dist/cjs/commands/login.js.map +1 -1
- package/dist/cjs/commands/logout.js +16 -0
- package/dist/cjs/commands/logout.js.map +1 -0
- package/dist/cjs/commands/serve.js +122 -0
- package/dist/cjs/commands/serve.js.map +1 -0
- package/dist/cjs/commands/storybook.js +102 -0
- package/dist/cjs/commands/storybook.js.map +1 -0
- package/dist/cjs/commands/validate.js +266 -18
- package/dist/cjs/commands/validate.js.map +1 -1
- package/dist/cjs/commands/whoami.js +48 -0
- package/dist/cjs/commands/whoami.js.map +1 -0
- package/dist/cjs/utils/print.js +12 -0
- package/dist/cjs/utils/print.js.map +1 -1
- package/dist/cjs/utils/project.js +11 -0
- package/dist/cjs/utils/project.js.map +1 -1
- package/dist/cjs/utils/wixApi.js +55 -0
- package/dist/cjs/utils/wixApi.js.map +1 -0
- package/dist/esm/auth/deviceFlow.js +106 -13
- package/dist/esm/auth/deviceFlow.js.map +1 -1
- package/dist/esm/auth/index.js +71 -13
- package/dist/esm/auth/index.js.map +1 -1
- package/dist/esm/auth/secretStore.js.map +1 -1
- package/dist/esm/cli.js +29 -1
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/commands/bundle.js +92 -0
- package/dist/esm/commands/bundle.js.map +1 -0
- package/dist/esm/commands/conversation.js +44 -0
- package/dist/esm/commands/conversation.js.map +1 -0
- package/dist/esm/commands/conversationWizard.js +527 -0
- package/dist/esm/commands/conversationWizard.js.map +1 -0
- package/dist/esm/commands/deploy.js +194 -0
- package/dist/esm/commands/deploy.js.map +1 -0
- package/dist/esm/commands/embed.js +112 -0
- package/dist/esm/commands/embed.js.map +1 -0
- package/dist/esm/commands/getClientId.js +56 -0
- package/dist/esm/commands/getClientId.js.map +1 -0
- package/dist/esm/commands/init.js +32 -27
- package/dist/esm/commands/init.js.map +1 -1
- package/dist/esm/commands/instructions.js +360 -0
- package/dist/esm/commands/instructions.js.map +1 -0
- package/dist/esm/commands/login.js +62 -6
- package/dist/esm/commands/login.js.map +1 -1
- package/dist/esm/commands/logout.js +12 -0
- package/dist/esm/commands/logout.js.map +1 -0
- package/dist/esm/commands/serve.js +117 -0
- package/dist/esm/commands/serve.js.map +1 -0
- package/dist/esm/commands/storybook.js +97 -0
- package/dist/esm/commands/storybook.js.map +1 -0
- package/dist/esm/commands/validate.js +269 -19
- package/dist/esm/commands/validate.js.map +1 -1
- package/dist/esm/commands/whoami.js +44 -0
- package/dist/esm/commands/whoami.js.map +1 -0
- package/dist/esm/utils/print.js +10 -0
- package/dist/esm/utils/print.js.map +1 -1
- package/dist/esm/utils/project.js +8 -0
- package/dist/esm/utils/project.js.map +1 -1
- package/dist/esm/utils/wixApi.js +51 -0
- package/dist/esm/utils/wixApi.js.map +1 -0
- package/dist/types/auth/deviceFlow.d.ts +3 -1
- package/dist/types/auth/deviceFlow.d.ts.map +1 -1
- package/dist/types/auth/index.d.ts +5 -1
- package/dist/types/auth/index.d.ts.map +1 -1
- package/dist/types/auth/secretStore.d.ts +2 -0
- package/dist/types/auth/secretStore.d.ts.map +1 -1
- package/dist/types/commands/bundle.d.ts +10 -0
- package/dist/types/commands/bundle.d.ts.map +1 -0
- package/dist/types/commands/conversation.d.ts +3 -0
- package/dist/types/commands/conversation.d.ts.map +1 -0
- package/dist/types/commands/conversationWizard.d.ts +3 -0
- package/dist/types/commands/conversationWizard.d.ts.map +1 -0
- package/dist/types/commands/deploy.d.ts +3 -0
- package/dist/types/commands/deploy.d.ts.map +1 -0
- package/dist/types/commands/embed.d.ts +3 -0
- package/dist/types/commands/embed.d.ts.map +1 -0
- package/dist/types/commands/getClientId.d.ts +3 -0
- package/dist/types/commands/getClientId.d.ts.map +1 -0
- package/dist/types/commands/init.d.ts.map +1 -1
- package/dist/types/commands/instructions.d.ts +3 -0
- package/dist/types/commands/instructions.d.ts.map +1 -0
- package/dist/types/commands/login.d.ts.map +1 -1
- package/dist/types/commands/logout.d.ts +3 -0
- package/dist/types/commands/logout.d.ts.map +1 -0
- package/dist/types/commands/serve.d.ts +3 -0
- package/dist/types/commands/serve.d.ts.map +1 -0
- package/dist/types/commands/storybook.d.ts +3 -0
- package/dist/types/commands/storybook.d.ts.map +1 -0
- package/dist/types/commands/validate.d.ts +5 -0
- package/dist/types/commands/validate.d.ts.map +1 -1
- package/dist/types/commands/whoami.d.ts +3 -0
- package/dist/types/commands/whoami.d.ts.map +1 -0
- package/dist/types/utils/print.d.ts +3 -0
- package/dist/types/utils/print.d.ts.map +1 -1
- package/dist/types/utils/project.d.ts +10 -0
- package/dist/types/utils/project.d.ts.map +1 -1
- package/dist/types/utils/wixApi.d.ts +9 -0
- package/dist/types/utils/wixApi.d.ts.map +1 -0
- package/package.json +5 -5
- package/defaults/package.json +0 -42
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
|
+
exports.promptForSiteId = promptForSiteId;
|
|
5
|
+
exports.refreshAccessToken = refreshAccessToken;
|
|
4
6
|
exports.runDeviceFlow = runDeviceFlow;
|
|
5
7
|
var readline = _interopRequireWildcard(require("readline"));
|
|
6
8
|
var _print = require("../utils/print");
|
|
@@ -11,28 +13,62 @@ const DEVICE_CODE_URL = 'https://www.wixapis.com/oauth2/device/code';
|
|
|
11
13
|
const TOKEN_URL = 'https://www.wixapis.com/oauth2/token';
|
|
12
14
|
const POLL_INTERVAL_MS = 3000;
|
|
13
15
|
const POLL_TIMEOUT_MS = 60_000;
|
|
16
|
+
let verboseMode = false;
|
|
17
|
+
function log(...args) {
|
|
18
|
+
if (verboseMode) {
|
|
19
|
+
console.log('[auth]', ...args);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
14
22
|
async function sleep(ms) {
|
|
15
23
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
16
24
|
}
|
|
17
25
|
async function requestDeviceCode() {
|
|
18
|
-
const
|
|
26
|
+
const url = `${DEVICE_CODE_URL}?client_id=${CLIENT_ID}&scope=session_bound_access`;
|
|
27
|
+
log(`POST ${url}`);
|
|
28
|
+
const res = await fetch(url);
|
|
29
|
+
log(`Response: ${res.status} ${res.statusText}`);
|
|
19
30
|
if (!res.ok) {
|
|
31
|
+
const body = await res.text().catch(() => '');
|
|
32
|
+
log(`Error body: ${body}`);
|
|
20
33
|
throw new Error(`Device code request failed: ${res.status} ${res.statusText}`);
|
|
21
34
|
}
|
|
22
|
-
|
|
35
|
+
const data = await res.json();
|
|
36
|
+
log(`Device code response:`, JSON.stringify(data, null, 2));
|
|
37
|
+
return data;
|
|
23
38
|
}
|
|
24
39
|
async function pollToken(deviceCode) {
|
|
25
40
|
const deadline = Date.now() + POLL_TIMEOUT_MS;
|
|
26
|
-
const
|
|
41
|
+
const body = {
|
|
42
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
43
|
+
client_id: CLIENT_ID,
|
|
44
|
+
device_code: deviceCode
|
|
45
|
+
};
|
|
46
|
+
log(`Poll URL: POST ${TOKEN_URL}`);
|
|
47
|
+
log(`Request body:`, JSON.stringify(body, null, 2));
|
|
48
|
+
let attempt = 0;
|
|
27
49
|
while (Date.now() < deadline) {
|
|
28
|
-
|
|
29
|
-
|
|
50
|
+
attempt++;
|
|
51
|
+
log(`Poll attempt #${attempt}`);
|
|
52
|
+
const res = await fetch(TOKEN_URL, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers: {
|
|
55
|
+
'Content-Type': 'application/json'
|
|
56
|
+
},
|
|
57
|
+
body: JSON.stringify(body)
|
|
30
58
|
});
|
|
59
|
+
log(`Response: ${res.status} ${res.statusText}`);
|
|
31
60
|
if (res.ok) {
|
|
32
|
-
|
|
61
|
+
const token = await res.json();
|
|
62
|
+
log(`Token response:`, JSON.stringify({
|
|
63
|
+
...token,
|
|
64
|
+
access_token: '***',
|
|
65
|
+
refresh_token: '***'
|
|
66
|
+
}, null, 2));
|
|
67
|
+
return token;
|
|
33
68
|
}
|
|
34
|
-
const
|
|
35
|
-
|
|
69
|
+
const errorBody = await res.json().catch(() => ({}));
|
|
70
|
+
log(`Poll error body:`, JSON.stringify(errorBody, null, 2));
|
|
71
|
+
if (errorBody.error === 'access_denied') {
|
|
36
72
|
throw new Error('Access denied');
|
|
37
73
|
}
|
|
38
74
|
|
|
@@ -41,6 +77,51 @@ async function pollToken(deviceCode) {
|
|
|
41
77
|
}
|
|
42
78
|
throw new Error('Verification failed — timed out after 60 seconds. Please run `web5 login` again.');
|
|
43
79
|
}
|
|
80
|
+
async function promptForSiteId() {
|
|
81
|
+
return new Promise(resolve => {
|
|
82
|
+
const rl = readline.createInterface({
|
|
83
|
+
input: process.stdin,
|
|
84
|
+
output: process.stdout
|
|
85
|
+
});
|
|
86
|
+
rl.question(' Enter your site ID (msid) or press Enter to skip: ', answer => {
|
|
87
|
+
rl.close();
|
|
88
|
+
const trimmed = answer.trim();
|
|
89
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
90
|
+
resolve(UUID_RE.test(trimmed) ? trimmed : null);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async function refreshAccessToken(refreshToken, siteId) {
|
|
95
|
+
const body = {
|
|
96
|
+
grant_type: 'refresh_token',
|
|
97
|
+
client_id: CLIENT_ID,
|
|
98
|
+
refresh_token: refreshToken
|
|
99
|
+
};
|
|
100
|
+
if (siteId) {
|
|
101
|
+
body.site_id = siteId;
|
|
102
|
+
}
|
|
103
|
+
log(`Refreshing access token: POST ${TOKEN_URL}`);
|
|
104
|
+
const res = await fetch(TOKEN_URL, {
|
|
105
|
+
method: 'POST',
|
|
106
|
+
headers: {
|
|
107
|
+
'Content-Type': 'application/json'
|
|
108
|
+
},
|
|
109
|
+
body: JSON.stringify(body)
|
|
110
|
+
});
|
|
111
|
+
log(`Refresh response: ${res.status} ${res.statusText}`);
|
|
112
|
+
if (!res.ok) {
|
|
113
|
+
const errorBody = await res.json().catch(() => ({}));
|
|
114
|
+
log(`Refresh error body:`, JSON.stringify(errorBody, null, 2));
|
|
115
|
+
throw new Error(`Token refresh failed (${res.status}): ${errorBody.error ?? res.statusText}`);
|
|
116
|
+
}
|
|
117
|
+
const token = await res.json();
|
|
118
|
+
log(`Refresh token response:`, JSON.stringify({
|
|
119
|
+
...token,
|
|
120
|
+
access_token: '***',
|
|
121
|
+
refresh_token: '***'
|
|
122
|
+
}, null, 2));
|
|
123
|
+
return token;
|
|
124
|
+
}
|
|
44
125
|
async function pressEnterToContinue() {
|
|
45
126
|
return new Promise(resolve => {
|
|
46
127
|
const rl = readline.createInterface({
|
|
@@ -53,16 +134,21 @@ async function pressEnterToContinue() {
|
|
|
53
134
|
});
|
|
54
135
|
});
|
|
55
136
|
}
|
|
56
|
-
async function runDeviceFlow() {
|
|
137
|
+
async function runDeviceFlow(verbose = false, noBrowser = false) {
|
|
138
|
+
verboseMode = verbose;
|
|
57
139
|
const code = await requestDeviceCode();
|
|
58
140
|
console.log('');
|
|
59
141
|
(0, _print.info)(`Verification code: ${code.userCode}`);
|
|
60
142
|
console.log(` ${code.verificationUri}`);
|
|
61
143
|
console.log('');
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
144
|
+
if (noBrowser) {
|
|
145
|
+
(0, _print.info)('Open the URL above in your browser to authenticate.');
|
|
146
|
+
} else {
|
|
147
|
+
await pressEnterToContinue();
|
|
148
|
+
const open = (await Promise.resolve().then(() => _interopRequireWildcard(require('open')))).default;
|
|
149
|
+
await open(code.verificationUri);
|
|
150
|
+
console.log('');
|
|
151
|
+
}
|
|
66
152
|
const spin = (0, _print.spinner)('Waiting for approval...');
|
|
67
153
|
try {
|
|
68
154
|
const token = await pollToken(code.deviceCode);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["readline","_interopRequireWildcard","require","_print","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","CLIENT_ID","DEVICE_CODE_URL","TOKEN_URL","POLL_INTERVAL_MS","POLL_TIMEOUT_MS","sleep","ms","Promise","resolve","setTimeout","requestDeviceCode","res","fetch","ok","Error","status","statusText","json","pollToken","deviceCode","deadline","Date","now","url","encodeURIComponent","method","body","catch","error","pressEnterToContinue","rl","createInterface","input","process","stdin","output","stdout","question","close","runDeviceFlow","code","console","log","info","userCode","verificationUri","open","then","spin","spinner","token","succeed","err","fail"],"sources":["../../../src/auth/deviceFlow.ts"],"sourcesContent":["import * as readline from 'readline';\nimport { spinner, info } from '../utils/print';\n\n// const CLIENT_ID = '602051c7-ec4b-4334-b90d-b029b076ba8f';\nconst CLIENT_ID = '6f95cec8-3e98-48b9-b4e5-1fb92fcd9973';\nconst DEVICE_CODE_URL = 'https://www.wixapis.com/oauth2/device/code';\nconst TOKEN_URL = 'https://www.wixapis.com/oauth2/token';\nconst POLL_INTERVAL_MS = 3000;\nconst POLL_TIMEOUT_MS = 60_000;\n\ninterface DeviceCodeResponse {\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n expiresIn: number;\n}\n\nexport interface TokenResponse {\n access_token: string;\n token_type: string;\n expires_in: number;\n refresh_token: string;\n}\n\nasync function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function requestDeviceCode(): Promise<DeviceCodeResponse> {\n const res = await fetch(\n `${DEVICE_CODE_URL}?client_id=${CLIENT_ID}&scope=session_bound_access`,\n );\n if (!res.ok) {\n throw new Error(\n `Device code request failed: ${res.status} ${res.statusText}`,\n );\n }\n return res.json() as Promise<DeviceCodeResponse>;\n}\n\nasync function pollToken(deviceCode: string): Promise<TokenResponse> {\n const deadline = Date.now() + POLL_TIMEOUT_MS;\n const url =\n `${TOKEN_URL}` +\n `?grant_type=${encodeURIComponent(\n 'urn:ietf:params:oauth:grant-type:device_code',\n )}` +\n `&client_id=${CLIENT_ID}` +\n `&device_code=${encodeURIComponent(deviceCode)}`;\n\n while (Date.now() < deadline) {\n const res = await fetch(url, { method: 'POST' });\n\n if (res.ok) {\n return res.json() as Promise<TokenResponse>;\n }\n\n const body = (await res.json().catch(() => ({}))) as { error?: string };\n\n if (body.error === 'access_denied') {\n throw new Error('Access denied');\n }\n\n // authorization_pending, slow_down, unknown_error, or any transient error → keep polling\n await sleep(POLL_INTERVAL_MS);\n }\n\n throw new Error(\n 'Verification failed — timed out after 60 seconds. Please run `web5 login` again.',\n );\n}\n\nasync function pressEnterToContinue(): Promise<void> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(' Press Enter to open in browser...', () => {\n rl.close();\n resolve();\n });\n });\n}\n\nexport async function runDeviceFlow(): Promise<TokenResponse> {\n const code = await requestDeviceCode();\n\n console.log('');\n info(`Verification code: ${code.userCode}`);\n console.log(` ${code.verificationUri}`);\n console.log('');\n\n await pressEnterToContinue();\n\n const open = (await import('open')).default;\n await open(code.verificationUri);\n console.log('');\n\n const spin = spinner('Waiting for approval...');\n\n try {\n const token = await pollToken(code.deviceCode);\n spin.succeed('Approved');\n return token;\n } catch (err) {\n spin.fail('Authentication failed');\n throw err;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["readline","_interopRequireWildcard","require","_print","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","CLIENT_ID","DEVICE_CODE_URL","TOKEN_URL","POLL_INTERVAL_MS","POLL_TIMEOUT_MS","verboseMode","log","args","console","sleep","ms","Promise","resolve","setTimeout","requestDeviceCode","url","res","fetch","status","statusText","ok","body","text","catch","Error","data","json","JSON","stringify","pollToken","deviceCode","deadline","Date","now","grant_type","client_id","device_code","attempt","method","headers","token","access_token","refresh_token","errorBody","error","promptForSiteId","rl","createInterface","input","process","stdin","output","stdout","question","answer","close","trimmed","trim","UUID_RE","test","refreshAccessToken","refreshToken","siteId","site_id","pressEnterToContinue","runDeviceFlow","verbose","noBrowser","code","info","userCode","verificationUri","open","then","spin","spinner","succeed","err","fail"],"sources":["../../../src/auth/deviceFlow.ts"],"sourcesContent":["import * as readline from 'readline';\nimport { spinner, info } from '../utils/print';\n\n// const CLIENT_ID = '602051c7-ec4b-4334-b90d-b029b076ba8f';\nconst CLIENT_ID = '6f95cec8-3e98-48b9-b4e5-1fb92fcd9973';\nconst DEVICE_CODE_URL = 'https://www.wixapis.com/oauth2/device/code';\nconst TOKEN_URL = 'https://www.wixapis.com/oauth2/token';\nconst POLL_INTERVAL_MS = 3000;\nconst POLL_TIMEOUT_MS = 60_000;\n\nlet verboseMode = false;\n\nfunction log(...args: unknown[]): void {\n if (verboseMode) {\n console.log('[auth]', ...args);\n }\n}\n\ninterface DeviceCodeResponse {\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n expiresIn: number;\n}\n\nexport interface TokenResponse {\n access_token: string;\n token_type: string;\n expires_in: number;\n refresh_token: string;\n}\n\nasync function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function requestDeviceCode(): Promise<DeviceCodeResponse> {\n const url = `${DEVICE_CODE_URL}?client_id=${CLIENT_ID}&scope=session_bound_access`;\n log(`POST ${url}`);\n\n const res = await fetch(url);\n log(`Response: ${res.status} ${res.statusText}`);\n\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n log(`Error body: ${body}`);\n throw new Error(\n `Device code request failed: ${res.status} ${res.statusText}`,\n );\n }\n\n const data = (await res.json()) as DeviceCodeResponse;\n log(`Device code response:`, JSON.stringify(data, null, 2));\n return data;\n}\n\nasync function pollToken(deviceCode: string): Promise<TokenResponse> {\n const deadline = Date.now() + POLL_TIMEOUT_MS;\n const body = {\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n client_id: CLIENT_ID,\n device_code: deviceCode,\n };\n\n log(`Poll URL: POST ${TOKEN_URL}`);\n log(`Request body:`, JSON.stringify(body, null, 2));\n\n let attempt = 0;\n while (Date.now() < deadline) {\n attempt++;\n log(`Poll attempt #${attempt}`);\n const res = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n log(`Response: ${res.status} ${res.statusText}`);\n\n if (res.ok) {\n const token = (await res.json()) as TokenResponse;\n log(\n `Token response:`,\n JSON.stringify(\n { ...token, access_token: '***', refresh_token: '***' },\n null,\n 2,\n ),\n );\n return token;\n }\n\n const errorBody = (await res.json().catch(() => ({}))) as {\n error?: string;\n };\n log(`Poll error body:`, JSON.stringify(errorBody, null, 2));\n\n if (errorBody.error === 'access_denied') {\n throw new Error('Access denied');\n }\n\n // authorization_pending, slow_down, unknown_error, or any transient error → keep polling\n await sleep(POLL_INTERVAL_MS);\n }\n\n throw new Error(\n 'Verification failed — timed out after 60 seconds. Please run `web5 login` again.',\n );\n}\n\nexport async function promptForSiteId(): Promise<string | null> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(\n ' Enter your site ID (msid) or press Enter to skip: ',\n (answer) => {\n rl.close();\n const trimmed = answer.trim();\n const UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n resolve(UUID_RE.test(trimmed) ? trimmed : null);\n },\n );\n });\n}\n\nexport async function refreshAccessToken(\n refreshToken: string,\n siteId?: string,\n): Promise<TokenResponse> {\n const body: Record<string, string> = {\n grant_type: 'refresh_token',\n client_id: CLIENT_ID,\n refresh_token: refreshToken,\n };\n\n if (siteId) {\n body.site_id = siteId;\n }\n\n log(`Refreshing access token: POST ${TOKEN_URL}`);\n\n const res = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n log(`Refresh response: ${res.status} ${res.statusText}`);\n\n if (!res.ok) {\n const errorBody = (await res.json().catch(() => ({}))) as {\n error?: string;\n };\n log(`Refresh error body:`, JSON.stringify(errorBody, null, 2));\n throw new Error(\n `Token refresh failed (${res.status}): ${\n errorBody.error ?? res.statusText\n }`,\n );\n }\n\n const token = (await res.json()) as TokenResponse;\n log(\n `Refresh token response:`,\n JSON.stringify(\n { ...token, access_token: '***', refresh_token: '***' },\n null,\n 2,\n ),\n );\n return token;\n}\n\nasync function pressEnterToContinue(): Promise<void> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(' Press Enter to open in browser...', () => {\n rl.close();\n resolve();\n });\n });\n}\n\nexport async function runDeviceFlow(\n verbose = false,\n noBrowser = false,\n): Promise<TokenResponse> {\n verboseMode = verbose;\n const code = await requestDeviceCode();\n\n console.log('');\n info(`Verification code: ${code.userCode}`);\n console.log(` ${code.verificationUri}`);\n console.log('');\n\n if (noBrowser) {\n info('Open the URL above in your browser to authenticate.');\n } else {\n await pressEnterToContinue();\n const open = (await import('open')).default;\n await open(code.verificationUri);\n console.log('');\n }\n\n const spin = spinner('Waiting for approval...');\n\n try {\n const token = await pollToken(code.deviceCode);\n spin.succeed('Approved');\n return token;\n } catch (err) {\n spin.fail('Authentication failed');\n throw err;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/cjs/auth/index.js
CHANGED
|
@@ -5,10 +5,23 @@ exports.getToken = getToken;
|
|
|
5
5
|
exports.isAuthenticated = isAuthenticated;
|
|
6
6
|
exports.login = login;
|
|
7
7
|
exports.logout = logout;
|
|
8
|
+
exports.switchSite = switchSite;
|
|
8
9
|
var _deviceFlow = require("./deviceFlow");
|
|
9
10
|
var _secretStore = require("./secretStore");
|
|
10
11
|
var _print = require("../utils/print");
|
|
11
|
-
|
|
12
|
+
// Refresh proactively if the access token expires within this window
|
|
13
|
+
const EXPIRY_BUFFER_MS = 60_000;
|
|
14
|
+
function credentialsFromToken(token, siteId) {
|
|
15
|
+
return {
|
|
16
|
+
access_token: token.access_token,
|
|
17
|
+
refresh_token: token.refresh_token,
|
|
18
|
+
expires_at: Date.now() + token.expires_in * 1000,
|
|
19
|
+
...(siteId ? {
|
|
20
|
+
site_id: siteId
|
|
21
|
+
} : {})
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async function login(apiKey, verbose = false, opts = {}) {
|
|
12
25
|
if (apiKey) {
|
|
13
26
|
await (0, _secretStore.writeCredentials)({
|
|
14
27
|
api_key: apiKey
|
|
@@ -16,13 +29,31 @@ async function login(apiKey) {
|
|
|
16
29
|
(0, _print.success)('API key saved');
|
|
17
30
|
return;
|
|
18
31
|
}
|
|
19
|
-
const token = await (0, _deviceFlow.runDeviceFlow)();
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
32
|
+
const token = await (0, _deviceFlow.runDeviceFlow)(verbose, opts.noBrowser ?? false);
|
|
33
|
+
console.log('');
|
|
34
|
+
const siteId = opts.siteId ?? (await (0, _deviceFlow.promptForSiteId)());
|
|
35
|
+
if (siteId) {
|
|
36
|
+
const siteToken = await (0, _deviceFlow.refreshAccessToken)(token.refresh_token, siteId);
|
|
37
|
+
await (0, _secretStore.writeCredentials)(credentialsFromToken(siteToken, siteId));
|
|
38
|
+
} else {
|
|
39
|
+
await (0, _secretStore.writeCredentials)(credentialsFromToken(token));
|
|
40
|
+
}
|
|
24
41
|
(0, _print.success)('Authenticated');
|
|
25
|
-
|
|
42
|
+
}
|
|
43
|
+
async function switchSite(siteId) {
|
|
44
|
+
const creds = await (0, _secretStore.readCredentials)();
|
|
45
|
+
if (!creds) {
|
|
46
|
+
throw new Error('Not authenticated. Run `web5 login` first.');
|
|
47
|
+
}
|
|
48
|
+
if (creds.api_key) {
|
|
49
|
+
throw new Error('Cannot switch site when using an API key — re-run `web5 login --site-id <msid>` instead.');
|
|
50
|
+
}
|
|
51
|
+
if (!creds.refresh_token) {
|
|
52
|
+
throw new Error('No refresh token available. Run `web5 login` first.');
|
|
53
|
+
}
|
|
54
|
+
const refreshed = await (0, _deviceFlow.refreshAccessToken)(creds.refresh_token, siteId);
|
|
55
|
+
await (0, _secretStore.writeCredentials)(credentialsFromToken(refreshed, siteId));
|
|
56
|
+
(0, _print.success)(`Switched to site ${siteId}`);
|
|
26
57
|
}
|
|
27
58
|
async function logout() {
|
|
28
59
|
await (0, _secretStore.clearCredentials)();
|
|
@@ -33,15 +64,37 @@ async function getToken() {
|
|
|
33
64
|
if (!creds) {
|
|
34
65
|
return null;
|
|
35
66
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
67
|
+
|
|
68
|
+
// API key path — no expiry concept
|
|
39
69
|
if (creds.api_key) {
|
|
40
70
|
return creds.api_key;
|
|
41
71
|
}
|
|
42
|
-
|
|
72
|
+
|
|
73
|
+
// Access token still valid
|
|
74
|
+
if (creds.access_token && creds.expires_at && creds.expires_at - Date.now() > EXPIRY_BUFFER_MS) {
|
|
75
|
+
return creds.access_token;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Access token missing or expiring soon — try refresh
|
|
79
|
+
if (creds.refresh_token) {
|
|
80
|
+
try {
|
|
81
|
+
const refreshed = await (0, _deviceFlow.refreshAccessToken)(creds.refresh_token, creds.site_id);
|
|
82
|
+
const updated = credentialsFromToken(refreshed, creds.site_id);
|
|
83
|
+
await (0, _secretStore.writeCredentials)(updated);
|
|
84
|
+
return updated.access_token;
|
|
85
|
+
} catch {
|
|
86
|
+
// Refresh token is expired or revoked — force re-login
|
|
87
|
+
await (0, _secretStore.clearCredentials)();
|
|
88
|
+
throw new Error('Session expired. Run `web5 login` to re-authenticate.');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
43
92
|
}
|
|
44
93
|
async function isAuthenticated() {
|
|
45
|
-
|
|
94
|
+
try {
|
|
95
|
+
return (await getToken()) !== null;
|
|
96
|
+
} catch {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
46
99
|
}
|
|
47
100
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_deviceFlow","require","_secretStore","_print","login","apiKey","writeCredentials","api_key","success","
|
|
1
|
+
{"version":3,"names":["_deviceFlow","require","_secretStore","_print","EXPIRY_BUFFER_MS","credentialsFromToken","token","siteId","access_token","refresh_token","expires_at","Date","now","expires_in","site_id","login","apiKey","verbose","opts","writeCredentials","api_key","success","runDeviceFlow","noBrowser","console","log","promptForSiteId","siteToken","refreshAccessToken","switchSite","creds","readCredentials","Error","refreshed","logout","clearCredentials","getToken","updated","isAuthenticated"],"sources":["../../../src/auth/index.ts"],"sourcesContent":["import {\n runDeviceFlow,\n refreshAccessToken,\n promptForSiteId,\n} from './deviceFlow';\nimport {\n writeCredentials,\n readCredentials,\n clearCredentials,\n} from './secretStore';\nimport { success } from '../utils/print';\n\nexport type { Credentials } from './secretStore';\n\n// Refresh proactively if the access token expires within this window\nconst EXPIRY_BUFFER_MS = 60_000;\n\nfunction credentialsFromToken(\n token: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n },\n siteId?: string,\n) {\n return {\n access_token: token.access_token,\n refresh_token: token.refresh_token,\n expires_at: Date.now() + token.expires_in * 1000,\n ...(siteId ? { site_id: siteId } : {}),\n };\n}\n\nexport async function login(\n apiKey?: string,\n verbose = false,\n opts: { siteId?: string; noBrowser?: boolean } = {},\n): Promise<void> {\n if (apiKey) {\n await writeCredentials({ api_key: apiKey });\n success('API key saved');\n return;\n }\n\n const token = await runDeviceFlow(verbose, opts.noBrowser ?? false);\n\n console.log('');\n const siteId = opts.siteId ?? (await promptForSiteId());\n if (siteId) {\n const siteToken = await refreshAccessToken(token.refresh_token, siteId);\n await writeCredentials(credentialsFromToken(siteToken, siteId));\n } else {\n await writeCredentials(credentialsFromToken(token));\n }\n\n success('Authenticated');\n}\n\nexport async function switchSite(siteId: string): Promise<void> {\n const creds = await readCredentials();\n if (!creds) {\n throw new Error('Not authenticated. Run `web5 login` first.');\n }\n if (creds.api_key) {\n throw new Error('Cannot switch site when using an API key — re-run `web5 login --site-id <msid>` instead.');\n }\n if (!creds.refresh_token) {\n throw new Error('No refresh token available. Run `web5 login` first.');\n }\n const refreshed = await refreshAccessToken(creds.refresh_token, siteId);\n await writeCredentials(credentialsFromToken(refreshed, siteId));\n success(`Switched to site ${siteId}`);\n}\n\nexport async function logout(): Promise<void> {\n await clearCredentials();\n success('Signed out \\u2014 credentials removed');\n}\n\nexport async function getToken(): Promise<string | null> {\n const creds = await readCredentials();\n if (!creds) {\n return null;\n }\n\n // API key path — no expiry concept\n if (creds.api_key) {\n return creds.api_key;\n }\n\n // Access token still valid\n if (\n creds.access_token &&\n creds.expires_at &&\n creds.expires_at - Date.now() > EXPIRY_BUFFER_MS\n ) {\n return creds.access_token;\n }\n\n // Access token missing or expiring soon — try refresh\n if (creds.refresh_token) {\n try {\n const refreshed = await refreshAccessToken(\n creds.refresh_token,\n creds.site_id,\n );\n const updated = credentialsFromToken(refreshed, creds.site_id);\n await writeCredentials(updated);\n return updated.access_token;\n } catch {\n // Refresh token is expired or revoked — force re-login\n await clearCredentials();\n throw new Error('Session expired. Run `web5 login` to re-authenticate.');\n }\n }\n\n return null;\n}\n\nexport async function isAuthenticated(): Promise<boolean> {\n try {\n return (await getToken()) !== null;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["crypto","_interopRequireWildcard","require","os","path","_promises","_fs","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","SERVICE","ACCOUNT","CRED_FILE","join","homedir","_storeType","getDerivedKey","uid","String","userInfo","raw","hostname","createHash","update","digest","detectStore","keytar","Promise","resolve","then","setPassword","deletePassword","encrypt","plaintext","key","iv","randomBytes","cipher","createCipheriv","encrypted","Buffer","concat","final","tag","getAuthTag","toString","decrypt","ciphertext","buf","from","subarray","decipher","createDecipheriv","setAuthTag","writeCredentials","creds","store","payload","JSON","stringify","atomicWrite","readCredentials","apiKey","process","env","WEB5_API_KEY","api_key","getPassword","parse","readFile","trim","clearCredentials","unlink"],"sources":["../../../src/auth/secretStore.ts"],"sourcesContent":["import * as crypto from 'crypto';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { readFile, unlink } from 'fs/promises';\nimport { atomicWrite } from '../utils/fs';\n\nconst SERVICE = 'wix-web5-cli';\nconst ACCOUNT = 'credentials';\nconst CRED_FILE = path.join(os.homedir(), '.wix', 'credentials.enc');\n\nexport interface Credentials {\n access_token?: string;\n refresh_token?: string;\n api_key?: string;\n}\n\ntype StoreType = 'keychain' | 'file';\n\nlet _storeType: StoreType | null = null;\n\nfunction getDerivedKey(): Buffer {\n const uid = String(os.userInfo().uid);\n const raw = `${os.hostname()}:${uid}`;\n return crypto.createHash('sha256').update(raw).digest();\n}\n\nasync function detectStore(): Promise<StoreType> {\n if (_storeType) {\n return _storeType;\n }\n\n try {\n // Dynamic import — keytar is optional; throws if the native module is absent\n const keytar = await import('keytar');\n await keytar.setPassword(SERVICE, '_probe', 'test');\n await keytar.deletePassword(SERVICE, '_probe');\n _storeType = 'keychain';\n } catch {\n _storeType = 'file';\n }\n\n return _storeType;\n}\n\nfunction encrypt(plaintext: string): string {\n const key = getDerivedKey();\n const iv = crypto.randomBytes(12);\n const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);\n const encrypted = Buffer.concat([\n cipher.update(plaintext, 'utf8'),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n return Buffer.concat([iv, tag, encrypted]).toString('base64');\n}\n\nfunction decrypt(ciphertext: string): string {\n const key = getDerivedKey();\n const buf = Buffer.from(ciphertext, 'base64');\n const iv = buf.subarray(0, 12);\n const tag = buf.subarray(12, 28);\n const encrypted = buf.subarray(28);\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);\n decipher.setAuthTag(tag);\n return decipher.update(encrypted) + decipher.final('utf8');\n}\n\nexport async function writeCredentials(creds: Credentials): Promise<void> {\n const store = await detectStore();\n const payload = JSON.stringify(creds);\n\n if (store === 'keychain') {\n const keytar = await import('keytar');\n await keytar.setPassword(SERVICE, ACCOUNT, payload);\n } else {\n await atomicWrite(CRED_FILE, encrypt(payload), 0o600);\n }\n}\n\nexport async function readCredentials(): Promise<Credentials | null> {\n // Env var takes highest priority — used in CI/CD pipelines\n const apiKey = process.env.WEB5_API_KEY;\n if (apiKey) {\n return { api_key: apiKey };\n }\n\n const store = await detectStore();\n\n if (store === 'keychain') {\n const keytar = await import('keytar');\n const payload = await keytar.getPassword(SERVICE, ACCOUNT);\n if (!payload) {\n return null;\n }\n return JSON.parse(payload) as Credentials;\n } else {\n try {\n const encrypted = await readFile(CRED_FILE, 'utf8');\n return JSON.parse(decrypt(encrypted.trim())) as Credentials;\n } catch {\n return null;\n }\n }\n}\n\nexport async function clearCredentials(): Promise<void> {\n const store = await detectStore();\n\n if (store === 'keychain') {\n const keytar = await import('keytar');\n await keytar.deletePassword(SERVICE, ACCOUNT);\n } else {\n try {\n await unlink(CRED_FILE);\n } catch {\n // Already gone — that's fine\n }\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AACA,IAAAC,EAAA,GAAAF,uBAAA,CAAAC,OAAA;AACA,IAAAE,IAAA,GAAAH,uBAAA,CAAAC,OAAA;AACA,IAAAG,SAAA,GAAAH,OAAA;AACA,IAAAI,GAAA,GAAAJ,OAAA;AAA0C,SAAAD,wBAAAM,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAR,uBAAA,YAAAA,CAAAM,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAE1C,MAAMkB,OAAO,GAAG,cAAc;AAC9B,MAAMC,OAAO,GAAG,aAAa;AAC7B,MAAMC,SAAS,GAAGxB,IAAI,CAACyB,IAAI,CAAC1B,EAAE,CAAC2B,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"names":["crypto","_interopRequireWildcard","require","os","path","_promises","_fs","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","SERVICE","ACCOUNT","CRED_FILE","join","homedir","_storeType","getDerivedKey","uid","String","userInfo","raw","hostname","createHash","update","digest","detectStore","keytar","Promise","resolve","then","setPassword","deletePassword","encrypt","plaintext","key","iv","randomBytes","cipher","createCipheriv","encrypted","Buffer","concat","final","tag","getAuthTag","toString","decrypt","ciphertext","buf","from","subarray","decipher","createDecipheriv","setAuthTag","writeCredentials","creds","store","payload","JSON","stringify","atomicWrite","readCredentials","apiKey","process","env","WEB5_API_KEY","api_key","getPassword","parse","readFile","trim","clearCredentials","unlink"],"sources":["../../../src/auth/secretStore.ts"],"sourcesContent":["import * as crypto from 'crypto';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { readFile, unlink } from 'fs/promises';\nimport { atomicWrite } from '../utils/fs';\n\nconst SERVICE = 'wix-web5-cli';\nconst ACCOUNT = 'credentials';\nconst CRED_FILE = path.join(os.homedir(), '.wix', 'credentials.enc');\n\nexport interface Credentials {\n access_token?: string;\n refresh_token?: string;\n expires_at?: number; // unix ms — when access_token expires\n site_id?: string; // msid — when set, access_token is scoped to this site\n api_key?: string;\n}\n\ntype StoreType = 'keychain' | 'file';\n\nlet _storeType: StoreType | null = null;\n\nfunction getDerivedKey(): Buffer {\n const uid = String(os.userInfo().uid);\n const raw = `${os.hostname()}:${uid}`;\n return crypto.createHash('sha256').update(raw).digest();\n}\n\nasync function detectStore(): Promise<StoreType> {\n if (_storeType) {\n return _storeType;\n }\n\n try {\n // Dynamic import — keytar is optional; throws if the native module is absent\n const keytar = await import('keytar');\n await keytar.setPassword(SERVICE, '_probe', 'test');\n await keytar.deletePassword(SERVICE, '_probe');\n _storeType = 'keychain';\n } catch {\n _storeType = 'file';\n }\n\n return _storeType;\n}\n\nfunction encrypt(plaintext: string): string {\n const key = getDerivedKey();\n const iv = crypto.randomBytes(12);\n const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);\n const encrypted = Buffer.concat([\n cipher.update(plaintext, 'utf8'),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n return Buffer.concat([iv, tag, encrypted]).toString('base64');\n}\n\nfunction decrypt(ciphertext: string): string {\n const key = getDerivedKey();\n const buf = Buffer.from(ciphertext, 'base64');\n const iv = buf.subarray(0, 12);\n const tag = buf.subarray(12, 28);\n const encrypted = buf.subarray(28);\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);\n decipher.setAuthTag(tag);\n return decipher.update(encrypted) + decipher.final('utf8');\n}\n\nexport async function writeCredentials(creds: Credentials): Promise<void> {\n const store = await detectStore();\n const payload = JSON.stringify(creds);\n\n if (store === 'keychain') {\n const keytar = await import('keytar');\n await keytar.setPassword(SERVICE, ACCOUNT, payload);\n } else {\n await atomicWrite(CRED_FILE, encrypt(payload), 0o600);\n }\n}\n\nexport async function readCredentials(): Promise<Credentials | null> {\n // Env var takes highest priority — used in CI/CD pipelines\n const apiKey = process.env.WEB5_API_KEY;\n if (apiKey) {\n return { api_key: apiKey };\n }\n\n const store = await detectStore();\n\n if (store === 'keychain') {\n const keytar = await import('keytar');\n const payload = await keytar.getPassword(SERVICE, ACCOUNT);\n if (!payload) {\n return null;\n }\n return JSON.parse(payload) as Credentials;\n } else {\n try {\n const encrypted = await readFile(CRED_FILE, 'utf8');\n return JSON.parse(decrypt(encrypted.trim())) as Credentials;\n } catch {\n return null;\n }\n }\n}\n\nexport async function clearCredentials(): Promise<void> {\n const store = await detectStore();\n\n if (store === 'keychain') {\n const keytar = await import('keytar');\n await keytar.deletePassword(SERVICE, ACCOUNT);\n } else {\n try {\n await unlink(CRED_FILE);\n } catch {\n // Already gone — that's fine\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/cjs/cli.js
CHANGED
|
@@ -4,15 +4,43 @@ var _commander = require("commander");
|
|
|
4
4
|
var fs = _interopRequireWildcard(require("fs"));
|
|
5
5
|
var path = _interopRequireWildcard(require("path"));
|
|
6
6
|
var _login = require("./commands/login");
|
|
7
|
+
var _logout = require("./commands/logout");
|
|
7
8
|
var _init = require("./commands/init");
|
|
8
9
|
var _validate = require("./commands/validate");
|
|
10
|
+
var _serve = require("./commands/serve");
|
|
11
|
+
var _embed = require("./commands/embed");
|
|
12
|
+
var _conversationWizard = require("./commands/conversationWizard");
|
|
13
|
+
var _instructions = require("./commands/instructions");
|
|
14
|
+
var _deploy = require("./commands/deploy");
|
|
15
|
+
var _getClientId = require("./commands/getClientId");
|
|
16
|
+
var _whoami = require("./commands/whoami");
|
|
9
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
10
18
|
// Read version from package.json at runtime (works from dist/cjs/ via ../../)
|
|
11
19
|
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf8'));
|
|
12
20
|
const program = new _commander.Command();
|
|
13
|
-
program.name('web5').description('Developer CLI for the Web5 platform').version(pkg.version);
|
|
21
|
+
program.name('web5').description('Developer CLI for the Web5 platform').version(pkg.version).option('--json', 'Output as machine-readable JSON (suppresses decorations)');
|
|
22
|
+
|
|
23
|
+
// Propagate --json to child processes via environment variable so that
|
|
24
|
+
// every command's action can call isJsonMode() without reading parent opts.
|
|
25
|
+
program.hook('preAction', () => {
|
|
26
|
+
if (program.opts().json) {
|
|
27
|
+
process.env.WEB5_JSON_MODE = '1';
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// ── Commands ──────────────────────────────────────────────────────────────
|
|
14
32
|
program.addCommand(_login.loginCommand);
|
|
33
|
+
program.addCommand(_logout.logoutCommand);
|
|
34
|
+
program.addCommand(_whoami.whoamiCommand);
|
|
15
35
|
program.addCommand(_init.initCommand);
|
|
16
36
|
program.addCommand(_validate.validateCommand);
|
|
37
|
+
program.addCommand(_deploy.deployCommand);
|
|
38
|
+
program.addCommand(_serve.serveCommand);
|
|
39
|
+
program.addCommand(_embed.embedCommand);
|
|
40
|
+
program.addCommand(_getClientId.getClientIdCommand);
|
|
41
|
+
|
|
42
|
+
// ── Wizards ───────────────────────────────────────────────────────────────
|
|
43
|
+
program.addCommand(_instructions.instructionsCommand);
|
|
44
|
+
program.addCommand(_conversationWizard.conversationsCommand);
|
|
17
45
|
program.parseAsync(process.argv);
|
|
18
46
|
//# sourceMappingURL=cli.js.map
|
package/dist/cjs/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_commander","require","fs","_interopRequireWildcard","path","_login","_init","_validate","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","pkg","JSON","parse","readFileSync","join","__dirname","program","Command","name","description","version","addCommand","loginCommand","initCommand","validateCommand","
|
|
1
|
+
{"version":3,"names":["_commander","require","fs","_interopRequireWildcard","path","_login","_logout","_init","_validate","_serve","_embed","_conversationWizard","_instructions","_deploy","_getClientId","_whoami","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","pkg","JSON","parse","readFileSync","join","__dirname","program","Command","name","description","version","option","hook","opts","json","process","env","WEB5_JSON_MODE","addCommand","loginCommand","logoutCommand","whoamiCommand","initCommand","validateCommand","deployCommand","serveCommand","embedCommand","getClientIdCommand","instructionsCommand","conversationsCommand","parseAsync","argv"],"sources":["../../src/cli.ts"],"sourcesContent":["import { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { loginCommand } from './commands/login';\nimport { logoutCommand } from './commands/logout';\nimport { initCommand } from './commands/init';\nimport { validateCommand } from './commands/validate';\nimport { serveCommand } from './commands/serve';\nimport { embedCommand } from './commands/embed';\nimport { conversationsCommand } from './commands/conversationWizard';\nimport { instructionsCommand } from './commands/instructions';\nimport { deployCommand } from './commands/deploy';\nimport { getClientIdCommand } from './commands/getClientId';\nimport { whoamiCommand } from './commands/whoami';\n\n// Read version from package.json at runtime (works from dist/cjs/ via ../../)\nconst pkg = JSON.parse(\n fs.readFileSync(path.join(__dirname, '../../package.json'), 'utf8'),\n) as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('web5')\n .description('Developer CLI for the Web5 platform')\n .version(pkg.version)\n .option('--json', 'Output as machine-readable JSON (suppresses decorations)');\n\n// Propagate --json to child processes via environment variable so that\n// every command's action can call isJsonMode() without reading parent opts.\nprogram.hook('preAction', () => {\n if (program.opts().json) {\n process.env.WEB5_JSON_MODE = '1';\n }\n});\n\n// ── Commands ──────────────────────────────────────────────────────────────\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(whoamiCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(validateCommand);\nprogram.addCommand(deployCommand);\nprogram.addCommand(serveCommand);\nprogram.addCommand(embedCommand);\nprogram.addCommand(getClientIdCommand);\n\n// ── Wizards ───────────────────────────────────────────────────────────────\nprogram.addCommand(instructionsCommand);\nprogram.addCommand(conversationsCommand);\n\nprogram.parseAsync(process.argv);\n"],"mappings":";;AAAA,IAAAA,UAAA,GAAAC,OAAA;AACA,IAAAC,EAAA,GAAAC,uBAAA,CAAAF,OAAA;AACA,IAAAG,IAAA,GAAAD,uBAAA,CAAAF,OAAA;AACA,IAAAI,MAAA,GAAAJ,OAAA;AACA,IAAAK,OAAA,GAAAL,OAAA;AACA,IAAAM,KAAA,GAAAN,OAAA;AACA,IAAAO,SAAA,GAAAP,OAAA;AACA,IAAAQ,MAAA,GAAAR,OAAA;AACA,IAAAS,MAAA,GAAAT,OAAA;AACA,IAAAU,mBAAA,GAAAV,OAAA;AACA,IAAAW,aAAA,GAAAX,OAAA;AACA,IAAAY,OAAA,GAAAZ,OAAA;AACA,IAAAa,YAAA,GAAAb,OAAA;AACA,IAAAc,OAAA,GAAAd,OAAA;AAAkD,SAAAE,wBAAAa,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAf,uBAAA,YAAAA,CAAAa,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAElD;AACA,MAAMkB,GAAG,GAAGC,IAAI,CAACC,KAAK,CACpBnC,EAAE,CAACoC,YAAY,CAAClC,IAAI,CAACmC,IAAI,CAACC,SAAS,EAAE,oBAAoB,CAAC,EAAE,MAAM,CACpE,CAAwB;AAExB,MAAMC,OAAO,GAAG,IAAIC,kBAAO,CAAC,CAAC;AAE7BD,OAAO,CACJE,IAAI,CAAC,MAAM,CAAC,CACZC,WAAW,CAAC,qCAAqC,CAAC,CAClDC,OAAO,CAACV,GAAG,CAACU,OAAO,CAAC,CACpBC,MAAM,CAAC,QAAQ,EAAE,0DAA0D,CAAC;;AAE/E;AACA;AACAL,OAAO,CAACM,IAAI,CAAC,WAAW,EAAE,MAAM;EAC9B,IAAIN,OAAO,CAACO,IAAI,CAAC,CAAC,CAACC,IAAI,EAAE;IACvBC,OAAO,CAACC,GAAG,CAACC,cAAc,GAAG,GAAG;EAClC;AACF,CAAC,CAAC;;AAEF;AACAX,OAAO,CAACY,UAAU,CAACC,mBAAY,CAAC;AAChCb,OAAO,CAACY,UAAU,CAACE,qBAAa,CAAC;AACjCd,OAAO,CAACY,UAAU,CAACG,qBAAa,CAAC;AACjCf,OAAO,CAACY,UAAU,CAACI,iBAAW,CAAC;AAC/BhB,OAAO,CAACY,UAAU,CAACK,yBAAe,CAAC;AACnCjB,OAAO,CAACY,UAAU,CAACM,qBAAa,CAAC;AACjClB,OAAO,CAACY,UAAU,CAACO,mBAAY,CAAC;AAChCnB,OAAO,CAACY,UAAU,CAACQ,mBAAY,CAAC;AAChCpB,OAAO,CAACY,UAAU,CAACS,+BAAkB,CAAC;;AAEtC;AACArB,OAAO,CAACY,UAAU,CAACU,iCAAmB,CAAC;AACvCtB,OAAO,CAACY,UAAU,CAACW,wCAAoB,CAAC;AAExCvB,OAAO,CAACwB,UAAU,CAACf,OAAO,CAACgB,IAAI,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.bundleCommand = void 0;
|
|
5
|
+
exports.runBundle = runBundle;
|
|
6
|
+
var _commander = require("commander");
|
|
7
|
+
var _child_process = require("child_process");
|
|
8
|
+
var _fs = require("fs");
|
|
9
|
+
var path = _interopRequireWildcard(require("path"));
|
|
10
|
+
var _project = require("../utils/project");
|
|
11
|
+
var _print = require("../utils/print");
|
|
12
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
13
|
+
async function runBundle(root, opts = {}) {
|
|
14
|
+
const {
|
|
15
|
+
watch,
|
|
16
|
+
minify = true,
|
|
17
|
+
outDir,
|
|
18
|
+
sourcemap
|
|
19
|
+
} = opts;
|
|
20
|
+
const viteBin = path.join(root, 'node_modules', '.bin', 'vite');
|
|
21
|
+
if (!(0, _fs.existsSync)(viteBin)) {
|
|
22
|
+
(0, _print.error)('vite not found. Run `npm install` in your project first.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const args = ['build', '--config', 'src/vite.cdn.config.ts'];
|
|
26
|
+
if (!minify) args.push('--minify', 'false');
|
|
27
|
+
if (outDir) args.push('--outDir', outDir);
|
|
28
|
+
if (sourcemap) args.push('--sourcemap');
|
|
29
|
+
if (watch) {
|
|
30
|
+
// Non-blocking watch mode — let vite output flow through
|
|
31
|
+
args.push('--watch');
|
|
32
|
+
(0, _print.success)('Starting bundle watch mode (press Ctrl+C to stop)...');
|
|
33
|
+
const child = (0, _child_process.spawn)(`"${viteBin}"`, args, {
|
|
34
|
+
cwd: root,
|
|
35
|
+
shell: true,
|
|
36
|
+
stdio: 'inherit'
|
|
37
|
+
});
|
|
38
|
+
child.on('error', err_ => {
|
|
39
|
+
(0, _print.error)(err_.message);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
42
|
+
await new Promise((_, reject) => {
|
|
43
|
+
child.on('exit', code => {
|
|
44
|
+
if (code !== 0) reject(new Error(`vite exited with code ${code}`));
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const sp = (0, _print.isJsonMode)() ? null : (0, _print.spinner)('Bundling actions and components...');
|
|
50
|
+
try {
|
|
51
|
+
(0, _child_process.execSync)(`"${viteBin}" ${args.join(' ')}`, {
|
|
52
|
+
cwd: root,
|
|
53
|
+
stdio: 'pipe'
|
|
54
|
+
});
|
|
55
|
+
sp == null || sp.stop();
|
|
56
|
+
const resolvedOutDir = outDir ? path.resolve(outDir) : path.join(root, 'dist', 'cdn');
|
|
57
|
+
if ((0, _print.isJsonMode)()) {
|
|
58
|
+
const files = (0, _fs.existsSync)(resolvedOutDir) ? (0, _fs.readdirSync)(resolvedOutDir).map(f => {
|
|
59
|
+
const full = path.join(resolvedOutDir, f);
|
|
60
|
+
return {
|
|
61
|
+
file: f,
|
|
62
|
+
size: (0, _fs.statSync)(full).size
|
|
63
|
+
};
|
|
64
|
+
}) : [];
|
|
65
|
+
console.log(JSON.stringify({
|
|
66
|
+
ok: true,
|
|
67
|
+
outDir: resolvedOutDir,
|
|
68
|
+
files
|
|
69
|
+
}));
|
|
70
|
+
} else {
|
|
71
|
+
sp == null || sp.stop();
|
|
72
|
+
(0, _print.success)('Bundle complete');
|
|
73
|
+
}
|
|
74
|
+
} catch (err_) {
|
|
75
|
+
var _stderr;
|
|
76
|
+
sp == null || sp.stop();
|
|
77
|
+
const msg = err_ instanceof Error ? ((_stderr = err_.stderr) == null ? void 0 : _stderr.toString().trim()) || err_.message : String(err_);
|
|
78
|
+
(0, _print.error)(msg);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const bundleCommand = exports.bundleCommand = new _commander.Command('bundle').description('Bundle actions and components into dist/cdn/').option('--watch', 'Re-bundle on source file changes').option('--no-minify', 'Disable minification (useful for debugging)').option('--outdir <path>', 'Override output directory (default: dist/cdn/)').option('--sourcemap', 'Generate source maps').action(async opts => {
|
|
83
|
+
const root = (0, _project.findProjectRoot)(process.cwd());
|
|
84
|
+
if (!root) {
|
|
85
|
+
(0, _print.error)('No web5.config.json found. Run this command from within a Web5 project.');
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
await runBundle(root, {
|
|
89
|
+
watch: opts.watch,
|
|
90
|
+
minify: opts.minify,
|
|
91
|
+
outDir: opts.outdir,
|
|
92
|
+
sourcemap: opts.sourcemap
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_commander","require","_child_process","_fs","path","_interopRequireWildcard","_project","_print","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","runBundle","root","opts","watch","minify","outDir","sourcemap","viteBin","join","existsSync","error","process","exit","args","push","success","child","spawn","cwd","shell","stdio","on","err_","message","Promise","_","reject","code","Error","sp","isJsonMode","spinner","execSync","stop","resolvedOutDir","resolve","files","readdirSync","map","full","file","size","statSync","console","log","JSON","stringify","ok","_stderr","msg","stderr","toString","trim","String","bundleCommand","exports","Command","description","option","action","findProjectRoot","outdir"],"sources":["../../../src/commands/bundle.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { execSync, spawn } from 'child_process';\nimport { existsSync, readdirSync, statSync } from 'fs';\nimport * as path from 'path';\nimport { findProjectRoot } from '../utils/project';\nimport { success, error, spinner, isJsonMode } from '../utils/print';\n\nexport interface BundleOptions {\n watch?: boolean;\n minify?: boolean;\n outDir?: string;\n sourcemap?: boolean;\n}\n\nexport async function runBundle(root: string, opts: BundleOptions = {}): Promise<void> {\n const { watch, minify = true, outDir, sourcemap } = opts;\n\n const viteBin = path.join(root, 'node_modules', '.bin', 'vite');\n if (!existsSync(viteBin)) {\n error('vite not found. Run `npm install` in your project first.');\n process.exit(1);\n }\n\n const args = ['build', '--config', 'src/vite.cdn.config.ts'];\n if (!minify) args.push('--minify', 'false');\n if (outDir) args.push('--outDir', outDir);\n if (sourcemap) args.push('--sourcemap');\n\n if (watch) {\n // Non-blocking watch mode — let vite output flow through\n args.push('--watch');\n success('Starting bundle watch mode (press Ctrl+C to stop)...');\n const child = spawn(`\"${viteBin}\"`, args, {\n cwd: root,\n shell: true,\n stdio: 'inherit',\n });\n child.on('error', (err_) => {\n error(err_.message);\n process.exit(1);\n });\n await new Promise<void>((_, reject) => {\n child.on('exit', (code) => {\n if (code !== 0) reject(new Error(`vite exited with code ${code}`));\n });\n });\n return;\n }\n\n const sp = isJsonMode() ? null : spinner('Bundling actions and components...');\n try {\n execSync(`\"${viteBin}\" ${args.join(' ')}`, { cwd: root, stdio: 'pipe' });\n sp?.stop();\n\n const resolvedOutDir = outDir\n ? path.resolve(outDir)\n : path.join(root, 'dist', 'cdn');\n\n if (isJsonMode()) {\n const files = existsSync(resolvedOutDir)\n ? readdirSync(resolvedOutDir).map((f) => {\n const full = path.join(resolvedOutDir, f);\n return { file: f, size: statSync(full).size };\n })\n : [];\n console.log(JSON.stringify({ ok: true, outDir: resolvedOutDir, files }));\n } else {\n sp?.stop();\n success('Bundle complete');\n }\n } catch (err_) {\n sp?.stop();\n const msg =\n err_ instanceof Error\n ? (err_ as Error & { stderr?: Buffer }).stderr?.toString().trim() ||\n err_.message\n : String(err_);\n error(msg);\n process.exit(1);\n }\n}\n\nexport const bundleCommand = new Command('bundle')\n .description('Bundle actions and components into dist/cdn/')\n .option('--watch', 'Re-bundle on source file changes')\n .option('--no-minify', 'Disable minification (useful for debugging)')\n .option('--outdir <path>', 'Override output directory (default: dist/cdn/)')\n .option('--sourcemap', 'Generate source maps')\n .action(async (opts: {\n watch?: boolean;\n minify: boolean;\n outdir?: string;\n sourcemap?: boolean;\n }) => {\n const root = findProjectRoot(process.cwd());\n if (!root) {\n error(\n 'No web5.config.json found. Run this command from within a Web5 project.',\n );\n process.exit(1);\n }\n await runBundle(root, {\n watch: opts.watch,\n minify: opts.minify,\n outDir: opts.outdir,\n sourcemap: opts.sourcemap,\n });\n });\n"],"mappings":"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","ignoreList":[]}
|