@kizenapps/cli 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/electron/main.js +9 -8
- package/dist/electron/main.js.map +1 -1
- package/dist/index.js +293 -58
- package/dist/index.js.map +1 -1
- package/dist/viewer/assets/index-B09qenTV.js +17 -0
- package/dist/viewer/assets/{index-C_6izRRh.js → index-CVd4BLit.js} +2 -2
- package/dist/viewer/assets/{index-CBBwr2o_.js → index-C_gRcfsL.js} +2 -2
- package/dist/viewer/assets/index-CcvbGL5I.js +17 -0
- package/dist/viewer/assets/index-Ci5up9QD.js +17 -0
- package/dist/viewer/assets/index-DOiSISo1.css +2 -0
- package/dist/viewer/assets/{index-DcGGXuA3.js → index-DSJAwx9Y.js} +2 -2
- package/dist/viewer/assets/index-WnCF0zx3.js +17 -0
- package/dist/viewer/assets/{index--m1PKX6N.js → index-_K33TupM.js} +2 -2
- package/dist/viewer/assets/index-dPV4go8k.js +17 -0
- package/dist/viewer/assets/index-xFuxlPJA.js +17 -0
- package/dist/viewer/index.html +2 -2
- package/package.json +1 -1
- package/dist/viewer/assets/index-2OcBnmZB.js +0 -17
- package/dist/viewer/assets/index-7ah1RuPy.js +0 -17
- package/dist/viewer/assets/index-B3gNsKTt.js +0 -17
- package/dist/viewer/assets/index-B40AtXqk.js +0 -17
- package/dist/viewer/assets/index-B4ikC-wc.js +0 -17
- package/dist/viewer/assets/index-BKOfPpLS.js +0 -17
- package/dist/viewer/assets/index-BM3JrC-1.js +0 -17
- package/dist/viewer/assets/index-BUnK11-F.js +0 -17
- package/dist/viewer/assets/index-Bc7IZVr6.js +0 -17
- package/dist/viewer/assets/index-C1KzcpVj.js +0 -17
- package/dist/viewer/assets/index-CHtXWYIY.js +0 -17
- package/dist/viewer/assets/index-CN9NvJkQ.js +0 -17
- package/dist/viewer/assets/index-CNKPBxhv.js +0 -17
- package/dist/viewer/assets/index-CgzK6zig.js +0 -17
- package/dist/viewer/assets/index-Cw2cxYy2.js +0 -17
- package/dist/viewer/assets/index-D06uhGtQ.js +0 -17
- package/dist/viewer/assets/index-DAHWT-g0.js +0 -17
- package/dist/viewer/assets/index-DAxJgHat.js +0 -17
- package/dist/viewer/assets/index-DF_geUaW.js +0 -17
- package/dist/viewer/assets/index-DlVmY-nR.js +0 -17
- package/dist/viewer/assets/index-FZw9Ev_R.js +0 -17
- package/dist/viewer/assets/index-M1Obm_99.js +0 -17
- package/dist/viewer/assets/index-_kM1Ri7v.js +0 -17
- package/dist/viewer/assets/index-aTt_sTlu.js +0 -17
- package/dist/viewer/assets/index-vYFGGFc2.js +0 -17
package/dist/electron/main.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/electron/main.ts
|
|
2
|
-
import { app, BrowserWindow, session, nativeImage, Menu, ipcMain } from "electron";
|
|
2
|
+
import { app, BrowserWindow, session, nativeImage, Menu, ipcMain, screen } from "electron";
|
|
3
3
|
import { join, dirname } from "path";
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
var args = process.argv.slice(2);
|
|
@@ -79,9 +79,10 @@ void app.whenReady().then(() => {
|
|
|
79
79
|
if (process.platform === "darwin" && !icon.isEmpty()) {
|
|
80
80
|
app.dock?.setIcon(icon);
|
|
81
81
|
}
|
|
82
|
+
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
|
|
82
83
|
const win = new BrowserWindow({
|
|
83
|
-
width
|
|
84
|
-
height
|
|
84
|
+
width,
|
|
85
|
+
height,
|
|
85
86
|
title: "Kizen App Builder",
|
|
86
87
|
icon,
|
|
87
88
|
webPreferences: {
|
|
@@ -186,11 +187,11 @@ void app.whenReady().then(() => {
|
|
|
186
187
|
return;
|
|
187
188
|
}
|
|
188
189
|
const level = type === "warning" ? "warn" : ["log", "warn", "error", "info"].includes(type) ? type : "log";
|
|
189
|
-
void Promise.all(
|
|
190
|
-
(
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
);
|
|
190
|
+
void Promise.all(
|
|
191
|
+
args2.map((arg) => serializeArgAsync(arg, sessionId))
|
|
192
|
+
).then((serializedArgs) => {
|
|
193
|
+
win.webContents.send("console-message", { level, args: serializedArgs });
|
|
194
|
+
});
|
|
194
195
|
});
|
|
195
196
|
void win.loadURL(`http://localhost:${String(port)}`);
|
|
196
197
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/electron/main.ts"],"sourcesContent":["import { app, BrowserWindow, session, nativeImage, Menu, ipcMain } from 'electron';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst args = process.argv.slice(2);\nconst port = parseInt(args.find((a) => a.startsWith('--port='))?.slice(7) ?? '3121', 10);\nconst userDataDir = args.find((a) => a.startsWith('--user-data-dir='))?.slice(16);\n\nif (userDataDir) {\n app.setPath('userData', userDataDir);\n}\n\napp.setName('Kizen App Builder');\n\nconst CSP_HEADERS = new Set([\n 'content-security-policy',\n 'content-security-policy-report-only',\n 'x-frame-options',\n]);\n\nconst KIZEN_DOMAINS = ['kizen.dev', 'kizen.com'];\n\nfunction isKizenUrl(url: string): boolean {\n try {\n const { hostname } = new URL(url);\n return KIZEN_DOMAINS.some((d) => hostname === d || hostname.endsWith('.' + d));\n } catch {\n return false;\n }\n}\n\nfunction setupSession(): void {\n // Strip CSP headers and fix SameSite cookies on Kizen responses.\n session.defaultSession.webRequest.onHeadersReceived((details, callback) => {\n const headers: Record<string, string[]> = {};\n\n for (const [key, value] of Object.entries(details.responseHeaders ?? {})) {\n if (!CSP_HEADERS.has(key.toLowerCase())) {\n headers[key] = value;\n }\n }\n\n if (isKizenUrl(details.url) && headers['set-cookie']) {\n headers['set-cookie'] = headers['set-cookie'].map((cookie) => {\n if (!/SameSite=/i.test(cookie)) {\n return cookie + '; SameSite=None; Secure';\n }\n\n return cookie.replace(/SameSite=\\w+/i, 'SameSite=None');\n });\n }\n\n callback({ responseHeaders: headers });\n });\n\n // Periodically re-patch existing Kizen cookies that arrived without SameSite=None.\n // Needed for cookies set before the interceptor was active or via JS document.cookie.\n setInterval(() => {\n void (async () => {\n for (const domain of KIZEN_DOMAINS) {\n try {\n const cookies = await session.defaultSession.cookies.get({ domain });\n for (const cookie of cookies) {\n if (cookie.sameSite !== 'no_restriction') {\n const raw = cookie.domain ?? domain;\n const bare = raw.startsWith('.') ? raw.slice(1) : raw;\n await session.defaultSession.cookies.set({\n url: `https://${bare}`,\n name: cookie.name,\n value: cookie.value,\n domain: raw,\n path: cookie.path ?? '/',\n secure: true,\n ...(cookie.httpOnly !== undefined && { httpOnly: cookie.httpOnly }),\n ...(cookie.expirationDate !== undefined && {\n expirationDate: cookie.expirationDate,\n }),\n sameSite: 'no_restriction',\n });\n }\n }\n } catch {\n /* ignore */\n }\n }\n })();\n }, 2000);\n}\n\nvoid app.whenReady().then(() => {\n Menu.setApplicationMenu(null);\n\n setupSession();\n\n const iconPath = join(dirname(fileURLToPath(import.meta.url)), 'icon.png');\n const icon = nativeImage.createFromPath(iconPath);\n\n if (process.platform === 'darwin' && !icon.isEmpty()) {\n app.dock?.setIcon(icon);\n }\n\n const win = new BrowserWindow({\n width: 1920,\n height: 1080,\n title: 'Kizen App Builder',\n icon,\n webPreferences: {\n nodeIntegration: false,\n contextIsolation: true,\n sandbox: false,\n preload: join(dirname(fileURLToPath(import.meta.url)), 'preload.cjs'),\n },\n });\n\n ipcMain.on('open-devtools', () => {\n win.webContents.openDevTools();\n });\n\n interface PropertyPreview {\n name: string;\n type: string;\n value?: string;\n subtype?: string;\n valuePreview?: ObjectPreview;\n }\n interface ObjectPreview {\n type: string;\n subtype?: string;\n overflow: boolean;\n properties: PropertyPreview[];\n }\n interface RemoteObject {\n type: string;\n subtype?: string;\n value?: unknown;\n description?: string;\n preview?: ObjectPreview;\n objectId?: string;\n }\n interface ConsoleApiCalledParams {\n type: string;\n args: RemoteObject[];\n }\n\n function parseProp(prop: PropertyPreview): unknown {\n if (prop.type === 'number') {\n return Number(prop.value);\n }\n if (prop.type === 'boolean') {\n return prop.value === 'true';\n }\n if (prop.type === 'undefined') {\n return undefined;\n }\n if (prop.type === 'object' && prop.value === 'null') {\n return null;\n }\n if (prop.type === 'object' && prop.valuePreview) {\n const { valuePreview } = prop;\n if (valuePreview.subtype === 'array') {\n return valuePreview.properties\n .filter((p) => /^\\d+$/.test(p.name))\n .sort((a, b) => parseInt(a.name) - parseInt(b.name))\n .map(parseProp);\n }\n const obj: Record<string, unknown> = {};\n for (const p of valuePreview.properties) {\n obj[p.name] = parseProp(p);\n }\n return obj;\n }\n return prop.value ?? `[${prop.type}]`;\n }\n\n function serializeArg(arg: RemoteObject): unknown {\n if (arg.value !== undefined) {\n return arg.value;\n }\n if (arg.preview) {\n const { preview } = arg;\n if (preview.subtype === 'array') {\n return preview.properties\n .filter((p) => /^\\d+$/.test(p.name))\n .sort((a, b) => parseInt(a.name) - parseInt(b.name))\n .map(parseProp);\n }\n const obj: Record<string, unknown> = {};\n for (const prop of preview.properties) {\n obj[prop.name] = parseProp(prop);\n }\n return obj;\n }\n return arg.description ?? `[${arg.type}]`;\n }\n\n const enableRuntime = (sessionId?: string): void => {\n void win.webContents.debugger.sendCommand(\n 'Runtime.enable',\n { generatePreview: true },\n sessionId,\n );\n };\n\n win.webContents.debugger.attach('1.3');\n enableRuntime();\n void win.webContents.debugger.sendCommand('Target.setAutoAttach', {\n autoAttach: true,\n waitForDebuggerOnStart: false,\n flatten: true,\n });\n\n async function serializeArgAsync(arg: RemoteObject, sessionId?: string): Promise<unknown> {\n if (arg.type === 'object' && arg.objectId) {\n try {\n const result: unknown = await win.webContents.debugger.sendCommand(\n 'Runtime.callFunctionOn',\n {\n objectId: arg.objectId,\n functionDeclaration:\n 'function() { const seen = new WeakSet(); return JSON.stringify(this, function(k, v) { if (typeof v === \"object\" && v !== null) { if (seen.has(v)) return \"[Circular]\"; seen.add(v); } return v; }); }',\n returnByValue: true,\n },\n sessionId,\n );\n const val = (result as { result: { value?: string } }).result.value;\n if (typeof val === 'string') {\n return JSON.parse(val);\n }\n } catch {\n // fall through to preview-based serialization\n }\n }\n return serializeArg(arg);\n }\n\n win.webContents.debugger.on('message', (_event, method, params, sessionId) => {\n if (method === 'Target.attachedToTarget') {\n const { sessionId: childSessionId } = params as { sessionId: string };\n enableRuntime(childSessionId);\n return;\n }\n\n if (method !== 'Runtime.consoleAPICalled') {\n return;\n }\n const { type, args } = params as ConsoleApiCalledParams;\n if (args[0]?.type === 'string' && String(args[0].value).includes('Electron Security Warning')) {\n return;\n }\n const level =\n type === 'warning' ? 'warn' : ['log', 'warn', 'error', 'info'].includes(type) ? type : 'log';\n void Promise.all(args.map((arg) => serializeArgAsync(arg, sessionId as string | undefined))).then(\n (serializedArgs) => {\n win.webContents.send('console-message', { level, args: serializedArgs });\n },\n );\n });\n\n void win.loadURL(`http://localhost:${String(port)}`);\n});\n\napp.on('window-all-closed', () => {\n app.quit();\n});\n"],"mappings":"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","names":["args"]}
|
|
1
|
+
{"version":3,"sources":["../../src/electron/main.ts"],"sourcesContent":["import { app, BrowserWindow, session, nativeImage, Menu, ipcMain, screen } from 'electron';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst args = process.argv.slice(2);\nconst port = parseInt(args.find((a) => a.startsWith('--port='))?.slice(7) ?? '3121', 10);\nconst userDataDir = args.find((a) => a.startsWith('--user-data-dir='))?.slice(16);\n\nif (userDataDir) {\n app.setPath('userData', userDataDir);\n}\n\napp.setName('Kizen App Builder');\n\nconst CSP_HEADERS = new Set([\n 'content-security-policy',\n 'content-security-policy-report-only',\n 'x-frame-options',\n]);\n\nconst KIZEN_DOMAINS = ['kizen.dev', 'kizen.com'];\n\nfunction isKizenUrl(url: string): boolean {\n try {\n const { hostname } = new URL(url);\n return KIZEN_DOMAINS.some((d) => hostname === d || hostname.endsWith('.' + d));\n } catch {\n return false;\n }\n}\n\nfunction setupSession(): void {\n // Strip CSP headers and fix SameSite cookies on Kizen responses.\n session.defaultSession.webRequest.onHeadersReceived((details, callback) => {\n const headers: Record<string, string[]> = {};\n\n for (const [key, value] of Object.entries(details.responseHeaders ?? {})) {\n if (!CSP_HEADERS.has(key.toLowerCase())) {\n headers[key] = value;\n }\n }\n\n if (isKizenUrl(details.url) && headers['set-cookie']) {\n headers['set-cookie'] = headers['set-cookie'].map((cookie) => {\n if (!/SameSite=/i.test(cookie)) {\n return cookie + '; SameSite=None; Secure';\n }\n\n return cookie.replace(/SameSite=\\w+/i, 'SameSite=None');\n });\n }\n\n callback({ responseHeaders: headers });\n });\n\n // Periodically re-patch existing Kizen cookies that arrived without SameSite=None.\n // Needed for cookies set before the interceptor was active or via JS document.cookie.\n setInterval(() => {\n void (async () => {\n for (const domain of KIZEN_DOMAINS) {\n try {\n const cookies = await session.defaultSession.cookies.get({ domain });\n for (const cookie of cookies) {\n if (cookie.sameSite !== 'no_restriction') {\n const raw = cookie.domain ?? domain;\n const bare = raw.startsWith('.') ? raw.slice(1) : raw;\n await session.defaultSession.cookies.set({\n url: `https://${bare}`,\n name: cookie.name,\n value: cookie.value,\n domain: raw,\n path: cookie.path ?? '/',\n secure: true,\n ...(cookie.httpOnly !== undefined && { httpOnly: cookie.httpOnly }),\n ...(cookie.expirationDate !== undefined && {\n expirationDate: cookie.expirationDate,\n }),\n sameSite: 'no_restriction',\n });\n }\n }\n } catch {\n /* ignore */\n }\n }\n })();\n }, 2000);\n}\n\nvoid app.whenReady().then(() => {\n Menu.setApplicationMenu(null);\n\n setupSession();\n\n const iconPath = join(dirname(fileURLToPath(import.meta.url)), 'icon.png');\n const icon = nativeImage.createFromPath(iconPath);\n\n if (process.platform === 'darwin' && !icon.isEmpty()) {\n app.dock?.setIcon(icon);\n }\n\n const { width, height } = screen.getPrimaryDisplay().workAreaSize;\n\n const win = new BrowserWindow({\n width,\n height,\n title: 'Kizen App Builder',\n icon,\n webPreferences: {\n nodeIntegration: false,\n contextIsolation: true,\n sandbox: false,\n preload: join(dirname(fileURLToPath(import.meta.url)), 'preload.cjs'),\n },\n });\n\n ipcMain.on('open-devtools', () => {\n win.webContents.openDevTools();\n });\n\n interface PropertyPreview {\n name: string;\n type: string;\n value?: string;\n subtype?: string;\n valuePreview?: ObjectPreview;\n }\n interface ObjectPreview {\n type: string;\n subtype?: string;\n overflow: boolean;\n properties: PropertyPreview[];\n }\n interface RemoteObject {\n type: string;\n subtype?: string;\n value?: unknown;\n description?: string;\n preview?: ObjectPreview;\n objectId?: string;\n }\n interface ConsoleApiCalledParams {\n type: string;\n args: RemoteObject[];\n }\n\n function parseProp(prop: PropertyPreview): unknown {\n if (prop.type === 'number') {\n return Number(prop.value);\n }\n if (prop.type === 'boolean') {\n return prop.value === 'true';\n }\n if (prop.type === 'undefined') {\n return undefined;\n }\n if (prop.type === 'object' && prop.value === 'null') {\n return null;\n }\n if (prop.type === 'object' && prop.valuePreview) {\n const { valuePreview } = prop;\n if (valuePreview.subtype === 'array') {\n return valuePreview.properties\n .filter((p) => /^\\d+$/.test(p.name))\n .sort((a, b) => parseInt(a.name) - parseInt(b.name))\n .map(parseProp);\n }\n const obj: Record<string, unknown> = {};\n for (const p of valuePreview.properties) {\n obj[p.name] = parseProp(p);\n }\n return obj;\n }\n return prop.value ?? `[${prop.type}]`;\n }\n\n function serializeArg(arg: RemoteObject): unknown {\n if (arg.value !== undefined) {\n return arg.value;\n }\n if (arg.preview) {\n const { preview } = arg;\n if (preview.subtype === 'array') {\n return preview.properties\n .filter((p) => /^\\d+$/.test(p.name))\n .sort((a, b) => parseInt(a.name) - parseInt(b.name))\n .map(parseProp);\n }\n const obj: Record<string, unknown> = {};\n for (const prop of preview.properties) {\n obj[prop.name] = parseProp(prop);\n }\n return obj;\n }\n return arg.description ?? `[${arg.type}]`;\n }\n\n const enableRuntime = (sessionId?: string): void => {\n void win.webContents.debugger.sendCommand(\n 'Runtime.enable',\n { generatePreview: true },\n sessionId,\n );\n };\n\n win.webContents.debugger.attach('1.3');\n enableRuntime();\n void win.webContents.debugger.sendCommand('Target.setAutoAttach', {\n autoAttach: true,\n waitForDebuggerOnStart: false,\n flatten: true,\n });\n\n async function serializeArgAsync(arg: RemoteObject, sessionId?: string): Promise<unknown> {\n if (arg.type === 'object' && arg.objectId) {\n try {\n const result: unknown = await win.webContents.debugger.sendCommand(\n 'Runtime.callFunctionOn',\n {\n objectId: arg.objectId,\n functionDeclaration:\n 'function() { const seen = new WeakSet(); return JSON.stringify(this, function(k, v) { if (typeof v === \"object\" && v !== null) { if (seen.has(v)) return \"[Circular]\"; seen.add(v); } return v; }); }',\n returnByValue: true,\n },\n sessionId,\n );\n const val = (result as { result: { value?: string } }).result.value;\n if (typeof val === 'string') {\n return JSON.parse(val);\n }\n } catch {\n // fall through to preview-based serialization\n }\n }\n return serializeArg(arg);\n }\n\n win.webContents.debugger.on('message', (_event, method, params, sessionId) => {\n if (method === 'Target.attachedToTarget') {\n const { sessionId: childSessionId } = params as { sessionId: string };\n enableRuntime(childSessionId);\n return;\n }\n\n if (method !== 'Runtime.consoleAPICalled') {\n return;\n }\n const { type, args } = params as ConsoleApiCalledParams;\n if (args[0]?.type === 'string' && String(args[0].value).includes('Electron Security Warning')) {\n return;\n }\n const level =\n type === 'warning' ? 'warn' : ['log', 'warn', 'error', 'info'].includes(type) ? type : 'log';\n void Promise.all(\n args.map((arg) => serializeArgAsync(arg, sessionId as string | undefined)),\n ).then((serializedArgs) => {\n win.webContents.send('console-message', { level, args: serializedArgs });\n });\n });\n\n void win.loadURL(`http://localhost:${String(port)}`);\n});\n\napp.on('window-all-closed', () => {\n app.quit();\n});\n"],"mappings":"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","names":["args"]}
|
package/dist/index.js
CHANGED
|
@@ -269,33 +269,14 @@ function createProxyCache() {
|
|
|
269
269
|
};
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
// src/lib/config.ts
|
|
273
|
-
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
274
|
-
import { join as join4 } from "path";
|
|
275
|
-
async function loadConfig(outputDir) {
|
|
276
|
-
try {
|
|
277
|
-
const content = await readFile2(join4(outputDir, "config.json"), "utf-8");
|
|
278
|
-
return JSON.parse(content);
|
|
279
|
-
} catch {
|
|
280
|
-
return {};
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
async function saveConfig(outputDir, config) {
|
|
284
|
-
await mkdir2(outputDir, { recursive: true });
|
|
285
|
-
await writeFile2(join4(outputDir, "config.json"), JSON.stringify(config, null, 2), "utf-8");
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// src/ui/CredentialSetupUI.tsx
|
|
289
|
-
import { useCallback, useEffect as useEffect2, useState as useState2 } from "react";
|
|
290
|
-
import { Box as Box3, Text as Text3, useInput } from "ink";
|
|
291
|
-
|
|
292
272
|
// src/lib/credentials.ts
|
|
293
|
-
import { mkdir as
|
|
273
|
+
import { mkdir as mkdir2, readFile as readFile2, readdir as readdir2, writeFile as writeFile2 } from "fs/promises";
|
|
294
274
|
import { homedir } from "os";
|
|
295
|
-
import { dirname, join as
|
|
275
|
+
import { dirname, join as join4 } from "path";
|
|
296
276
|
var ENVIRONMENTS = ["go", "fmo", "staging", "integration", "test1"];
|
|
297
|
-
var GLOBAL_CREDENTIALS_DIR =
|
|
298
|
-
var GLOBAL_CREDENTIALS_PATH =
|
|
277
|
+
var GLOBAL_CREDENTIALS_DIR = join4(homedir(), ".kizenappbuilder");
|
|
278
|
+
var GLOBAL_CREDENTIALS_PATH = join4(GLOBAL_CREDENTIALS_DIR, "credentials.json");
|
|
279
|
+
var DEFAULT_PROFILE_NAME = "credentials";
|
|
299
280
|
function isValidEnvironment(value) {
|
|
300
281
|
return ENVIRONMENTS.includes(value);
|
|
301
282
|
}
|
|
@@ -313,7 +294,7 @@ function parseCredentials(raw) {
|
|
|
313
294
|
};
|
|
314
295
|
}
|
|
315
296
|
async function loadCredentialsFromFile(filePath) {
|
|
316
|
-
const content = await
|
|
297
|
+
const content = await readFile2(filePath, "utf-8");
|
|
317
298
|
return parseCredentials(JSON.parse(content));
|
|
318
299
|
}
|
|
319
300
|
async function loadGlobalCredentials() {
|
|
@@ -324,11 +305,63 @@ async function loadGlobalCredentials() {
|
|
|
324
305
|
}
|
|
325
306
|
}
|
|
326
307
|
async function saveGlobalCredentials(credentials) {
|
|
327
|
-
await
|
|
328
|
-
await
|
|
308
|
+
await mkdir2(dirname(GLOBAL_CREDENTIALS_PATH), { recursive: true });
|
|
309
|
+
await writeFile2(GLOBAL_CREDENTIALS_PATH, JSON.stringify(credentials, null, 2), "utf-8");
|
|
310
|
+
}
|
|
311
|
+
function getProfilePath(name) {
|
|
312
|
+
return join4(GLOBAL_CREDENTIALS_DIR, `${name}.json`);
|
|
313
|
+
}
|
|
314
|
+
async function listCredentialProfiles() {
|
|
315
|
+
const profiles = [
|
|
316
|
+
{ name: DEFAULT_PROFILE_NAME, path: GLOBAL_CREDENTIALS_PATH, isDefault: true }
|
|
317
|
+
];
|
|
318
|
+
try {
|
|
319
|
+
const entries = await readdir2(GLOBAL_CREDENTIALS_DIR);
|
|
320
|
+
for (const entry of entries) {
|
|
321
|
+
if (!entry.endsWith(".json")) continue;
|
|
322
|
+
const name = entry.slice(0, -5);
|
|
323
|
+
if (name === DEFAULT_PROFILE_NAME) continue;
|
|
324
|
+
profiles.push({ name, path: join4(GLOBAL_CREDENTIALS_DIR, entry), isDefault: false });
|
|
325
|
+
}
|
|
326
|
+
} catch {
|
|
327
|
+
}
|
|
328
|
+
return profiles;
|
|
329
|
+
}
|
|
330
|
+
async function saveCredentialProfile(name, credentials) {
|
|
331
|
+
if (name === DEFAULT_PROFILE_NAME) {
|
|
332
|
+
await saveGlobalCredentials(credentials);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
await mkdir2(GLOBAL_CREDENTIALS_DIR, { recursive: true });
|
|
336
|
+
await writeFile2(getProfilePath(name), JSON.stringify(credentials, null, 2), "utf-8");
|
|
337
|
+
}
|
|
338
|
+
async function loadCredentialProfile(name) {
|
|
339
|
+
try {
|
|
340
|
+
return await loadCredentialsFromFile(getProfilePath(name));
|
|
341
|
+
} catch {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// src/lib/config.ts
|
|
347
|
+
import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
348
|
+
import { join as join5 } from "path";
|
|
349
|
+
async function loadConfig(outputDir) {
|
|
350
|
+
try {
|
|
351
|
+
const content = await readFile3(join5(outputDir, "config.json"), "utf-8");
|
|
352
|
+
return JSON.parse(content);
|
|
353
|
+
} catch {
|
|
354
|
+
return {};
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
async function saveConfig(outputDir, config) {
|
|
358
|
+
await mkdir3(outputDir, { recursive: true });
|
|
359
|
+
await writeFile3(join5(outputDir, "config.json"), JSON.stringify(config, null, 2), "utf-8");
|
|
329
360
|
}
|
|
330
361
|
|
|
331
362
|
// src/ui/CredentialSetupUI.tsx
|
|
363
|
+
import { useCallback, useEffect as useEffect2, useState as useState2 } from "react";
|
|
364
|
+
import { Box as Box3, Text as Text3, useInput } from "ink";
|
|
332
365
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
333
366
|
var FIELDS = ["apiKey", "userId", "businessId"];
|
|
334
367
|
var FIELD_LABELS = {
|
|
@@ -339,32 +372,39 @@ var FIELD_LABELS = {
|
|
|
339
372
|
var Hint = ({ text }) => /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: text });
|
|
340
373
|
var CredentialSetupUI = ({
|
|
341
374
|
initialMode,
|
|
375
|
+
showProfileManager,
|
|
342
376
|
onComplete,
|
|
343
377
|
onCancel
|
|
344
378
|
}) => {
|
|
345
379
|
const [phase, setPhase] = useState2(
|
|
346
|
-
initialMode === "global" ? { type: "loading" } : { type: "mode-select", cursor: 0 }
|
|
380
|
+
initialMode === "global" && !showProfileManager ? { type: "loading" } : initialMode === "global" && showProfileManager ? { type: "profile-loading" } : { type: "mode-select", cursor: 0 }
|
|
347
381
|
);
|
|
348
382
|
const [inputBuffer, setInputBuffer] = useState2("");
|
|
349
383
|
const [error, setError] = useState2(null);
|
|
384
|
+
const [activeProfileName, setActiveProfileName] = useState2(void 0);
|
|
350
385
|
const handleModeChosen = useCallback(
|
|
351
386
|
async (mode) => {
|
|
352
387
|
if (mode === "local") {
|
|
353
388
|
onComplete({ mode: "local", credentials: null });
|
|
354
389
|
return;
|
|
355
390
|
}
|
|
356
|
-
setPhase({ type: "loading" });
|
|
357
|
-
const existing = await loadGlobalCredentials();
|
|
358
|
-
const envCursor2 = existing ? Math.max(0, ENVIRONMENTS.indexOf(existing.environment)) : 0;
|
|
359
|
-
setPhase({
|
|
360
|
-
type: "creds-entry",
|
|
361
|
-
field: 0,
|
|
362
|
-
values: existing ?? {},
|
|
363
|
-
envCursor: envCursor2
|
|
364
|
-
});
|
|
391
|
+
setPhase({ type: "profile-loading" });
|
|
365
392
|
},
|
|
366
393
|
[onComplete]
|
|
367
394
|
);
|
|
395
|
+
const handleProfileChosen = useCallback(async (profile) => {
|
|
396
|
+
if (profile === null) {
|
|
397
|
+
setPhase({ type: "profile-loading" });
|
|
398
|
+
const profiles = await listCredentialProfiles();
|
|
399
|
+
setPhase({ type: "name-entry", nameBuffer: "", existingProfiles: profiles });
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
setActiveProfileName(profile.isDefault ? void 0 : profile.name);
|
|
403
|
+
setPhase({ type: "loading" });
|
|
404
|
+
const existing = profile.isDefault ? await loadGlobalCredentials() : await loadCredentialProfile(profile.name);
|
|
405
|
+
const envCursor2 = existing ? Math.max(0, ENVIRONMENTS.indexOf(existing.environment)) : 0;
|
|
406
|
+
setPhase({ type: "creds-entry", field: 0, values: existing ?? {}, envCursor: envCursor2 });
|
|
407
|
+
}, []);
|
|
368
408
|
const handleSave = useCallback(
|
|
369
409
|
async (values2, envCursor2) => {
|
|
370
410
|
const environment = ENVIRONMENTS[envCursor2] ?? "go";
|
|
@@ -376,20 +416,32 @@ var CredentialSetupUI = ({
|
|
|
376
416
|
};
|
|
377
417
|
setPhase({ type: "saving" });
|
|
378
418
|
try {
|
|
379
|
-
|
|
380
|
-
|
|
419
|
+
const profileName = activeProfileName ?? DEFAULT_PROFILE_NAME;
|
|
420
|
+
await saveCredentialProfile(profileName, credentials);
|
|
421
|
+
onComplete({
|
|
422
|
+
mode: "global",
|
|
423
|
+
credentials,
|
|
424
|
+
...activeProfileName !== void 0 && { profileName: activeProfileName }
|
|
425
|
+
});
|
|
381
426
|
} catch (err) {
|
|
382
427
|
setError(err instanceof Error ? err.message : String(err));
|
|
383
428
|
setPhase({ type: "creds-entry", field: 0, values: values2, envCursor: envCursor2 });
|
|
384
429
|
}
|
|
385
430
|
},
|
|
386
|
-
[onComplete]
|
|
431
|
+
[onComplete, activeProfileName]
|
|
387
432
|
);
|
|
388
433
|
useInput((input, key) => {
|
|
389
434
|
if (key.ctrl && input === "c") {
|
|
390
435
|
process.exit(0);
|
|
391
436
|
}
|
|
392
437
|
if (key.escape) {
|
|
438
|
+
if (phase.type === "creds-entry" || phase.type === "name-entry") {
|
|
439
|
+
if (initialMode === "global" && showProfileManager) {
|
|
440
|
+
setPhase({ type: "profile-loading" });
|
|
441
|
+
void loadProfileList();
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
393
445
|
onCancel?.();
|
|
394
446
|
return;
|
|
395
447
|
}
|
|
@@ -404,6 +456,49 @@ var CredentialSetupUI = ({
|
|
|
404
456
|
}
|
|
405
457
|
return;
|
|
406
458
|
}
|
|
459
|
+
if (phase.type === "profile-select") {
|
|
460
|
+
const { profiles, cursor } = phase;
|
|
461
|
+
const addNewIdx = profiles.length;
|
|
462
|
+
const totalItems = profiles.length + 1;
|
|
463
|
+
if (key.upArrow) {
|
|
464
|
+
setPhase({ ...phase, cursor: (cursor - 1 + totalItems) % totalItems });
|
|
465
|
+
} else if (key.downArrow) {
|
|
466
|
+
setPhase({ ...phase, cursor: (cursor + 1) % totalItems });
|
|
467
|
+
} else if (key.return) {
|
|
468
|
+
if (cursor === addNewIdx) {
|
|
469
|
+
setPhase({ type: "name-entry", nameBuffer: "", existingProfiles: profiles });
|
|
470
|
+
} else {
|
|
471
|
+
void handleProfileChosen(profiles[cursor] ?? profiles[0]);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
if (phase.type === "name-entry") {
|
|
477
|
+
const { nameBuffer, nameError: _nameError, existingProfiles } = phase;
|
|
478
|
+
if (key.backspace || key.delete) {
|
|
479
|
+
setPhase({ type: "name-entry", nameBuffer: nameBuffer.slice(0, -1), existingProfiles });
|
|
480
|
+
} else if (key.return) {
|
|
481
|
+
const trimmed = nameBuffer.trim();
|
|
482
|
+
if (!trimmed) {
|
|
483
|
+
setPhase({ ...phase, nameError: "Name cannot be empty" });
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
if (trimmed === DEFAULT_PROFILE_NAME) {
|
|
487
|
+
setPhase({ ...phase, nameError: `"${DEFAULT_PROFILE_NAME}" is reserved` });
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
if (existingProfiles.some((p) => p.name === trimmed)) {
|
|
491
|
+
setPhase({ ...phase, nameError: `Profile "${trimmed}" already exists` });
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
setActiveProfileName(trimmed);
|
|
495
|
+
setPhase({ type: "creds-entry", field: 0, values: {}, envCursor: 0 });
|
|
496
|
+
setInputBuffer("");
|
|
497
|
+
} else if (input && !key.ctrl && !key.meta) {
|
|
498
|
+
setPhase({ type: "name-entry", nameBuffer: nameBuffer + input, existingProfiles });
|
|
499
|
+
}
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
407
502
|
if (phase.type === "creds-entry") {
|
|
408
503
|
const { field, values: values2, envCursor: envCursor2 } = phase;
|
|
409
504
|
const isEnvField2 = field === FIELDS.length;
|
|
@@ -448,9 +543,22 @@ var CredentialSetupUI = ({
|
|
|
448
543
|
}
|
|
449
544
|
}
|
|
450
545
|
});
|
|
546
|
+
const loadProfileList = useCallback(async () => {
|
|
547
|
+
const profiles = await listCredentialProfiles();
|
|
548
|
+
setPhase({ type: "profile-select", profiles, cursor: 0 });
|
|
549
|
+
}, []);
|
|
451
550
|
useEffect2(() => {
|
|
452
|
-
if (
|
|
453
|
-
void
|
|
551
|
+
if (phase.type === "profile-loading") {
|
|
552
|
+
void loadProfileList();
|
|
553
|
+
}
|
|
554
|
+
}, [phase.type, loadProfileList]);
|
|
555
|
+
useEffect2(() => {
|
|
556
|
+
if (initialMode === "global" && !showProfileManager) {
|
|
557
|
+
void (async () => {
|
|
558
|
+
const existing = await loadGlobalCredentials();
|
|
559
|
+
const envCursor2 = existing ? Math.max(0, ENVIRONMENTS.indexOf(existing.environment)) : 0;
|
|
560
|
+
setPhase({ type: "creds-entry", field: 0, values: existing ?? {}, envCursor: envCursor2 });
|
|
561
|
+
})();
|
|
454
562
|
}
|
|
455
563
|
}, []);
|
|
456
564
|
useEffect2(() => {
|
|
@@ -458,8 +566,9 @@ var CredentialSetupUI = ({
|
|
|
458
566
|
setInputBuffer(phase.values.apiKey ?? "");
|
|
459
567
|
}
|
|
460
568
|
}, [phase.type]);
|
|
461
|
-
if (phase.type === "loading" || phase.type === "saving") {
|
|
462
|
-
|
|
569
|
+
if (phase.type === "loading" || phase.type === "saving" || phase.type === "profile-loading") {
|
|
570
|
+
const label = phase.type === "saving" ? "Saving credentials\u2026" : phase.type === "profile-loading" ? "Loading profiles\u2026" : "Loading credentials\u2026";
|
|
571
|
+
return /* @__PURE__ */ jsx3(Box3, { paddingY: 1, paddingX: 2, children: /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: label }) });
|
|
463
572
|
}
|
|
464
573
|
if (phase.type === "done") {
|
|
465
574
|
return null;
|
|
@@ -489,8 +598,58 @@ var CredentialSetupUI = ({
|
|
|
489
598
|
/* @__PURE__ */ jsx3(Hint, { text: "\u2191\u2193 to move \xB7 Enter to select \xB7 Ctrl+C to quit" })
|
|
490
599
|
] });
|
|
491
600
|
}
|
|
601
|
+
if (phase.type === "profile-select") {
|
|
602
|
+
const { profiles, cursor } = phase;
|
|
603
|
+
const addNewIdx = profiles.length;
|
|
604
|
+
return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", paddingY: 1, paddingX: 2, gap: 1, children: [
|
|
605
|
+
/* @__PURE__ */ jsx3(Logo, {}),
|
|
606
|
+
/* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", marginTop: 1, children: [
|
|
607
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "Kizen App Builder" }),
|
|
608
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "\u2500".repeat(24) })
|
|
609
|
+
] }),
|
|
610
|
+
/* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", gap: 0, children: [
|
|
611
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, children: "Credential profiles" }),
|
|
612
|
+
profiles.map((profile, i) => {
|
|
613
|
+
const selected = cursor === i;
|
|
614
|
+
return /* @__PURE__ */ jsxs2(Box3, { gap: 2, children: [
|
|
615
|
+
/* @__PURE__ */ jsx3(Text3, { ...selected && { color: "cyan" }, children: selected ? "\u276F" : " " }),
|
|
616
|
+
/* @__PURE__ */ jsx3(Text3, { bold: selected, ...selected && { color: "cyan" }, children: profile.isDefault ? "Default" : profile.name }),
|
|
617
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: profile.path })
|
|
618
|
+
] }, profile.name);
|
|
619
|
+
}),
|
|
620
|
+
/* @__PURE__ */ jsxs2(Box3, { gap: 2, children: [
|
|
621
|
+
/* @__PURE__ */ jsx3(Text3, { ...cursor === addNewIdx && { color: "cyan" }, children: cursor === addNewIdx ? "\u276F" : " " }),
|
|
622
|
+
/* @__PURE__ */ jsx3(Text3, { bold: cursor === addNewIdx, ...cursor === addNewIdx && { color: "cyan" }, children: "+ Add new profile" })
|
|
623
|
+
] })
|
|
624
|
+
] }),
|
|
625
|
+
/* @__PURE__ */ jsx3(Hint, { text: "\u2191\u2193 to move \xB7 Enter to select \xB7 Esc to cancel" })
|
|
626
|
+
] });
|
|
627
|
+
}
|
|
628
|
+
if (phase.type === "name-entry") {
|
|
629
|
+
const { nameBuffer, nameError } = phase;
|
|
630
|
+
return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", paddingY: 1, paddingX: 2, gap: 1, children: [
|
|
631
|
+
/* @__PURE__ */ jsx3(Logo, {}),
|
|
632
|
+
/* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", marginTop: 1, children: [
|
|
633
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "Kizen App Builder" }),
|
|
634
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "\u2500".repeat(24) })
|
|
635
|
+
] }),
|
|
636
|
+
/* @__PURE__ */ jsx3(Box3, { flexDirection: "column", gap: 0, children: /* @__PURE__ */ jsx3(Text3, { bold: true, children: "New credential profile" }) }),
|
|
637
|
+
nameError && /* @__PURE__ */ jsxs2(Text3, { color: "red", children: [
|
|
638
|
+
"Error: ",
|
|
639
|
+
nameError
|
|
640
|
+
] }),
|
|
641
|
+
/* @__PURE__ */ jsxs2(Box3, { gap: 2, children: [
|
|
642
|
+
/* @__PURE__ */ jsx3(Box3, { width: 12, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "Profile name" }) }),
|
|
643
|
+
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: ">" }),
|
|
644
|
+
/* @__PURE__ */ jsx3(Text3, { children: nameBuffer }),
|
|
645
|
+
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: "\u2588" })
|
|
646
|
+
] }),
|
|
647
|
+
/* @__PURE__ */ jsx3(Hint, { text: "Type a name \xB7 Enter to confirm \xB7 Esc to go back" })
|
|
648
|
+
] });
|
|
649
|
+
}
|
|
492
650
|
const { field: activeField, values, envCursor } = phase;
|
|
493
651
|
const isEnvField = activeField === FIELDS.length;
|
|
652
|
+
const profileLabel = activeProfileName !== void 0 ? activeProfileName : DEFAULT_PROFILE_NAME;
|
|
494
653
|
return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", paddingY: 1, paddingX: 2, gap: 1, children: [
|
|
495
654
|
/* @__PURE__ */ jsx3(Logo, {}),
|
|
496
655
|
/* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", marginTop: 1, children: [
|
|
@@ -498,10 +657,10 @@ var CredentialSetupUI = ({
|
|
|
498
657
|
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "\u2500".repeat(24) })
|
|
499
658
|
] }),
|
|
500
659
|
/* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", gap: 0, children: [
|
|
501
|
-
/* @__PURE__ */ jsx3(Text3, { bold: true, children: "Global credentials" }),
|
|
660
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, children: activeProfileName !== void 0 ? `Profile: ${activeProfileName}` : "Global credentials" }),
|
|
502
661
|
/* @__PURE__ */ jsxs2(Text3, { dimColor: true, children: [
|
|
503
662
|
"Saved to: ",
|
|
504
|
-
GLOBAL_CREDENTIALS_PATH
|
|
663
|
+
activeProfileName !== void 0 ? `~/.kizenappbuilder/${activeProfileName}.json` : GLOBAL_CREDENTIALS_PATH
|
|
505
664
|
] })
|
|
506
665
|
] }),
|
|
507
666
|
error && /* @__PURE__ */ jsxs2(Text3, { color: "red", children: [
|
|
@@ -531,7 +690,11 @@ var CredentialSetupUI = ({
|
|
|
531
690
|
}) })
|
|
532
691
|
] })
|
|
533
692
|
] }),
|
|
534
|
-
isEnvField ? /* @__PURE__ */ jsx3(Hint, { text: "\u2190\u2192 to select \xB7 \u2191\u2193 to move \xB7 Enter to save \xB7 Esc to cancel" }) : /* @__PURE__ */ jsx3(Hint, { text: "\u2191\u2193 to move \xB7 Backspace to delete \xB7 Esc to cancel" })
|
|
693
|
+
isEnvField ? /* @__PURE__ */ jsx3(Hint, { text: "\u2190\u2192 to select \xB7 \u2191\u2193 to move \xB7 Enter to save \xB7 Esc to cancel" }) : /* @__PURE__ */ jsx3(Hint, { text: "\u2191\u2193 to move \xB7 Backspace to delete \xB7 Esc to cancel" }),
|
|
694
|
+
/* @__PURE__ */ jsxs2(Text3, { dimColor: true, children: [
|
|
695
|
+
"Profile: ",
|
|
696
|
+
profileLabel
|
|
697
|
+
] })
|
|
535
698
|
] });
|
|
536
699
|
};
|
|
537
700
|
|
|
@@ -591,7 +754,7 @@ async function fileExists(filePath) {
|
|
|
591
754
|
return false;
|
|
592
755
|
}
|
|
593
756
|
}
|
|
594
|
-
function createRequestHandler(viewerPath, createServerLog, createProxyLog, credentialsRef) {
|
|
757
|
+
function createRequestHandler(viewerPath, createServerLog, createProxyLog, credentialsRef, activeProfileRef, outputDir, broadcast) {
|
|
595
758
|
const proxyCache = createProxyCache();
|
|
596
759
|
return (req, res) => {
|
|
597
760
|
void (async () => {
|
|
@@ -603,6 +766,34 @@ function createRequestHandler(viewerPath, createServerLog, createProxyLog, crede
|
|
|
603
766
|
res.end(credentialsRef.current !== null ? JSON.stringify(credentialsRef.current) : "{}");
|
|
604
767
|
return;
|
|
605
768
|
}
|
|
769
|
+
if (url === "/api/credential-profiles" && req.method === "GET") {
|
|
770
|
+
const profiles = await listCredentialProfiles();
|
|
771
|
+
res.writeHead(200, { "Content-Type": "application/json; charset=utf-8" });
|
|
772
|
+
res.end(JSON.stringify({ profiles, active: activeProfileRef.current }));
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
if (url === "/api/credentials/switch" && req.method === "POST") {
|
|
776
|
+
const chunks = [];
|
|
777
|
+
for await (const chunk of req) {
|
|
778
|
+
chunks.push(chunk);
|
|
779
|
+
}
|
|
780
|
+
const body = JSON.parse(Buffer.concat(chunks).toString("utf-8") || "{}");
|
|
781
|
+
const profileName = body.profile;
|
|
782
|
+
const creds = profileName === void 0 || profileName === "" ? await loadGlobalCredentials() : await loadCredentialProfile(profileName);
|
|
783
|
+
if (creds !== null) {
|
|
784
|
+
credentialsRef.current = creds;
|
|
785
|
+
activeProfileRef.current = profileName || void 0;
|
|
786
|
+
const active = activeProfileRef.current;
|
|
787
|
+
await saveConfig(outputDir, {
|
|
788
|
+
credentialMode: "global",
|
|
789
|
+
...active !== void 0 && { activeCredentialProfile: active }
|
|
790
|
+
});
|
|
791
|
+
broadcast({ type: "credentials-updated", credentials: creds });
|
|
792
|
+
}
|
|
793
|
+
res.writeHead(200, { "Content-Type": "application/json; charset=utf-8" });
|
|
794
|
+
res.end(JSON.stringify({ ok: creds !== null }));
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
606
797
|
if (url === "/api/bundle") {
|
|
607
798
|
const bundlePath = join6(process.cwd(), ".kizenapp", "bundle.json");
|
|
608
799
|
try {
|
|
@@ -686,10 +877,20 @@ function createRequestHandler(viewerPath, createServerLog, createProxyLog, crede
|
|
|
686
877
|
res.writeHead(200, { "Content-Type": mimeType });
|
|
687
878
|
createReadStream(resolvedPath).pipe(res);
|
|
688
879
|
} catch (err) {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
880
|
+
if (url.startsWith("/api/proxy")) {
|
|
881
|
+
createProxyLog({
|
|
882
|
+
kind: "request",
|
|
883
|
+
method: req.method ?? "GET",
|
|
884
|
+
status: 502,
|
|
885
|
+
fromCache: false,
|
|
886
|
+
url: url.slice("/api/proxy".length) || "/"
|
|
887
|
+
});
|
|
888
|
+
} else {
|
|
889
|
+
createProxyLog({
|
|
890
|
+
kind: "info",
|
|
891
|
+
message: `Error handling ${url}: ${err instanceof Error ? err.message : String(err)}`
|
|
892
|
+
});
|
|
893
|
+
}
|
|
693
894
|
if (!res.headersSent) {
|
|
694
895
|
res.writeHead(502);
|
|
695
896
|
res.end("Bad Gateway");
|
|
@@ -702,10 +903,16 @@ var DevUI = ({
|
|
|
702
903
|
port,
|
|
703
904
|
pluginDir,
|
|
704
905
|
outputDir,
|
|
705
|
-
credentials: initialCredentials
|
|
906
|
+
credentials: initialCredentials,
|
|
907
|
+
credentialMode: initialCredentialMode,
|
|
908
|
+
activeCredentialProfile: initialActiveProfile
|
|
706
909
|
}) => {
|
|
707
910
|
const credentialsRef = useRef(initialCredentials);
|
|
911
|
+
const activeProfileRef = useRef(initialActiveProfile);
|
|
708
912
|
const [credMode, setCredMode] = useState3("main");
|
|
913
|
+
const [credentialMode, setCredentialMode] = useState3(
|
|
914
|
+
initialCredentialMode
|
|
915
|
+
);
|
|
709
916
|
const [status, setStatus] = useState3("starting");
|
|
710
917
|
const [errorMessage, setErrorMessage] = useState3(null);
|
|
711
918
|
const [serverLogHistory, setServerLogHistory] = useState3([]);
|
|
@@ -775,8 +982,14 @@ var DevUI = ({
|
|
|
775
982
|
const handleCredentialsDone = useCallback2(
|
|
776
983
|
(result) => {
|
|
777
984
|
credentialsRef.current = result.credentials;
|
|
985
|
+
activeProfileRef.current = result.profileName;
|
|
778
986
|
setCredMode("main");
|
|
779
|
-
|
|
987
|
+
setCredentialMode(result.mode);
|
|
988
|
+
const profile = result.profileName;
|
|
989
|
+
void saveConfig(outputDir, {
|
|
990
|
+
credentialMode: result.mode,
|
|
991
|
+
...profile !== void 0 && { activeCredentialProfile: profile }
|
|
992
|
+
});
|
|
780
993
|
broadcast({ type: "credentials-updated", credentials: result.credentials });
|
|
781
994
|
},
|
|
782
995
|
[outputDir, broadcast]
|
|
@@ -862,7 +1075,10 @@ var DevUI = ({
|
|
|
862
1075
|
viewerPath,
|
|
863
1076
|
createServerLog,
|
|
864
1077
|
createProxyLog,
|
|
865
|
-
credentialsRef
|
|
1078
|
+
credentialsRef,
|
|
1079
|
+
activeProfileRef,
|
|
1080
|
+
outputDir,
|
|
1081
|
+
broadcast
|
|
866
1082
|
);
|
|
867
1083
|
const server = createServer(handler);
|
|
868
1084
|
const wss = new WebSocketServer({ server });
|
|
@@ -899,6 +1115,8 @@ var DevUI = ({
|
|
|
899
1115
|
return /* @__PURE__ */ jsx4(
|
|
900
1116
|
CredentialSetupUI,
|
|
901
1117
|
{
|
|
1118
|
+
...credentialMode !== void 0 && { initialMode: credentialMode },
|
|
1119
|
+
showProfileManager: credentialMode === "global",
|
|
902
1120
|
onComplete: handleCredentialsDone,
|
|
903
1121
|
onCancel: () => {
|
|
904
1122
|
setCredMode("main");
|
|
@@ -1032,6 +1250,7 @@ function devCommand(program2) {
|
|
|
1032
1250
|
ensureGitignore(pluginDir);
|
|
1033
1251
|
let credentials = null;
|
|
1034
1252
|
let credentialMode;
|
|
1253
|
+
let activeCredentialProfile;
|
|
1035
1254
|
if (options.credentials) {
|
|
1036
1255
|
credentials = await loadCredentialsFromFile(options.credentials);
|
|
1037
1256
|
} else {
|
|
@@ -1040,16 +1259,31 @@ function devCommand(program2) {
|
|
|
1040
1259
|
credentialMode = "local";
|
|
1041
1260
|
} else if (config.credentialMode === "global") {
|
|
1042
1261
|
credentialMode = "global";
|
|
1043
|
-
|
|
1262
|
+
activeCredentialProfile = config.activeCredentialProfile;
|
|
1263
|
+
if (activeCredentialProfile) {
|
|
1264
|
+
credentials = await loadCredentialProfile(activeCredentialProfile);
|
|
1265
|
+
if (!credentials) {
|
|
1266
|
+
credentials = await loadGlobalCredentials();
|
|
1267
|
+
activeCredentialProfile = void 0;
|
|
1268
|
+
}
|
|
1269
|
+
} else {
|
|
1270
|
+
credentials = await loadGlobalCredentials();
|
|
1271
|
+
}
|
|
1044
1272
|
if (!credentials) {
|
|
1045
1273
|
const result = await runSetupUI("global");
|
|
1046
1274
|
credentials = result.credentials;
|
|
1275
|
+
activeCredentialProfile = result.profileName;
|
|
1047
1276
|
}
|
|
1048
1277
|
} else {
|
|
1049
1278
|
const result = await runSetupUI();
|
|
1050
1279
|
credentials = result.credentials;
|
|
1051
1280
|
credentialMode = result.mode;
|
|
1052
|
-
|
|
1281
|
+
activeCredentialProfile = result.profileName;
|
|
1282
|
+
const profile = result.profileName;
|
|
1283
|
+
await saveConfig(outputDir, {
|
|
1284
|
+
credentialMode: result.mode,
|
|
1285
|
+
...profile !== void 0 && { activeCredentialProfile: profile }
|
|
1286
|
+
});
|
|
1053
1287
|
}
|
|
1054
1288
|
}
|
|
1055
1289
|
const { waitUntilExit } = render2(
|
|
@@ -1058,7 +1292,8 @@ function devCommand(program2) {
|
|
|
1058
1292
|
pluginDir,
|
|
1059
1293
|
outputDir,
|
|
1060
1294
|
credentials,
|
|
1061
|
-
...credentialMode !== void 0 && { credentialMode }
|
|
1295
|
+
...credentialMode !== void 0 && { credentialMode },
|
|
1296
|
+
...activeCredentialProfile !== void 0 && { activeCredentialProfile }
|
|
1062
1297
|
}),
|
|
1063
1298
|
{ exitOnCtrlC: false }
|
|
1064
1299
|
);
|