@wix/web50-cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/bin/web5.js +1 -2
  2. package/dist/cjs/auth/deviceFlow.js +175 -16
  3. package/dist/cjs/auth/deviceFlow.js.map +1 -1
  4. package/dist/cjs/auth/index.js +93 -10
  5. package/dist/cjs/auth/index.js.map +1 -1
  6. package/dist/cjs/auth/secretStore.js.map +1 -1
  7. package/dist/cjs/cli.js +29 -1
  8. package/dist/cjs/cli.js.map +1 -1
  9. package/dist/cjs/commands/bundle.js +103 -0
  10. package/dist/cjs/commands/bundle.js.map +1 -0
  11. package/dist/cjs/commands/conversation.js +50 -0
  12. package/dist/cjs/commands/conversation.js.map +1 -0
  13. package/dist/cjs/commands/conversationWizard.js +528 -0
  14. package/dist/cjs/commands/conversationWizard.js.map +1 -0
  15. package/dist/cjs/commands/deploy.js +237 -0
  16. package/dist/cjs/commands/deploy.js.map +1 -0
  17. package/dist/cjs/commands/ecom.js +239 -0
  18. package/dist/cjs/commands/ecom.js.map +1 -0
  19. package/dist/cjs/commands/embed.js +118 -0
  20. package/dist/cjs/commands/embed.js.map +1 -0
  21. package/dist/cjs/commands/init.js +65 -29
  22. package/dist/cjs/commands/init.js.map +1 -1
  23. package/dist/cjs/commands/instructions.js +456 -0
  24. package/dist/cjs/commands/instructions.js.map +1 -0
  25. package/dist/cjs/commands/login.js +63 -4
  26. package/dist/cjs/commands/login.js.map +1 -1
  27. package/dist/cjs/commands/logout.js +16 -0
  28. package/dist/cjs/commands/logout.js.map +1 -0
  29. package/dist/cjs/commands/serve.js +122 -0
  30. package/dist/cjs/commands/serve.js.map +1 -0
  31. package/dist/cjs/commands/storybook.js +102 -0
  32. package/dist/cjs/commands/storybook.js.map +1 -0
  33. package/dist/cjs/commands/validate.js +617 -17
  34. package/dist/cjs/commands/validate.js.map +1 -1
  35. package/dist/cjs/commands/whoami.js +48 -0
  36. package/dist/cjs/commands/whoami.js.map +1 -0
  37. package/dist/cjs/templates/aiInstructionsSchema.js +5 -1
  38. package/dist/cjs/templates/aiInstructionsSchema.js.map +1 -1
  39. package/dist/cjs/templates/cmsMappingSchema.js +132 -0
  40. package/dist/cjs/templates/cmsMappingSchema.js.map +1 -0
  41. package/dist/cjs/utils/print.js +12 -0
  42. package/dist/cjs/utils/print.js.map +1 -1
  43. package/dist/cjs/utils/project.js +24 -0
  44. package/dist/cjs/utils/project.js.map +1 -1
  45. package/dist/cjs/utils/wixApi.js +57 -0
  46. package/dist/cjs/utils/wixApi.js.map +1 -0
  47. package/dist/esm/auth/deviceFlow.js +182 -17
  48. package/dist/esm/auth/deviceFlow.js.map +1 -1
  49. package/dist/esm/auth/index.js +98 -11
  50. package/dist/esm/auth/index.js.map +1 -1
  51. package/dist/esm/auth/secretStore.js.map +1 -1
  52. package/dist/esm/cli.js +29 -1
  53. package/dist/esm/cli.js.map +1 -1
  54. package/dist/esm/commands/bundle.js +100 -0
  55. package/dist/esm/commands/bundle.js.map +1 -0
  56. package/dist/esm/commands/conversation.js +44 -0
  57. package/dist/esm/commands/conversation.js.map +1 -0
  58. package/dist/esm/commands/conversationWizard.js +529 -0
  59. package/dist/esm/commands/conversationWizard.js.map +1 -0
  60. package/dist/esm/commands/deploy.js +239 -0
  61. package/dist/esm/commands/deploy.js.map +1 -0
  62. package/dist/esm/commands/ecom.js +234 -0
  63. package/dist/esm/commands/ecom.js.map +1 -0
  64. package/dist/esm/commands/embed.js +112 -0
  65. package/dist/esm/commands/embed.js.map +1 -0
  66. package/dist/esm/commands/init.js +66 -30
  67. package/dist/esm/commands/init.js.map +1 -1
  68. package/dist/esm/commands/instructions.js +459 -0
  69. package/dist/esm/commands/instructions.js.map +1 -0
  70. package/dist/esm/commands/login.js +66 -6
  71. package/dist/esm/commands/login.js.map +1 -1
  72. package/dist/esm/commands/logout.js +12 -0
  73. package/dist/esm/commands/logout.js.map +1 -0
  74. package/dist/esm/commands/serve.js +117 -0
  75. package/dist/esm/commands/serve.js.map +1 -0
  76. package/dist/esm/commands/storybook.js +97 -0
  77. package/dist/esm/commands/storybook.js.map +1 -0
  78. package/dist/esm/commands/validate.js +623 -19
  79. package/dist/esm/commands/validate.js.map +1 -1
  80. package/dist/esm/commands/whoami.js +44 -0
  81. package/dist/esm/commands/whoami.js.map +1 -0
  82. package/dist/esm/templates/aiInstructionsSchema.js +5 -1
  83. package/dist/esm/templates/aiInstructionsSchema.js.map +1 -1
  84. package/dist/esm/templates/cmsMappingSchema.js +128 -0
  85. package/dist/esm/templates/cmsMappingSchema.js.map +1 -0
  86. package/dist/esm/utils/print.js +10 -0
  87. package/dist/esm/utils/print.js.map +1 -1
  88. package/dist/esm/utils/project.js +23 -0
  89. package/dist/esm/utils/project.js.map +1 -1
  90. package/dist/esm/utils/wixApi.js +53 -0
  91. package/dist/esm/utils/wixApi.js.map +1 -0
  92. package/dist/types/auth/deviceFlow.d.ts +3 -1
  93. package/dist/types/auth/deviceFlow.d.ts.map +1 -1
  94. package/dist/types/auth/index.d.ts +6 -1
  95. package/dist/types/auth/index.d.ts.map +1 -1
  96. package/dist/types/auth/secretStore.d.ts +2 -0
  97. package/dist/types/auth/secretStore.d.ts.map +1 -1
  98. package/dist/types/commands/bundle.d.ts +10 -0
  99. package/dist/types/commands/bundle.d.ts.map +1 -0
  100. package/dist/types/commands/conversation.d.ts +3 -0
  101. package/dist/types/commands/conversation.d.ts.map +1 -0
  102. package/dist/types/commands/conversationWizard.d.ts +3 -0
  103. package/dist/types/commands/conversationWizard.d.ts.map +1 -0
  104. package/dist/types/commands/deploy.d.ts +3 -0
  105. package/dist/types/commands/deploy.d.ts.map +1 -0
  106. package/dist/types/commands/ecom.d.ts +3 -0
  107. package/dist/types/commands/ecom.d.ts.map +1 -0
  108. package/dist/types/commands/embed.d.ts +3 -0
  109. package/dist/types/commands/embed.d.ts.map +1 -0
  110. package/dist/types/commands/init.d.ts.map +1 -1
  111. package/dist/types/commands/instructions.d.ts +3 -0
  112. package/dist/types/commands/instructions.d.ts.map +1 -0
  113. package/dist/types/commands/login.d.ts.map +1 -1
  114. package/dist/types/commands/logout.d.ts +3 -0
  115. package/dist/types/commands/logout.d.ts.map +1 -0
  116. package/dist/types/commands/serve.d.ts +3 -0
  117. package/dist/types/commands/serve.d.ts.map +1 -0
  118. package/dist/types/commands/storybook.d.ts +3 -0
  119. package/dist/types/commands/storybook.d.ts.map +1 -0
  120. package/dist/types/commands/validate.d.ts +7 -0
  121. package/dist/types/commands/validate.d.ts.map +1 -1
  122. package/dist/types/commands/whoami.d.ts +3 -0
  123. package/dist/types/commands/whoami.d.ts.map +1 -0
  124. package/dist/types/templates/aiInstructionsSchema.d.ts.map +1 -1
  125. package/dist/types/templates/cmsMappingSchema.d.ts +2 -0
  126. package/dist/types/templates/cmsMappingSchema.d.ts.map +1 -0
  127. package/dist/types/utils/print.d.ts +3 -0
  128. package/dist/types/utils/print.d.ts.map +1 -1
  129. package/dist/types/utils/project.d.ts +12 -0
  130. package/dist/types/utils/project.d.ts.map +1 -1
  131. package/dist/types/utils/wixApi.d.ts +9 -0
  132. package/dist/types/utils/wixApi.d.ts.map +1 -0
  133. package/package.json +5 -5
  134. package/defaults/package.json +0 -42
