@nocobase/cli 2.1.0-alpha.21 → 2.1.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/download.js +170 -37
- package/dist/commands/env/add.js +39 -12
- package/dist/commands/init.js +90 -47
- package/dist/commands/install.js +191 -57
- package/dist/commands/prompts-stages.js +6 -0
- package/dist/commands/prompts-test.js +6 -0
- package/dist/lib/api-client.js +49 -5
- package/dist/lib/cli-locale.js +115 -0
- package/dist/lib/env-auth.js +2 -2
- package/dist/lib/prompt-catalog.js +87 -58
- package/dist/lib/prompt-validators.js +9 -8
- package/dist/lib/prompt-web-ui.js +143 -74
- package/dist/lib/run-npm.js +10 -10
- package/dist/lib/runtime-generator.js +12 -1
- package/dist/locale/en-US.json +333 -0
- package/dist/locale/zh-CN.json +333 -0
- package/package.json +5 -3
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { spawn } from 'node:child_process';
|
|
10
10
|
import net from 'node:net';
|
|
11
|
+
import { translateCli } from "./cli-locale.js";
|
|
11
12
|
const API_BASE_URL_EXAMPLE = 'http://localhost:13000/api';
|
|
12
13
|
const ENV_KEY_PATTERN = /^[A-Za-z0-9]+$/;
|
|
13
14
|
const TCP_PORT_EXAMPLE = '13000';
|
|
@@ -21,10 +22,10 @@ export function validateApiBaseUrl(value) {
|
|
|
21
22
|
url = new URL(raw);
|
|
22
23
|
}
|
|
23
24
|
catch {
|
|
24
|
-
return
|
|
25
|
+
return translateCli('validators.apiBaseUrl.invalid', { example: API_BASE_URL_EXAMPLE });
|
|
25
26
|
}
|
|
26
27
|
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
27
|
-
return
|
|
28
|
+
return translateCli('validators.apiBaseUrl.invalidProtocol', { example: API_BASE_URL_EXAMPLE });
|
|
28
29
|
}
|
|
29
30
|
return undefined;
|
|
30
31
|
}
|
|
@@ -34,7 +35,7 @@ export function validateEnvKey(value) {
|
|
|
34
35
|
return undefined;
|
|
35
36
|
}
|
|
36
37
|
if (!ENV_KEY_PATTERN.test(raw)) {
|
|
37
|
-
return '
|
|
38
|
+
return translateCli('validators.envKey.invalid');
|
|
38
39
|
}
|
|
39
40
|
return undefined;
|
|
40
41
|
}
|
|
@@ -59,7 +60,7 @@ export function validateTcpPort(value) {
|
|
|
59
60
|
}
|
|
60
61
|
const port = parseTcpPort(raw);
|
|
61
62
|
if (port === undefined) {
|
|
62
|
-
return
|
|
63
|
+
return translateCli('validators.tcpPort.invalid', { example: TCP_PORT_EXAMPLE });
|
|
63
64
|
}
|
|
64
65
|
return undefined;
|
|
65
66
|
}
|
|
@@ -138,7 +139,7 @@ async function allocateAvailableTcpPort() {
|
|
|
138
139
|
: undefined;
|
|
139
140
|
if (!port) {
|
|
140
141
|
server.close(() => {
|
|
141
|
-
reject(new Error('
|
|
142
|
+
reject(new Error(translateCli('validators.tcpPort.allocateFailed')));
|
|
142
143
|
});
|
|
143
144
|
return;
|
|
144
145
|
}
|
|
@@ -160,7 +161,7 @@ export async function findAvailableTcpPort() {
|
|
|
160
161
|
return candidate;
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
|
-
throw new Error('
|
|
164
|
+
throw new Error(translateCli('validators.tcpPort.allocateNotDockerPublished'));
|
|
164
165
|
}
|
|
165
166
|
export async function validateAvailableTcpPort(value) {
|
|
166
167
|
const raw = String(value ?? '').trim();
|
|
@@ -174,11 +175,11 @@ export async function validateAvailableTcpPort(value) {
|
|
|
174
175
|
const port = parseTcpPort(raw);
|
|
175
176
|
const available = await canListenOnTcpPort(port);
|
|
176
177
|
if (!available) {
|
|
177
|
-
return
|
|
178
|
+
return translateCli('validators.tcpPort.alreadyInUse', { port });
|
|
178
179
|
}
|
|
179
180
|
const dockerPorts = await getDockerPublishedTcpPorts();
|
|
180
181
|
if (dockerPorts.has(port)) {
|
|
181
|
-
return
|
|
182
|
+
return translateCli('validators.tcpPort.alreadyInUseByDocker', { port });
|
|
182
183
|
}
|
|
183
184
|
return undefined;
|
|
184
185
|
}
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { spawn } from 'node:child_process';
|
|
10
10
|
import { createServer } from 'node:http';
|
|
11
|
-
import {
|
|
11
|
+
import { createCliTranslate, resolveCliLocale, resolveLocalizedText, } from "./cli-locale.js";
|
|
12
|
+
import { isPromptBlockSkipped, runPromptFieldValidate, } from "./prompt-catalog.js";
|
|
12
13
|
const DEFAULT_SUBMIT = '/__pwc_ui_submit';
|
|
13
14
|
const DEFAULT_REFLOW = '/__pwc_ui_reflow';
|
|
14
15
|
const DEFAULT_VALIDATE_STEP = '/__pwc_ui_validate_step';
|
|
@@ -19,6 +20,9 @@ export const PWC_FORM_META_STEP = '_pwcStep';
|
|
|
19
20
|
export const PWC_FORM_META_FIELD = '_pwcField';
|
|
20
21
|
const DEFAULT_TIMEOUT_MS = 30 * 60 * 1000;
|
|
21
22
|
const DEFAULT_HOST = '127.0.0.1';
|
|
23
|
+
function resolveUiText(text, locale, fallback = '') {
|
|
24
|
+
return resolveLocalizedText(text, { locale, fallback });
|
|
25
|
+
}
|
|
22
26
|
function hasValueKey(iv, key) {
|
|
23
27
|
return (Object.prototype.hasOwnProperty.call(iv, key) && iv[key] !== undefined && iv[key] !== null);
|
|
24
28
|
}
|
|
@@ -72,12 +76,17 @@ function defaultValueForInput(key, def, out) {
|
|
|
72
76
|
case 'boolean':
|
|
73
77
|
return def.initialValue !== undefined ? Boolean(def.initialValue) : true;
|
|
74
78
|
case 'select': {
|
|
75
|
-
const first =
|
|
79
|
+
const first = def.options
|
|
80
|
+
.find((o) => typeof o === 'string' || o.disabled !== true);
|
|
81
|
+
const firstValue = typeof first === 'string' ? first : first?.value;
|
|
76
82
|
const i = def.initialValue;
|
|
77
|
-
|
|
83
|
+
const enabledValues = def.options
|
|
84
|
+
.filter((o) => typeof o === 'string' || o.disabled !== true)
|
|
85
|
+
.map((o) => (typeof o === 'string' ? o : o.value));
|
|
86
|
+
if (i !== undefined && enabledValues.includes(i)) {
|
|
78
87
|
return i;
|
|
79
88
|
}
|
|
80
|
-
return
|
|
89
|
+
return firstValue ?? '';
|
|
81
90
|
}
|
|
82
91
|
case 'password':
|
|
83
92
|
return def.initialValue ?? '';
|
|
@@ -143,7 +152,9 @@ function normalizeWebRawForBlock(def, raw, key) {
|
|
|
143
152
|
}
|
|
144
153
|
case 'select': {
|
|
145
154
|
const s = String(raw ?? '');
|
|
146
|
-
const list =
|
|
155
|
+
const list = def.options
|
|
156
|
+
.filter((o) => typeof o === 'string' || o.disabled !== true)
|
|
157
|
+
.map((o) => (typeof o === 'string' ? o : o.value));
|
|
147
158
|
if (list.includes(s)) {
|
|
148
159
|
return s;
|
|
149
160
|
}
|
|
@@ -171,6 +182,8 @@ function normalizeWebRawForBlock(def, raw, key) {
|
|
|
171
182
|
* Runs per-field **`validate`** (including async) from the catalog (honoring {@link BuildWebPresetFromBodyOptions}).
|
|
172
183
|
*/
|
|
173
184
|
export async function buildWebPresetFromBody(catalog, raw, userSeed = {}, buildOpts = {}) {
|
|
185
|
+
const locale = resolveCliLocale(buildOpts.locale);
|
|
186
|
+
const t = createCliTranslate(locale);
|
|
174
187
|
const scope = buildOpts.scopeKeys ?? null;
|
|
175
188
|
const inScope = (k) => scope === null || scope.has(k);
|
|
176
189
|
const preset = {};
|
|
@@ -198,18 +211,18 @@ export async function buildWebPresetFromBody(catalog, raw, userSeed = {}, buildO
|
|
|
198
211
|
val = defaultValueForInput(key, def, preset);
|
|
199
212
|
}
|
|
200
213
|
if (def.type === 'text' && def.required && val === '' && inScope(key)) {
|
|
201
|
-
return { preset: {}, error:
|
|
214
|
+
return { preset: {}, error: t('promptCatalog.web.fieldRequired', { key }), fieldKey: key };
|
|
202
215
|
}
|
|
203
216
|
if (def.type === 'password' && def.required && val === '' && inScope(key)) {
|
|
204
|
-
return { preset: {}, error:
|
|
217
|
+
return { preset: {}, error: t('promptCatalog.web.fieldRequired', { key }), fieldKey: key };
|
|
205
218
|
}
|
|
206
219
|
if (def.type === 'integer' && def.required && inScope(key)) {
|
|
207
|
-
const
|
|
208
|
-
if (
|
|
209
|
-
return { preset: {}, error:
|
|
220
|
+
const trimmed = String(raw[key] ?? '').trim();
|
|
221
|
+
if (trimmed === '') {
|
|
222
|
+
return { preset: {}, error: t('promptCatalog.web.fieldRequired', { key }), fieldKey: key };
|
|
210
223
|
}
|
|
211
|
-
if (!/^-?\d+$/.test(
|
|
212
|
-
return { preset: {}, error:
|
|
224
|
+
if (!/^-?\d+$/.test(trimmed)) {
|
|
225
|
+
return { preset: {}, error: t('promptCatalog.web.fieldMustBeInteger', { key }), fieldKey: key };
|
|
213
226
|
}
|
|
214
227
|
}
|
|
215
228
|
preset[key] = val;
|
|
@@ -229,7 +242,8 @@ function escapeHtml(s) {
|
|
|
229
242
|
.replace(/"/g, '"')
|
|
230
243
|
.replace(/'/g, ''');
|
|
231
244
|
}
|
|
232
|
-
function computePwcWizardSteps(options, merged) {
|
|
245
|
+
function computePwcWizardSteps(options, merged, locale) {
|
|
246
|
+
const t = createCliTranslate(locale);
|
|
233
247
|
if (options.stages && options.stages.length > 0) {
|
|
234
248
|
if (options.stages.length === 1) {
|
|
235
249
|
const st0 = options.stages[0];
|
|
@@ -239,12 +253,12 @@ function computePwcWizardSteps(options, merged) {
|
|
|
239
253
|
allKeys.push(key);
|
|
240
254
|
}
|
|
241
255
|
}
|
|
242
|
-
const
|
|
243
|
-
const
|
|
256
|
+
const title = resolveUiText(st0.sectionTitle, locale).trim();
|
|
257
|
+
const description = resolveUiText(st0.sectionDescription, locale).trim();
|
|
244
258
|
return [
|
|
245
259
|
{
|
|
246
|
-
title:
|
|
247
|
-
...(
|
|
260
|
+
title: title && title.length > 0 ? title : t('promptCatalog.web.defaultFormTitle'),
|
|
261
|
+
...(description && description.length > 0 ? { description } : {}),
|
|
248
262
|
keys: allKeys,
|
|
249
263
|
},
|
|
250
264
|
];
|
|
@@ -256,11 +270,11 @@ function computePwcWizardSteps(options, merged) {
|
|
|
256
270
|
keys.push(key);
|
|
257
271
|
}
|
|
258
272
|
}
|
|
259
|
-
const
|
|
260
|
-
const
|
|
273
|
+
const title = resolveUiText(st.sectionTitle, locale).trim();
|
|
274
|
+
const description = resolveUiText(st.sectionDescription, locale).trim();
|
|
261
275
|
return {
|
|
262
|
-
title:
|
|
263
|
-
...(
|
|
276
|
+
title: title && title.length > 0 ? title : t('promptCatalog.web.defaultStepTitle', { index: i + 1 }),
|
|
277
|
+
...(description && description.length > 0 ? { description } : {}),
|
|
264
278
|
keys,
|
|
265
279
|
};
|
|
266
280
|
});
|
|
@@ -275,23 +289,31 @@ function computePwcWizardSteps(options, merged) {
|
|
|
275
289
|
return [];
|
|
276
290
|
}
|
|
277
291
|
/* Single `catalog` (no `stages`): one page, no side Steps nav — use `stages` for multi-page UI. */
|
|
278
|
-
return [{ title: '
|
|
292
|
+
return [{ title: t('promptCatalog.web.defaultFormTitle'), keys: allKeys }];
|
|
279
293
|
}
|
|
280
294
|
/** antd Form.Item-style explain line (per-field error / help). */
|
|
281
295
|
const PWC_FORM_ITEM_EXPLAIN = '<div class="pwc-form-item-explain" data-pwc-explain="1" role="alert" hidden></div>';
|
|
282
296
|
/** Suffix slot for status icon (e.g. fail) — filled by client script. */
|
|
283
297
|
const PWC_FORM_ITEM_SUFFIX = '<span class="pwc-form-item-suffix" data-pwc-suffix="1" aria-hidden="true"></span>';
|
|
284
|
-
function renderPwcRadioOptions(key, def, defaults, hidden) {
|
|
298
|
+
function renderPwcRadioOptions(key, def, defaults, hidden, locale) {
|
|
285
299
|
return def.options
|
|
286
300
|
.map((o, index) => {
|
|
287
301
|
const val = typeof o === 'string' ? o : o.value;
|
|
288
|
-
const lab = typeof o === 'string' ? o : o.label
|
|
289
|
-
const hint = typeof o === 'string'
|
|
302
|
+
const lab = typeof o === 'string' ? o : resolveUiText(o.label, locale, o.value);
|
|
303
|
+
const hint = typeof o === 'string'
|
|
304
|
+
? ''
|
|
305
|
+
: o.hint
|
|
306
|
+
? `<div class="pwc-radio-option-hint">${escapeHtml(resolveUiText(o.hint, locale))}</div>`
|
|
307
|
+
: '';
|
|
308
|
+
const optionDisabled = typeof o !== 'string' && o.disabled === true;
|
|
290
309
|
const checked = String(defaults[key] ?? '') === val ? ' checked' : '';
|
|
291
310
|
const required = def.required && index === 0 ? ' required' : '';
|
|
292
|
-
const disabled = hidden ? ' disabled' : '';
|
|
293
|
-
|
|
294
|
-
|
|
311
|
+
const disabled = hidden || optionDisabled ? ' disabled' : '';
|
|
312
|
+
const optionClass = optionDisabled ? 'pwc-radio-option pwc-radio-option--disabled' : 'pwc-radio-option';
|
|
313
|
+
const ariaDisabled = optionDisabled ? ' aria-disabled="true"' : '';
|
|
314
|
+
const staticDisabled = optionDisabled ? ' data-pwc-static-disabled="1"' : '';
|
|
315
|
+
return (`<label class="${optionClass}"${ariaDisabled}>` +
|
|
316
|
+
`<input class="pwc-radio-input" name="${escapeHtml(key)}" type="radio" value="${escapeHtml(String(val))}"${checked}${required}${disabled}${staticDisabled} />` +
|
|
295
317
|
`<span class="pwc-radio-option-body">` +
|
|
296
318
|
`<span class="pwc-radio-option-label">${escapeHtml(String(lab))}</span>` +
|
|
297
319
|
hint +
|
|
@@ -300,18 +322,18 @@ function renderPwcRadioOptions(key, def, defaults, hidden) {
|
|
|
300
322
|
})
|
|
301
323
|
.join('');
|
|
302
324
|
}
|
|
303
|
-
function renderPwcFieldRow(key, def, defaults, show) {
|
|
325
|
+
function renderPwcFieldRow(key, def, defaults, show, locale) {
|
|
304
326
|
if (!isInputBlock(def)) {
|
|
305
327
|
return '';
|
|
306
328
|
}
|
|
307
|
-
const labelText = 'message' in def ? def.message : key;
|
|
329
|
+
const labelText = 'message' in def ? resolveUiText(def.message, locale, key) : key;
|
|
308
330
|
const hidden = show[key] === false;
|
|
309
331
|
const display = hidden ? 'none' : 'block';
|
|
310
332
|
const itemOpen = (extraClass) => `<div class="pwc-form-item${extraClass ? ` ${extraClass}` : ''}" data-pwc-wrap="${escapeHtml(key)}" data-pwc-field="${escapeHtml(key)}" style="display:${display}">`;
|
|
311
333
|
if (def.type === 'text') {
|
|
312
334
|
const req = def.required ? ' required' : '';
|
|
313
335
|
const disabled = hidden ? ' disabled' : '';
|
|
314
|
-
const ph = def.placeholder ? ` placeholder="${escapeHtml(def.placeholder)}"` : '';
|
|
336
|
+
const ph = def.placeholder ? ` placeholder="${escapeHtml(resolveUiText(def.placeholder, locale))}"` : '';
|
|
315
337
|
const v = escapeHtml(String(defaults[key] ?? ''));
|
|
316
338
|
return (itemOpen('') +
|
|
317
339
|
`<div class="pwc-form-item-label"><span class="pwc-l">${escapeHtml(labelText)}</span></div>` +
|
|
@@ -334,7 +356,7 @@ function renderPwcFieldRow(key, def, defaults, show) {
|
|
|
334
356
|
}
|
|
335
357
|
if (def.type === 'select') {
|
|
336
358
|
if (def.variant === 'radio') {
|
|
337
|
-
const opts = renderPwcRadioOptions(key, def, defaults, hidden);
|
|
359
|
+
const opts = renderPwcRadioOptions(key, def, defaults, hidden, locale);
|
|
338
360
|
return (itemOpen('') +
|
|
339
361
|
`<div class="pwc-form-item-label"><span class="pwc-l">${escapeHtml(labelText)}</span></div>` +
|
|
340
362
|
`<div class="pwc-form-item-control">` +
|
|
@@ -348,9 +370,10 @@ function renderPwcFieldRow(key, def, defaults, show) {
|
|
|
348
370
|
const opts = def.options
|
|
349
371
|
.map((o) => {
|
|
350
372
|
const val = typeof o === 'string' ? o : o.value;
|
|
351
|
-
const lab = typeof o === 'string' ? o : o.label
|
|
373
|
+
const lab = typeof o === 'string' ? o : resolveUiText(o.label, locale, o.value);
|
|
352
374
|
const sel = String(defaults[key] ?? '') === val ? ' selected' : '';
|
|
353
|
-
|
|
375
|
+
const disabledOpt = typeof o !== 'string' && o.disabled === true ? ' disabled' : '';
|
|
376
|
+
return `<option value="${escapeHtml(String(val))}"${sel}${disabledOpt}>${escapeHtml(String(lab))}</option>`;
|
|
354
377
|
})
|
|
355
378
|
.join('');
|
|
356
379
|
const req = def.required ? ' required' : '';
|
|
@@ -382,7 +405,7 @@ function renderPwcFieldRow(key, def, defaults, show) {
|
|
|
382
405
|
`</div></div>`);
|
|
383
406
|
}
|
|
384
407
|
if (def.type === 'integer') {
|
|
385
|
-
const ph = def.placeholder ? ` placeholder="${escapeHtml(def.placeholder)}"` : '';
|
|
408
|
+
const ph = def.placeholder ? ` placeholder="${escapeHtml(resolveUiText(def.placeholder, locale))}"` : '';
|
|
386
409
|
const req = def.required ? ' required' : '';
|
|
387
410
|
const disabled = hidden ? ' disabled' : '';
|
|
388
411
|
const v = String(defaults[key] ?? 0);
|
|
@@ -412,7 +435,7 @@ const PWC_FORM_FAIL_ICON_SVG = `<svg class="pwc-form-fail__svg" viewBox="0 0 14
|
|
|
412
435
|
* with CSS aligned to antd tokens (icon 32px, 14px title, `colorSplit` rail, `wait` / `process` / `finish`).
|
|
413
436
|
* Primary in steps uses antd default blue in light / `#1668dc` in dark; form primary buttons still use the page accent.
|
|
414
437
|
*/
|
|
415
|
-
function buildPwcAntdStyleStepsHeader(stepDefs, currentIndex, total, visibleStepIndices) {
|
|
438
|
+
function buildPwcAntdStyleStepsHeader(stepDefs, currentIndex, total, visibleStepIndices, uiText) {
|
|
416
439
|
const parts = [];
|
|
417
440
|
for (let i = 0; i < total; i += 1) {
|
|
418
441
|
const st = i < stepDefs.length ? stepDefs[i] : { title: `Step ${i + 1}`, keys: [] };
|
|
@@ -427,7 +450,7 @@ function buildPwcAntdStyleStepsHeader(stepDefs, currentIndex, total, visibleStep
|
|
|
427
450
|
const num = visiblePos + 1;
|
|
428
451
|
const hiddenAttr = visiblePos === -1 ? ' hidden' : '';
|
|
429
452
|
const iconHtml = state === 'finish'
|
|
430
|
-
? `<span class="pwc-ad-icon pwc-ad-icon--finish" aria-label="
|
|
453
|
+
? `<span class="pwc-ad-icon pwc-ad-icon--finish" aria-label="${escapeHtml(uiText.doneAriaLabel)}">${PWC_AD_CHECK_SVG}</span>`
|
|
431
454
|
: `<span class="pwc-ad-icon" aria-label="${num}"><span class="pwc-ad-icon-num">${num}</span></span>`;
|
|
432
455
|
const ariaCurrent = state === 'process' ? 'step' : 'false';
|
|
433
456
|
const nextVisible = visibleStepIndices.indexOf(i + 1) !== -1;
|
|
@@ -447,7 +470,7 @@ function buildPwcAntdStyleStepsHeader(stepDefs, currentIndex, total, visibleStep
|
|
|
447
470
|
`</div>` +
|
|
448
471
|
`</div></li>`);
|
|
449
472
|
}
|
|
450
|
-
return (`<nav class="pwc-ad-steps pwc-ad-steps--vertical" id="pwcAntSteps" aria-label="
|
|
473
|
+
return (`<nav class="pwc-ad-steps pwc-ad-steps--vertical" id="pwcAntSteps" aria-label="${escapeHtml(uiText.stepsAriaLabel)}" style="--pwc-ad-n:${total}">` +
|
|
451
474
|
`<ol class="pwc-ad-steps-list pwc-ad-steps-list--vertical">${parts.join('')}</ol></nav>`);
|
|
452
475
|
}
|
|
453
476
|
function computeInitialVisibleStepIndices(catalog, stepDefs, show) {
|
|
@@ -467,7 +490,7 @@ function computeInitialVisibleStepIndices(catalog, stepDefs, show) {
|
|
|
467
490
|
}
|
|
468
491
|
return visible.length > 0 ? visible : [0];
|
|
469
492
|
}
|
|
470
|
-
function buildPwcFormHtml(catalog, defaults, show, stepDefs, initialStepIndex, totalSteps) {
|
|
493
|
+
function buildPwcFormHtml(catalog, defaults, show, stepDefs, initialStepIndex, totalSteps, locale, uiText) {
|
|
471
494
|
if (stepDefs.length === 0) {
|
|
472
495
|
return '';
|
|
473
496
|
}
|
|
@@ -476,8 +499,8 @@ function buildPwcFormHtml(catalog, defaults, show, stepDefs, initialStepIndex, t
|
|
|
476
499
|
const out = [];
|
|
477
500
|
if (!oneStep) {
|
|
478
501
|
out.push('<div class="pwc-wizard pwc-wizard--with-sidebar" id="pwcWizard">');
|
|
479
|
-
out.push(
|
|
480
|
-
out.push(buildPwcAntdStyleStepsHeader(stepDefs, initialStepIndex, totalSteps, visibleStepIndices));
|
|
502
|
+
out.push(`<aside class="pwc-wizard-sidenav" id="pwcWizardSidenav" aria-label="${escapeHtml(uiText.stepsSidebarAriaLabel)}">`);
|
|
503
|
+
out.push(buildPwcAntdStyleStepsHeader(stepDefs, initialStepIndex, totalSteps, visibleStepIndices, uiText));
|
|
481
504
|
out.push('</aside><div class="pwc-wizard-main">');
|
|
482
505
|
}
|
|
483
506
|
else {
|
|
@@ -494,23 +517,23 @@ function buildPwcFormHtml(catalog, defaults, show, stepDefs, initialStepIndex, t
|
|
|
494
517
|
for (const key of sd.keys) {
|
|
495
518
|
const def = catalog[key];
|
|
496
519
|
if (def) {
|
|
497
|
-
out.push(renderPwcFieldRow(key, def, defaults, show));
|
|
520
|
+
out.push(renderPwcFieldRow(key, def, defaults, show, locale));
|
|
498
521
|
}
|
|
499
522
|
}
|
|
500
523
|
out.push('</section>');
|
|
501
524
|
}
|
|
502
525
|
if (!oneStep) {
|
|
503
|
-
out.push(`<div class="pwc-wizard-ctl" id="pwcWizardCtl" role="group" aria-label="
|
|
504
|
-
`<button type="button" class="pwc-btn-pager" id="pwcBack" ${initialStepIndex === 0 ? 'hidden' : ''}
|
|
526
|
+
out.push(`<div class="pwc-wizard-ctl" id="pwcWizardCtl" role="group" aria-label="${escapeHtml(uiText.stepNavigationAriaLabel)}">` +
|
|
527
|
+
`<button type="button" class="pwc-btn-pager" id="pwcBack" ${initialStepIndex === 0 ? 'hidden' : ''}>${escapeHtml(uiText.back)}</button>` +
|
|
505
528
|
`<div class="pwc-wizard-ctl-spacer" aria-hidden="true"></div>` +
|
|
506
|
-
`<button type="button" class="pwc-btn-pager pwc-btn-pager--primary" id="pwcNext" ${initialStepIndex >= totalSteps - 1 ? 'hidden' : ''}
|
|
507
|
-
`<button type="submit" class="pwc-btn-submit pwc-wizard-ctl__submit" id="pwcFormSubmit" ${initialStepIndex < totalSteps - 1 ? 'hidden' : ''}
|
|
529
|
+
`<button type="button" class="pwc-btn-pager pwc-btn-pager--primary" id="pwcNext" ${initialStepIndex >= totalSteps - 1 ? 'hidden' : ''}>${escapeHtml(uiText.next)}</button>` +
|
|
530
|
+
`<button type="submit" class="pwc-btn-submit pwc-wizard-ctl__submit" id="pwcFormSubmit" ${initialStepIndex < totalSteps - 1 ? 'hidden' : ''}>${escapeHtml(uiText.submit)}</button>` +
|
|
508
531
|
`</div>`);
|
|
509
532
|
}
|
|
510
533
|
else {
|
|
511
|
-
out.push(`<div class="pwc-wizard-ctl" id="pwcWizardCtl" role="group" aria-label="
|
|
534
|
+
out.push(`<div class="pwc-wizard-ctl" id="pwcWizardCtl" role="group" aria-label="${escapeHtml(uiText.submitAriaLabel)}">` +
|
|
512
535
|
`<div class="pwc-wizard-ctl-spacer" aria-hidden="true"></div>` +
|
|
513
|
-
`<button type="submit" class="pwc-btn-submit pwc-wizard-ctl__submit" id="pwcFormSubmit"
|
|
536
|
+
`<button type="submit" class="pwc-btn-submit pwc-wizard-ctl__submit" id="pwcFormSubmit">${escapeHtml(uiText.submit)}</button>` +
|
|
514
537
|
`</div>`);
|
|
515
538
|
}
|
|
516
539
|
/* Status / error Alert: under main form column only, not full-width under the side Steps. */
|
|
@@ -565,7 +588,7 @@ export function mergeWebUICatalogsFromStages(stages) {
|
|
|
565
588
|
const sectionBeforeKey = new Map();
|
|
566
589
|
const used = new Set();
|
|
567
590
|
for (const stage of stages) {
|
|
568
|
-
const title = stage.sectionTitle
|
|
591
|
+
const title = typeof stage.sectionTitle === 'string' ? stage.sectionTitle.trim() : '';
|
|
569
592
|
let needTitle = Boolean(title);
|
|
570
593
|
for (const [key, def] of Object.entries(stage.catalog)) {
|
|
571
594
|
if (isInputBlock(def) && needTitle && title) {
|
|
@@ -652,6 +675,8 @@ export function runPromptCatalogWebUI(catalogOrOptions, options) {
|
|
|
652
675
|
return runPromptCatalogWebUIImpl({ catalog: catalogOrOptions });
|
|
653
676
|
}
|
|
654
677
|
function runPromptCatalogWebUIImpl(options) {
|
|
678
|
+
const locale = resolveCliLocale(options.locale);
|
|
679
|
+
const t = createCliTranslate(locale);
|
|
655
680
|
const { merged } = resolveMergedCatalog(options);
|
|
656
681
|
const userSeed = mergeValueSeedsFromOptions(options);
|
|
657
682
|
const formDefaults = buildWebFormValuesFromCatalog(merged, userSeed);
|
|
@@ -660,15 +685,34 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
660
685
|
const reflowPath = options.reflowPath ?? DEFAULT_REFLOW;
|
|
661
686
|
const host = options.host ?? DEFAULT_HOST;
|
|
662
687
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
663
|
-
const pageTitle = options.pageTitle
|
|
664
|
-
const h1 = options.documentHeading
|
|
665
|
-
const documentHint = options.documentHint
|
|
666
|
-
'This server is only bound to the loopback interface. After submit, the CLI continues in the same terminal session.';
|
|
688
|
+
const pageTitle = resolveUiText(options.pageTitle, locale, t('promptCatalog.web.pageTitle'));
|
|
689
|
+
const h1 = resolveUiText(options.documentHeading, locale, t('promptCatalog.web.documentHeading'));
|
|
690
|
+
const documentHint = resolveUiText(options.documentHint, locale, t('promptCatalog.web.documentHint'));
|
|
667
691
|
const catalog = merged;
|
|
668
|
-
const pwcStepDefs = computePwcWizardSteps(options, catalog);
|
|
692
|
+
const pwcStepDefs = computePwcWizardSteps(options, catalog, locale);
|
|
669
693
|
const pwcNSteps = Math.max(1, pwcStepDefs.length);
|
|
670
694
|
const resolveValidateStepPath = options.validateStepPath ?? DEFAULT_VALIDATE_STEP;
|
|
671
695
|
const resolveValidateFieldPath = options.validateFieldPath ?? DEFAULT_VALIDATE_FIELD;
|
|
696
|
+
const uiText = {
|
|
697
|
+
stepsAriaLabel: t('promptCatalog.web.stepsAriaLabel'),
|
|
698
|
+
stepsSidebarAriaLabel: t('promptCatalog.web.stepsSidebarAriaLabel'),
|
|
699
|
+
stepNavigationAriaLabel: t('promptCatalog.web.stepNavigationAriaLabel'),
|
|
700
|
+
submitAriaLabel: t('promptCatalog.web.submitAriaLabel'),
|
|
701
|
+
back: t('promptCatalog.web.back'),
|
|
702
|
+
next: t('promptCatalog.web.next'),
|
|
703
|
+
submit: t('promptCatalog.web.submit'),
|
|
704
|
+
checking: t('promptCatalog.web.checking'),
|
|
705
|
+
sending: t('promptCatalog.web.sending'),
|
|
706
|
+
successTitle: t('promptCatalog.web.successTitle'),
|
|
707
|
+
errorTitle: t('promptCatalog.web.errorTitle'),
|
|
708
|
+
savedAndClosing: t('promptCatalog.web.savedAndClosing'),
|
|
709
|
+
savedCloseBlocked: t('promptCatalog.web.savedCloseBlocked'),
|
|
710
|
+
invalidValue: t('promptCatalog.web.invalidValue'),
|
|
711
|
+
invalidRequest: t('promptCatalog.web.invalidRequest'),
|
|
712
|
+
invalidStep: t('promptCatalog.web.invalidStep'),
|
|
713
|
+
invalidField: t('promptCatalog.web.invalidField'),
|
|
714
|
+
doneAriaLabel: 'done',
|
|
715
|
+
};
|
|
672
716
|
let server;
|
|
673
717
|
let timeoutId;
|
|
674
718
|
return new Promise((resolve, reject) => {
|
|
@@ -686,15 +730,16 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
686
730
|
};
|
|
687
731
|
const servePage = (port) => {
|
|
688
732
|
const base = `http://${host}:${port}`;
|
|
689
|
-
const formInner = buildPwcFormHtml(catalog, formDefaults, initialShow, pwcStepDefs, 0, pwcNSteps);
|
|
733
|
+
const formInner = buildPwcFormHtml(catalog, formDefaults, initialShow, pwcStepDefs, 0, pwcNSteps, locale, uiText);
|
|
690
734
|
const wizardClientJson = JSON.stringify({ n: pwcNSteps, stepDefs: pwcStepDefs });
|
|
691
735
|
const pwcValStepUrl = pwcNSteps > 1 ? JSON.stringify(base + resolveValidateStepPath) : 'null';
|
|
692
736
|
const pwcValFieldUrl = JSON.stringify(base + resolveValidateFieldPath);
|
|
737
|
+
const uiTextJson = JSON.stringify(uiText);
|
|
693
738
|
const pwcShellClass = options.stages && options.stages.length > 0
|
|
694
739
|
? 'pwc-shell pwc-shell--stages'
|
|
695
740
|
: 'pwc-shell';
|
|
696
741
|
const page = `<!doctype html>
|
|
697
|
-
<html lang="
|
|
742
|
+
<html lang="${escapeHtml(locale)}">
|
|
698
743
|
<head>
|
|
699
744
|
<meta charset="utf-8" />
|
|
700
745
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
@@ -1099,6 +1144,15 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1099
1144
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--pwc-ad-color-primary) 8%, transparent);
|
|
1100
1145
|
background: color-mix(in srgb, var(--pwc-ad-color-primary) 2%, var(--pwc-ad-color-container));
|
|
1101
1146
|
}
|
|
1147
|
+
.pwc-radio-option--disabled {
|
|
1148
|
+
cursor: not-allowed;
|
|
1149
|
+
background: var(--pwc-ad-color-fill-alter);
|
|
1150
|
+
}
|
|
1151
|
+
.pwc-radio-option--disabled:hover {
|
|
1152
|
+
border-color: var(--pwc-ad-color-border);
|
|
1153
|
+
box-shadow: none;
|
|
1154
|
+
background: var(--pwc-ad-color-fill-alter);
|
|
1155
|
+
}
|
|
1102
1156
|
.pwc-radio-input {
|
|
1103
1157
|
margin: 3px 0 0;
|
|
1104
1158
|
width: 16px;
|
|
@@ -1107,6 +1161,9 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1107
1161
|
accent-color: var(--pwc-ad-color-primary);
|
|
1108
1162
|
cursor: pointer;
|
|
1109
1163
|
}
|
|
1164
|
+
.pwc-radio-option--disabled .pwc-radio-input {
|
|
1165
|
+
cursor: not-allowed;
|
|
1166
|
+
}
|
|
1110
1167
|
.pwc-radio-option-body { min-width: 0; }
|
|
1111
1168
|
.pwc-radio-option-label {
|
|
1112
1169
|
display: block;
|
|
@@ -1114,12 +1171,18 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1114
1171
|
line-height: 1.5715;
|
|
1115
1172
|
color: var(--pwc-ad-color-text);
|
|
1116
1173
|
}
|
|
1174
|
+
.pwc-radio-option--disabled .pwc-radio-option-label {
|
|
1175
|
+
color: color-mix(in srgb, var(--pwc-ad-color-text) 55%, transparent);
|
|
1176
|
+
}
|
|
1117
1177
|
.pwc-radio-option-hint {
|
|
1118
1178
|
margin-top: 2px;
|
|
1119
1179
|
font-size: 12px;
|
|
1120
1180
|
line-height: 1.5;
|
|
1121
1181
|
color: var(--pwc-ad-color-text-description);
|
|
1122
1182
|
}
|
|
1183
|
+
.pwc-radio-option--disabled .pwc-radio-option-hint {
|
|
1184
|
+
color: color-mix(in srgb, var(--pwc-ad-color-text-description) 70%, transparent);
|
|
1185
|
+
}
|
|
1123
1186
|
.pwc-radio-input:focus-visible {
|
|
1124
1187
|
outline: none;
|
|
1125
1188
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--pwc-ad-color-primary) 20%, transparent);
|
|
@@ -1130,6 +1193,11 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1130
1193
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--pwc-ad-color-primary) 12%, transparent);
|
|
1131
1194
|
background: color-mix(in srgb, var(--pwc-ad-color-primary) 5%, var(--pwc-ad-color-container));
|
|
1132
1195
|
}
|
|
1196
|
+
.pwc-radio-option--disabled:has(.pwc-radio-input:checked) {
|
|
1197
|
+
border-color: var(--pwc-ad-color-border);
|
|
1198
|
+
box-shadow: none;
|
|
1199
|
+
background: var(--pwc-ad-color-fill-alter);
|
|
1200
|
+
}
|
|
1133
1201
|
.pwc-form-item-has-error .pwc-radio-option {
|
|
1134
1202
|
border-color: var(--pwc-form-color-error);
|
|
1135
1203
|
}
|
|
@@ -1328,6 +1396,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1328
1396
|
var pwcFieldMeta = ${JSON.stringify(PWC_FORM_META_FIELD)};
|
|
1329
1397
|
var s = document.getElementById('pwcStatus');
|
|
1330
1398
|
var wcfg = ${wizardClientJson};
|
|
1399
|
+
var uiText = ${uiTextJson};
|
|
1331
1400
|
var pwcN = wcfg && typeof wcfg.n === 'number' ? wcfg.n : 1;
|
|
1332
1401
|
var pwcSteps = (wcfg && wcfg.stepDefs) || [];
|
|
1333
1402
|
var pwcCur = 0;
|
|
@@ -1367,7 +1436,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1367
1436
|
s.setAttribute('role', 'alert');
|
|
1368
1437
|
s.innerHTML =
|
|
1369
1438
|
'<span class="pwc-ad-alert__icon" aria-hidden="true">' + pwcErrIcon + '</span>' +
|
|
1370
|
-
'<div class="pwc-ad-alert__inner"><div class="pwc-ad-alert__title">
|
|
1439
|
+
'<div class="pwc-ad-alert__inner"><div class="pwc-ad-alert__title">' + pwcEsc(uiText.errorTitle) + '</div>' +
|
|
1371
1440
|
'<div class="pwc-ad-alert__desc">' + pwcEsc(t) + '</div></div>';
|
|
1372
1441
|
}
|
|
1373
1442
|
function pwcSetStatusSuccess(message) {
|
|
@@ -1377,7 +1446,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1377
1446
|
s.setAttribute('role', 'status');
|
|
1378
1447
|
s.innerHTML =
|
|
1379
1448
|
'<span class="pwc-ad-alert__icon" aria-hidden="true">' + pwcOkIcon + '</span>' +
|
|
1380
|
-
'<div class="pwc-ad-alert__inner"><div class="pwc-ad-alert__title">
|
|
1449
|
+
'<div class="pwc-ad-alert__inner"><div class="pwc-ad-alert__title">' + pwcEsc(uiText.successTitle) + '</div>' +
|
|
1381
1450
|
'<div class="pwc-ad-alert__desc">' + pwcEsc(t) + '</div></div>';
|
|
1382
1451
|
}
|
|
1383
1452
|
function pwcScheduleWindowClose() {
|
|
@@ -1387,9 +1456,9 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1387
1456
|
window.close();
|
|
1388
1457
|
pwcCloseProbeTimer = setTimeout(function () {
|
|
1389
1458
|
if (!s || document.visibilityState !== 'visible') { return; }
|
|
1390
|
-
pwcSetStatusSuccess(
|
|
1459
|
+
pwcSetStatusSuccess(uiText.savedCloseBlocked);
|
|
1391
1460
|
}, 600);
|
|
1392
|
-
},
|
|
1461
|
+
}, 5000);
|
|
1393
1462
|
}
|
|
1394
1463
|
function pwcSetFieldError(key, message) {
|
|
1395
1464
|
if (!form || !key) { return; }
|
|
@@ -1536,7 +1605,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1536
1605
|
w.style.display = hidden ? 'none' : 'block';
|
|
1537
1606
|
var ctrls = w.querySelectorAll('input, select, textarea');
|
|
1538
1607
|
for (var i = 0; i < ctrls.length; i++) {
|
|
1539
|
-
ctrls[i].disabled = hidden;
|
|
1608
|
+
ctrls[i].disabled = hidden || ctrls[i].getAttribute('data-pwc-static-disabled') === '1';
|
|
1540
1609
|
}
|
|
1541
1610
|
if (!hidden && k && !pwcIsFieldDirty(k) && Object.prototype.hasOwnProperty.call(vals, k)) {
|
|
1542
1611
|
setControlValue(form, k, vals[k]);
|
|
@@ -1701,8 +1770,8 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1701
1770
|
var inp = getControl(form, k);
|
|
1702
1771
|
if (inp == null) { continue; }
|
|
1703
1772
|
if (typeof inp.checkValidity === 'function' && !inp.checkValidity()) {
|
|
1704
|
-
|
|
1705
|
-
|
|
1773
|
+
var vm = (typeof inp.validationMessage === 'string' && inp.validationMessage) ? inp.validationMessage : uiText.invalidValue;
|
|
1774
|
+
pwcSetFieldError(k, vm);
|
|
1706
1775
|
if (typeof inp.focus === 'function') { inp.focus(); }
|
|
1707
1776
|
return false;
|
|
1708
1777
|
}
|
|
@@ -1760,7 +1829,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1760
1829
|
if (pwcValStep == null) {
|
|
1761
1830
|
return reflow().then(function () { pwcSetStep(pwcVisibleNext(pwcCur)); });
|
|
1762
1831
|
}
|
|
1763
|
-
pwcSetStatusHint(
|
|
1832
|
+
pwcSetStatusHint(uiText.checking);
|
|
1764
1833
|
return fetch(pwcValStep, {
|
|
1765
1834
|
method: 'POST',
|
|
1766
1835
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -1828,7 +1897,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1828
1897
|
form.addEventListener('submit', function (e) {
|
|
1829
1898
|
e.preventDefault();
|
|
1830
1899
|
if (pwcN > 1 && pwcVisibleStepPosition(pwcCur) < pwcVisibleSteps.length - 1) { return; }
|
|
1831
|
-
pwcSetStatusHint(
|
|
1900
|
+
pwcSetStatusHint(uiText.sending);
|
|
1832
1901
|
pwcClearAllFieldErrors();
|
|
1833
1902
|
fetch(sub, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(collect()) })
|
|
1834
1903
|
.then(function (r) {
|
|
@@ -1843,7 +1912,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1843
1912
|
return r.json();
|
|
1844
1913
|
})
|
|
1845
1914
|
.then(function () {
|
|
1846
|
-
pwcSetStatusSuccess(
|
|
1915
|
+
pwcSetStatusSuccess(uiText.savedAndClosing);
|
|
1847
1916
|
pwcScheduleWindowClose();
|
|
1848
1917
|
})
|
|
1849
1918
|
.catch(function (err) {
|
|
@@ -1913,10 +1982,10 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1913
1982
|
: NaN;
|
|
1914
1983
|
if (!Number.isInteger(step) || step < 0 || step >= pwcStepDefs.length) {
|
|
1915
1984
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1916
|
-
res.end(JSON.stringify({ ok: false, error: '
|
|
1985
|
+
res.end(JSON.stringify({ ok: false, error: t('promptCatalog.web.invalidStep') }));
|
|
1917
1986
|
return;
|
|
1918
1987
|
}
|
|
1919
|
-
const { error, fieldKey } = await buildWebPresetFromBody(catalog, readFormFromClient(readFormFromClientStrippingPwcMeta(raw)), userSeed, { scopeKeys: new Set(pwcStepDefs[step].keys) });
|
|
1988
|
+
const { error, fieldKey } = await buildWebPresetFromBody(catalog, readFormFromClient(readFormFromClientStrippingPwcMeta(raw)), userSeed, { scopeKeys: new Set(pwcStepDefs[step].keys), locale });
|
|
1920
1989
|
if (error) {
|
|
1921
1990
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1922
1991
|
res.end(JSON.stringify(fieldKey ? { ok: false, error, fieldKey } : { ok: false, error }));
|
|
@@ -1927,7 +1996,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1927
1996
|
}
|
|
1928
1997
|
catch {
|
|
1929
1998
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1930
|
-
res.end(JSON.stringify({ ok: false, error: '
|
|
1999
|
+
res.end(JSON.stringify({ ok: false, error: t('promptCatalog.web.invalidRequest') }));
|
|
1931
2000
|
}
|
|
1932
2001
|
})();
|
|
1933
2002
|
});
|
|
@@ -1946,10 +2015,10 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1946
2015
|
: '';
|
|
1947
2016
|
if (!fieldKey || !Object.prototype.hasOwnProperty.call(catalog, fieldKey)) {
|
|
1948
2017
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1949
|
-
res.end(JSON.stringify({ ok: false, error: '
|
|
2018
|
+
res.end(JSON.stringify({ ok: false, error: t('promptCatalog.web.invalidField') }));
|
|
1950
2019
|
return;
|
|
1951
2020
|
}
|
|
1952
|
-
const { error } = await buildWebPresetFromBody(catalog, readFormFromClient(readFormFromClientStrippingPwcMeta(raw)), userSeed, { scopeKeys: new Set([fieldKey]) });
|
|
2021
|
+
const { error } = await buildWebPresetFromBody(catalog, readFormFromClient(readFormFromClientStrippingPwcMeta(raw)), userSeed, { scopeKeys: new Set([fieldKey]), locale });
|
|
1953
2022
|
if (error) {
|
|
1954
2023
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1955
2024
|
res.end(JSON.stringify({ ok: false, error, fieldKey }));
|
|
@@ -1960,7 +2029,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1960
2029
|
}
|
|
1961
2030
|
catch {
|
|
1962
2031
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1963
|
-
res.end(JSON.stringify({ ok: false, error: '
|
|
2032
|
+
res.end(JSON.stringify({ ok: false, error: t('promptCatalog.web.invalidRequest') }));
|
|
1964
2033
|
}
|
|
1965
2034
|
})();
|
|
1966
2035
|
});
|
|
@@ -1973,7 +2042,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1973
2042
|
void (async () => {
|
|
1974
2043
|
try {
|
|
1975
2044
|
const raw = JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
1976
|
-
const { preset, error, fieldKey } = await buildWebPresetFromBody(catalog, readFormFromClient(raw), userSeed);
|
|
2045
|
+
const { preset, error, fieldKey } = await buildWebPresetFromBody(catalog, readFormFromClient(raw), userSeed, { locale });
|
|
1977
2046
|
if (error) {
|
|
1978
2047
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
1979
2048
|
res.end(JSON.stringify(fieldKey ? { ok: false, error, fieldKey } : { ok: false, error }));
|
|
@@ -1994,7 +2063,7 @@ function runPromptCatalogWebUIImpl(options) {
|
|
|
1994
2063
|
}
|
|
1995
2064
|
catch (e) {
|
|
1996
2065
|
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
1997
|
-
res.end('
|
|
2066
|
+
res.end(t('promptCatalog.web.invalidRequest'));
|
|
1998
2067
|
}
|
|
1999
2068
|
})();
|
|
2000
2069
|
});
|