package/bin/web5.js CHANGED
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env node
2
- // eslint-disable-next-line import/no-unresolved
3
- require('../dist/cjs/cli');
2
+ require('../dist/cjs/cli.js'); // eslint-disable-line import/no-unresolved
@@ -1,38 +1,73 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
+ exports.promptSiteSelection = promptSiteSelection;
5
+ exports.refreshAccessToken = refreshAccessToken;
4
6
  exports.runDeviceFlow = runDeviceFlow;
5
- var readline = _interopRequireWildcard(require("readline"));
6
7
  var _print = require("../utils/print");
7
8
  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); }
8
- // const CLIENT_ID = '602051c7-ec4b-4334-b90d-b029b076ba8f';
9
- const CLIENT_ID = '6f95cec8-3e98-48b9-b4e5-1fb92fcd9973';
9
+ const CLIENT_ID = '602051c7-ec4b-4334-b90d-b029b076ba8f'; // web5 cli client id
10
+ // const CLIENT_ID = '6f95cec8-3e98-48b9-b4e5-1fb92fcd9973'; // Regular wix client id
10
11
  const DEVICE_CODE_URL = 'https://www.wixapis.com/oauth2/device/code';
11
12
  const TOKEN_URL = 'https://www.wixapis.com/oauth2/token';
12
13
  const POLL_INTERVAL_MS = 3000;
13
14
  const POLL_TIMEOUT_MS = 60_000;
15
+ let verboseMode = false;
16
+ function log(...args) {
17
+ if (verboseMode) {
18
+ console.log('[auth]', ...args);
19
+ }
20
+ }
14
21
  async function sleep(ms) {
15
22
  return new Promise(resolve => setTimeout(resolve, ms));
16
23
  }
17
24
  async function requestDeviceCode() {
18
- const res = await fetch(`${DEVICE_CODE_URL}?client_id=${CLIENT_ID}&scope=session_bound_access`);
25
+ const url = `${DEVICE_CODE_URL}?client_id=${CLIENT_ID}&scope=offline_access`;
26
+ log(`POST ${url}`);
27
+ const res = await fetch(url);
28
+ log(`Response: ${res.status} ${res.statusText}`);
19
29
  if (!res.ok) {
30
+ const body = await res.text().catch(() => '');
31
+ log(`Error body: ${body}`);
20
32
  throw new Error(`Device code request failed: ${res.status} ${res.statusText}`);
21
33
  }
22
- return res.json();
34
+ const data = await res.json();
35
+ log(`Device code response:`, JSON.stringify(data, null, 2));
36
+ return data;
23
37
  }
24
38
  async function pollToken(deviceCode) {
25
39
  const deadline = Date.now() + POLL_TIMEOUT_MS;
26
- const url = `${TOKEN_URL}` + `?grant_type=${encodeURIComponent('urn:ietf:params:oauth:grant-type:device_code')}` + `&client_id=${CLIENT_ID}` + `&device_code=${encodeURIComponent(deviceCode)}`;
40
+ const body = {
41
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
42
+ client_id: CLIENT_ID,
43
+ device_code: deviceCode
44
+ };
45
+ log(`Poll URL: POST ${TOKEN_URL}`);
46
+ log(`Request body:`, JSON.stringify(body, null, 2));
47
+ let attempt = 0;
27
48
  while (Date.now() < deadline) {
28
- const res = await fetch(url, {
29
- method: 'POST'
49
+ attempt++;
50
+ log(`Poll attempt #${attempt}`);
51
+ const res = await fetch(TOKEN_URL, {
52
+ method: 'POST',
53
+ headers: {
54
+ 'Content-Type': 'application/json'
55
+ },
56
+ body: JSON.stringify(body)
30
57
  });
58
+ log(`Response: ${res.status} ${res.statusText}`);
31
59
  if (res.ok) {
32
- return res.json();
60
+ const token = await res.json();
61
+ log(`Token response:`, JSON.stringify({
62
+ ...token,
63
+ access_token: '***',
64
+ refresh_token: '***'
65
+ }, null, 2));
66
+ return token;
33
67
  }
34
- const body = await res.json().catch(() => ({}));
35
- if (body.error === 'access_denied') {
68
+ const errorBody = await res.json().catch(() => ({}));
69
+ log(`Poll error body:`, JSON.stringify(errorBody, null, 2));
70
+ if (errorBody.error === 'access_denied') {
36
71
  throw new Error('Access denied');
37
72
  }
38
73
 
@@ -41,7 +76,126 @@ async function pollToken(deviceCode) {
41
76
  }
42
77
  throw new Error('Verification failed — timed out after 60 seconds. Please run `web5 login` again.');
43
78
  }
79
+ const WEB5_SITES_URL = 'https://www.wixapis.com/web5/_api/cli/web5-sites';
80
+ async function fetchWeb5Sites(accessToken) {
81
+ log(`GET ${WEB5_SITES_URL}`);
82
+ const res = await fetch(WEB5_SITES_URL, {
83
+ headers: {
84
+ Authorization: `Bearer ${accessToken}`,
85
+ Connection: 'close'
86
+ }
87
+ });
88
+ log(`Response: ${res.status} ${res.statusText}`);
89
+ if (!res.ok) {
90
+ const body = await res.text().catch(() => '');
91
+ log(`Error body: ${body}`);
92
+ throw new Error(`Failed to fetch sites: ${res.status} ${res.statusText} — ${body}`);
93
+ }
94
+ const data = await res.json();
95
+ log(`Sites response:`, JSON.stringify(data, null, 2));
96
+ return data.sites ?? [];
97
+ }
98
+ async function createWeb5Site(accessToken, name) {
99
+ const url = `${WEB5_SITES_URL}/create`;
100
+ log(`POST ${url}`);
101
+ const res = await fetch(url, {
102
+ method: 'POST',
103
+ headers: {
104
+ Authorization: `Bearer ${accessToken}`,
105
+ 'Content-Type': 'application/json',
106
+ Connection: 'close'
107
+ },
108
+ body: JSON.stringify({
109
+ name
110
+ })
111
+ });
112
+ log(`Response: ${res.status} ${res.statusText}`);
113
+ if (!res.ok) {
114
+ const body = await res.text().catch(() => '');
115
+ log(`Error body: ${body}`);
116
+ throw new Error(`Failed to create site: ${res.status} ${res.statusText} — ${body}`);
117
+ }
118
+ const site = await res.json();
119
+ log(`Create site response:`, JSON.stringify(site, null, 2));
120
+ return site;
121
+ }
122
+ async function promptCreateSite(accessToken, inquirer) {
123
+ const {
124
+ siteName
125
+ } = await inquirer.prompt([{
126
+ type: 'input',
127
+ name: 'siteName',
128
+ message: 'Enter a name for your new web5 site:',
129
+ validate: v => v.trim().length > 0 || 'Name is required'
130
+ }]);
131
+ const spin = (0, _print.spinner)('Creating new site...');
132
+ const newSite = await createWeb5Site(accessToken, siteName.trim());
133
+ spin.succeed(`Created site "${newSite.name}" (${newSite.msid})`);
134
+ return newSite.msid;
135
+ }
136
+ async function promptSiteSelection(accessToken) {
137
+ const {
138
+ default: inquirer
139
+ } = await Promise.resolve().then(() => _interopRequireWildcard(require('inquirer')));
140
+ const sites = await fetchWeb5Sites(accessToken);
141
+ if (sites.length === 0) {
142
+ (0, _print.info)("No web5 sites found. Let's create one.");
143
+ return promptCreateSite(accessToken, inquirer);
144
+ }
145
+ const CREATE_NEW = '__create_new__';
146
+ const choices = [...sites.map(s => ({
147
+ name: `${s.name} (${s.msid})`,
148
+ value: s.msid
149
+ })), {
150
+ name: 'Create a new web5 site',
151
+ value: CREATE_NEW
152
+ }];
153
+ const {
154
+ chosen
155
+ } = await inquirer.prompt([{
156
+ type: 'list',
157
+ name: 'chosen',
158
+ message: 'Select a web5 site:',
159
+ choices
160
+ }]);
161
+ if (chosen === CREATE_NEW) {
162
+ return promptCreateSite(accessToken, inquirer);
163
+ }
164
+ return chosen;
165
+ }
166
+ async function refreshAccessToken(refreshToken, siteId) {
167
+ const body = {
168
+ grant_type: 'refresh_token',
169
+ client_id: CLIENT_ID,
170
+ refresh_token: refreshToken
171
+ };
172
+ if (siteId) {
173
+ body.site_id = siteId;
174
+ }
175
+ log(`Refreshing access token: POST ${TOKEN_URL}`);
176
+ const res = await fetch(TOKEN_URL, {
177
+ method: 'POST',
178
+ headers: {
179
+ 'Content-Type': 'application/json'
180
+ },
181
+ body: JSON.stringify(body)
182
+ });
183
+ log(`Refresh response: ${res.status} ${res.statusText}`);
184
+ if (!res.ok) {
185
+ const errorBody = await res.json().catch(() => ({}));
186
+ log(`Refresh error body:`, JSON.stringify(errorBody, null, 2));
187
+ throw new Error(`Token refresh failed (${res.status}): ${errorBody.error ?? res.statusText}`);
188
+ }
189
+ const token = await res.json();
190
+ log(`Refresh token response:`, JSON.stringify({
191
+ ...token,
192
+ access_token: '***',
193
+ refresh_token: '***'
194
+ }, null, 2));
195
+ return token;
196
+ }
44
197
  async function pressEnterToContinue() {
198
+ const readline = await Promise.resolve().then(() => _interopRequireWildcard(require('readline')));
45
199
  return new Promise(resolve => {
46
200
  const rl = readline.createInterface({
47
201
  input: process.stdin,
@@ -53,16 +207,21 @@ async function pressEnterToContinue() {
53
207
  });
54
208
  });
55
209
  }
56
- async function runDeviceFlow() {
210
+ async function runDeviceFlow(verbose = false, noBrowser = false) {
211
+ verboseMode = verbose;
57
212
  const code = await requestDeviceCode();
58
213
  console.log('');
59
214
  (0, _print.info)(`Verification code: ${code.userCode}`);
60
215
  console.log(` ${code.verificationUri}`);
61
216
  console.log('');
62
- await pressEnterToContinue();
63
- const open = (await Promise.resolve().then(() => _interopRequireWildcard(require('open')))).default;
64
- await open(code.verificationUri);
65
- console.log('');
217
+ if (noBrowser) {
218
+ (0, _print.info)('Open the URL above in your browser to authenticate.');
219
+ } else {
220
+ await pressEnterToContinue();
221
+ const open = (await Promise.resolve().then(() => _interopRequireWildcard(require('open')))).default;
222
+ await open(code.verificationUri);
223
+ console.log('');
224
+ }
66
225
  const spin = (0, _print.spinner)('Waiting for approval...');
67
226
  try {
68
227
  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":["_print","require","_interopRequireWildcard","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","WEB5_SITES_URL","fetchWeb5Sites","accessToken","Authorization","Connection","sites","createWeb5Site","name","site","promptCreateSite","inquirer","siteName","prompt","type","message","validate","v","trim","length","spin","spinner","newSite","succeed","msid","promptSiteSelection","then","info","CREATE_NEW","choices","map","s","value","chosen","refreshAccessToken","refreshToken","siteId","site_id","pressEnterToContinue","readline","rl","createInterface","input","process","stdin","output","stdout","question","close","runDeviceFlow","verbose","noBrowser","code","userCode","verificationUri","open","err","fail"],"sources":["../../../src/auth/deviceFlow.ts"],"sourcesContent":["import { spinner, info } from '../utils/print';\n\nconst CLIENT_ID = '602051c7-ec4b-4334-b90d-b029b076ba8f'; // web5 cli client id\n// const CLIENT_ID = '6f95cec8-3e98-48b9-b4e5-1fb92fcd9973'; // Regular wix client id\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=offline_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\nconst WEB5_SITES_URL = 'https://www.wixapis.com/web5/_api/cli/web5-sites';\n\ninterface Site {\n msid: string;\n name: string;\n}\n\nasync function fetchWeb5Sites(accessToken: string): Promise<Site[]> {\n log(`GET ${WEB5_SITES_URL}`);\n const res = await fetch(WEB5_SITES_URL, {\n headers: { Authorization: `Bearer ${accessToken}`, Connection: 'close' },\n });\n log(`Response: ${res.status} ${res.statusText}`);\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n log(`Error body: ${body}`);\n throw new Error(\n `Failed to fetch sites: ${res.status} ${res.statusText} — ${body}`,\n );\n }\n const data = (await res.json()) as { sites?: Site[] };\n log(`Sites response:`, JSON.stringify(data, null, 2));\n return data.sites ?? [];\n}\n\nasync function createWeb5Site(\n accessToken: string,\n name: string,\n): Promise<Site> {\n const url = `${WEB5_SITES_URL}/create`;\n log(`POST ${url}`);\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n Connection: 'close',\n },\n body: JSON.stringify({ name }),\n });\n log(`Response: ${res.status} ${res.statusText}`);\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n log(`Error body: ${body}`);\n throw new Error(\n `Failed to create site: ${res.status} ${res.statusText} — ${body}`,\n );\n }\n const site = (await res.json()) as Site;\n log(`Create site response:`, JSON.stringify(site, null, 2));\n return site;\n}\n\nasync function promptCreateSite(\n accessToken: string,\n inquirer: typeof import('inquirer'),\n): Promise<string> {\n const { siteName } = await inquirer.prompt<{ siteName: string }>([\n {\n type: 'input',\n name: 'siteName',\n message: 'Enter a name for your new web5 site:',\n validate: (v: string) => v.trim().length > 0 || 'Name is required',\n },\n ]);\n const spin = spinner('Creating new site...');\n const newSite = await createWeb5Site(accessToken, siteName.trim());\n spin.succeed(`Created site \"${newSite.name}\" (${newSite.msid})`);\n return newSite.msid;\n}\n\nexport async function promptSiteSelection(\n accessToken: string,\n): Promise<string> {\n const { default: inquirer } = await import('inquirer');\n const sites = await fetchWeb5Sites(accessToken);\n\n if (sites.length === 0) {\n info(\"No web5 sites found. Let's create one.\");\n return promptCreateSite(accessToken, inquirer);\n }\n\n const CREATE_NEW = '__create_new__';\n const choices = [\n ...sites.map((s) => ({ name: `${s.name} (${s.msid})`, value: s.msid })),\n { name: 'Create a new web5 site', value: CREATE_NEW },\n ];\n\n const { chosen } = await inquirer.prompt<{ chosen: string }>([\n {\n type: 'list',\n name: 'chosen',\n message: 'Select a web5 site:',\n choices,\n },\n ]);\n\n if (chosen === CREATE_NEW) {\n return promptCreateSite(accessToken, inquirer);\n }\n\n return chosen;\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 const readline = await import('readline');\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":[]}
@@ -2,13 +2,30 @@
2
2
 
3
3
  exports.__esModule = true;
4
4
  exports.getToken = getToken;
5
+ exports.getTokenForSite = getTokenForSite;
5
6
  exports.isAuthenticated = isAuthenticated;
6
7
  exports.login = login;
7
8
  exports.logout = logout;
9
+ exports.switchSite = switchSite;
8
10
  var _deviceFlow = require("./deviceFlow");
9
11
  var _secretStore = require("./secretStore");
10
12
  var _print = require("../utils/print");
11
- async function login(apiKey) {
13
+ // Refresh proactively if the access token expires within this window
14
+ const EXPIRY_BUFFER_MS = 60_000;
15
+
16
+ // Per-process in-memory cache for site-scoped tokens. Never persisted.
17
+ const siteTokenCache = new Map();
18
+ function credentialsFromToken(token, siteId) {
19
+ return {
20
+ access_token: token.access_token,
21
+ refresh_token: token.refresh_token,
22
+ expires_at: Date.now() + token.expires_in * 1000,
23
+ ...(siteId ? {
24
+ site_id: siteId
25
+ } : {})
26
+ };
27
+ }
28
+ async function login(apiKey, verbose = false, opts = {}) {
12
29
  if (apiKey) {
13
30
  await (0, _secretStore.writeCredentials)({
14
31
  api_key: apiKey
@@ -16,13 +33,30 @@ async function login(apiKey) {
16
33
  (0, _print.success)('API key saved');
17
34
  return;
18
35
  }
19
- const token = await (0, _deviceFlow.runDeviceFlow)();
20
- await (0, _secretStore.writeCredentials)({
21
- access_token: token.access_token,
22
- refresh_token: token.refresh_token
23
- });
36
+ const token = await (0, _deviceFlow.runDeviceFlow)(verbose, opts.noBrowser ?? false);
37
+ console.log('');
38
+ const siteId = opts.siteId ?? (await (0, _deviceFlow.promptSiteSelection)(token.access_token));
39
+ const siteToken = await (0, _deviceFlow.refreshAccessToken)(token.refresh_token, siteId);
40
+ await (0, _secretStore.writeCredentials)(credentialsFromToken(siteToken, siteId));
24
41
  (0, _print.success)('Authenticated');
25
- (0, _print.success)('Tokens stored in system keychain');
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
+ // Get an unscoped token to fetch the sites list, then let user pick
55
+ const baseToken = await (0, _deviceFlow.refreshAccessToken)(creds.refresh_token);
56
+ const resolvedSiteId = siteId ?? (await (0, _deviceFlow.promptSiteSelection)(baseToken.access_token));
57
+ const refreshed = await (0, _deviceFlow.refreshAccessToken)(creds.refresh_token, resolvedSiteId);
58
+ await (0, _secretStore.writeCredentials)(credentialsFromToken(refreshed, resolvedSiteId));
59
+ (0, _print.success)(`Switched to site ${resolvedSiteId}`);
26
60
  }
27
61
  async function logout() {
28
62
  await (0, _secretStore.clearCredentials)();
@@ -33,15 +67,64 @@ async function getToken() {
33
67
  if (!creds) {
34
68
  return null;
35
69
  }
36
- if (creds.access_token) {
70
+
71
+ // API key path — no expiry concept
72
+ if (creds.api_key) {
73
+ return creds.api_key;
74
+ }
75
+
76
+ // Access token still valid
77
+ if (creds.access_token && creds.expires_at && creds.expires_at - Date.now() > EXPIRY_BUFFER_MS) {
37
78
  return creds.access_token;
38
79
  }
80
+
81
+ // Access token missing or expiring soon — try refresh
82
+ if (creds.refresh_token) {
83
+ try {
84
+ const refreshed = await (0, _deviceFlow.refreshAccessToken)(creds.refresh_token, creds.site_id);
85
+ const updated = credentialsFromToken(refreshed, creds.site_id);
86
+ await (0, _secretStore.writeCredentials)(updated);
87
+ return updated.access_token;
88
+ } catch {
89
+ // Refresh token is expired or revoked — force re-login
90
+ await (0, _secretStore.clearCredentials)();
91
+ throw new Error('Session expired. Run `web5 login` to re-authenticate.');
92
+ }
93
+ }
94
+ return null;
95
+ }
96
+ async function getTokenForSite(msid) {
97
+ const cached = siteTokenCache.get(msid);
98
+ if (cached && cached.expires_at - Date.now() > EXPIRY_BUFFER_MS) {
99
+ return cached.access_token;
100
+ }
101
+ const creds = await (0, _secretStore.readCredentials)();
102
+ if (!creds) {
103
+ throw new Error('Not authenticated. Run `web5 login` first.');
104
+ }
39
105
  if (creds.api_key) {
40
106
  return creds.api_key;
41
107
  }
42
- return creds.refresh_token ?? null;
108
+ if (!creds.refresh_token) {
109
+ throw new Error('Not authenticated. Run `web5 login` first.');
110
+ }
111
+ try {
112
+ const refreshed = await (0, _deviceFlow.refreshAccessToken)(creds.refresh_token, msid);
113
+ const entry = {
114
+ access_token: refreshed.access_token,
115
+ expires_at: Date.now() + refreshed.expires_in * 1000
116
+ };
117
+ siteTokenCache.set(msid, entry);
118
+ return entry.access_token;
119
+ } catch {
120
+ throw new Error(`Failed to get a token scoped to site ${msid}. ` + `Verify the msid in web5.config.json is correct and you have access to that site.`);
121
+ }
43
122
  }
44
123
  async function isAuthenticated() {
45
- return (await getToken()) !== null;
124
+ try {
125
+ return (await getToken()) !== null;
126
+ } catch {
127
+ return false;
128
+ }
46
129
  }
47
130
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_deviceFlow","require","_secretStore","_print","login","apiKey","writeCredentials","api_key","success","token","runDeviceFlow","access_token","refresh_token","logout","clearCredentials","getToken","creds","readCredentials","isAuthenticated"],"sources":["../../../src/auth/index.ts"],"sourcesContent":["import { runDeviceFlow } from './deviceFlow';\nimport {\n writeCredentials,\n readCredentials,\n clearCredentials,\n} from './secretStore';\nimport { success } from '../utils/print';\n\nexport type { Credentials } from './secretStore';\n\nexport async function login(apiKey?: string): 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();\n await writeCredentials({\n access_token: token.access_token,\n refresh_token: token.refresh_token,\n });\n success('Authenticated');\n success('Tokens stored in system keychain');\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 if (creds.access_token) {\n return creds.access_token;\n }\n if (creds.api_key) {\n return creds.api_key;\n }\n return creds.refresh_token ?? null;\n}\n\nexport async function isAuthenticated(): Promise<boolean> {\n return (await getToken()) !== null;\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAKA,IAAAE,MAAA,GAAAF,OAAA;AAIO,eAAeG,KAAKA,CAACC,MAAe,EAAiB;EAC1D,IAAIA,MAAM,EAAE;IACV,MAAM,IAAAC,6BAAgB,EAAC;MAAEC,OAAO,EAAEF;IAAO,CAAC,CAAC;IAC3C,IAAAG,cAAO,EAAC,eAAe,CAAC;IACxB;EACF;EAEA,MAAMC,KAAK,GAAG,MAAM,IAAAC,yBAAa,EAAC,CAAC;EACnC,MAAM,IAAAJ,6BAAgB,EAAC;IACrBK,YAAY,EAAEF,KAAK,CAACE,YAAY;IAChCC,aAAa,EAAEH,KAAK,CAACG;EACvB,CAAC,CAAC;EACF,IAAAJ,cAAO,EAAC,eAAe,CAAC;EACxB,IAAAA,cAAO,EAAC,kCAAkC,CAAC;AAC7C;AAEO,eAAeK,MAAMA,CAAA,EAAkB;EAC5C,MAAM,IAAAC,6BAAgB,EAAC,CAAC;EACxB,IAAAN,cAAO,EAAC,uCAAuC,CAAC;AAClD;AAEO,eAAeO,QAAQA,CAAA,EAA2B;EACvD,MAAMC,KAAK,GAAG,MAAM,IAAAC,4BAAe,EAAC,CAAC;EACrC,IAAI,CAACD,KAAK,EAAE;IACV,OAAO,IAAI;EACb;EACA,IAAIA,KAAK,CAACL,YAAY,EAAE;IACtB,OAAOK,KAAK,CAACL,YAAY;EAC3B;EACA,IAAIK,KAAK,CAACT,OAAO,EAAE;IACjB,OAAOS,KAAK,CAACT,OAAO;EACtB;EACA,OAAOS,KAAK,CAACJ,aAAa,IAAI,IAAI;AACpC;AAEO,eAAeM,eAAeA,CAAA,EAAqB;EACxD,OAAO,CAAC,MAAMH,QAAQ,CAAC,CAAC,MAAM,IAAI;AACpC","ignoreList":[]}
1
+ {"version":3,"names":["_deviceFlow","require","_secretStore","_print","EXPIRY_BUFFER_MS","siteTokenCache","Map","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","promptSiteSelection","siteToken","refreshAccessToken","switchSite","creds","readCredentials","Error","baseToken","resolvedSiteId","refreshed","logout","clearCredentials","getToken","updated","getTokenForSite","msid","cached","get","entry","set","isAuthenticated"],"sources":["../../../src/auth/index.ts"],"sourcesContent":["import {\n runDeviceFlow,\n refreshAccessToken,\n promptSiteSelection,\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\n// Per-process in-memory cache for site-scoped tokens. Never persisted.\nconst siteTokenCache = new Map<\n string,\n { access_token: string; expires_at: number }\n>();\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 promptSiteSelection(token.access_token));\n const siteToken = await refreshAccessToken(token.refresh_token, siteId);\n await writeCredentials(credentialsFromToken(siteToken, siteId));\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(\n 'Cannot switch site when using an API key — re-run `web5 login --site-id <msid>` instead.',\n );\n }\n if (!creds.refresh_token) {\n throw new Error('No refresh token available. Run `web5 login` first.');\n }\n // Get an unscoped token to fetch the sites list, then let user pick\n const baseToken = await refreshAccessToken(creds.refresh_token);\n const resolvedSiteId =\n siteId ?? (await promptSiteSelection(baseToken.access_token));\n const refreshed = await refreshAccessToken(\n creds.refresh_token,\n resolvedSiteId,\n );\n await writeCredentials(credentialsFromToken(refreshed, resolvedSiteId));\n success(`Switched to site ${resolvedSiteId}`);\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 getTokenForSite(msid: string): Promise<string> {\n const cached = siteTokenCache.get(msid);\n if (cached && cached.expires_at - Date.now() > EXPIRY_BUFFER_MS) {\n return cached.access_token;\n }\n\n const creds = await readCredentials();\n if (!creds) {\n throw new Error('Not authenticated. Run `web5 login` first.');\n }\n\n if (creds.api_key) {\n return creds.api_key;\n }\n\n if (!creds.refresh_token) {\n throw new Error('Not authenticated. Run `web5 login` first.');\n }\n\n try {\n const refreshed = await refreshAccessToken(creds.refresh_token, msid);\n const entry = {\n access_token: refreshed.access_token,\n expires_at: Date.now() + refreshed.expires_in * 1000,\n };\n siteTokenCache.set(msid, entry);\n return entry.access_token;\n } catch {\n throw new Error(\n `Failed to get a token scoped to site ${msid}. ` +\n `Verify the msid in web5.config.json is correct and you have access to that site.`,\n );\n }\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":"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","ignoreList":[]}
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":";;;;;;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;AAYpE,IAAIC,UAA4B,GAAG,IAAI;AAEvC,SAASC,aAAaA,CAAA,EAAW;EAC/B,MAAMC,GAAG,GAAGC,MAAM,CAAC/B,EAAE,CAACgC,QAAQ,CAAC,CAAC,CAACF,GAAG,CAAC;EACrC,MAAMG,GAAG,GAAG,GAAGjC,EAAE,CAACkC,QAAQ,CAAC,CAAC,IAAIJ,GAAG,EAAE;EACrC,OAAOjC,MAAM,CAACsC,UAAU,CAAC,QAAQ,CAAC,CAACC,MAAM,CAACH,GAAG,CAAC,CAACI,MAAM,CAAC,CAAC;AACzD;AAEA,eAAeC,WAAWA,CAAA,EAAuB;EAC/C,IAAIV,UAAU,EAAE;IACd,OAAOA,UAAU;EACnB;EAEA,IAAI;IACF;IACA,MAAMW,MAAM,GAAG,MAAAC,OAAA,CAAAC,OAAA,GAAAC,IAAA,OAAA5C,uBAAA,CAAAC,OAAA,CAAa,QAAQ,GAAC;IACrC,MAAMwC,MAAM,CAACI,WAAW,CAACpB,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;IACnD,MAAMgB,MAAM,CAACK,cAAc,CAACrB,OAAO,EAAE,QAAQ,CAAC;IAC9CK,UAAU,GAAG,UAAU;EACzB,CAAC,CAAC,MAAM;IACNA,UAAU,GAAG,MAAM;EACrB;EAEA,OAAOA,UAAU;AACnB;AAEA,SAASiB,OAAOA,CAACC,SAAiB,EAAU;EAC1C,MAAMC,GAAG,GAAGlB,aAAa,CAAC,CAAC;EAC3B,MAAMmB,EAAE,GAAGnD,MAAM,CAACoD,WAAW,CAAC,EAAE,CAAC;EACjC,MAAMC,MAAM,GAAGrD,MAAM,CAACsD,cAAc,CAAC,aAAa,EAAEJ,GAAG,EAAEC,EAAE,CAAC;EAC5D,MAAMI,SAAS,GAAGC,MAAM,CAACC,MAAM,CAAC,CAC9BJ,MAAM,CAACd,MAAM,CAACU,SAAS,EAAE,MAAM,CAAC,EAChCI,MAAM,CAACK,KAAK,CAAC,CAAC,CACf,CAAC;EACF,MAAMC,GAAG,GAAGN,MAAM,CAACO,UAAU,CAAC,CAAC;EAC/B,OAAOJ,MAAM,CAACC,MAAM,CAAC,CAACN,EAAE,EAAEQ,GAAG,EAAEJ,SAAS,CAAC,CAAC,CAACM,QAAQ,CAAC,QAAQ,CAAC;AAC/D;AAEA,SAASC,OAAOA,CAACC,UAAkB,EAAU;EAC3C,MAAMb,GAAG,GAAGlB,aAAa,CAAC,CAAC;EAC3B,MAAMgC,GAAG,GAAGR,MAAM,CAACS,IAAI,CAACF,UAAU,EAAE,QAAQ,CAAC;EAC7C,MAAMZ,EAAE,GAAGa,GAAG,CAACE,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;EAC9B,MAAMP,GAAG,GAAGK,GAAG,CAACE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;EAChC,MAAMX,SAAS,GAAGS,GAAG,CAACE,QAAQ,CAAC,EAAE,CAAC;EAClC,MAAMC,QAAQ,GAAGnE,MAAM,CAACoE,gBAAgB,CAAC,aAAa,EAAElB,GAAG,EAAEC,EAAE,CAAC;EAChEgB,QAAQ,CAACE,UAAU,CAACV,GAAG,CAAC;EACxB,OAAOQ,QAAQ,CAAC5B,MAAM,CAACgB,SAAS,CAAC,GAAGY,QAAQ,CAACT,KAAK,CAAC,MAAM,CAAC;AAC5D;AAEO,eAAeY,gBAAgBA,CAACC,KAAkB,EAAiB;EACxE,MAAMC,KAAK,GAAG,MAAM/B,WAAW,CAAC,CAAC;EACjC,MAAMgC,OAAO,GAAGC,IAAI,CAACC,SAAS,CAACJ,KAAK,CAAC;EAErC,IAAIC,KAAK,KAAK,UAAU,EAAE;IACxB,MAAM9B,MAAM,GAAG,MAAAC,OAAA,CAAAC,OAAA,GAAAC,IAAA,OAAA5C,uBAAA,CAAAC,OAAA,CAAa,QAAQ,GAAC;IACrC,MAAMwC,MAAM,CAACI,WAAW,CAACpB,OAAO,EAAEC,OAAO,EAAE8C,OAAO,CAAC;EACrD,CAAC,MAAM;IACL,MAAM,IAAAG,eAAW,EAAChD,SAAS,EAAEoB,OAAO,CAACyB,OAAO,CAAC,EAAE,KAAK,CAAC;EACvD;AACF;AAEO,eAAeI,eAAeA,CAAA,EAAgC;EACnE;EACA,MAAMC,MAAM,GAAGC,OAAO,CAACC,GAAG,CAACC,YAAY;EACvC,IAAIH,MAAM,EAAE;IACV,OAAO;MAAEI,OAAO,EAAEJ;IAAO,CAAC;EAC5B;EAEA,MAAMN,KAAK,GAAG,MAAM/B,WAAW,CAAC,CAAC;EAEjC,IAAI+B,KAAK,KAAK,UAAU,EAAE;IACxB,MAAM9B,MAAM,GAAG,MAAAC,OAAA,CAAAC,OAAA,GAAAC,IAAA,OAAA5C,uBAAA,CAAAC,OAAA,CAAa,QAAQ,GAAC;IACrC,MAAMuE,OAAO,GAAG,MAAM/B,MAAM,CAACyC,WAAW,CAACzD,OAAO,EAAEC,OAAO,CAAC;IAC1D,IAAI,CAAC8C,OAAO,EAAE;MACZ,OAAO,IAAI;IACb;IACA,OAAOC,IAAI,CAACU,KAAK,CAACX,OAAO,CAAC;EAC5B,CAAC,MAAM;IACL,IAAI;MACF,MAAMlB,SAAS,GAAG,MAAM,IAAA8B,kBAAQ,EAACzD,SAAS,EAAE,MAAM,CAAC;MACnD,OAAO8C,IAAI,CAACU,KAAK,CAACtB,OAAO,CAACP,SAAS,CAAC+B,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,MAAM;MACN,OAAO,IAAI;IACb;EACF;AACF;AAEO,eAAeC,gBAAgBA,CAAA,EAAkB;EACtD,MAAMf,KAAK,GAAG,MAAM/B,WAAW,CAAC,CAAC;EAEjC,IAAI+B,KAAK,KAAK,UAAU,EAAE;IACxB,MAAM9B,MAAM,GAAG,MAAAC,OAAA,CAAAC,OAAA,GAAAC,IAAA,OAAA5C,uBAAA,CAAAC,OAAA,CAAa,QAAQ,GAAC;IACrC,MAAMwC,MAAM,CAACK,cAAc,CAACrB,OAAO,EAAEC,OAAO,CAAC;EAC/C,CAAC,MAAM;IACL,IAAI;MACF,MAAM,IAAA6D,gBAAM,EAAC5D,SAAS,CAAC;IACzB,CAAC,CAAC,MAAM;MACN;IAAA;EAEJ;AACF","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 _whoami = require("./commands/whoami");
16
+ var _ecom = require("./commands/ecom");
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).addHelpCommand(false).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(_ecom.ecomCommand);
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
@@ -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","parseAsync","process","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 { initCommand } from './commands/init';\nimport { validateCommand } from './commands/validate';\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\nprogram.addCommand(loginCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(validateCommand);\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,KAAA,GAAAL,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AAAsD,SAAAE,wBAAAK,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAP,uBAAA,YAAAA,CAAAK,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;AAEtD;AACA,MAAMkB,GAAG,GAAGC,IAAI,CAACC,KAAK,CACpB3B,EAAE,CAAC4B,YAAY,CAAC1B,IAAI,CAAC2B,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;AAEvBJ,OAAO,CAACK,UAAU,CAACC,mBAAY,CAAC;AAChCN,OAAO,CAACK,UAAU,CAACE,iBAAW,CAAC;AAC/BP,OAAO,CAACK,UAAU,CAACG,yBAAe,CAAC;AAEnCR,OAAO,CAACS,UAAU,CAACC,OAAO,CAACC,IAAI,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_commander","require","fs","_interopRequireWildcard","path","_login","_logout","_init","_validate","_serve","_embed","_conversationWizard","_instructions","_deploy","_whoami","_ecom","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","addHelpCommand","option","hook","opts","json","process","env","WEB5_JSON_MODE","addCommand","loginCommand","logoutCommand","whoamiCommand","initCommand","validateCommand","deployCommand","serveCommand","embedCommand","ecomCommand","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 { whoamiCommand } from './commands/whoami';\nimport { ecomCommand } from './commands/ecom';\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 .addHelpCommand(false)\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(ecomCommand);\n\n// ── Wizards ───────────────────────────────────────────────────────────────\nprogram.addCommand(instructionsCommand);\nprogram.addCommand(conversationsCommand);\n\nprogram.parseAsync(process.argv);\n"],"mappings":"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","ignoreList":[]}