@kizenapps/cli 0.3.0 → 0.4.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/chunk-4OYGMEFM.js +3675 -0
- package/dist/chunk-4OYGMEFM.js.map +1 -0
- package/dist/chunk-4Z6S6LWP.js +6134 -0
- package/dist/chunk-4Z6S6LWP.js.map +1 -0
- package/dist/chunk-5WPGAZLP.js +6136 -0
- package/dist/chunk-5WPGAZLP.js.map +1 -0
- package/dist/chunk-6XGFZ4W5.js +3673 -0
- package/dist/chunk-6XGFZ4W5.js.map +1 -0
- package/dist/chunk-KMKDY2I6.js +46 -0
- package/dist/chunk-KMKDY2I6.js.map +1 -0
- package/dist/chunk-LSHHXCC6.js +3639 -0
- package/dist/chunk-LSHHXCC6.js.map +1 -0
- package/dist/chunk-NNDSADQG.js +3641 -0
- package/dist/chunk-NNDSADQG.js.map +1 -0
- package/dist/chunk-SEGVTWSK.js +44 -0
- package/dist/chunk-SEGVTWSK.js.map +1 -0
- package/dist/devtools-HNR7DD7Q.js +68 -0
- package/dist/devtools-HNR7DD7Q.js.map +1 -0
- package/dist/devtools-HW3UQAHH.js +69 -0
- package/dist/devtools-HW3UQAHH.js.map +1 -0
- package/dist/devtools-KXIXZGBY.js +64 -0
- package/dist/devtools-KXIXZGBY.js.map +1 -0
- package/dist/devtools-PDXM3L35.js +67 -0
- package/dist/devtools-PDXM3L35.js.map +1 -0
- package/dist/devtools-SDEASRYI.js +66 -0
- package/dist/devtools-SDEASRYI.js.map +1 -0
- package/dist/devtools-XBEEGBQ4.js +66 -0
- package/dist/devtools-XBEEGBQ4.js.map +1 -0
- package/dist/dist-4P5P64FK.js +8474 -0
- package/dist/dist-4P5P64FK.js.map +1 -0
- package/dist/dist-AVHDSU4X.js +137 -0
- package/dist/dist-AVHDSU4X.js.map +1 -0
- package/dist/dist-NUJOSN7W.js +8472 -0
- package/dist/dist-NUJOSN7W.js.map +1 -0
- package/dist/dist-QHDMIBVE.js +135 -0
- package/dist/dist-QHDMIBVE.js.map +1 -0
- package/dist/electron/icon.png +0 -0
- package/dist/electron/main.js +45 -3
- package/dist/electron/main.js.map +1 -1
- package/dist/electron/preload.cjs +5 -0
- package/dist/gzip-size-K37OQCQ2.js +137 -0
- package/dist/gzip-size-K37OQCQ2.js.map +1 -0
- package/dist/gzip-size-SHZBT5GU.js +139 -0
- package/dist/gzip-size-SHZBT5GU.js.map +1 -0
- package/dist/index.js +577 -168
- package/dist/index.js.map +1 -1
- package/dist/viewer/assets/calendarSource.worker-C9iglnKD.js +24 -0
- package/dist/viewer/assets/expression.worker-Cin-WNVB.js +5 -0
- package/dist/viewer/assets/floatingFrame.worker-CWLtchq3.js +23 -0
- package/dist/viewer/assets/generic.worker-DRXu0-5B.js +23 -0
- package/dist/viewer/assets/index-BERinSUs.css +2 -0
- package/dist/viewer/assets/index-BExFCUNb.js +582 -0
- package/dist/viewer/assets/index-BTnaSAbf.js +582 -0
- package/dist/viewer/assets/index-BsYWmcLM.css +2 -0
- package/dist/viewer/assets/index-C9gGMSH0.js +582 -0
- package/dist/viewer/assets/index-CGp_x2sR.js +582 -0
- package/dist/viewer/assets/index-D1lc5mUR.js +582 -0
- package/dist/viewer/assets/index-DBXDPp8Y.css +2 -0
- package/dist/viewer/assets/index-DUFimvi2.js +582 -0
- package/dist/viewer/assets/index-DVM12um9.js +582 -0
- package/dist/viewer/assets/index-DiwdXOw0.css +2 -0
- package/dist/viewer/assets/index-DxGbfW9l.js +582 -0
- package/dist/viewer/assets/index-o7N1iv71.js +582 -0
- package/dist/viewer/assets/index-wLgWfI8W.js +582 -0
- package/dist/viewer/assets/recordDetail.worker-BIHPFt8Y.js +23 -0
- package/dist/viewer/icon.png +0 -0
- package/dist/viewer/index.html +2 -2
- package/package.json +17 -13
- package/dist/viewer/assets/calendarSource.worker-DF0wAwJR.js +0 -24
- package/dist/viewer/assets/expression.worker-_W4VR2xe.js +0 -5
- package/dist/viewer/assets/floatingFrame.worker-DXcDBfqJ.js +0 -23
- package/dist/viewer/assets/generic.worker-CsqlYndL.js +0 -23
- package/dist/viewer/assets/index-CW_UqFf3.css +0 -1
- package/dist/viewer/assets/index-DaB01Qok.js +0 -637
- package/dist/viewer/assets/recordDetail.worker-Ccm59Np6.js +0 -23
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/build.ts","../src/ui/BuildUI.tsx","../src/lib/runBuild.ts","../src/lib/readFiles.ts","../src/commands/dev.ts","../src/ui/DevUI.tsx"],"sourcesContent":["import { program } from 'commander';\nimport { buildCommand } from './commands/build.js';\nimport { devCommand } from './commands/dev.js';\n\nprogram.name('appbuilder').description('Kizen plugin app builder').version('0.1.0');\n\nbuildCommand(program);\ndevCommand(program);\n\nprogram.parse();\n","import { createElement } from 'react';\nimport { render } from 'ink';\nimport type { Command } from 'commander';\nimport { BuildUI } from '../ui/BuildUI.js';\n\nexport function buildCommand(program: Command): void {\n program\n .command('build')\n .description('Bundle the plugin app into .kizenapp directory')\n .action(async () => {\n const outputDir = `${process.cwd()}/.kizenapp`;\n const pluginDir = process.cwd();\n const { waitUntilExit } = render(createElement(BuildUI, { outputDir, pluginDir }));\n await waitUntilExit();\n });\n}\n","import type { FC } from 'react';\nimport { useEffect, useState } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport { runBuild } from '../lib/runBuild.js';\nimport type { BuildStepName } from '../lib/runBuild.js';\n\ntype BuildStep = BuildStepName | 'done' | 'error';\n\ninterface BuildUIProps {\n outputDir: string;\n pluginDir: string;\n}\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nconst Spinner: FC = () => {\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const id = setInterval(() => {\n setFrame((prev) => (prev + 1) % SPINNER_FRAMES.length);\n }, 80);\n\n return () => {\n clearInterval(id);\n };\n }, []);\n\n return <Text color=\"cyan\">{SPINNER_FRAMES[frame] ?? '⠋'}</Text>;\n};\n\nconst STEPS: BuildStepName[] = [\n 'creating-dir',\n 'reading-files',\n 'minifying',\n 'packaging',\n 'writing-bundle',\n];\n\nconst STEP_LABELS: Record<BuildStepName, string> = {\n 'creating-dir': 'Creating .kizenapp directory',\n 'reading-files': 'Reading plugin files',\n minifying: 'Minifying scripts',\n packaging: 'Packaging plugin',\n 'writing-bundle': 'Writing bundle.json',\n};\n\nexport const BuildUI: FC<BuildUIProps> = ({ outputDir, pluginDir }) => {\n const { exit } = useApp();\n const [step, setStep] = useState<BuildStep>('creating-dir');\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n\n useEffect(() => {\n void runBuild(pluginDir, outputDir, setStep)\n .then(() => {\n setStep('done');\n exit();\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n setErrorMessage(message);\n setStep('error');\n exit(err instanceof Error ? err : new Error(message));\n });\n }, [outputDir, pluginDir, exit]);\n\n const currentIndex = STEPS.indexOf(step as BuildStepName);\n const isError = step === 'error';\n const isDone = step === 'done';\n\n return (\n <Box flexDirection=\"column\" paddingY={1} paddingX={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color=\"cyan\">\n Kizen App Builder\n </Text>\n <Text dimColor>{'─'.repeat(22)}</Text>\n </Box>\n\n <Box flexDirection=\"column\" gap={1}>\n {STEPS.map((s, i) => {\n const isActive = step === s;\n const isStepDone = isDone || currentIndex > i;\n const isFailed = isError && i === currentIndex;\n\n return (\n <Box key={s} gap={1}>\n {isFailed ? (\n <Text color=\"red\">✗ {STEP_LABELS[s]}</Text>\n ) : isStepDone ? (\n <Text color=\"green\">✓ {STEP_LABELS[s]}</Text>\n ) : isActive ? (\n <>\n <Spinner />\n <Text>{STEP_LABELS[s]}</Text>\n </>\n ) : (\n <Text dimColor>· {STEP_LABELS[s]}</Text>\n )}\n </Box>\n );\n })}\n\n {errorMessage !== null && (\n <Box marginTop={1}>\n <Text color=\"red\">{errorMessage}</Text>\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { minifyFiles, packagePlugin, transformDeployablePlugin } from '@kizenapps/packager';\nimport type { DeployablePlugin } from '@kizenapps/packager';\nimport { readLocalFiles } from './readFiles.js';\n\nexport type BuildStepName =\n | 'creating-dir'\n | 'reading-files'\n | 'minifying'\n | 'packaging'\n | 'writing-bundle';\n\ntype SerializableDeployablePlugin = Omit<DeployablePlugin, 'thumbnail' | 'kznFile'> & {\n thumbnail: string | null;\n kznFile: string | null;\n};\n\nconst serializePlugin = (plugin: DeployablePlugin): SerializableDeployablePlugin => ({\n ...plugin,\n thumbnail: plugin.thumbnail ? Buffer.from(plugin.thumbnail).toString('base64') : null,\n kznFile: plugin.kznFile ? Buffer.from(plugin.kznFile).toString('base64') : null,\n});\n\nexport async function runBuild(\n pluginDir: string,\n outputDir: string,\n onStep?: (step: BuildStepName) => void,\n): Promise<void> {\n await mkdir(outputDir, { recursive: true });\n\n onStep?.('reading-files');\n const files = await readLocalFiles(pluginDir);\n\n onStep?.('minifying');\n const minified = await minifyFiles(files);\n\n onStep?.('packaging');\n const manifestFile = minified.find((f) => f.path === 'kizen.json');\n if (!manifestFile) {\n throw new Error('kizen.json not found in plugin directory.');\n }\n const manifests = JSON.parse(manifestFile.content) as Parameters<typeof packagePlugin>[1];\n const packaged = packagePlugin(minified, manifests);\n const deployable = Object.values(packaged).map(transformDeployablePlugin);\n\n onStep?.('writing-bundle');\n const bundle = deployable.map(serializePlugin);\n await writeFile(join(outputDir, 'bundle.json'), JSON.stringify(bundle, null, 2), 'utf-8');\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport type { FileContent } from '@kizenapps/packager';\n\nconst IMAGE_EXTENSIONS = new Set(['.png', '.svg']);\nconst BINARY_EXTENSIONS = new Set(['.kzn']);\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', '.kizenapp', '.github']);\n\nasync function walk(dir: string, rootDir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const paths: string[] = [];\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name)) {\n continue;\n }\n\n paths.push(...(await walk(join(dir, entry.name), rootDir)));\n } else if (entry.isFile()) {\n paths.push(join(dir, entry.name));\n }\n }\n\n return paths;\n}\n\nexport async function readLocalFiles(rootDir: string): Promise<FileContent[]> {\n const absolutePaths = await walk(rootDir, rootDir);\n\n return Promise.all(\n absolutePaths.map(async (absPath): Promise<FileContent> => {\n const relPath = relative(rootDir, absPath).split('\\\\').join('/');\n const dotIndex = relPath.lastIndexOf('.');\n const ext = dotIndex >= 0 ? relPath.slice(dotIndex).toLowerCase() : '';\n\n if (IMAGE_EXTENSIONS.has(ext)) {\n const buf = await readFile(absPath);\n return { path: relPath, content: '', base64Image: buf.toString('base64') };\n }\n\n if (BINARY_EXTENSIONS.has(ext)) {\n const buf = await readFile(absPath);\n return { path: relPath, content: '', binaryData: buf };\n }\n\n const content = await readFile(absPath, 'utf-8');\n return { path: relPath, content };\n }),\n );\n}\n","import { createElement } from 'react';\nimport { render } from 'ink';\nimport type { Command } from 'commander';\nimport { DevUI } from '../ui/DevUI.js';\n\nexport function devCommand(program: Command): void {\n program\n .command('dev')\n .description('Start the plugin viewer dev server')\n .option('-p, --port <port>', 'port to listen on', '3121')\n .action(async (options: { port: string }) => {\n const port = parseInt(options.port, 10);\n const pluginDir = process.cwd();\n const outputDir = `${pluginDir}/.kizenapp`;\n const { waitUntilExit } = render(createElement(DevUI, { port, pluginDir, outputDir }), {\n exitOnCtrlC: false,\n });\n await waitUntilExit();\n });\n}\n","import type { FC } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { spawn } from 'node:child_process';\nimport {\n createReadStream,\n readFileSync,\n statSync,\n unlinkSync,\n watch,\n writeFileSync,\n} from 'node:fs';\nimport type { FSWatcher } from 'node:fs';\nimport { access, readFile } from 'node:fs/promises';\nimport { createServer } from 'node:http';\nimport type { IncomingMessage, Server, ServerResponse } from 'node:http';\nimport { createRequire } from 'node:module';\nimport { dirname, extname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { type WebSocket, WebSocketServer } from 'ws';\nimport { runBuild } from '../lib/runBuild.js';\n\ntype ServerStatus = 'starting' | 'running' | 'error';\ntype BuildStatus = 'pending' | 'building' | 'done' | 'error';\n\nconst SKIP_WATCH_PREFIXES = ['.kizenapp', '.git'];\nconst LOG_LIMIT = 50;\nconst LOG_DISPLAY = 8;\n\ninterface DevUIProps {\n port: number;\n pluginDir: string;\n outputDir: string;\n}\n\nconst MIME_TYPES: Readonly<Record<string, string>> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.json': 'application/json; charset=utf-8',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.map': 'application/json',\n};\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nconst Spinner: FC = () => {\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const id = setInterval(() => {\n setFrame((prev) => (prev + 1) % SPINNER_FRAMES.length);\n }, 80);\n\n return () => {\n clearInterval(id);\n };\n }, []);\n\n return <Text color=\"cyan\">{SPINNER_FRAMES[frame] ?? '⠋'}</Text>;\n};\n\nfunction getViewerPath(): string {\n const filename = fileURLToPath(import.meta.url);\n return join(dirname(filename), 'viewer');\n}\n\nfunction getElectronMainPath(): string {\n const filename = fileURLToPath(import.meta.url);\n return join(dirname(filename), 'electron', 'main.js');\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction createRequestHandler(\n viewerPath: string,\n createServerLog: (message: string) => void,\n createProxyLog: (message: string) => void,\n): (req: IncomingMessage, res: ServerResponse) => void {\n return (req, res) => {\n void (async () => {\n const url = req.url ?? '/';\n\n createServerLog(`Received request: ${url}`);\n\n if (url === '/api/bundle') {\n const bundlePath = join(process.cwd(), '.kizenapp', 'bundle.json');\n try {\n const content = await readFile(bundlePath, 'utf-8');\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(content);\n } catch {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end('{}');\n }\n return;\n }\n\n if (url.startsWith('/api/proxy')) {\n const proxyTarget = req.headers['x-proxy-target'];\n if (typeof proxyTarget !== 'string') {\n res.writeHead(400);\n res.end('Missing x-proxy-target header');\n return;\n }\n\n const upstreamPath = url.slice('/api/proxy'.length) || '/';\n const upstreamUrl = `${proxyTarget}${upstreamPath}`;\n\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk as Buffer);\n }\n\n const body = chunks.length > 0 ? Buffer.concat(chunks) : undefined;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { host, 'x-proxy-target': _drop, ...forwardHeaders } = req.headers;\n\n const resolvedBody = body && body.length > 0 ? body : undefined;\n const upstream = await fetch(upstreamUrl, {\n ...(req.method !== undefined && { method: req.method }),\n headers: forwardHeaders as Record<string, string>,\n ...(resolvedBody !== undefined && { body: resolvedBody }),\n });\n\n createProxyLog(`${req.method ?? 'GET'} ${upstreamPath} → ${String(upstream.status)}`);\n\n // Node fetch auto-decompresses the body, so strip encoding/length headers\n // that describe the compressed wire format — they no longer apply.\n const responseHeaders = Object.fromEntries(upstream.headers);\n delete responseHeaders['content-encoding'];\n delete responseHeaders['content-length'];\n\n res.writeHead(upstream.status, responseHeaders);\n res.end(Buffer.from(await upstream.arrayBuffer()));\n return;\n }\n\n const rawPath = url === '/' ? '/index.html' : url;\n const filePath = join(viewerPath, rawPath);\n const resolvedPath = (await fileExists(filePath)) ? filePath : join(viewerPath, 'index.html');\n const ext = extname(resolvedPath);\n const mimeType = MIME_TYPES[ext] ?? 'application/octet-stream';\n res.writeHead(200, { 'Content-Type': mimeType });\n createReadStream(resolvedPath).pipe(res);\n })();\n };\n}\n\nexport const DevUI: FC<DevUIProps> = ({ port, pluginDir, outputDir }) => {\n const [status, setStatus] = useState<ServerStatus>('starting');\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [serverLogHistory, setServerLogHistory] = useState<string[]>([]);\n const [buildLogHistory, setBuildLogHistory] = useState<string[]>([]);\n const [proxyLogHistory, setProxyLogHistory] = useState<string[]>([]);\n const [buildStatus, setBuildStatus] = useState<BuildStatus>('pending');\n const [buildError, setBuildError] = useState<string | null>(null);\n const [lastBuilt, setLastBuilt] = useState<Date | null>(null);\n const [wsClientCount, setWsClientCount] = useState(0);\n\n const buildingRef = useRef(false);\n const electronLaunchedRef = useRef(false);\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const wsClientsRef = useRef<Set<WebSocket>>(new Set());\n const pendingMessagesRef = useRef<string[]>([]);\n\n useInput((input, key) => {\n if (input === 'q' || (key.ctrl && input === 'c')) {\n process.exit(0);\n }\n });\n\n useEffect(() => {\n if (status !== 'running' || electronLaunchedRef.current) {\n return;\n }\n\n electronLaunchedRef.current = true;\n\n const _require = createRequire(import.meta.url);\n const electronBin = _require('electron') as string;\n const electronMain = getElectronMainPath();\n const userDataDir = join(outputDir, '.electron');\n\n // Patch Electron's CFBundleName so macOS shows \"Kizen Dev\" in the Dock.\n // Breaks the pnpm hard link first so the global content-addressable store is unaffected.\n if (process.platform === 'darwin') {\n try {\n const plistPath = join(dirname(dirname(electronBin)), 'Info.plist');\n const plist = readFileSync(plistPath, 'utf-8');\n if (!plist.includes('>Kizen Dev<')) {\n if (statSync(plistPath).nlink > 1) {\n unlinkSync(plistPath);\n writeFileSync(plistPath, plist);\n }\n writeFileSync(\n plistPath,\n plist\n .replace(/(<key>CFBundleName<\\/key>\\s*<string>)[^<]*(<\\/string>)/, '$1Kizen Dev$2')\n .replace(\n /(<key>CFBundleDisplayName<\\/key>\\s*<string>)[^<]*(<\\/string>)/,\n '$1Kizen Dev$2',\n ),\n );\n }\n } catch {\n // Non-fatal — Dock will show \"Electron\" if patching fails\n }\n }\n\n const proc = spawn(\n electronBin,\n [electronMain, `--port=${String(port)}`, `--user-data-dir=${userDataDir}`],\n {\n stdio: 'ignore',\n },\n );\n proc.unref();\n process.on('exit', () => {\n proc.kill();\n });\n }, [status, port, outputDir]);\n\n const createServerLog = useCallback((message: string): void => {\n setServerLogHistory((h) =>\n [...h, `${new Date().toLocaleTimeString()}: ${message}`].slice(-LOG_LIMIT),\n );\n }, []);\n\n const broadcast = useCallback((msg: object): void => {\n const json = JSON.stringify(msg);\n if (wsClientsRef.current.size === 0) {\n pendingMessagesRef.current = [...pendingMessagesRef.current, json].slice(-LOG_LIMIT);\n return;\n }\n for (const client of wsClientsRef.current) {\n if (client.readyState === 1) {\n client.send(json);\n }\n }\n }, []);\n\n const createProxyLog = useCallback(\n (message: string): void => {\n setProxyLogHistory((h) =>\n [...h, `${new Date().toLocaleTimeString()}: ${message}`].slice(-LOG_LIMIT),\n );\n broadcast({ type: 'proxy-log', message });\n },\n [broadcast],\n );\n\n const createBuildLog = useCallback(\n (message: string): void => {\n setBuildLogHistory((h) =>\n [...h, `${new Date().toLocaleTimeString()}: ${message}`].slice(-LOG_LIMIT),\n );\n broadcast({ type: 'log', message });\n },\n [broadcast],\n );\n\n const triggerBuild = useCallback(() => {\n if (buildingRef.current) {\n return;\n }\n\n buildingRef.current = true;\n\n setBuildStatus('building');\n setBuildError(null);\n createBuildLog('Build started');\n\n void runBuild(pluginDir, outputDir)\n .then(() => {\n createBuildLog('Build finished');\n setBuildStatus('done');\n setLastBuilt(new Date());\n\n createBuildLog('Notifying viewers to reload');\n for (const client of wsClientsRef.current) {\n if (client.readyState === 1) {\n client.send(JSON.stringify({ type: 'rebuild' }));\n }\n }\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n setBuildError(message);\n setBuildStatus('error');\n })\n .finally(() => {\n buildingRef.current = false;\n });\n }, [pluginDir, outputDir, createBuildLog]);\n\n useEffect(() => {\n triggerBuild();\n\n const watcher: FSWatcher = watch(pluginDir, { recursive: true }, (_, filename) => {\n if (!filename) {\n return;\n }\n\n const normalized = filename.replace(/\\\\/g, '/');\n\n if (SKIP_WATCH_PREFIXES.some((prefix) => normalized.startsWith(prefix))) {\n return;\n }\n\n createBuildLog(`File change detected: ${filename}`);\n\n if (debounceTimerRef.current !== null) {\n clearTimeout(debounceTimerRef.current);\n }\n debounceTimerRef.current = setTimeout(triggerBuild, 150);\n });\n\n return () => {\n watcher.close();\n\n if (debounceTimerRef.current !== null) {\n clearTimeout(debounceTimerRef.current);\n }\n };\n }, [pluginDir, triggerBuild, createBuildLog]);\n\n useEffect(() => {\n const viewerPath = getViewerPath();\n\n void fileExists(join(viewerPath, 'index.html')).then((viewerBuilt) => {\n if (!viewerBuilt) {\n setErrorMessage(\"Viewer not built. Run 'pnpm build:viewer' first.\");\n setStatus('error');\n return;\n }\n\n const handler = createRequestHandler(viewerPath, createServerLog, createProxyLog);\n const server: Server = createServer(handler);\n const wss = new WebSocketServer({ server });\n\n wss.on('connection', (ws: WebSocket) => {\n for (const json of pendingMessagesRef.current) {\n if (ws.readyState === 1) {\n ws.send(json);\n }\n }\n pendingMessagesRef.current = [];\n\n createServerLog('Viewer connected for live reload');\n wsClientsRef.current.add(ws);\n setWsClientCount(wsClientsRef.current.size);\n\n ws.on('close', () => {\n wsClientsRef.current.delete(ws);\n setWsClientCount(wsClientsRef.current.size);\n });\n });\n\n server.listen(port, () => {\n setStatus('running');\n createServerLog(`Server started on port ${String(port)}`);\n });\n\n server.on('error', (err: Error) => {\n setErrorMessage(err.message);\n setStatus('error');\n });\n\n return () => {\n wss.close();\n server.close();\n };\n });\n }, [port, createServerLog, createProxyLog]);\n\n const elapsedSeconds =\n lastBuilt !== null ? Math.round((Date.now() - lastBuilt.getTime()) / 1000) : null;\n const elapsedLabel =\n elapsedSeconds === null\n ? ''\n : elapsedSeconds < 5\n ? ' (just now)'\n : ` (${String(elapsedSeconds)}s ago)`;\n\n return (\n <Box flexDirection=\"column\" paddingY={1} paddingX={1}>\n {/* Header */}\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box gap={1}>\n <Text bold color=\"cyan\">\n Kizen App Builder\n </Text>\n </Box>\n </Box>\n\n {/* Build log */}\n <Box flexDirection=\"column\">\n <Box gap={1} marginBottom={0}>\n {buildStatus === 'pending' && <Text dimColor>Build waiting...</Text>}\n {buildStatus === 'building' && (\n <>\n <Spinner />\n <Text>Building Plugin Package...</Text>\n </>\n )}\n {buildStatus === 'done' && (\n <Text color=\"green\">\n ✓ Built Plugin Package\n {lastBuilt !== null ? ` at ${lastBuilt.toLocaleTimeString()}` : ''}\n <Text dimColor>{elapsedLabel}</Text>\n </Text>\n )}\n {buildStatus === 'error' && (\n <Text color=\"red\">✗ Build error: {buildError ?? 'unknown error'}</Text>\n )}\n </Box>\n <Box\n flexDirection=\"column\"\n height={LOG_DISPLAY}\n borderStyle=\"round\"\n borderColor=\"gray\"\n overflow=\"hidden\"\n >\n {buildLogHistory.slice(-LOG_DISPLAY).map((log, index) => (\n <Text key={index} dimColor wrap=\"truncate\">\n {log}\n </Text>\n ))}\n </Box>\n </Box>\n\n {/* Web server log */}\n <Box marginTop={1} flexDirection=\"column\">\n <Box gap={2}>\n {status === 'starting' && <Text dimColor>Starting server...</Text>}\n {status === 'running' && (\n <>\n <Text color=\"green\">✓ Dev Server running</Text>\n <Text dimColor>\n ● {wsClientCount} viewer{wsClientCount !== 1 ? 's' : ''}\n </Text>\n </>\n )}\n {status === 'error' && <Text color=\"red\">✗ {errorMessage ?? 'Server error'}</Text>}\n </Box>\n <Box\n flexDirection=\"column\"\n height={LOG_DISPLAY}\n borderStyle=\"round\"\n borderColor=\"gray\"\n overflow=\"hidden\"\n >\n {serverLogHistory.slice(-LOG_DISPLAY).map((log, index) => (\n <Text key={index} dimColor wrap=\"truncate\">\n {log}\n </Text>\n ))}\n </Box>\n </Box>\n\n {/* Proxy log */}\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>Proxy</Text>\n <Box\n flexDirection=\"column\"\n height={LOG_DISPLAY}\n borderStyle=\"round\"\n borderColor=\"gray\"\n overflow=\"hidden\"\n >\n {proxyLogHistory.length === 0 ? (\n <Text dimColor> No proxy requests yet.</Text>\n ) : (\n proxyLogHistory.slice(-LOG_DISPLAY).map((log, i) => (\n <Text key={i} dimColor wrap=\"truncate\">\n {log}\n </Text>\n ))\n )}\n </Box>\n </Box>\n\n {/* Footer */}\n <Box marginTop={1}>\n <Text dimColor>q to quit</Text>\n </Box>\n </Box>\n );\n};\n"],"mappings":";;;AAAA,SAAS,eAAe;;;ACAxB,SAAS,qBAAqB;AAC9B,SAAS,cAAc;;;ACAvB,SAAS,WAAW,gBAAgB;AACpC,SAAS,KAAK,MAAM,cAAc;;;ACFlC,SAAS,OAAO,iBAAiB;AACjC,SAAS,QAAAA,aAAY;AACrB,SAAS,aAAa,eAAe,iCAAiC;;;ACFtE,SAAS,SAAS,gBAAgB;AAClC,SAAS,MAAM,gBAAgB;AAG/B,IAAM,mBAAmB,oBAAI,IAAI,CAAC,QAAQ,MAAM,CAAC;AACjD,IAAM,oBAAoB,oBAAI,IAAI,CAAC,MAAM,CAAC;AAE1C,IAAM,YAAY,oBAAI,IAAI,CAAC,gBAAgB,QAAQ,aAAa,SAAS,CAAC;AAE1E,eAAe,KAAK,KAAa,SAAoC;AACnE,QAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,QAAM,QAAkB,CAAC;AAEzB,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,YAAY,GAAG;AACvB,UAAI,UAAU,IAAI,MAAM,IAAI,GAAG;AAC7B;AAAA,MACF;AAEA,YAAM,KAAK,GAAI,MAAM,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,OAAO,CAAE;AAAA,IAC5D,WAAW,MAAM,OAAO,GAAG;AACzB,YAAM,KAAK,KAAK,KAAK,MAAM,IAAI,CAAC;AAAA,IAClC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,eAAe,SAAyC;AAC5E,QAAM,gBAAgB,MAAM,KAAK,SAAS,OAAO;AAEjD,SAAO,QAAQ;AAAA,IACb,cAAc,IAAI,OAAO,YAAkC;AACzD,YAAM,UAAU,SAAS,SAAS,OAAO,EAAE,MAAM,IAAI,EAAE,KAAK,GAAG;AAC/D,YAAM,WAAW,QAAQ,YAAY,GAAG;AACxC,YAAM,MAAM,YAAY,IAAI,QAAQ,MAAM,QAAQ,EAAE,YAAY,IAAI;AAEpE,UAAI,iBAAiB,IAAI,GAAG,GAAG;AAC7B,cAAM,MAAM,MAAM,SAAS,OAAO;AAClC,eAAO,EAAE,MAAM,SAAS,SAAS,IAAI,aAAa,IAAI,SAAS,QAAQ,EAAE;AAAA,MAC3E;AAEA,UAAI,kBAAkB,IAAI,GAAG,GAAG;AAC9B,cAAM,MAAM,MAAM,SAAS,OAAO;AAClC,eAAO,EAAE,MAAM,SAAS,SAAS,IAAI,YAAY,IAAI;AAAA,MACvD;AAEA,YAAM,UAAU,MAAM,SAAS,SAAS,OAAO;AAC/C,aAAO,EAAE,MAAM,SAAS,QAAQ;AAAA,IAClC,CAAC;AAAA,EACH;AACF;;;ADjCA,IAAM,kBAAkB,CAAC,YAA4D;AAAA,EACnF,GAAG;AAAA,EACH,WAAW,OAAO,YAAY,OAAO,KAAK,OAAO,SAAS,EAAE,SAAS,QAAQ,IAAI;AAAA,EACjF,SAAS,OAAO,UAAU,OAAO,KAAK,OAAO,OAAO,EAAE,SAAS,QAAQ,IAAI;AAC7E;AAEA,eAAsB,SACpB,WACA,WACA,QACe;AACf,QAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAE1C,WAAS,eAAe;AACxB,QAAM,QAAQ,MAAM,eAAe,SAAS;AAE5C,WAAS,WAAW;AACpB,QAAM,WAAW,MAAM,YAAY,KAAK;AAExC,WAAS,WAAW;AACpB,QAAM,eAAe,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY;AACjE,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AACA,QAAM,YAAY,KAAK,MAAM,aAAa,OAAO;AACjD,QAAM,WAAW,cAAc,UAAU,SAAS;AAClD,QAAM,aAAa,OAAO,OAAO,QAAQ,EAAE,IAAI,yBAAyB;AAExE,WAAS,gBAAgB;AACzB,QAAM,SAAS,WAAW,IAAI,eAAe;AAC7C,QAAM,UAAUC,MAAK,WAAW,aAAa,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,OAAO;AAC1F;;;ADrBS,SAgEO,UAhEP,KA4CH,YA5CG;AAfT,IAAM,iBAAiB,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAExE,IAAM,UAAc,MAAM;AACxB,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,CAAC;AAEpC,YAAU,MAAM;AACd,UAAM,KAAK,YAAY,MAAM;AAC3B,eAAS,CAAC,UAAU,OAAO,KAAK,eAAe,MAAM;AAAA,IACvD,GAAG,EAAE;AAEL,WAAO,MAAM;AACX,oBAAc,EAAE;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO,oBAAC,QAAK,OAAM,QAAQ,yBAAe,KAAK,KAAK,UAAI;AAC1D;AAEA,IAAM,QAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,cAA6C;AAAA,EACjD,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,kBAAkB;AACpB;AAEO,IAAM,UAA4B,CAAC,EAAE,WAAW,UAAU,MAAM;AACrE,QAAM,EAAE,KAAK,IAAI,OAAO;AACxB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAoB,cAAc;AAC1D,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,IAAI;AAEpE,YAAU,MAAM;AACd,SAAK,SAAS,WAAW,WAAW,OAAO,EACxC,KAAK,MAAM;AACV,cAAQ,MAAM;AACd,WAAK;AAAA,IACP,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,sBAAgB,OAAO;AACvB,cAAQ,OAAO;AACf,WAAK,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,IACtD,CAAC;AAAA,EACL,GAAG,CAAC,WAAW,WAAW,IAAI,CAAC;AAE/B,QAAM,eAAe,MAAM,QAAQ,IAAqB;AACxD,QAAM,UAAU,SAAS;AACzB,QAAM,SAAS,SAAS;AAExB,SACE,qBAAC,OAAI,eAAc,UAAS,UAAU,GAAG,UAAU,GACjD;AAAA,yBAAC,OAAI,eAAc,UAAS,cAAc,GACxC;AAAA,0BAAC,QAAK,MAAI,MAAC,OAAM,QAAO,+BAExB;AAAA,MACA,oBAAC,QAAK,UAAQ,MAAE,mBAAI,OAAO,EAAE,GAAE;AAAA,OACjC;AAAA,IAEA,qBAAC,OAAI,eAAc,UAAS,KAAK,GAC9B;AAAA,YAAM,IAAI,CAAC,GAAG,MAAM;AACnB,cAAM,WAAW,SAAS;AAC1B,cAAM,aAAa,UAAU,eAAe;AAC5C,cAAM,WAAW,WAAW,MAAM;AAElC,eACE,oBAAC,OAAY,KAAK,GACf,qBACC,qBAAC,QAAK,OAAM,OAAM;AAAA;AAAA,UAAG,YAAY,CAAC;AAAA,WAAE,IAClC,aACF,qBAAC,QAAK,OAAM,SAAQ;AAAA;AAAA,UAAG,YAAY,CAAC;AAAA,WAAE,IACpC,WACF,iCACE;AAAA,8BAAC,WAAQ;AAAA,UACT,oBAAC,QAAM,sBAAY,CAAC,GAAE;AAAA,WACxB,IAEA,qBAAC,QAAK,UAAQ,MAAC;AAAA;AAAA,UAAG,YAAY,CAAC;AAAA,WAAE,KAX3B,CAaV;AAAA,MAEJ,CAAC;AAAA,MAEA,iBAAiB,QAChB,oBAAC,OAAI,WAAW,GACd,8BAAC,QAAK,OAAM,OAAO,wBAAa,GAClC;AAAA,OAEJ;AAAA,KACF;AAEJ;;;AD1GO,SAAS,aAAaC,UAAwB;AACnD,EAAAA,SACG,QAAQ,OAAO,EACf,YAAY,gDAAgD,EAC5D,OAAO,YAAY;AAClB,UAAM,YAAY,GAAG,QAAQ,IAAI,CAAC;AAClC,UAAM,YAAY,QAAQ,IAAI;AAC9B,UAAM,EAAE,cAAc,IAAI,OAAO,cAAc,SAAS,EAAE,WAAW,UAAU,CAAC,CAAC;AACjF,UAAM,cAAc;AAAA,EACtB,CAAC;AACL;;;AIfA,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,UAAAC,eAAc;;;ACAvB,SAAS,aAAa,aAAAC,YAAW,QAAQ,YAAAC,iBAAgB;AACzD,SAAS,OAAAC,MAAK,QAAAC,OAAM,gBAAgB;AACpC,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,QAAQ,YAAAC,iBAAgB;AACjC,SAAS,oBAAoB;AAE7B,SAAS,qBAAqB;AAC9B,SAAS,SAAS,SAAS,QAAAC,aAAY;AACvC,SAAS,qBAAqB;AAC9B,SAAyB,uBAAuB;AA+CvC,SA8VG,YAAAC,WA9VH,OAAAC,MA8VG,QAAAC,aA9VH;AAzCT,IAAM,sBAAsB,CAAC,aAAa,MAAM;AAChD,IAAM,YAAY;AAClB,IAAM,cAAc;AAQpB,IAAM,aAA+C;AAAA,EACnD,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AACV;AAEA,IAAMC,kBAAiB,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAExE,IAAMC,WAAc,MAAM;AACxB,QAAM,CAAC,OAAO,QAAQ,IAAIC,UAAS,CAAC;AAEpC,EAAAC,WAAU,MAAM;AACd,UAAM,KAAK,YAAY,MAAM;AAC3B,eAAS,CAAC,UAAU,OAAO,KAAKH,gBAAe,MAAM;AAAA,IACvD,GAAG,EAAE;AAEL,WAAO,MAAM;AACX,oBAAc,EAAE;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO,gBAAAF,KAACM,OAAA,EAAK,OAAM,QAAQ,UAAAJ,gBAAe,KAAK,KAAK,UAAI;AAC1D;AAEA,SAAS,gBAAwB;AAC/B,QAAM,WAAW,cAAc,YAAY,GAAG;AAC9C,SAAOK,MAAK,QAAQ,QAAQ,GAAG,QAAQ;AACzC;AAEA,SAAS,sBAA8B;AACrC,QAAM,WAAW,cAAc,YAAY,GAAG;AAC9C,SAAOA,MAAK,QAAQ,QAAQ,GAAG,YAAY,SAAS;AACtD;AAEA,eAAe,WAAW,UAAoC;AAC5D,MAAI;AACF,UAAM,OAAO,QAAQ;AACrB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,qBACP,YACA,iBACA,gBACqD;AACrD,SAAO,CAAC,KAAK,QAAQ;AACnB,UAAM,YAAY;AAChB,YAAM,MAAM,IAAI,OAAO;AAEvB,sBAAgB,qBAAqB,GAAG,EAAE;AAE1C,UAAI,QAAQ,eAAe;AACzB,cAAM,aAAaA,MAAK,QAAQ,IAAI,GAAG,aAAa,aAAa;AACjE,YAAI;AACF,gBAAM,UAAU,MAAMC,UAAS,YAAY,OAAO;AAClD,cAAI,UAAU,KAAK,EAAE,gBAAgB,kCAAkC,CAAC;AACxE,cAAI,IAAI,OAAO;AAAA,QACjB,QAAQ;AACN,cAAI,UAAU,KAAK,EAAE,gBAAgB,kCAAkC,CAAC;AACxE,cAAI,IAAI,IAAI;AAAA,QACd;AACA;AAAA,MACF;AAEA,UAAI,IAAI,WAAW,YAAY,GAAG;AAChC,cAAM,cAAc,IAAI,QAAQ,gBAAgB;AAChD,YAAI,OAAO,gBAAgB,UAAU;AACnC,cAAI,UAAU,GAAG;AACjB,cAAI,IAAI,+BAA+B;AACvC;AAAA,QACF;AAEA,cAAM,eAAe,IAAI,MAAM,aAAa,MAAM,KAAK;AACvD,cAAM,cAAc,GAAG,WAAW,GAAG,YAAY;AAEjD,cAAM,SAAmB,CAAC;AAC1B,yBAAiB,SAAS,KAAK;AAC7B,iBAAO,KAAK,KAAe;AAAA,QAC7B;AAEA,cAAM,OAAO,OAAO,SAAS,IAAI,OAAO,OAAO,MAAM,IAAI;AAGzD,cAAM,EAAE,MAAM,kBAAkB,OAAO,GAAG,eAAe,IAAI,IAAI;AAEjE,cAAM,eAAe,QAAQ,KAAK,SAAS,IAAI,OAAO;AACtD,cAAM,WAAW,MAAM,MAAM,aAAa;AAAA,UACxC,GAAI,IAAI,WAAW,UAAa,EAAE,QAAQ,IAAI,OAAO;AAAA,UACrD,SAAS;AAAA,UACT,GAAI,iBAAiB,UAAa,EAAE,MAAM,aAAa;AAAA,QACzD,CAAC;AAED,uBAAe,GAAG,IAAI,UAAU,KAAK,IAAI,YAAY,WAAM,OAAO,SAAS,MAAM,CAAC,EAAE;AAIpF,cAAM,kBAAkB,OAAO,YAAY,SAAS,OAAO;AAC3D,eAAO,gBAAgB,kBAAkB;AACzC,eAAO,gBAAgB,gBAAgB;AAEvC,YAAI,UAAU,SAAS,QAAQ,eAAe;AAC9C,YAAI,IAAI,OAAO,KAAK,MAAM,SAAS,YAAY,CAAC,CAAC;AACjD;AAAA,MACF;AAEA,YAAM,UAAU,QAAQ,MAAM,gBAAgB;AAC9C,YAAM,WAAWD,MAAK,YAAY,OAAO;AACzC,YAAM,eAAgB,MAAM,WAAW,QAAQ,IAAK,WAAWA,MAAK,YAAY,YAAY;AAC5F,YAAM,MAAM,QAAQ,YAAY;AAChC,YAAM,WAAW,WAAW,GAAG,KAAK;AACpC,UAAI,UAAU,KAAK,EAAE,gBAAgB,SAAS,CAAC;AAC/C,uBAAiB,YAAY,EAAE,KAAK,GAAG;AAAA,IACzC,GAAG;AAAA,EACL;AACF;AAEO,IAAM,QAAwB,CAAC,EAAE,MAAM,WAAW,UAAU,MAAM;AACvE,QAAM,CAAC,QAAQ,SAAS,IAAIH,UAAuB,UAAU;AAC7D,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAwB,IAAI;AACpE,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,UAAmB,CAAC,CAAC;AACrE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAmB,CAAC,CAAC;AACnE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAmB,CAAC,CAAC;AACnE,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAsB,SAAS;AACrE,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAwB,IAAI;AAChE,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAsB,IAAI;AAC5D,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAS,CAAC;AAEpD,QAAM,cAAc,OAAO,KAAK;AAChC,QAAM,sBAAsB,OAAO,KAAK;AACxC,QAAM,mBAAmB,OAA6C,IAAI;AAC1E,QAAM,eAAe,OAAuB,oBAAI,IAAI,CAAC;AACrD,QAAM,qBAAqB,OAAiB,CAAC,CAAC;AAE9C,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,UAAU,OAAQ,IAAI,QAAQ,UAAU,KAAM;AAChD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAED,EAAAC,WAAU,MAAM;AACd,QAAI,WAAW,aAAa,oBAAoB,SAAS;AACvD;AAAA,IACF;AAEA,wBAAoB,UAAU;AAE9B,UAAM,WAAW,cAAc,YAAY,GAAG;AAC9C,UAAM,cAAc,SAAS,UAAU;AACvC,UAAM,eAAe,oBAAoB;AACzC,UAAM,cAAcE,MAAK,WAAW,WAAW;AAI/C,QAAI,QAAQ,aAAa,UAAU;AACjC,UAAI;AACF,cAAM,YAAYA,MAAK,QAAQ,QAAQ,WAAW,CAAC,GAAG,YAAY;AAClE,cAAM,QAAQ,aAAa,WAAW,OAAO;AAC7C,YAAI,CAAC,MAAM,SAAS,aAAa,GAAG;AAClC,cAAI,SAAS,SAAS,EAAE,QAAQ,GAAG;AACjC,uBAAW,SAAS;AACpB,0BAAc,WAAW,KAAK;AAAA,UAChC;AACA;AAAA,YACE;AAAA,YACA,MACG,QAAQ,0DAA0D,eAAe,EACjF;AAAA,cACC;AAAA,cACA;AAAA,YACF;AAAA,UACJ;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,OAAO;AAAA,MACX;AAAA,MACA,CAAC,cAAc,UAAU,OAAO,IAAI,CAAC,IAAI,mBAAmB,WAAW,EAAE;AAAA,MACzE;AAAA,QACE,OAAO;AAAA,MACT;AAAA,IACF;AACA,SAAK,MAAM;AACX,YAAQ,GAAG,QAAQ,MAAM;AACvB,WAAK,KAAK;AAAA,IACZ,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,MAAM,SAAS,CAAC;AAE5B,QAAM,kBAAkB,YAAY,CAAC,YAA0B;AAC7D;AAAA,MAAoB,CAAC,MACnB,CAAC,GAAG,GAAG,IAAG,oBAAI,KAAK,GAAE,mBAAmB,CAAC,KAAK,OAAO,EAAE,EAAE,MAAM,CAAC,SAAS;AAAA,IAC3E;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,YAAY,YAAY,CAAC,QAAsB;AACnD,UAAM,OAAO,KAAK,UAAU,GAAG;AAC/B,QAAI,aAAa,QAAQ,SAAS,GAAG;AACnC,yBAAmB,UAAU,CAAC,GAAG,mBAAmB,SAAS,IAAI,EAAE,MAAM,CAAC,SAAS;AACnF;AAAA,IACF;AACA,eAAW,UAAU,aAAa,SAAS;AACzC,UAAI,OAAO,eAAe,GAAG;AAC3B,eAAO,KAAK,IAAI;AAAA,MAClB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiB;AAAA,IACrB,CAAC,YAA0B;AACzB;AAAA,QAAmB,CAAC,MAClB,CAAC,GAAG,GAAG,IAAG,oBAAI,KAAK,GAAE,mBAAmB,CAAC,KAAK,OAAO,EAAE,EAAE,MAAM,CAAC,SAAS;AAAA,MAC3E;AACA,gBAAU,EAAE,MAAM,aAAa,QAAQ,CAAC;AAAA,IAC1C;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,iBAAiB;AAAA,IACrB,CAAC,YAA0B;AACzB;AAAA,QAAmB,CAAC,MAClB,CAAC,GAAG,GAAG,IAAG,oBAAI,KAAK,GAAE,mBAAmB,CAAC,KAAK,OAAO,EAAE,EAAE,MAAM,CAAC,SAAS;AAAA,MAC3E;AACA,gBAAU,EAAE,MAAM,OAAO,QAAQ,CAAC;AAAA,IACpC;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,eAAe,YAAY,MAAM;AACrC,QAAI,YAAY,SAAS;AACvB;AAAA,IACF;AAEA,gBAAY,UAAU;AAEtB,mBAAe,UAAU;AACzB,kBAAc,IAAI;AAClB,mBAAe,eAAe;AAE9B,SAAK,SAAS,WAAW,SAAS,EAC/B,KAAK,MAAM;AACV,qBAAe,gBAAgB;AAC/B,qBAAe,MAAM;AACrB,mBAAa,oBAAI,KAAK,CAAC;AAEvB,qBAAe,6BAA6B;AAC5C,iBAAW,UAAU,aAAa,SAAS;AACzC,YAAI,OAAO,eAAe,GAAG;AAC3B,iBAAO,KAAK,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC,CAAC;AAAA,QACjD;AAAA,MACF;AAAA,IACF,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,oBAAc,OAAO;AACrB,qBAAe,OAAO;AAAA,IACxB,CAAC,EACA,QAAQ,MAAM;AACb,kBAAY,UAAU;AAAA,IACxB,CAAC;AAAA,EACL,GAAG,CAAC,WAAW,WAAW,cAAc,CAAC;AAEzC,EAAAF,WAAU,MAAM;AACd,iBAAa;AAEb,UAAM,UAAqB,MAAM,WAAW,EAAE,WAAW,KAAK,GAAG,CAAC,GAAG,aAAa;AAChF,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AAEA,YAAM,aAAa,SAAS,QAAQ,OAAO,GAAG;AAE9C,UAAI,oBAAoB,KAAK,CAAC,WAAW,WAAW,WAAW,MAAM,CAAC,GAAG;AACvE;AAAA,MACF;AAEA,qBAAe,yBAAyB,QAAQ,EAAE;AAElD,UAAI,iBAAiB,YAAY,MAAM;AACrC,qBAAa,iBAAiB,OAAO;AAAA,MACvC;AACA,uBAAiB,UAAU,WAAW,cAAc,GAAG;AAAA,IACzD,CAAC;AAED,WAAO,MAAM;AACX,cAAQ,MAAM;AAEd,UAAI,iBAAiB,YAAY,MAAM;AACrC,qBAAa,iBAAiB,OAAO;AAAA,MACvC;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,cAAc,cAAc,CAAC;AAE5C,EAAAA,WAAU,MAAM;AACd,UAAM,aAAa,cAAc;AAEjC,SAAK,WAAWE,MAAK,YAAY,YAAY,CAAC,EAAE,KAAK,CAAC,gBAAgB;AACpE,UAAI,CAAC,aAAa;AAChB,wBAAgB,kDAAkD;AAClE,kBAAU,OAAO;AACjB;AAAA,MACF;AAEA,YAAM,UAAU,qBAAqB,YAAY,iBAAiB,cAAc;AAChF,YAAM,SAAiB,aAAa,OAAO;AAC3C,YAAM,MAAM,IAAI,gBAAgB,EAAE,OAAO,CAAC;AAE1C,UAAI,GAAG,cAAc,CAAC,OAAkB;AACtC,mBAAW,QAAQ,mBAAmB,SAAS;AAC7C,cAAI,GAAG,eAAe,GAAG;AACvB,eAAG,KAAK,IAAI;AAAA,UACd;AAAA,QACF;AACA,2BAAmB,UAAU,CAAC;AAE9B,wBAAgB,kCAAkC;AAClD,qBAAa,QAAQ,IAAI,EAAE;AAC3B,yBAAiB,aAAa,QAAQ,IAAI;AAE1C,WAAG,GAAG,SAAS,MAAM;AACnB,uBAAa,QAAQ,OAAO,EAAE;AAC9B,2BAAiB,aAAa,QAAQ,IAAI;AAAA,QAC5C,CAAC;AAAA,MACH,CAAC;AAED,aAAO,OAAO,MAAM,MAAM;AACxB,kBAAU,SAAS;AACnB,wBAAgB,0BAA0B,OAAO,IAAI,CAAC,EAAE;AAAA,MAC1D,CAAC;AAED,aAAO,GAAG,SAAS,CAAC,QAAe;AACjC,wBAAgB,IAAI,OAAO;AAC3B,kBAAU,OAAO;AAAA,MACnB,CAAC;AAED,aAAO,MAAM;AACX,YAAI,MAAM;AACV,eAAO,MAAM;AAAA,MACf;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,iBAAiB,cAAc,CAAC;AAE1C,QAAM,iBACJ,cAAc,OAAO,KAAK,OAAO,KAAK,IAAI,IAAI,UAAU,QAAQ,KAAK,GAAI,IAAI;AAC/E,QAAM,eACJ,mBAAmB,OACf,KACA,iBAAiB,IACf,gBACA,KAAK,OAAO,cAAc,CAAC;AAEnC,SACE,gBAAAN,MAACQ,MAAA,EAAI,eAAc,UAAS,UAAU,GAAG,UAAU,GAEjD;AAAA,oBAAAT,KAACS,MAAA,EAAI,eAAc,UAAS,cAAc,GACxC,0BAAAT,KAACS,MAAA,EAAI,KAAK,GACR,0BAAAT,KAACM,OAAA,EAAK,MAAI,MAAC,OAAM,QAAO,+BAExB,GACF,GACF;AAAA,IAGA,gBAAAL,MAACQ,MAAA,EAAI,eAAc,UACjB;AAAA,sBAAAR,MAACQ,MAAA,EAAI,KAAK,GAAG,cAAc,GACxB;AAAA,wBAAgB,aAAa,gBAAAT,KAACM,OAAA,EAAK,UAAQ,MAAC,8BAAgB;AAAA,QAC5D,gBAAgB,cACf,gBAAAL,MAAAF,WAAA,EACE;AAAA,0BAAAC,KAACG,UAAA,EAAQ;AAAA,UACT,gBAAAH,KAACM,OAAA,EAAK,wCAA0B;AAAA,WAClC;AAAA,QAED,gBAAgB,UACf,gBAAAL,MAACK,OAAA,EAAK,OAAM,SAAQ;AAAA;AAAA,UAEjB,cAAc,OAAO,OAAO,UAAU,mBAAmB,CAAC,KAAK;AAAA,UAChE,gBAAAN,KAACM,OAAA,EAAK,UAAQ,MAAE,wBAAa;AAAA,WAC/B;AAAA,QAED,gBAAgB,WACf,gBAAAL,MAACK,OAAA,EAAK,OAAM,OAAM;AAAA;AAAA,UAAgB,cAAc;AAAA,WAAgB;AAAA,SAEpE;AAAA,MACA,gBAAAN;AAAA,QAACS;AAAA,QAAA;AAAA,UACC,eAAc;AAAA,UACd,QAAQ;AAAA,UACR,aAAY;AAAA,UACZ,aAAY;AAAA,UACZ,UAAS;AAAA,UAER,0BAAgB,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,UAC7C,gBAAAT,KAACM,OAAA,EAAiB,UAAQ,MAAC,MAAK,YAC7B,iBADQ,KAEX,CACD;AAAA;AAAA,MACH;AAAA,OACF;AAAA,IAGA,gBAAAL,MAACQ,MAAA,EAAI,WAAW,GAAG,eAAc,UAC/B;AAAA,sBAAAR,MAACQ,MAAA,EAAI,KAAK,GACP;AAAA,mBAAW,cAAc,gBAAAT,KAACM,OAAA,EAAK,UAAQ,MAAC,gCAAkB;AAAA,QAC1D,WAAW,aACV,gBAAAL,MAAAF,WAAA,EACE;AAAA,0BAAAC,KAACM,OAAA,EAAK,OAAM,SAAQ,uCAAoB;AAAA,UACxC,gBAAAL,MAACK,OAAA,EAAK,UAAQ,MAAC;AAAA;AAAA,YACV;AAAA,YAAc;AAAA,YAAQ,kBAAkB,IAAI,MAAM;AAAA,aACvD;AAAA,WACF;AAAA,QAED,WAAW,WAAW,gBAAAL,MAACK,OAAA,EAAK,OAAM,OAAM;AAAA;AAAA,UAAG,gBAAgB;AAAA,WAAe;AAAA,SAC7E;AAAA,MACA,gBAAAN;AAAA,QAACS;AAAA,QAAA;AAAA,UACC,eAAc;AAAA,UACd,QAAQ;AAAA,UACR,aAAY;AAAA,UACZ,aAAY;AAAA,UACZ,UAAS;AAAA,UAER,2BAAiB,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,UAC9C,gBAAAT,KAACM,OAAA,EAAiB,UAAQ,MAAC,MAAK,YAC7B,iBADQ,KAEX,CACD;AAAA;AAAA,MACH;AAAA,OACF;AAAA,IAGA,gBAAAL,MAACQ,MAAA,EAAI,WAAW,GAAG,eAAc,UAC/B;AAAA,sBAAAT,KAACM,OAAA,EAAK,UAAQ,MAAC,mBAAK;AAAA,MACpB,gBAAAN;AAAA,QAACS;AAAA,QAAA;AAAA,UACC,eAAc;AAAA,UACd,QAAQ;AAAA,UACR,aAAY;AAAA,UACZ,aAAY;AAAA,UACZ,UAAS;AAAA,UAER,0BAAgB,WAAW,IAC1B,gBAAAT,KAACM,OAAA,EAAK,UAAQ,MAAC,qCAAuB,IAEtC,gBAAgB,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,MAC5C,gBAAAN,KAACM,OAAA,EAAa,UAAQ,MAAC,MAAK,YACzB,iBADQ,CAEX,CACD;AAAA;AAAA,MAEL;AAAA,OACF;AAAA,IAGA,gBAAAN,KAACS,MAAA,EAAI,WAAW,GACd,0BAAAT,KAACM,OAAA,EAAK,UAAQ,MAAC,uBAAS,GAC1B;AAAA,KACF;AAEJ;;;ADnfO,SAAS,WAAWI,UAAwB;AACjD,EAAAA,SACG,QAAQ,KAAK,EACb,YAAY,oCAAoC,EAChD,OAAO,qBAAqB,qBAAqB,MAAM,EACvD,OAAO,OAAO,YAA8B;AAC3C,UAAM,OAAO,SAAS,QAAQ,MAAM,EAAE;AACtC,UAAM,YAAY,QAAQ,IAAI;AAC9B,UAAM,YAAY,GAAG,SAAS;AAC9B,UAAM,EAAE,cAAc,IAAIC,QAAOC,eAAc,OAAO,EAAE,MAAM,WAAW,UAAU,CAAC,GAAG;AAAA,MACrF,aAAa;AAAA,IACf,CAAC;AACD,UAAM,cAAc;AAAA,EACtB,CAAC;AACL;;;ALfA,QAAQ,KAAK,YAAY,EAAE,YAAY,0BAA0B,EAAE,QAAQ,OAAO;AAElF,aAAa,OAAO;AACpB,WAAW,OAAO;AAElB,QAAQ,MAAM;","names":["join","join","program","createElement","render","useEffect","useState","Box","Text","readFile","join","Fragment","jsx","jsxs","SPINNER_FRAMES","Spinner","useState","useEffect","Text","join","readFile","Box","program","render","createElement"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/build.ts","../src/ui/BuildUI.tsx","../src/lib/runBuild.ts","../src/lib/readFiles.ts","../src/ui/Logo.tsx","../src/lib/gitignore.ts","../src/commands/dev.ts","../src/ui/DevUI.tsx","../src/lib/config.ts","../src/ui/CredentialSetupUI.tsx","../src/lib/credentials.ts"],"sourcesContent":["import { program } from 'commander';\nimport { buildCommand } from './commands/build.js';\nimport { devCommand } from './commands/dev.js';\n\nprogram.name('appbuilder').description('Kizen plugin app builder').version('0.1.0');\n\nbuildCommand(program);\ndevCommand(program);\n\nprogram.parse();\n","import { createElement } from 'react';\nimport { render } from 'ink';\nimport type { Command } from 'commander';\nimport { BuildUI } from '../ui/BuildUI.js';\nimport { ensureGitignore } from '../lib/gitignore.js';\n\nexport function buildCommand(program: Command): void {\n program\n .command('build')\n .description('Bundle the plugin app into .kizenapp directory')\n .action(async () => {\n const pluginDir = process.cwd();\n const outputDir = `${pluginDir}/.kizenapp`;\n ensureGitignore(pluginDir);\n const { waitUntilExit } = render(createElement(BuildUI, { outputDir, pluginDir }));\n await waitUntilExit();\n });\n}\n","import type { FC } from 'react';\nimport { useEffect, useState } from 'react';\nimport { Box, Text, useApp } from 'ink';\nimport { runBuild } from '../lib/runBuild.js';\nimport type { BuildStepName } from '../lib/runBuild.js';\nimport { Logo } from './Logo.js';\n\ntype BuildStep = BuildStepName | 'done' | 'error';\n\ninterface BuildUIProps {\n outputDir: string;\n pluginDir: string;\n}\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nconst Spinner: FC = () => {\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const id = setInterval(() => {\n setFrame((prev) => (prev + 1) % SPINNER_FRAMES.length);\n }, 80);\n\n return () => {\n clearInterval(id);\n };\n }, []);\n\n return <Text color=\"cyan\">{SPINNER_FRAMES[frame] ?? '⠋'}</Text>;\n};\n\nconst STEPS: BuildStepName[] = [\n 'creating-dir',\n 'reading-files',\n 'minifying',\n 'packaging',\n 'writing-bundle',\n];\n\nconst STEP_LABELS: Record<BuildStepName, string> = {\n 'creating-dir': 'Creating .kizenapp directory',\n 'reading-files': 'Reading plugin files',\n minifying: 'Minifying scripts',\n packaging: 'Packaging plugin',\n 'writing-bundle': 'Writing bundle.json',\n};\n\nexport const BuildUI: FC<BuildUIProps> = ({ outputDir, pluginDir }) => {\n const app = useApp();\n const [step, setStep] = useState<BuildStep>('creating-dir');\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n\n useEffect(() => {\n void runBuild(pluginDir, outputDir, setStep)\n .then(() => {\n setStep('done');\n app.exit();\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n setErrorMessage(message);\n setStep('error');\n app.exit();\n });\n }, [outputDir, pluginDir, app]);\n\n const currentIndex = STEPS.indexOf(step as BuildStepName);\n const isError = step === 'error';\n const isDone = step === 'done';\n\n return (\n <Box flexDirection=\"column\" paddingY={1} paddingX={2}>\n <Logo />\n\n <Box flexDirection=\"column\" marginTop={1} marginBottom={1}>\n <Text bold color=\"cyan\">\n Kizen App Builder\n </Text>\n <Text dimColor>{'─'.repeat(24)}</Text>\n </Box>\n\n <Box flexDirection=\"column\" gap={0}>\n {STEPS.map((s, i) => {\n const isActive = step === s;\n const isStepDone = isDone || currentIndex > i;\n const isFailed = isError && i === currentIndex;\n\n return (\n <Box key={s} gap={1}>\n {isFailed ? (\n <Text color=\"red\">✗ {STEP_LABELS[s]}</Text>\n ) : isStepDone ? (\n <Text color=\"green\">✓ {STEP_LABELS[s]}</Text>\n ) : isActive ? (\n <>\n <Spinner />\n <Text>{STEP_LABELS[s]}</Text>\n </>\n ) : (\n <Text dimColor> {STEP_LABELS[s]}</Text>\n )}\n </Box>\n );\n })}\n\n {errorMessage !== null && (\n <Box marginTop={1} borderStyle=\"single\" borderColor=\"red\" paddingX={1}>\n <Text color=\"red\">{errorMessage}</Text>\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { minifyFiles, packagePlugin, transformDeployablePlugin } from '@kizenapps/packager';\nimport type { DeployablePlugin } from '@kizenapps/packager';\nimport { readLocalFiles } from './readFiles.js';\n\nexport type BuildStepName =\n | 'creating-dir'\n | 'reading-files'\n | 'minifying'\n | 'packaging'\n | 'writing-bundle';\n\ntype SerializableDeployablePlugin = Omit<DeployablePlugin, 'thumbnail' | 'kznFile'> & {\n thumbnail: string | null;\n kznFile: string | null;\n};\n\nconst serializePlugin = (plugin: DeployablePlugin): SerializableDeployablePlugin => ({\n ...plugin,\n thumbnail: plugin.thumbnail ? Buffer.from(plugin.thumbnail).toString('base64') : null,\n kznFile: plugin.kznFile ? Buffer.from(plugin.kznFile).toString('base64') : null,\n});\n\nexport async function runBuild(\n pluginDir: string,\n outputDir: string,\n onStep?: (step: BuildStepName) => void,\n): Promise<void> {\n await mkdir(outputDir, { recursive: true });\n\n onStep?.('reading-files');\n const files = await readLocalFiles(pluginDir);\n\n onStep?.('minifying');\n const minified = await minifyFiles(files);\n\n onStep?.('packaging');\n const manifestFile = minified.find((f) => f.path === 'kizen.json');\n if (!manifestFile) {\n throw new Error('kizen.json not found in plugin directory.');\n }\n const manifests = JSON.parse(manifestFile.content) as Parameters<typeof packagePlugin>[1];\n const packaged = packagePlugin(minified, manifests);\n const deployable = Object.values(packaged).map(transformDeployablePlugin);\n\n onStep?.('writing-bundle');\n const bundle = deployable.map(serializePlugin);\n await writeFile(join(outputDir, 'bundle.json'), JSON.stringify(bundle, null, 2), 'utf-8');\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport type { FileContent } from '@kizenapps/packager';\n\nconst IMAGE_EXTENSIONS = new Set(['.png', '.svg']);\nconst BINARY_EXTENSIONS = new Set(['.kzn']);\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', '.kizenapp', '.github']);\n\nasync function walk(dir: string, rootDir: string): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true });\n const paths: string[] = [];\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name)) {\n continue;\n }\n\n paths.push(...(await walk(join(dir, entry.name), rootDir)));\n } else if (entry.isFile()) {\n paths.push(join(dir, entry.name));\n }\n }\n\n return paths;\n}\n\nexport async function readLocalFiles(rootDir: string): Promise<FileContent[]> {\n const absolutePaths = await walk(rootDir, rootDir);\n\n return Promise.all(\n absolutePaths.map(async (absPath): Promise<FileContent> => {\n const relPath = relative(rootDir, absPath).split('\\\\').join('/');\n const dotIndex = relPath.lastIndexOf('.');\n const ext = dotIndex >= 0 ? relPath.slice(dotIndex).toLowerCase() : '';\n\n if (IMAGE_EXTENSIONS.has(ext)) {\n const buf = await readFile(absPath);\n return { path: relPath, content: '', base64Image: buf.toString('base64') };\n }\n\n if (BINARY_EXTENSIONS.has(ext)) {\n const buf = await readFile(absPath);\n return { path: relPath, content: '', binaryData: buf };\n }\n\n const content = await readFile(absPath, 'utf-8');\n return { path: relPath, content };\n }),\n );\n}\n","import type { FC } from 'react';\nimport { Box, Text } from 'ink';\n\nconst LOGO_LINES = [\n ' @@@ ',\n ' @@@@@ @@@@@@@ ',\n ' @@@@ @@@@@@@@@@ ',\n ' @@@@ @@@@@ ',\n ' @@@ @@@@ @@@@@ @@@@@@@ ',\n ' @@@@ @@@@ @@@@ @@@@@@@@@@@@@',\n ' @@@@ @@@@ @@@@@',\n ' @@@@ @@@ @@@@ @@@',\n ' @@@@ @@@@@@ ',\n ' @@@@@@ @@@@ ',\n ' @@@ @@@@@ @@@ @@@@ ',\n ' @@@@@ @@@@ @@@@ ',\n ' @@@@@@@@@@@@@ @@@ @@@ @@@ ',\n ' @@@@@@@@ @@@@ @@@ @@@@ ',\n ' @@@@@ @@@@ ',\n ' @@@@@@@@@@@ @@@@ ',\n ' @@@@@@@ @@@@@ ',\n ' @@@@ ',\n];\n\nexport const Logo: FC = () => (\n <Box flexDirection=\"column\">\n {LOGO_LINES.map((line, i) => (\n <Text key={i} color=\"cyan\">\n {line}\n </Text>\n ))}\n </Box>\n);\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport function ensureGitignore(projectDir: string): void {\n const gitignorePath = path.join(projectDir, '.gitignore');\n const entry = '.kizenapp/';\n\n let contents = '';\n if (fs.existsSync(gitignorePath)) {\n contents = fs.readFileSync(gitignorePath, 'utf8');\n const lines = contents.split('\\n').map((l) => l.trim());\n if (lines.includes(entry) || lines.includes('.kizenapp')) {\n return;\n }\n }\n\n const addition = contents.endsWith('\\n') ? entry + '\\n' : '\\n' + entry + '\\n';\n fs.writeFileSync(gitignorePath, contents + addition);\n}\n","import { createElement } from 'react';\nimport { render } from 'ink';\nimport type { Command } from 'commander';\nimport { DevUI } from '../ui/DevUI.js';\nimport { CredentialSetupUI } from '../ui/CredentialSetupUI.js';\nimport type { CredentialMode, CredentialSetupResult } from '../ui/CredentialSetupUI.js';\nimport { loadCredentialsFromFile, loadGlobalCredentials } from '../lib/credentials.js';\nimport type { Credentials } from '../lib/credentials.js';\nimport { loadConfig, saveConfig } from '../lib/config.js';\nimport { ensureGitignore } from '../lib/gitignore.js';\n\nasync function runSetupUI(initialMode?: CredentialMode): Promise<CredentialSetupResult> {\n return new Promise((resolve) => {\n let unmountFn: (() => void) | null = null;\n const handleComplete = (result: CredentialSetupResult): void => {\n unmountFn?.();\n resolve(result);\n };\n const { unmount } = render(\n createElement(CredentialSetupUI, {\n ...(initialMode !== undefined && { initialMode }),\n onComplete: handleComplete,\n }),\n { exitOnCtrlC: false },\n );\n unmountFn = unmount;\n });\n}\n\nexport function devCommand(program: Command): void {\n program\n .command('dev')\n .description('Start the plugin viewer dev server')\n .option('-p, --port <port>', 'port to listen on', '3121')\n .option('-c, --credentials <path>', 'path to a credentials JSON file')\n .action(async (options: { port: string; credentials?: string }) => {\n const port = parseInt(options.port, 10);\n const pluginDir = process.cwd();\n const outputDir = `${pluginDir}/.kizenapp`;\n ensureGitignore(pluginDir);\n\n let credentials: Credentials | null = null;\n let credentialMode: CredentialMode | undefined;\n\n if (options.credentials) {\n credentials = await loadCredentialsFromFile(options.credentials);\n } else {\n const config = await loadConfig(outputDir);\n\n if (config.credentialMode === 'local') {\n credentialMode = 'local';\n } else if (config.credentialMode === 'global') {\n credentialMode = 'global';\n // Load silently — only show TUI if the file was deleted since last run\n credentials = await loadGlobalCredentials();\n if (!credentials) {\n const result = await runSetupUI('global');\n credentials = result.credentials;\n }\n } else {\n // First run — show full mode selection TUI\n const result = await runSetupUI();\n credentials = result.credentials;\n credentialMode = result.mode;\n await saveConfig(outputDir, { credentialMode: result.mode });\n }\n }\n\n const { waitUntilExit } = render(\n createElement(DevUI, {\n port,\n pluginDir,\n outputDir,\n credentials,\n ...(credentialMode !== undefined && { credentialMode }),\n }),\n { exitOnCtrlC: false },\n );\n await waitUntilExit();\n });\n}\n","import type { FC } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { spawn } from 'node:child_process';\nimport { createReadStream, watch } from 'node:fs';\nimport type { FSWatcher } from 'node:fs';\nimport { access, readFile } from 'node:fs/promises';\nimport { createServer } from 'node:http';\nimport type { IncomingMessage, Server, ServerResponse } from 'node:http';\nimport { createRequire } from 'node:module';\nimport { dirname, extname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { type WebSocket, WebSocketServer } from 'ws';\nimport { runBuild } from '../lib/runBuild.js';\nimport type { Credentials } from '../lib/credentials.js';\nimport { saveConfig } from '../lib/config.js';\nimport { CredentialSetupUI } from './CredentialSetupUI.js';\nimport type { CredentialMode, CredentialSetupResult } from './CredentialSetupUI.js';\nimport { Logo } from './Logo.js';\n\ntype ServerStatus = 'starting' | 'running' | 'error';\ntype BuildStatus = 'pending' | 'building' | 'done' | 'error';\n\nconst SKIP_WATCH_PREFIXES = ['.kizenapp', '.git'];\nconst LOG_LIMIT = 50;\nconst LOG_DISPLAY = 8;\n\ninterface DevUIProps {\n port: number;\n pluginDir: string;\n outputDir: string;\n credentials: Credentials | null;\n credentialMode?: CredentialMode;\n}\n\nconst MIME_TYPES: Readonly<Record<string, string>> = {\n '.html': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.json': 'application/json; charset=utf-8',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.map': 'application/json',\n};\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nconst Spinner: FC = () => {\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const id = setInterval(() => {\n setFrame((prev) => (prev + 1) % SPINNER_FRAMES.length);\n }, 80);\n\n return () => {\n clearInterval(id);\n };\n }, []);\n\n return <Text color=\"cyan\">{SPINNER_FRAMES[frame] ?? '⠋'}</Text>;\n};\n\nfunction getViewerPath(): string {\n const filename = fileURLToPath(import.meta.url);\n return join(dirname(filename), 'viewer');\n}\n\nfunction getElectronMainPath(): string {\n const filename = fileURLToPath(import.meta.url);\n return join(dirname(filename), 'electron', 'main.js');\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction createRequestHandler(\n viewerPath: string,\n createServerLog: (message: string) => void,\n createProxyLog: (message: string) => void,\n credentialsRef: { current: Credentials | null },\n): (req: IncomingMessage, res: ServerResponse) => void {\n return (req, res) => {\n void (async () => {\n const url = req.url ?? '/';\n\n try {\n createServerLog(`Received request: ${url}`);\n\n if (url === '/api/credentials') {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(credentialsRef.current !== null ? JSON.stringify(credentialsRef.current) : '{}');\n return;\n }\n\n if (url === '/api/bundle') {\n const bundlePath = join(process.cwd(), '.kizenapp', 'bundle.json');\n try {\n const content = await readFile(bundlePath, 'utf-8');\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(content);\n } catch {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end('{}');\n }\n return;\n }\n\n if (url.startsWith('/api/proxy')) {\n const proxyTarget = req.headers['x-proxy-target'];\n if (typeof proxyTarget !== 'string') {\n res.writeHead(400);\n res.end('Missing x-proxy-target header');\n return;\n }\n\n const upstreamPath = url.slice('/api/proxy'.length) || '/';\n const upstreamUrl = `${proxyTarget}${upstreamPath}`;\n\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(chunk as Buffer);\n }\n\n const body = chunks.length > 0 ? Buffer.concat(chunks) : undefined;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { host, 'x-proxy-target': _drop, ...forwardHeaders } = req.headers;\n\n const resolvedBody = body && body.length > 0 ? body : undefined;\n const upstream = await fetch(upstreamUrl, {\n ...(req.method !== undefined && { method: req.method }),\n headers: forwardHeaders as Record<string, string>,\n ...(resolvedBody !== undefined && { body: resolvedBody }),\n });\n\n createProxyLog(`${req.method ?? 'GET'} ${upstreamPath} → ${String(upstream.status)}`);\n\n // Node fetch auto-decompresses the body, so strip encoding/length headers\n // that describe the compressed wire format — they no longer apply.\n const responseHeaders = Object.fromEntries(upstream.headers);\n delete responseHeaders['content-encoding'];\n delete responseHeaders['content-length'];\n\n res.writeHead(upstream.status, responseHeaders);\n res.end(Buffer.from(await upstream.arrayBuffer()));\n return;\n }\n\n const rawPath = url === '/' ? '/index.html' : url;\n const filePath = join(viewerPath, rawPath);\n const resolvedPath = (await fileExists(filePath))\n ? filePath\n : join(viewerPath, 'index.html');\n const ext = extname(resolvedPath);\n const mimeType = MIME_TYPES[ext] ?? 'application/octet-stream';\n res.writeHead(200, { 'Content-Type': mimeType });\n createReadStream(resolvedPath).pipe(res);\n } catch (err) {\n createProxyLog(\n `Error handling ${url}: ${err instanceof Error ? err.message : String(err)}`,\n );\n if (!res.headersSent) {\n res.writeHead(502);\n res.end('Bad Gateway');\n }\n }\n })();\n };\n}\n\nexport const DevUI: FC<DevUIProps> = ({\n port,\n pluginDir,\n outputDir,\n credentials: initialCredentials,\n}) => {\n const credentialsRef = useRef<Credentials | null>(initialCredentials);\n const [credMode, setCredMode] = useState<'main' | 'editing'>('main');\n\n const [status, setStatus] = useState<ServerStatus>('starting');\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [serverLogHistory, setServerLogHistory] = useState<string[]>([]);\n const [buildLogHistory, setBuildLogHistory] = useState<string[]>([]);\n const [proxyLogHistory, setProxyLogHistory] = useState<string[]>([]);\n const [buildStatus, setBuildStatus] = useState<BuildStatus>('pending');\n const [buildError, setBuildError] = useState<string | null>(null);\n const [lastBuilt, setLastBuilt] = useState<Date | null>(null);\n const [wsClientCount, setWsClientCount] = useState(0);\n\n const buildingRef = useRef(false);\n const electronLaunchedRef = useRef(false);\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const wsClientsRef = useRef<Set<WebSocket>>(new Set());\n const pendingMessagesRef = useRef<string[]>([]);\n\n useInput(\n (input, key) => {\n if (input === 'q' || (key.ctrl && input === 'c')) {\n process.exit(0);\n }\n if (input === 'c') {\n setCredMode('editing');\n }\n if (input === 'd') {\n broadcast({ type: 'open-devtools' });\n }\n },\n { isActive: credMode === 'main' },\n );\n\n useEffect(() => {\n if (status !== 'running' || electronLaunchedRef.current) {\n return;\n }\n\n electronLaunchedRef.current = true;\n\n const _require = createRequire(import.meta.url);\n const electronBin = _require('electron') as string;\n const electronMain = getElectronMainPath();\n const userDataDir = join(outputDir, '.electron');\n\n const proc = spawn(\n electronBin,\n [electronMain, `--port=${String(port)}`, `--user-data-dir=${userDataDir}`],\n {\n stdio: 'ignore',\n },\n );\n proc.unref();\n process.on('exit', () => {\n proc.kill();\n });\n }, [status, port, outputDir]);\n\n const createServerLog = useCallback((message: string): void => {\n setServerLogHistory((h) =>\n [...h, `${new Date().toLocaleTimeString()}: ${message}`].slice(-LOG_LIMIT),\n );\n }, []);\n\n const broadcast = useCallback((msg: object): void => {\n const json = JSON.stringify(msg);\n if (wsClientsRef.current.size === 0) {\n pendingMessagesRef.current = [...pendingMessagesRef.current, json].slice(-LOG_LIMIT);\n return;\n }\n for (const client of wsClientsRef.current) {\n if (client.readyState === 1) {\n client.send(json);\n }\n }\n }, []);\n\n const handleCredentialsDone = useCallback(\n (result: CredentialSetupResult): void => {\n credentialsRef.current = result.credentials;\n setCredMode('main');\n void saveConfig(outputDir, { credentialMode: result.mode });\n broadcast({ type: 'credentials-updated', credentials: result.credentials });\n },\n [outputDir, broadcast],\n );\n\n const createProxyLog = useCallback(\n (message: string): void => {\n setProxyLogHistory((h) =>\n [...h, `${new Date().toLocaleTimeString()}: ${message}`].slice(-LOG_LIMIT),\n );\n broadcast({ type: 'proxy-log', message });\n },\n [broadcast],\n );\n\n const createBuildLog = useCallback(\n (message: string): void => {\n setBuildLogHistory((h) =>\n [...h, `${new Date().toLocaleTimeString()}: ${message}`].slice(-LOG_LIMIT),\n );\n broadcast({ type: 'log', message });\n },\n [broadcast],\n );\n\n const triggerBuild = useCallback(() => {\n if (buildingRef.current) {\n return;\n }\n\n buildingRef.current = true;\n\n setBuildStatus('building');\n setBuildError(null);\n createBuildLog('Build started');\n\n void runBuild(pluginDir, outputDir)\n .then(() => {\n createBuildLog('Build finished');\n setBuildStatus('done');\n setLastBuilt(new Date());\n\n createBuildLog('Notifying viewers to reload');\n for (const client of wsClientsRef.current) {\n if (client.readyState === 1) {\n client.send(JSON.stringify({ type: 'rebuild' }));\n }\n }\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n setBuildError(message);\n setBuildStatus('error');\n })\n .finally(() => {\n buildingRef.current = false;\n });\n }, [pluginDir, outputDir, createBuildLog]);\n\n useEffect(() => {\n triggerBuild();\n\n const watcher: FSWatcher = watch(pluginDir, { recursive: true }, (_, filename) => {\n if (!filename) {\n return;\n }\n\n const normalized = filename.replace(/\\\\/g, '/');\n\n if (SKIP_WATCH_PREFIXES.some((prefix) => normalized.startsWith(prefix))) {\n return;\n }\n\n createBuildLog(`File change detected: ${filename}`);\n\n if (debounceTimerRef.current !== null) {\n clearTimeout(debounceTimerRef.current);\n }\n debounceTimerRef.current = setTimeout(triggerBuild, 150);\n });\n\n return () => {\n watcher.close();\n\n if (debounceTimerRef.current !== null) {\n clearTimeout(debounceTimerRef.current);\n }\n };\n }, [pluginDir, triggerBuild, createBuildLog]);\n\n useEffect(() => {\n const viewerPath = getViewerPath();\n\n void fileExists(join(viewerPath, 'index.html')).then((viewerBuilt) => {\n if (!viewerBuilt) {\n setErrorMessage(\"Viewer not built. Run 'pnpm build:viewer' first.\");\n setStatus('error');\n return;\n }\n\n const handler = createRequestHandler(\n viewerPath,\n createServerLog,\n createProxyLog,\n credentialsRef,\n );\n const server: Server = createServer(handler);\n const wss = new WebSocketServer({ server });\n\n wss.on('connection', (ws: WebSocket) => {\n for (const json of pendingMessagesRef.current) {\n if (ws.readyState === 1) {\n ws.send(json);\n }\n }\n pendingMessagesRef.current = [];\n\n createServerLog('Viewer connected for live reload');\n wsClientsRef.current.add(ws);\n setWsClientCount(wsClientsRef.current.size);\n\n ws.on('close', () => {\n wsClientsRef.current.delete(ws);\n setWsClientCount(wsClientsRef.current.size);\n });\n });\n\n server.listen(port, () => {\n setStatus('running');\n createServerLog(`Server started on port ${String(port)}`);\n });\n\n server.on('error', (err: Error) => {\n setErrorMessage(err.message);\n setStatus('error');\n });\n\n return () => {\n wss.close();\n server.close();\n };\n });\n }, [port, createServerLog, createProxyLog]);\n\n if (credMode === 'editing') {\n return (\n <CredentialSetupUI\n onComplete={handleCredentialsDone}\n onCancel={() => {\n setCredMode('main');\n }}\n />\n );\n }\n\n const elapsedSeconds =\n lastBuilt !== null ? Math.round((Date.now() - lastBuilt.getTime()) / 1000) : null;\n const elapsedLabel =\n elapsedSeconds === null\n ? ''\n : elapsedSeconds < 5\n ? ' (just now)'\n : ` (${String(elapsedSeconds)}s ago)`;\n\n return (\n <Box flexDirection=\"column\" paddingY={1} paddingX={2}>\n {/* Logo + header */}\n <Logo />\n <Box flexDirection=\"column\" marginTop={1} marginBottom={1}>\n <Text bold color=\"cyan\">\n Kizen App Builder\n </Text>\n <Text dimColor>{'─'.repeat(24)}</Text>\n </Box>\n\n {/* Build panel */}\n <Box flexDirection=\"column\">\n <Box gap={2} marginBottom={0}>\n <Text bold dimColor>\n Build\n </Text>\n {buildStatus === 'pending' && <Text dimColor>waiting…</Text>}\n {buildStatus === 'building' && (\n <Box gap={1}>\n <Spinner />\n <Text>Building plugin package…</Text>\n </Box>\n )}\n {buildStatus === 'done' && (\n <Box gap={1}>\n <Text color=\"green\">✓ Built</Text>\n {lastBuilt !== null && (\n <Text dimColor>\n at {lastBuilt.toLocaleTimeString()}\n {elapsedLabel}\n </Text>\n )}\n </Box>\n )}\n {buildStatus === 'error' && <Text color=\"red\">✗ {buildError ?? 'unknown error'}</Text>}\n </Box>\n <Box\n flexDirection=\"column\"\n height={LOG_DISPLAY}\n borderStyle=\"single\"\n borderColor=\"gray\"\n overflow=\"hidden\"\n >\n {buildLogHistory.slice(-LOG_DISPLAY).map((log, index) => (\n <Text key={index} dimColor wrap=\"truncate\">\n {log}\n </Text>\n ))}\n </Box>\n </Box>\n\n {/* Server panel */}\n <Box marginTop={1} flexDirection=\"column\">\n <Box gap={2}>\n <Text bold dimColor>\n Server\n </Text>\n {status === 'starting' && <Text dimColor>starting…</Text>}\n {status === 'running' && (\n <Box gap={2}>\n <Text color=\"green\">✓ Running</Text>\n <Text dimColor>\n ● {wsClientCount} viewer{wsClientCount !== 1 ? 's' : ''}\n </Text>\n </Box>\n )}\n {status === 'error' && <Text color=\"red\">✗ {errorMessage ?? 'Server error'}</Text>}\n </Box>\n <Box\n flexDirection=\"column\"\n height={LOG_DISPLAY}\n borderStyle=\"single\"\n borderColor=\"gray\"\n overflow=\"hidden\"\n >\n {serverLogHistory.slice(-LOG_DISPLAY).map((log, index) => (\n <Text key={index} dimColor wrap=\"truncate\">\n {log}\n </Text>\n ))}\n </Box>\n </Box>\n\n {/* Proxy panel */}\n <Box marginTop={1} flexDirection=\"column\">\n <Box gap={2}>\n <Text bold dimColor>\n Proxy\n </Text>\n <Text color=\"green\">✓ Active</Text>\n </Box>\n <Box\n flexDirection=\"column\"\n height={LOG_DISPLAY}\n borderStyle=\"single\"\n borderColor=\"gray\"\n overflow=\"hidden\"\n >\n {proxyLogHistory.length === 0 ? (\n <Text dimColor> No requests yet.</Text>\n ) : (\n proxyLogHistory.slice(-LOG_DISPLAY).map((log, i) => (\n <Text key={i} dimColor wrap=\"truncate\">\n {log}\n </Text>\n ))\n )}\n </Box>\n </Box>\n\n {/* Footer */}\n <Box marginTop={1} gap={1}>\n <Text dimColor>[</Text>\n <Text>q</Text>\n <Text dimColor>] quit [</Text>\n <Text>c</Text>\n <Text dimColor>] credentials [</Text>\n <Text>d</Text>\n <Text dimColor>] devtools</Text>\n </Box>\n </Box>\n );\n};\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nexport interface AppBuilderConfig {\n credentialMode?: 'global' | 'local';\n}\n\nexport async function loadConfig(outputDir: string): Promise<AppBuilderConfig> {\n try {\n const content = await readFile(join(outputDir, 'config.json'), 'utf-8');\n return JSON.parse(content) as AppBuilderConfig;\n } catch {\n return {};\n }\n}\n\nexport async function saveConfig(outputDir: string, config: AppBuilderConfig): Promise<void> {\n await mkdir(outputDir, { recursive: true });\n await writeFile(join(outputDir, 'config.json'), JSON.stringify(config, null, 2), 'utf-8');\n}\n","import type { FC } from 'react';\nimport { useCallback, useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport {\n ENVIRONMENTS,\n GLOBAL_CREDENTIALS_PATH,\n loadGlobalCredentials,\n saveGlobalCredentials,\n} from '../lib/credentials.js';\nimport type { Credentials } from '../lib/credentials.js';\nimport { Logo } from './Logo.js';\n\ntype Mode = 'global' | 'local';\n\ntype Phase =\n | { type: 'mode-select'; cursor: 0 | 1 }\n | { type: 'loading' }\n | { type: 'creds-entry'; field: number; values: Partial<Credentials>; envCursor: number }\n | { type: 'saving' }\n | { type: 'done' };\n\nconst FIELDS = ['apiKey', 'userId', 'businessId'] as const;\nconst FIELD_LABELS: Record<string, string> = {\n apiKey: 'API Key',\n userId: 'User ID',\n businessId: 'Business ID',\n};\n\nexport type CredentialMode = 'global' | 'local';\n\nexport interface CredentialSetupResult {\n mode: CredentialMode;\n credentials: Credentials | null;\n}\n\ninterface CredentialSetupUIProps {\n initialMode?: CredentialMode;\n onComplete: (result: CredentialSetupResult) => void;\n onCancel?: () => void;\n}\n\nconst Hint: FC<{ text: string }> = ({ text }) => <Text dimColor>{text}</Text>;\n\nexport const CredentialSetupUI: FC<CredentialSetupUIProps> = ({\n initialMode,\n onComplete,\n onCancel,\n}) => {\n const [phase, setPhase] = useState<Phase>(\n initialMode === 'global' ? { type: 'loading' } : { type: 'mode-select', cursor: 0 },\n );\n const [inputBuffer, setInputBuffer] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const handleModeChosen = useCallback(\n async (mode: Mode) => {\n if (mode === 'local') {\n onComplete({ mode: 'local', credentials: null });\n return;\n }\n\n setPhase({ type: 'loading' });\n\n const existing = await loadGlobalCredentials();\n const envCursor = existing ? Math.max(0, ENVIRONMENTS.indexOf(existing.environment)) : 0;\n setPhase({\n type: 'creds-entry',\n field: 0,\n values: existing ?? {},\n envCursor,\n });\n },\n [onComplete],\n );\n\n const handleSave = useCallback(\n async (values: Partial<Credentials>, envCursor: number) => {\n const environment = ENVIRONMENTS[envCursor] ?? 'go';\n const credentials: Credentials = {\n apiKey: values.apiKey ?? '',\n userId: values.userId ?? '',\n businessId: values.businessId ?? '',\n environment,\n };\n setPhase({ type: 'saving' });\n try {\n await saveGlobalCredentials(credentials);\n onComplete({ mode: 'global', credentials });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setPhase({ type: 'creds-entry', field: 0, values, envCursor });\n }\n },\n [onComplete],\n );\n\n useInput((input, key) => {\n if (key.ctrl && input === 'c') {\n process.exit(0);\n }\n\n if (key.escape) {\n onCancel?.();\n return;\n }\n\n if (phase.type === 'mode-select') {\n if (key.upArrow) {\n setPhase({ type: 'mode-select', cursor: 0 });\n } else if (key.downArrow) {\n setPhase({ type: 'mode-select', cursor: 1 });\n } else if (key.return) {\n const mode: Mode = phase.cursor === 0 ? 'global' : 'local';\n void handleModeChosen(mode);\n }\n return;\n }\n\n if (phase.type === 'creds-entry') {\n const { field, values, envCursor } = phase;\n const isEnvField = field === FIELDS.length;\n\n if (isEnvField) {\n if (key.leftArrow) {\n setPhase({\n ...phase,\n envCursor: (envCursor - 1 + ENVIRONMENTS.length) % ENVIRONMENTS.length,\n });\n } else if (key.rightArrow) {\n setPhase({ ...phase, envCursor: (envCursor + 1) % ENVIRONMENTS.length });\n } else if (key.upArrow) {\n setPhase({ ...phase, field: field - 1 });\n setInputBuffer(values[FIELDS[field - 1] as keyof typeof values] ?? '');\n } else if (key.return) {\n void handleSave(values, envCursor);\n }\n return;\n }\n\n const fieldName = FIELDS[field];\n if (!fieldName) {\n return;\n }\n\n if (key.backspace || key.delete) {\n setInputBuffer((prev) => prev.slice(0, -1));\n } else if (key.upArrow && field > 0) {\n const updatedValues = { ...values, [fieldName]: inputBuffer };\n const prevField = field - 1;\n setPhase({ ...phase, field: prevField, values: updatedValues });\n setInputBuffer(updatedValues[FIELDS[prevField] as keyof typeof updatedValues] ?? '');\n } else if (key.return || key.tab || key.downArrow) {\n // Advance to next field\n const updatedValues = { ...values, [fieldName]: inputBuffer };\n const nextField = field + 1;\n setPhase({ ...phase, field: nextField, values: updatedValues });\n if (nextField < FIELDS.length) {\n setInputBuffer(updatedValues[FIELDS[nextField] as keyof typeof updatedValues] ?? '');\n } else {\n setInputBuffer('');\n }\n } else if (input && !key.ctrl && !key.meta) {\n setInputBuffer((prev) => prev + input);\n }\n }\n });\n\n // Trigger global credential load when initialMode skips mode selection\n useEffect(() => {\n if (initialMode === 'global') {\n void handleModeChosen('global');\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Reset input buffer when switching to creds-entry\n useEffect(() => {\n if (phase.type === 'creds-entry' && phase.field === 0) {\n setInputBuffer(phase.values.apiKey ?? '');\n }\n }, [phase.type]); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (phase.type === 'loading' || phase.type === 'saving') {\n return (\n <Box paddingY={1} paddingX={2}>\n <Text dimColor>\n {phase.type === 'loading' ? 'Loading credentials…' : 'Saving credentials…'}\n </Text>\n </Box>\n );\n }\n\n if (phase.type === 'done') {\n return null;\n }\n\n if (phase.type === 'mode-select') {\n const options: { label: string; desc: string; mode: Mode }[] = [\n { label: 'Global', desc: `~/.kizenappbuilder/credentials.json`, mode: 'global' },\n { label: 'Local', desc: 'Enter credentials in the browser dev tools', mode: 'local' },\n ];\n\n return (\n <Box flexDirection=\"column\" paddingY={1} paddingX={2} gap={1}>\n <Logo />\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold color=\"cyan\">\n Kizen App Builder\n </Text>\n <Text dimColor>{'─'.repeat(24)}</Text>\n </Box>\n <Box flexDirection=\"column\" gap={0}>\n <Text bold>Credential mode</Text>\n {options.map((opt, i) => {\n const selected = phase.cursor === i;\n return (\n <Box key={opt.mode} gap={2}>\n <Text {...(selected && { color: 'cyan' as const })}>{selected ? '❯' : ' '}</Text>\n <Text bold={selected} {...(selected && { color: 'cyan' as const })}>\n {opt.label}\n </Text>\n <Text dimColor>{opt.desc}</Text>\n </Box>\n );\n })}\n </Box>\n <Hint text=\"↑↓ to move · Enter to select · Ctrl+C to quit\" />\n </Box>\n );\n }\n\n // creds-entry phase\n const { field: activeField, values, envCursor } = phase;\n const isEnvField = activeField === FIELDS.length;\n\n return (\n <Box flexDirection=\"column\" paddingY={1} paddingX={2} gap={1}>\n <Logo />\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold color=\"cyan\">\n Kizen App Builder\n </Text>\n <Text dimColor>{'─'.repeat(24)}</Text>\n </Box>\n <Box flexDirection=\"column\" gap={0}>\n <Text bold>Global credentials</Text>\n <Text dimColor>Saved to: {GLOBAL_CREDENTIALS_PATH}</Text>\n </Box>\n {error && <Text color=\"red\">Error: {error}</Text>}\n <Box flexDirection=\"column\" gap={0}>\n {FIELDS.map((name, i) => {\n const isActive = activeField === i;\n const displayValue = isActive ? inputBuffer : (values[name] ?? '');\n return (\n <Box key={name} gap={2}>\n <Box width={12}>\n <Text bold={isActive} {...(isActive && { color: 'cyan' as const })}>\n {FIELD_LABELS[name]}\n </Text>\n </Box>\n <Text {...(isActive && { color: 'cyan' as const })}>{'>'}</Text>\n <Text>{displayValue}</Text>\n {isActive && <Text color=\"cyan\">{'█'}</Text>}\n </Box>\n );\n })}\n <Box gap={2}>\n <Box width={12}>\n <Text bold={isEnvField} {...(isEnvField && { color: 'cyan' as const })}>\n Environment\n </Text>\n </Box>\n <Text {...(isEnvField && { color: 'cyan' as const })}>{'>'}</Text>\n <Box gap={1}>\n {ENVIRONMENTS.map((env, i) => {\n const isSelected = i === envCursor;\n if (isEnvField) {\n return (\n <Text key={env} bold={isSelected} {...(isSelected && { color: 'cyan' as const })}>\n {isSelected ? `[${env}]` : env}\n </Text>\n );\n }\n return (\n <Text key={env} dimColor={!isSelected} bold={isSelected}>\n {env}\n </Text>\n );\n })}\n </Box>\n </Box>\n </Box>\n {isEnvField ? (\n <Hint text=\"←→ to select · ↑↓ to move · Enter to save · Esc to cancel\" />\n ) : (\n <Hint text=\"↑↓ to move · Backspace to delete · Esc to cancel\" />\n )}\n </Box>\n );\n};\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nexport const ENVIRONMENTS = ['go', 'fmo', 'staging', 'integration', 'test1'] as const;\nexport type Environment = (typeof ENVIRONMENTS)[number];\n\nexport interface Credentials {\n apiKey: string;\n userId: string;\n businessId: string;\n environment: Environment;\n}\n\nconst GLOBAL_CREDENTIALS_DIR = join(homedir(), '.kizenappbuilder');\nexport const GLOBAL_CREDENTIALS_PATH = join(GLOBAL_CREDENTIALS_DIR, 'credentials.json');\n\nfunction isValidEnvironment(value: unknown): value is Environment {\n return ENVIRONMENTS.includes(value as Environment);\n}\n\nfunction parseCredentials(raw: unknown): Credentials {\n if (typeof raw !== 'object' || raw === null) {\n throw new Error('Credentials must be a JSON object');\n }\n const obj = raw as Record<string, unknown>;\n const env = obj.environment;\n return {\n apiKey: typeof obj.apiKey === 'string' ? obj.apiKey : '',\n userId: typeof obj.userId === 'string' ? obj.userId : '',\n businessId: typeof obj.businessId === 'string' ? obj.businessId : '',\n environment: isValidEnvironment(env) ? env : 'go',\n };\n}\n\nexport async function loadCredentialsFromFile(filePath: string): Promise<Credentials> {\n const content = await readFile(filePath, 'utf-8');\n return parseCredentials(JSON.parse(content) as unknown);\n}\n\nexport async function loadGlobalCredentials(): Promise<Credentials | null> {\n try {\n return await loadCredentialsFromFile(GLOBAL_CREDENTIALS_PATH);\n } catch {\n return null;\n }\n}\n\nexport async function saveGlobalCredentials(credentials: Credentials): Promise<void> {\n await mkdir(dirname(GLOBAL_CREDENTIALS_PATH), { recursive: true });\n await writeFile(GLOBAL_CREDENTIALS_PATH, JSON.stringify(credentials, null, 2), 'utf-8');\n}\n"],"mappings":"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","names":["Box","Text","join","join","jsx","Text","Box","program","createElement","render","useCallback","useEffect","useState","Box","Text","useInput","readFile","dirname","join","mkdir","readFile","writeFile","join","useEffect","useState","Box","Text","mkdir","readFile","writeFile","join","jsx","jsxs","Text","useState","envCursor","values","isEnvField","useEffect","Box","jsx","jsxs","SPINNER_FRAMES","Spinner","useState","useEffect","Text","join","dirname","readFile","useInput","useCallback","Box","render","createElement","program"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
(function(){var e={QUERY_REQUEST:`query:request`,UI_OUTPUT:`outputui`,IFRAME_OUTPUT:`iframeoutput`,POSTFORMDATA_REQUEST:`postformdata:request`,SETSTATE:`setstate`,DONE:`done`,RUN:`run`,OPEN_WINDOW:`openwindow`,COMMUNICATE:`communicate`,HIDE:`hide`,SHOW:`show`,EXPAND:`expand`,COLLAPSE:`collapse`,HIDE_HEADER:`hideheader`,SHOW_HEADER:`showheader`,OPEN_CREATE_RECORD_MODAL_REQUEST:`opencreaterecordmodal:request`,OPEN_CREATE_RELATED_RECORD_MODAL_REQUEST:`opencreaterelatedrecordmodal:request`,SHOW_TOAST:`showtoast`,CLEAR_TOASTS:`cleartoasts`,REFRESH_TIMELINE:`refreshtimeline`,REFRESH_ENTITY:`refreshentity`,UPLOADFILE_REQUEST:`uploadfile:request`,UPDATE_SESSION_DATA:`updatesessiondata`,INSTALL_THIRD_PARTY_SCRIPT_REQUEST:`installthirdpartyscript:request`,PROMPT_REQUEST:`prompt:request`,DYNAMIC_PROMPT_REQUEST:`dynamicprompt:request`,RELEASE_BLOCKING_SCRIPT:`releaseblockingscript`,AUTHORIZE:`authorize`,COPY_TO_CLIPBOARD:`copytoclipboard`},t={QUERY_RESPONSE:`query:response`,POSTFORMDATA_RESPONSE:`postformdata:response`,ERROR:`error`,UPLOADFILE_RESPONSE:`uploadfile:response`,UPLOADFILE_PROGRESS:`uploadfile:progress`,INSTALL_THIRD_PARTY_SCRIPT_RESPONSE:`installthirdpartyscript:response`,PROMPT_RESPONSE:`prompt:response`,REFRESH_ENTITY_RESPONSE:`refreshentity:response`,CREATE_RECORD_RESPONSE:`createrecord:response`,CREATE_RELATED_RECORD_RESPONSE:`createrelatedrecord:response`},n={RUN_FRAME_SCRIPT:`runframescript`,SEND_MESSAGE_TO_FRAME:`sendmessagetoframe`,CALL_THIRD_PARTY_SCRIPT:`callthirdpartyscript`},r=/https:\/\/.*widget\.freshworks\.com\/.*\.js/,i=/https:\/\/widget\.intercom\.io\/widget\/[a-z0-9]+/,a={FRESHWORKS:`freshworks`,INTERCOM:`intercom`},o=e=>{if(r.test(e))return a.FRESHWORKS;if(i.test(e))return a.INTERCOM};a.FRESHWORKS,a.INTERCOM,a.FRESHWORKS,a.INTERCOM,a.FRESHWORKS,a.INTERCOM;var s=class{instance;scriptUrl;integration;constructor(e,t){this.instance=e,this.scriptUrl=t;let n=o(t);if(n)this.integration=n;else throw Error(`Error: Disallowed script url: ${t}`)}get type(){return this.integration}call(...t){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.CALL_THIRD_PARTY_SCRIPT,eventName:`thirdParty:${n.CALL_THIRD_PARTY_SCRIPT}`,recipient:{script:this.scriptUrl,type:this.type},params:t}))}},c=()=>{let e=new Date().getTime();return typeof performance<`u`&&typeof performance.now==`function`&&(e+=performance.now()),`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,t=>{let n=(e+Math.random()*16)%16|0;return e=Math.floor(e/16),(t===`x`?n:n&3|8).toString(16)})},l=Object.getPrototypeOf(async function(){}).constructor,u=e=>{let t=`
|
|
2
|
+
const __cleanup = this.__cleanup.bind(this);
|
|
3
|
+
const __error = this.onError.bind(this);
|
|
4
|
+
let __kizen_internal_result;
|
|
5
|
+
{
|
|
6
|
+
this.__setup();
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
__kizen_internal_result = await (async () => { ${e} })();
|
|
10
|
+
} catch (ex) {
|
|
11
|
+
__error(ex);
|
|
12
|
+
} finally {
|
|
13
|
+
__cleanup(__kizen_internal_result);
|
|
14
|
+
}
|
|
15
|
+
`;try{return{fn:new l(t),functionBody:t}}catch{let e=`
|
|
16
|
+
this.__setup();
|
|
17
|
+
this.onError({ message: "The script has a syntax error and could not be parsed" });
|
|
18
|
+
this.__cleanup();
|
|
19
|
+
`;return{fn:new l(e),functionBody:e}}},d=class{promises;isDebug;constructor({isDebug:e=!1}){this.promises=new Map,this.isDebug=e}delete(e){this.isDebug&&console.log(`Deleting promise ${e}`),this.promises.delete(e)}get(e){return this.isDebug&&console.log(`Getting promise ${e}`),this.promises.get(e)}set(e,t,n){this.promises.set(e,{resolve:t,reject:n})}id(){return c()}register(e,t){let n=this.id();return this.set(n,e,t),n}resolve(e,t){this.get(e)?.resolve(t),this.delete(e)}reject(e,t){this.get(e)?.reject(t),this.delete(e)}},f=e=>({key:`action__${e.api_name}`,type:`custom_object`,label:e.name,allow_multiple:!0}),p=(e,t)=>{let n=(e.fields??[]).filter(e=>e.type!==`container`&&e.type!==`description`).map(e=>({...e,when:t?`(${t}) && (${e.when??`true`})`:e.when})),r=(e.fields??[]).filter(e=>e.type===`container`).flatMap(e=>p(e,e.when)),i=e.actions?.filter(e=>e.hint_object_name)??[];return[...n,...r,...i.map(e=>({...f(e),match_hint:e.hint_object_name??``}))]},m=(e,t)=>{let n=p(e).reduce((e,t)=>({...e,[t.key]:t}),{}),r=Object.keys(t),i={};return r.forEach(e=>{let r=t[e],a=n[e];if(a?.type){switch(a.type){case`boolean`:let t=r;if(!t)return;i[e]=t.value;return;case`custom_object`:{let t=r;if(!t)return;i[e]={objectId:t.value?.id,objectName:t.value?.objectName};return}case`field`:{let t=r;if(!t?.value)return;Array.isArray(t.value)?i[e]=t.value.map(e=>({fieldId:e.value,fieldName:e.label,objectId:t.associatedObject?.id,objectName:t.associatedObject?.name})):typeof t.value==`object`&&typeof t.associatedObject==`object`&&(i[e]={fieldId:t.value.value,fieldName:t.value.label,objectId:t.associatedObject.id,objectName:t.associatedObject.name});return}case`number`:{let t=r;if(!t)return;try{let n=Number(t.value);if(!n&&n!==0)return;i[e]=n}catch{i[e]=NaN}return}case`select`:{let t=r;if(!t)return;i[e]=t.value;return}case`text`:{let t=r?.value;if(t){i[e]=t;return}let n=a.default;n&&(i[e]=n);return}case`description`:case`container`:return}return r?.value}}),i},h=(t,n)=>r=>async(i,a,o)=>new Promise((s,c)=>{let l=n.register(s,c);t.postMessage(JSON.stringify({action:e.QUERY_REQUEST,id:l,method:r,url:i,payload:a,options:o}))}),g=(t,n)=>(r,i,a=!0)=>new Promise((o,s)=>{let c=n.register(o,s);t.postMessage(JSON.stringify({action:e.POSTFORMDATA_REQUEST,url:r,id:c,payload:i,createNewTab:a}))}),_=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.PROMPT_REQUEST,id:o,config:r}))}),v=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.DYNAMIC_PROMPT_REQUEST,id:o,config:r}))}),y=(e,n,r)=>{switch(e){case t.QUERY_RESPONSE:{let{id:e,data:t,error:i}=JSON.parse(n.data);i?r.reject(e,i):r.resolve(e,t);break}case t.POSTFORMDATA_RESPONSE:{let{id:e,success:t}=JSON.parse(n.data);t?r.resolve(e):r.reject(e);break}case t.UPLOADFILE_RESPONSE:{let{id:e,data:t,error:i}=JSON.parse(n.data);t?r.resolve(e,t):r.reject(e,i);break}case t.INSTALL_THIRD_PARTY_SCRIPT_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);t.success?r.resolve(e,t):r.reject(e);break}case t.PROMPT_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.CREATE_RECORD_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.CREATE_RELATED_RECORD_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.REFRESH_ENTITY_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);t.success?r.resolve(e,!0):r.reject(e);break}}},b=`integration:${n.RUN_FRAME_SCRIPT}`,x=class{instance;constructor(e){this.instance=e}runFrameScript(t,r,i){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.RUN_FRAME_SCRIPT,eventName:b,recipient:{frame:t,script:r},args:i}))}sendMessageToOwnFrame(t,r){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.SEND_MESSAGE_TO_FRAME,args:{payload:t,path:r}}))}},S=async e=>{let t=null;try{t=await e.json()}catch{}return{status:e.status,statusText:e.statusText,body:t}},C=(e,t,n={},r=``)=>`(function() { ${r}
|
|
20
|
+
return ${`(${e.toString()})({ state: {{${t}}}, args: ${JSON.stringify(n)}, utils: __kizen_utils })`}; })()`,w=class{user;teamMember;business;clientObject;appPath;dataCache=new Map;queryOptions={};api;postFormData;executionTimer=0;setupExecutions=0;cleanupExecutions=0;isDebug=!1;scriptBody;internalState={indicator:`none`};console=console;instance;breakOnException=!1;args;communicate;shouldPreserve=!1;uploadFileHandler;internalSessionData;pluginComponentId;installThirdPartyScriptHandler;promptHandler;dynamicPromptHandler;refreshEntityHandler;openCreateRecordHandler;openCreateRelatedRecordHandler;runnerType;pluginApiName;tempPromptState={};partialLocation;constructor({user:e,teamMember:t,business:n,clientObject:r,appPath:i,isDebug:a,kizenRequest:o,postFormData:s,scriptBody:c,instance:l,args:u,uploadFile:d,sessionData:f,pluginComponentId:p,installThirdPartyScript:m,prompt:h,refreshEntity:g,openCreateRecord:_,openCreateRelatedRecord:v,pluginApiName:y,dynamicPrompt:b,location:S}){this.user=e,this.teamMember=t,this.business=n,this.clientObject=r,this.partialLocation=S,this.appPath=i,this.isDebug=a??!1,this.api={get:o(`get`),post:o(`post`),put:o(`put`),delete:o(`delete`),patch:o(`patch`)},this.postFormData=s,this.scriptBody=c,this.instance=l,this.communicate=new x(l),this.uploadFileHandler=d,this.internalSessionData=f??{},this.pluginComponentId=p,this.installThirdPartyScriptHandler=m,this.promptHandler=h,this.refreshEntityHandler=g,this.openCreateRecordHandler=_,this.openCreateRelatedRecordHandler=v,this.runnerType=`base`,this.pluginApiName=y,this.dynamicPromptHandler=b;try{this.args=JSON.parse(u??`{}`)}catch{this.args={}}}onError(e){if(this.breakOnException)debugger;this.instance.postMessage(JSON.stringify({action:t.ERROR,error:e?.message}))}set debug(e){this.isDebug=e,this.breakOnException=e}set preserve(e){this.shouldPreserve=e}get preserve(){return this.shouldPreserve}parseDate(e){return e.split(`-`)}parsePhone(e){return e.replace(/\+/g,``)}openWindow(t,n=`_blank`){this.instance.postMessage(JSON.stringify({action:e.OPEN_WINDOW,url:t,target:n,features:`noopener noreferrer`}))}authorize(t,n={}){if(!t)throw Error(`Service name is required to authorize`);this.instance.postMessage(JSON.stringify({action:e.AUTHORIZE,serviceName:t,config:{successRedirectPath:n.successRedirectPath??`/marketplace/${this.pluginApiName}/auth`,errorRedirectPath:n.errorRedirectPath??`/marketplace/${this.pluginApiName}/auth`}}))}getServiceUrl(e,t){if(!e)throw Error(`Service name is required to get a service url`);let n=`/external-integrations/proxy/${this.pluginApiName}/${e}`;return t.startsWith(`/`)?`${n}${t}`:`${n}/${t}`}get currentBusiness(){return this.business}get applicationPath(){return this.appPath}get currentUser(){return{profile:{id:this.teamMember?.id??``,full_name:this.teamMember?.full_name??``,first_name:this.teamMember?.first_name??``,last_name:this.teamMember?.last_name??``,email:this.teamMember?.email??``,phone:this.teamMember?.phone??``,created:this.teamMember?.created??``,crm_client_id:this.user?.crm_client_id??``}}}get sessionData(){return this.internalSessionData}get config(){return this.args.__kizen_clean_config?new Proxy(this.args.__kizen_clean_config??{},{get:(e,t)=>{if(Reflect.has(e,t))return Reflect.get(e,t)}}):{}}get location(){return new Proxy(this.partialLocation,{get:(e,t)=>{if(t===`toJSON`)return()=>this.partialLocation;if(Reflect.has(e,t))return Reflect.get(e,t);throw Error(`Property ${String(t)} is not available on location object for plugin apps`)}})}get userConfig(){let e=this.args.__kizen_user_config?.__kizen_clean_config;return e?new Proxy(e,{get:(e,t)=>{if(Reflect.has(e,t))return Reflect.get(e,t)}}):{}}setSessionData(t){if(typeof t!=`object`)throw Error(`Invalid session update with type ${typeof t}`);if(Array.isArray(t))throw Error(`Invalid session update with type array`);this.internalSessionData={...this.internalSessionData,...t},this.instance.postMessage(JSON.stringify({action:e.UPDATE_SESSION_DATA,update:t}))}async get(e,t){try{if(this.isRelativeUrl(e)){let n=this.dataCache.get(e);if(n&&!t?.ignoreCache)return t?.returnErrors?[n.data,null]:n.data;let{data:r}=await this.api.get(e,{...this.queryOptions,headers:this.buildHeaders(t?.headers)});return this.dataCache.set(e,{ts:Date.now(),data:r}),t?.returnErrors?[r,null]:r}else{let n=await fetch(e,{method:`GET`,headers:new Headers(t?.headers),credentials:t?.credentials??`same-origin`});if(!n.ok)throw await S(n);let r=await n.json();return t?.returnErrors?[r,null]:r}}catch(e){if(t?.returnErrors)return[null,e];this.onError(e)}}async getWithErrors(e,t){return this.get(e,{...t,returnErrors:!0})}async getUserConfig(){if(!this.args.pluginId||!this.pluginComponentId)throw Error(`User config is not available for scripts not associated to a plugin or plugin component`);return(await this.get(`/employee/mine/configs/plugins/${this.args.pluginId}`,{ignoreCache:!0})).config?.[this.pluginComponentId]??{}}async setUserConfig(e){if(!this.args.pluginId||!this.pluginComponentId)throw Error(`User config is not available for scripts not associated to a plugin or plugin component`);let t=await this.get(`/employee/mine/configs/plugins/${this.args.pluginId}`,{ignoreCache:!0});return await this.post(`/employee/mine/configs/plugins/${this.args.pluginId}`,{config:{...t?.config,[this.pluginComponentId]:{...t?.config?.[this.pluginComponentId],...e}}})}async patch(e,t,n){try{if(this.isRelativeUrl(e)){let{data:r}=await this.api.patch(e,t,{...this.queryOptions,headers:n?.headers});return n?.returnErrors?[r,null]:r}else{let r=await fetch(e,{method:`PATCH`,body:t?JSON.stringify(t):null,headers:new Headers(n?.headers),credentials:n?.credentials??`same-origin`});if(!r.ok)throw await S(r);let i=await r.json();return n?.returnErrors?[i,null]:i}}catch(e){if(n?.returnErrors)return[null,e];this.onError(e)}}async patchWithErrors(e,t,n){return this.patch(e,t,{...n,returnErrors:!0})}async post(e,t,n){try{if(this.isRelativeUrl(e)){let{data:r}=await this.api.post(e,t,{...this.queryOptions,headers:this.buildHeaders(n?.headers)});return n?.returnErrors?[r,null]:r}else{let r=await fetch(e,{method:`POST`,body:t?JSON.stringify(t):null,headers:new Headers(n?.headers),credentials:n?.credentials??`same-origin`});if(!r.ok)throw await S(r);let i=await r.json();return n?.returnErrors?[i,null]:i}}catch(e){if(n?.returnErrors)return[null,e];this.onError(e)}}async postWithErrors(e,t,n){return this.post(e,t,{...n,returnErrors:!0})}async delete(e,t){try{if(this.isRelativeUrl(e)){let{data:n}=await this.api.delete(e,{...this.queryOptions,headers:this.buildHeaders(t?.headers)});return t?.returnErrors?[n,null]:n}else{let n=await fetch(e,{method:`DELETE`,headers:new Headers(t?.headers),credentials:t?.credentials??`same-origin`});if(!n.ok)throw await S(n);let r=null;return n.status!==204&&(r=await n.json()),t?.returnErrors?[r,null]:r}}catch(e){if(t?.returnErrors)return[null,e];this.onError(e)}}async deleteWithErrors(e,t){return this.delete(e,{...t,returnErrors:!0})}async openCreateRecordModal(e){return this.openCreateRecordHandler(e)}async openCreateRelatedRecordModal(e,t){return this.openCreateRelatedRecordHandler(e,t)}showToast(t,n){this.instance.postMessage(JSON.stringify({action:e.SHOW_TOAST,message:t,toastOptions:n}))}clearToasts(){this.instance.postMessage(JSON.stringify({action:e.CLEAR_TOASTS}))}outputUI(t){this.instance.postMessage(JSON.stringify({action:e.UI_OUTPUT,markup:t}))}prompt(e){return this.promptHandler(e)}async dynamicPrompt(e){let t=`__kizen_state`,n=`const __kizen_utils = {};
|
|
21
|
+
`;if(e.registerUtils){let t=Object.keys(e.registerUtils);n+=t.map(t=>{let n=e.registerUtils?.[t];if(typeof n!=`function`)throw Error(`Registered util ${t} is not a function, got ${typeof n}`);return`__kizen_utils["${t}"] = (${n.toString()});`}).join(`
|
|
22
|
+
`)}let r=e.content?.map(e=>{let r=``;`optionMapper`in e&&(r=C(e.optionMapper,t,e.args,n));let i=``;`getFetchUrl`in e&&(i=C(e.getFetchUrl,t,e.args,n));let a=``;`getHeaders`in e&&(a=C(e.getHeaders,t,e.args,n));let o=``;return`getBody`in e&&(o=C(e.getBody,t,e.args,n)),{...e,optionMapper:r,getFetchUrl:i,getHeaders:a,getBody:o}}),i={...e,content:r},a={fields:i.content},o=await this.dynamicPromptHandler(i),s=m(a,o.values);return{...o,values:s}}outputIframe(t,n,r){this.instance.postMessage(JSON.stringify({action:e.IFRAME_OUTPUT,url:t,allow:n,sandbox:r,preserve:this.preserve}))}getBase64EncodedBlob(e){return new Promise((t,n)=>{let r=new FileReader;r.readAsDataURL(e),r.onload=()=>{t(r.result)},r.onerror=e=>{n(e)}})}async uploadFile(e,t,n=!1){let r=await this.getBase64EncodedBlob(e);return await this.uploadFileHandler({file:r,fileName:t??`file_`+String(Date.now()),isPublic:n})}afterSetup(){}__setup(){if(this.setupExecutions!==0)throw Error(`Setup must be called exactly once, and should never be called by a script directly.`);if(this.cleanupExecutions!==0)throw Error(`Setup was called after cleanup`);this.isDebug&&this.console.log(`Running script:
|
|
23
|
+
|
|
24
|
+
${this.scriptBody}`),this.setupExecutions++,this.executionTimer=performance.now(),this.afterSetup()}__cleanup(e){if(this.cleanupExecutions!==0)throw Error(`Cleanup must be called exactly once, and should never be called by a script directly.`);if(this.setupExecutions!==1)throw Error(`Cleanup was called before setup`);this.cleanupExecutions++,this.setIndicator(`none`);let t=performance.now();this.isDebug&&this.console.log(`Script execution took ${String(t-this.executionTimer)}ms`),this.done(this.preserve,e)}setIndicator(e=`none`){this.internalState.indicator=e,this.setState({indicator:e})}wait(e){return new Promise(t=>setTimeout(t,e))}done(t,n){this.instance.postMessage(JSON.stringify({action:e.DONE,result:n,preserve:t}))}setState(t){this.instance.postMessage(JSON.stringify({action:e.SETSTATE,state:t}))}isRelativeUrl(e){return e.startsWith(`/`)}buildHeaders(e={}){return{...e,"X-Request-Type":`kizen-ui-scripting-api`}}refreshTimelineForId(t){t&&this.instance.postMessage(JSON.stringify({action:e.REFRESH_TIMELINE,entityId:t}))}refreshEntityForId(e){if(e)return this.refreshEntityHandler(e)}async installThirdPartyScript(e){try{let t=await this.installThirdPartyScriptHandler(e,this.args);return new s(this.instance,t.url)}catch{this.onError(Error(`Third party script ${e} could not be installed.`))}}releaseBlockingScript(){this.instance.postMessage(JSON.stringify({action:e.RELEASE_BLOCKING_SCRIPT}))}copyToClipboard(t){this.instance.postMessage(JSON.stringify({action:e.COPY_TO_CLIPBOARD,text:t}))}createDateObject(e){if(typeof e!=`string`)throw Error(`Invalid date string ${String(e)}`);if(!/^\d{4}-\d{2}-\d{2}$/.test(e))throw Error(`Date string ${e} is not in the format YYYY-MM-DD`);let t=e.split(`-`).map(e=>parseInt(e,10));if(t.length<3)throw Error(`Date string ${e} could not be parsed into valid date parts`);return new Date(t[0],t[1]-1,t[2])}formatDateForResponse(e){return e.getTime()}},T=new d({isDebug:!1}),E=null,D=e=>()=>new Promise((t,n)=>{n(Error(`${e} is not supported in calendar source scripts`))});self.onmessage=async t=>{let{action:n,script:r,setup:i,args:a,sessionData:o={},pluginComponentId:s,pluginApiName:c,location:l}=JSON.parse(t.data);if(n===e.RUN&&i&&r){let{fn:e,functionBody:t}=u(r);E=new w({user:i.user,teamMember:i.teamMember,business:i.business,clientObject:i.clientObject,isDebug:i.isDebug,appPath:i.appPath,scriptBody:r,functionBody:t,instance:self,kizenRequest:h(self,T),postFormData:g(self,T),uploadFile:D(`uploadFile`),installThirdPartyScript:D(`installThirdPartyScript`),args:a??``,sessionData:o,pluginComponentId:s,prompt:_(self,T),dynamicPrompt:v(self,T),refreshEntity:D(`refreshEntity`),openCreateRecord:D(`openCreateRecord`),openCreateRelatedRecord:D(`openCreateRelatedRecord`),pluginApiName:c,location:l}),await e.bind(E)()}else y(n,t,T)}})();
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
(function(){var e=(e,t)=>e.replace(/{{(.*?)}}/g,(e,r)=>n(r,t)),t=(t,n,r)=>{let i=`return ${e(t,n)};`;return r&&console.log(`Initial expression:
|
|
2
|
+
${t}
|
|
3
|
+
|
|
4
|
+
Interpreted as:
|
|
5
|
+
${i}`),Function(i)()},n=(e,t)=>{let n=t[e];return n?n.value===void 0?`null`:JSON.stringify(n.value):`null`};self.onmessage=e=>{let{expression:n,args:r,isDebug:i=!1}=JSON.parse(e.data),a=t(n,r,i);self.postMessage(JSON.stringify({result:a}))}})();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
(function(){var e={QUERY_REQUEST:`query:request`,UI_OUTPUT:`outputui`,IFRAME_OUTPUT:`iframeoutput`,POSTFORMDATA_REQUEST:`postformdata:request`,SETSTATE:`setstate`,DONE:`done`,RUN:`run`,OPEN_WINDOW:`openwindow`,COMMUNICATE:`communicate`,HIDE:`hide`,SHOW:`show`,EXPAND:`expand`,COLLAPSE:`collapse`,HIDE_HEADER:`hideheader`,SHOW_HEADER:`showheader`,OPEN_CREATE_RECORD_MODAL_REQUEST:`opencreaterecordmodal:request`,OPEN_CREATE_RELATED_RECORD_MODAL_REQUEST:`opencreaterelatedrecordmodal:request`,SHOW_TOAST:`showtoast`,CLEAR_TOASTS:`cleartoasts`,REFRESH_TIMELINE:`refreshtimeline`,REFRESH_ENTITY:`refreshentity`,UPLOADFILE_REQUEST:`uploadfile:request`,UPDATE_SESSION_DATA:`updatesessiondata`,INSTALL_THIRD_PARTY_SCRIPT_REQUEST:`installthirdpartyscript:request`,PROMPT_REQUEST:`prompt:request`,DYNAMIC_PROMPT_REQUEST:`dynamicprompt:request`,RELEASE_BLOCKING_SCRIPT:`releaseblockingscript`,AUTHORIZE:`authorize`,COPY_TO_CLIPBOARD:`copytoclipboard`},t={QUERY_RESPONSE:`query:response`,POSTFORMDATA_RESPONSE:`postformdata:response`,ERROR:`error`,UPLOADFILE_RESPONSE:`uploadfile:response`,UPLOADFILE_PROGRESS:`uploadfile:progress`,INSTALL_THIRD_PARTY_SCRIPT_RESPONSE:`installthirdpartyscript:response`,PROMPT_RESPONSE:`prompt:response`,REFRESH_ENTITY_RESPONSE:`refreshentity:response`,CREATE_RECORD_RESPONSE:`createrecord:response`,CREATE_RELATED_RECORD_RESPONSE:`createrelatedrecord:response`},n={RUN_FRAME_SCRIPT:`runframescript`,SEND_MESSAGE_TO_FRAME:`sendmessagetoframe`,CALL_THIRD_PARTY_SCRIPT:`callthirdpartyscript`},r=/https:\/\/.*widget\.freshworks\.com\/.*\.js/,i=/https:\/\/widget\.intercom\.io\/widget\/[a-z0-9]+/,a={FRESHWORKS:`freshworks`,INTERCOM:`intercom`},o=e=>{if(r.test(e))return a.FRESHWORKS;if(i.test(e))return a.INTERCOM};a.FRESHWORKS,a.INTERCOM,a.FRESHWORKS,a.INTERCOM,a.FRESHWORKS,a.INTERCOM;var s=class{instance;scriptUrl;integration;constructor(e,t){this.instance=e,this.scriptUrl=t;let n=o(t);if(n)this.integration=n;else throw Error(`Error: Disallowed script url: ${t}`)}get type(){return this.integration}call(...t){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.CALL_THIRD_PARTY_SCRIPT,eventName:`thirdParty:${n.CALL_THIRD_PARTY_SCRIPT}`,recipient:{script:this.scriptUrl,type:this.type},params:t}))}},c=e=>({key:`action__${e.api_name}`,type:`custom_object`,label:e.name,allow_multiple:!0}),l=(e,t)=>{let n=(e.fields??[]).filter(e=>e.type!==`container`&&e.type!==`description`).map(e=>({...e,when:t?`(${t}) && (${e.when??`true`})`:e.when})),r=(e.fields??[]).filter(e=>e.type===`container`).flatMap(e=>l(e,e.when)),i=e.actions?.filter(e=>e.hint_object_name)??[];return[...n,...r,...i.map(e=>({...c(e),match_hint:e.hint_object_name??``}))]},u=(e,t)=>{let n=l(e).reduce((e,t)=>({...e,[t.key]:t}),{}),r=Object.keys(t),i={};return r.forEach(e=>{let r=t[e],a=n[e];if(a?.type){switch(a.type){case`boolean`:let t=r;if(!t)return;i[e]=t.value;return;case`custom_object`:{let t=r;if(!t)return;i[e]={objectId:t.value?.id,objectName:t.value?.objectName};return}case`field`:{let t=r;if(!t?.value)return;Array.isArray(t.value)?i[e]=t.value.map(e=>({fieldId:e.value,fieldName:e.label,objectId:t.associatedObject?.id,objectName:t.associatedObject?.name})):typeof t.value==`object`&&typeof t.associatedObject==`object`&&(i[e]={fieldId:t.value.value,fieldName:t.value.label,objectId:t.associatedObject.id,objectName:t.associatedObject.name});return}case`number`:{let t=r;if(!t)return;try{let n=Number(t.value);if(!n&&n!==0)return;i[e]=n}catch{i[e]=NaN}return}case`select`:{let t=r;if(!t)return;i[e]=t.value;return}case`text`:{let t=r?.value;if(t){i[e]=t;return}let n=a.default;n&&(i[e]=n);return}case`description`:case`container`:return}return r?.value}}),i},d=(t,n)=>r=>async(i,a,o)=>new Promise((s,c)=>{let l=n.register(s,c);t.postMessage(JSON.stringify({action:e.QUERY_REQUEST,id:l,method:r,url:i,payload:a,options:o}))}),f=(t,n)=>(r,i,a=!0)=>new Promise((o,s)=>{let c=n.register(o,s);t.postMessage(JSON.stringify({action:e.POSTFORMDATA_REQUEST,url:r,id:c,payload:i,createNewTab:a}))}),p=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.PROMPT_REQUEST,id:o,config:r}))}),m=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.DYNAMIC_PROMPT_REQUEST,id:o,config:r}))}),h=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.UPLOADFILE_REQUEST,id:o,payload:r}))}),g=(t,n)=>(r,i)=>new Promise((a,o)=>{let s=n.register(a,o);t.postMessage(JSON.stringify({action:e.INSTALL_THIRD_PARTY_SCRIPT_REQUEST,url:r,id:s,args:i}))}),_=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.REFRESH_ENTITY,id:o,entityId:r}))}),v=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.OPEN_CREATE_RECORD_MODAL_REQUEST,id:o,entityId:r}))}),y=(t,n)=>(r,i)=>new Promise((a,o)=>{let s=n.register(a,o);t.postMessage(JSON.stringify({action:e.OPEN_CREATE_RELATED_RECORD_MODAL_REQUEST,id:s,objectId:r,relatedEntityId:i}))}),b=(e,n,r)=>{switch(e){case t.QUERY_RESPONSE:{let{id:e,data:t,error:i}=JSON.parse(n.data);i?r.reject(e,i):r.resolve(e,t);break}case t.POSTFORMDATA_RESPONSE:{let{id:e,success:t}=JSON.parse(n.data);t?r.resolve(e):r.reject(e);break}case t.UPLOADFILE_RESPONSE:{let{id:e,data:t,error:i}=JSON.parse(n.data);t?r.resolve(e,t):r.reject(e,i);break}case t.INSTALL_THIRD_PARTY_SCRIPT_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);t.success?r.resolve(e,t):r.reject(e);break}case t.PROMPT_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.CREATE_RECORD_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.CREATE_RELATED_RECORD_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.REFRESH_ENTITY_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);t.success?r.resolve(e,!0):r.reject(e);break}}},x=`integration:${n.RUN_FRAME_SCRIPT}`,S=class{instance;constructor(e){this.instance=e}runFrameScript(t,r,i){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.RUN_FRAME_SCRIPT,eventName:x,recipient:{frame:t,script:r},args:i}))}sendMessageToOwnFrame(t,r){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.SEND_MESSAGE_TO_FRAME,args:{payload:t,path:r}}))}},C=async e=>{let t=null;try{t=await e.json()}catch{}return{status:e.status,statusText:e.statusText,body:t}},w=(e,t,n={},r=``)=>`(function() { ${r}
|
|
2
|
+
return ${`(${e.toString()})({ state: {{${t}}}, args: ${JSON.stringify(n)}, utils: __kizen_utils })`}; })()`,T=class{user;teamMember;business;clientObject;appPath;dataCache=new Map;queryOptions={};api;postFormData;executionTimer=0;setupExecutions=0;cleanupExecutions=0;isDebug=!1;scriptBody;internalState={indicator:`none`};console=console;instance;breakOnException=!1;args;communicate;shouldPreserve=!1;uploadFileHandler;internalSessionData;pluginComponentId;installThirdPartyScriptHandler;promptHandler;dynamicPromptHandler;refreshEntityHandler;openCreateRecordHandler;openCreateRelatedRecordHandler;runnerType;pluginApiName;tempPromptState={};partialLocation;constructor({user:e,teamMember:t,business:n,clientObject:r,appPath:i,isDebug:a,kizenRequest:o,postFormData:s,scriptBody:c,instance:l,args:u,uploadFile:d,sessionData:f,pluginComponentId:p,installThirdPartyScript:m,prompt:h,refreshEntity:g,openCreateRecord:_,openCreateRelatedRecord:v,pluginApiName:y,dynamicPrompt:b,location:x}){this.user=e,this.teamMember=t,this.business=n,this.clientObject=r,this.partialLocation=x,this.appPath=i,this.isDebug=a??!1,this.api={get:o(`get`),post:o(`post`),put:o(`put`),delete:o(`delete`),patch:o(`patch`)},this.postFormData=s,this.scriptBody=c,this.instance=l,this.communicate=new S(l),this.uploadFileHandler=d,this.internalSessionData=f??{},this.pluginComponentId=p,this.installThirdPartyScriptHandler=m,this.promptHandler=h,this.refreshEntityHandler=g,this.openCreateRecordHandler=_,this.openCreateRelatedRecordHandler=v,this.runnerType=`base`,this.pluginApiName=y,this.dynamicPromptHandler=b;try{this.args=JSON.parse(u??`{}`)}catch{this.args={}}}onError(e){if(this.breakOnException)debugger;this.instance.postMessage(JSON.stringify({action:t.ERROR,error:e?.message}))}set debug(e){this.isDebug=e,this.breakOnException=e}set preserve(e){this.shouldPreserve=e}get preserve(){return this.shouldPreserve}parseDate(e){return e.split(`-`)}parsePhone(e){return e.replace(/\+/g,``)}openWindow(t,n=`_blank`){this.instance.postMessage(JSON.stringify({action:e.OPEN_WINDOW,url:t,target:n,features:`noopener noreferrer`}))}authorize(t,n={}){if(!t)throw Error(`Service name is required to authorize`);this.instance.postMessage(JSON.stringify({action:e.AUTHORIZE,serviceName:t,config:{successRedirectPath:n.successRedirectPath??`/marketplace/${this.pluginApiName}/auth`,errorRedirectPath:n.errorRedirectPath??`/marketplace/${this.pluginApiName}/auth`}}))}getServiceUrl(e,t){if(!e)throw Error(`Service name is required to get a service url`);let n=`/external-integrations/proxy/${this.pluginApiName}/${e}`;return t.startsWith(`/`)?`${n}${t}`:`${n}/${t}`}get currentBusiness(){return this.business}get applicationPath(){return this.appPath}get currentUser(){return{profile:{id:this.teamMember?.id??``,full_name:this.teamMember?.full_name??``,first_name:this.teamMember?.first_name??``,last_name:this.teamMember?.last_name??``,email:this.teamMember?.email??``,phone:this.teamMember?.phone??``,created:this.teamMember?.created??``,crm_client_id:this.user?.crm_client_id??``}}}get sessionData(){return this.internalSessionData}get config(){return this.args.__kizen_clean_config?new Proxy(this.args.__kizen_clean_config??{},{get:(e,t)=>{if(Reflect.has(e,t))return Reflect.get(e,t)}}):{}}get location(){return new Proxy(this.partialLocation,{get:(e,t)=>{if(t===`toJSON`)return()=>this.partialLocation;if(Reflect.has(e,t))return Reflect.get(e,t);throw Error(`Property ${String(t)} is not available on location object for plugin apps`)}})}get userConfig(){let e=this.args.__kizen_user_config?.__kizen_clean_config;return e?new Proxy(e,{get:(e,t)=>{if(Reflect.has(e,t))return Reflect.get(e,t)}}):{}}setSessionData(t){if(typeof t!=`object`)throw Error(`Invalid session update with type ${typeof t}`);if(Array.isArray(t))throw Error(`Invalid session update with type array`);this.internalSessionData={...this.internalSessionData,...t},this.instance.postMessage(JSON.stringify({action:e.UPDATE_SESSION_DATA,update:t}))}async get(e,t){try{if(this.isRelativeUrl(e)){let n=this.dataCache.get(e);if(n&&!t?.ignoreCache)return t?.returnErrors?[n.data,null]:n.data;let{data:r}=await this.api.get(e,{...this.queryOptions,headers:this.buildHeaders(t?.headers)});return this.dataCache.set(e,{ts:Date.now(),data:r}),t?.returnErrors?[r,null]:r}else{let n=await fetch(e,{method:`GET`,headers:new Headers(t?.headers),credentials:t?.credentials??`same-origin`});if(!n.ok)throw await C(n);let r=await n.json();return t?.returnErrors?[r,null]:r}}catch(e){if(t?.returnErrors)return[null,e];this.onError(e)}}async getWithErrors(e,t){return this.get(e,{...t,returnErrors:!0})}async getUserConfig(){if(!this.args.pluginId||!this.pluginComponentId)throw Error(`User config is not available for scripts not associated to a plugin or plugin component`);return(await this.get(`/employee/mine/configs/plugins/${this.args.pluginId}`,{ignoreCache:!0})).config?.[this.pluginComponentId]??{}}async setUserConfig(e){if(!this.args.pluginId||!this.pluginComponentId)throw Error(`User config is not available for scripts not associated to a plugin or plugin component`);let t=await this.get(`/employee/mine/configs/plugins/${this.args.pluginId}`,{ignoreCache:!0});return await this.post(`/employee/mine/configs/plugins/${this.args.pluginId}`,{config:{...t?.config,[this.pluginComponentId]:{...t?.config?.[this.pluginComponentId],...e}}})}async patch(e,t,n){try{if(this.isRelativeUrl(e)){let{data:r}=await this.api.patch(e,t,{...this.queryOptions,headers:n?.headers});return n?.returnErrors?[r,null]:r}else{let r=await fetch(e,{method:`PATCH`,body:t?JSON.stringify(t):null,headers:new Headers(n?.headers),credentials:n?.credentials??`same-origin`});if(!r.ok)throw await C(r);let i=await r.json();return n?.returnErrors?[i,null]:i}}catch(e){if(n?.returnErrors)return[null,e];this.onError(e)}}async patchWithErrors(e,t,n){return this.patch(e,t,{...n,returnErrors:!0})}async post(e,t,n){try{if(this.isRelativeUrl(e)){let{data:r}=await this.api.post(e,t,{...this.queryOptions,headers:this.buildHeaders(n?.headers)});return n?.returnErrors?[r,null]:r}else{let r=await fetch(e,{method:`POST`,body:t?JSON.stringify(t):null,headers:new Headers(n?.headers),credentials:n?.credentials??`same-origin`});if(!r.ok)throw await C(r);let i=await r.json();return n?.returnErrors?[i,null]:i}}catch(e){if(n?.returnErrors)return[null,e];this.onError(e)}}async postWithErrors(e,t,n){return this.post(e,t,{...n,returnErrors:!0})}async delete(e,t){try{if(this.isRelativeUrl(e)){let{data:n}=await this.api.delete(e,{...this.queryOptions,headers:this.buildHeaders(t?.headers)});return t?.returnErrors?[n,null]:n}else{let n=await fetch(e,{method:`DELETE`,headers:new Headers(t?.headers),credentials:t?.credentials??`same-origin`});if(!n.ok)throw await C(n);let r=null;return n.status!==204&&(r=await n.json()),t?.returnErrors?[r,null]:r}}catch(e){if(t?.returnErrors)return[null,e];this.onError(e)}}async deleteWithErrors(e,t){return this.delete(e,{...t,returnErrors:!0})}async openCreateRecordModal(e){return this.openCreateRecordHandler(e)}async openCreateRelatedRecordModal(e,t){return this.openCreateRelatedRecordHandler(e,t)}showToast(t,n){this.instance.postMessage(JSON.stringify({action:e.SHOW_TOAST,message:t,toastOptions:n}))}clearToasts(){this.instance.postMessage(JSON.stringify({action:e.CLEAR_TOASTS}))}outputUI(t){this.instance.postMessage(JSON.stringify({action:e.UI_OUTPUT,markup:t}))}prompt(e){return this.promptHandler(e)}async dynamicPrompt(e){let t=`__kizen_state`,n=`const __kizen_utils = {};
|
|
3
|
+
`;if(e.registerUtils){let t=Object.keys(e.registerUtils);n+=t.map(t=>{let n=e.registerUtils?.[t];if(typeof n!=`function`)throw Error(`Registered util ${t} is not a function, got ${typeof n}`);return`__kizen_utils["${t}"] = (${n.toString()});`}).join(`
|
|
4
|
+
`)}let r=e.content?.map(e=>{let r=``;`optionMapper`in e&&(r=w(e.optionMapper,t,e.args,n));let i=``;`getFetchUrl`in e&&(i=w(e.getFetchUrl,t,e.args,n));let a=``;`getHeaders`in e&&(a=w(e.getHeaders,t,e.args,n));let o=``;return`getBody`in e&&(o=w(e.getBody,t,e.args,n)),{...e,optionMapper:r,getFetchUrl:i,getHeaders:a,getBody:o}}),i={...e,content:r},a={fields:i.content},o=await this.dynamicPromptHandler(i),s=u(a,o.values);return{...o,values:s}}outputIframe(t,n,r){this.instance.postMessage(JSON.stringify({action:e.IFRAME_OUTPUT,url:t,allow:n,sandbox:r,preserve:this.preserve}))}getBase64EncodedBlob(e){return new Promise((t,n)=>{let r=new FileReader;r.readAsDataURL(e),r.onload=()=>{t(r.result)},r.onerror=e=>{n(e)}})}async uploadFile(e,t,n=!1){let r=await this.getBase64EncodedBlob(e);return await this.uploadFileHandler({file:r,fileName:t??`file_`+String(Date.now()),isPublic:n})}afterSetup(){}__setup(){if(this.setupExecutions!==0)throw Error(`Setup must be called exactly once, and should never be called by a script directly.`);if(this.cleanupExecutions!==0)throw Error(`Setup was called after cleanup`);this.isDebug&&this.console.log(`Running script:
|
|
5
|
+
|
|
6
|
+
${this.scriptBody}`),this.setupExecutions++,this.executionTimer=performance.now(),this.afterSetup()}__cleanup(e){if(this.cleanupExecutions!==0)throw Error(`Cleanup must be called exactly once, and should never be called by a script directly.`);if(this.setupExecutions!==1)throw Error(`Cleanup was called before setup`);this.cleanupExecutions++,this.setIndicator(`none`);let t=performance.now();this.isDebug&&this.console.log(`Script execution took ${String(t-this.executionTimer)}ms`),this.done(this.preserve,e)}setIndicator(e=`none`){this.internalState.indicator=e,this.setState({indicator:e})}wait(e){return new Promise(t=>setTimeout(t,e))}done(t,n){this.instance.postMessage(JSON.stringify({action:e.DONE,result:n,preserve:t}))}setState(t){this.instance.postMessage(JSON.stringify({action:e.SETSTATE,state:t}))}isRelativeUrl(e){return e.startsWith(`/`)}buildHeaders(e={}){return{...e,"X-Request-Type":`kizen-ui-scripting-api`}}refreshTimelineForId(t){t&&this.instance.postMessage(JSON.stringify({action:e.REFRESH_TIMELINE,entityId:t}))}refreshEntityForId(e){if(e)return this.refreshEntityHandler(e)}async installThirdPartyScript(e){try{let t=await this.installThirdPartyScriptHandler(e,this.args);return new s(this.instance,t.url)}catch{this.onError(Error(`Third party script ${e} could not be installed.`))}}releaseBlockingScript(){this.instance.postMessage(JSON.stringify({action:e.RELEASE_BLOCKING_SCRIPT}))}copyToClipboard(t){this.instance.postMessage(JSON.stringify({action:e.COPY_TO_CLIPBOARD,text:t}))}createDateObject(e){if(typeof e!=`string`)throw Error(`Invalid date string ${String(e)}`);if(!/^\d{4}-\d{2}-\d{2}$/.test(e))throw Error(`Date string ${e} is not in the format YYYY-MM-DD`);let t=e.split(`-`).map(e=>parseInt(e,10));if(t.length<3)throw Error(`Date string ${e} could not be parsed into valid date parts`);return new Date(t[0],t[1]-1,t[2])}formatDateForResponse(e){return e.getTime()}},E=class extends T{constructor(e){super(e),this.runnerType=`floatingFrame`}hide(t={}){this.instance.postMessage(JSON.stringify({action:e.HIDE,config:t}))}hideHeader(){this.instance.postMessage(JSON.stringify({action:e.HIDE_HEADER}))}showHeader(){this.instance.postMessage(JSON.stringify({action:e.SHOW_HEADER}))}show(t={}){this.instance.postMessage(JSON.stringify({action:e.SHOW,config:t}))}expand(){this.instance.postMessage(JSON.stringify({action:e.EXPAND}))}collapse(){this.instance.postMessage(JSON.stringify({action:e.COLLAPSE}))}afterSetup(){this.show()}},D=()=>{let e=new Date().getTime();return typeof performance<`u`&&typeof performance.now==`function`&&(e+=performance.now()),`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,t=>{let n=(e+Math.random()*16)%16|0;return e=Math.floor(e/16),(t===`x`?n:n&3|8).toString(16)})},O=Object.getPrototypeOf(async function(){}).constructor,k=e=>{let t=`
|
|
7
|
+
const __cleanup = this.__cleanup.bind(this);
|
|
8
|
+
const __error = this.onError.bind(this);
|
|
9
|
+
{
|
|
10
|
+
this.__setup();
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
${e}
|
|
14
|
+
} catch (ex) {
|
|
15
|
+
__error(ex);
|
|
16
|
+
} finally {
|
|
17
|
+
__cleanup();
|
|
18
|
+
}
|
|
19
|
+
`;try{return{fn:new O(t),functionBody:t}}catch{let e=`
|
|
20
|
+
this.__setup();
|
|
21
|
+
this.onError({ message: "The script has a syntax error and could not be parsed" });
|
|
22
|
+
this.__cleanup();
|
|
23
|
+
`;return{fn:new O(e),functionBody:e}}},A=new class{promises;isDebug;constructor({isDebug:e=!1}){this.promises=new Map,this.isDebug=e}delete(e){this.isDebug&&console.log(`Deleting promise ${e}`),this.promises.delete(e)}get(e){return this.isDebug&&console.log(`Getting promise ${e}`),this.promises.get(e)}set(e,t,n){this.promises.set(e,{resolve:t,reject:n})}id(){return D()}register(e,t){let n=this.id();return this.set(n,e,t),n}resolve(e,t){this.get(e)?.resolve(t),this.delete(e)}reject(e,t){this.get(e)?.reject(t),this.delete(e)}}({isDebug:!1});self.onmessage=async t=>{let{action:n,script:r,setup:i,args:a,sessionData:o={},pluginComponentId:s,pluginApiName:c,location:l}=JSON.parse(t.data);if(n===e.RUN&&i&&r){let{fn:e,functionBody:t}=k(r),n=new E({user:i.user,teamMember:i.teamMember,business:i.business,clientObject:i.clientObject,appPath:i.appPath,isDebug:i.isDebug,scriptBody:r,functionBody:t,instance:self,kizenRequest:d(self,A),postFormData:f(self,A),uploadFile:h(self,A),installThirdPartyScript:g(self,A),args:a??``,sessionData:o,pluginComponentId:s,prompt:p(self,A),dynamicPrompt:m(self,A),refreshEntity:_(self,A),openCreateRecord:v(self,A),openCreateRelatedRecord:y(self,A),pluginApiName:c,location:l});await e.bind(n)()}else b(n,t,A)}})();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
(function(){var e={QUERY_REQUEST:`query:request`,UI_OUTPUT:`outputui`,IFRAME_OUTPUT:`iframeoutput`,POSTFORMDATA_REQUEST:`postformdata:request`,SETSTATE:`setstate`,DONE:`done`,RUN:`run`,OPEN_WINDOW:`openwindow`,COMMUNICATE:`communicate`,HIDE:`hide`,SHOW:`show`,EXPAND:`expand`,COLLAPSE:`collapse`,HIDE_HEADER:`hideheader`,SHOW_HEADER:`showheader`,OPEN_CREATE_RECORD_MODAL_REQUEST:`opencreaterecordmodal:request`,OPEN_CREATE_RELATED_RECORD_MODAL_REQUEST:`opencreaterelatedrecordmodal:request`,SHOW_TOAST:`showtoast`,CLEAR_TOASTS:`cleartoasts`,REFRESH_TIMELINE:`refreshtimeline`,REFRESH_ENTITY:`refreshentity`,UPLOADFILE_REQUEST:`uploadfile:request`,UPDATE_SESSION_DATA:`updatesessiondata`,INSTALL_THIRD_PARTY_SCRIPT_REQUEST:`installthirdpartyscript:request`,PROMPT_REQUEST:`prompt:request`,DYNAMIC_PROMPT_REQUEST:`dynamicprompt:request`,RELEASE_BLOCKING_SCRIPT:`releaseblockingscript`,AUTHORIZE:`authorize`,COPY_TO_CLIPBOARD:`copytoclipboard`},t={QUERY_RESPONSE:`query:response`,POSTFORMDATA_RESPONSE:`postformdata:response`,ERROR:`error`,UPLOADFILE_RESPONSE:`uploadfile:response`,UPLOADFILE_PROGRESS:`uploadfile:progress`,INSTALL_THIRD_PARTY_SCRIPT_RESPONSE:`installthirdpartyscript:response`,PROMPT_RESPONSE:`prompt:response`,REFRESH_ENTITY_RESPONSE:`refreshentity:response`,CREATE_RECORD_RESPONSE:`createrecord:response`,CREATE_RELATED_RECORD_RESPONSE:`createrelatedrecord:response`},n={RUN_FRAME_SCRIPT:`runframescript`,SEND_MESSAGE_TO_FRAME:`sendmessagetoframe`,CALL_THIRD_PARTY_SCRIPT:`callthirdpartyscript`},r=/https:\/\/.*widget\.freshworks\.com\/.*\.js/,i=/https:\/\/widget\.intercom\.io\/widget\/[a-z0-9]+/,a={FRESHWORKS:`freshworks`,INTERCOM:`intercom`},o=e=>{if(r.test(e))return a.FRESHWORKS;if(i.test(e))return a.INTERCOM};a.FRESHWORKS,a.INTERCOM,a.FRESHWORKS,a.INTERCOM,a.FRESHWORKS,a.INTERCOM;var s=class{instance;scriptUrl;integration;constructor(e,t){this.instance=e,this.scriptUrl=t;let n=o(t);if(n)this.integration=n;else throw Error(`Error: Disallowed script url: ${t}`)}get type(){return this.integration}call(...t){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.CALL_THIRD_PARTY_SCRIPT,eventName:`thirdParty:${n.CALL_THIRD_PARTY_SCRIPT}`,recipient:{script:this.scriptUrl,type:this.type},params:t}))}},c=()=>{let e=new Date().getTime();return typeof performance<`u`&&typeof performance.now==`function`&&(e+=performance.now()),`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,t=>{let n=(e+Math.random()*16)%16|0;return e=Math.floor(e/16),(t===`x`?n:n&3|8).toString(16)})},l=Object.getPrototypeOf(async function(){}).constructor,u=e=>{let t=`
|
|
2
|
+
const __cleanup = this.__cleanup.bind(this);
|
|
3
|
+
const __error = this.onError.bind(this);
|
|
4
|
+
{
|
|
5
|
+
this.__setup();
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
${e}
|
|
9
|
+
} catch (ex) {
|
|
10
|
+
__error(ex);
|
|
11
|
+
} finally {
|
|
12
|
+
__cleanup();
|
|
13
|
+
}
|
|
14
|
+
`;try{return{fn:new l(t),functionBody:t}}catch{let e=`
|
|
15
|
+
this.__setup();
|
|
16
|
+
this.onError({ message: "The script has a syntax error and could not be parsed" });
|
|
17
|
+
this.__cleanup();
|
|
18
|
+
`;return{fn:new l(e),functionBody:e}}},d=class{promises;isDebug;constructor({isDebug:e=!1}){this.promises=new Map,this.isDebug=e}delete(e){this.isDebug&&console.log(`Deleting promise ${e}`),this.promises.delete(e)}get(e){return this.isDebug&&console.log(`Getting promise ${e}`),this.promises.get(e)}set(e,t,n){this.promises.set(e,{resolve:t,reject:n})}id(){return c()}register(e,t){let n=this.id();return this.set(n,e,t),n}resolve(e,t){this.get(e)?.resolve(t),this.delete(e)}reject(e,t){this.get(e)?.reject(t),this.delete(e)}},f=e=>({key:`action__${e.api_name}`,type:`custom_object`,label:e.name,allow_multiple:!0}),p=(e,t)=>{let n=(e.fields??[]).filter(e=>e.type!==`container`&&e.type!==`description`).map(e=>({...e,when:t?`(${t}) && (${e.when??`true`})`:e.when})),r=(e.fields??[]).filter(e=>e.type===`container`).flatMap(e=>p(e,e.when)),i=e.actions?.filter(e=>e.hint_object_name)??[];return[...n,...r,...i.map(e=>({...f(e),match_hint:e.hint_object_name??``}))]},m=(e,t)=>{let n=p(e).reduce((e,t)=>({...e,[t.key]:t}),{}),r=Object.keys(t),i={};return r.forEach(e=>{let r=t[e],a=n[e];if(a?.type){switch(a.type){case`boolean`:let t=r;if(!t)return;i[e]=t.value;return;case`custom_object`:{let t=r;if(!t)return;i[e]={objectId:t.value?.id,objectName:t.value?.objectName};return}case`field`:{let t=r;if(!t?.value)return;Array.isArray(t.value)?i[e]=t.value.map(e=>({fieldId:e.value,fieldName:e.label,objectId:t.associatedObject?.id,objectName:t.associatedObject?.name})):typeof t.value==`object`&&typeof t.associatedObject==`object`&&(i[e]={fieldId:t.value.value,fieldName:t.value.label,objectId:t.associatedObject.id,objectName:t.associatedObject.name});return}case`number`:{let t=r;if(!t)return;try{let n=Number(t.value);if(!n&&n!==0)return;i[e]=n}catch{i[e]=NaN}return}case`select`:{let t=r;if(!t)return;i[e]=t.value;return}case`text`:{let t=r?.value;if(t){i[e]=t;return}let n=a.default;n&&(i[e]=n);return}case`description`:case`container`:return}return r?.value}}),i},h=(t,n)=>r=>async(i,a,o)=>new Promise((s,c)=>{let l=n.register(s,c);t.postMessage(JSON.stringify({action:e.QUERY_REQUEST,id:l,method:r,url:i,payload:a,options:o}))}),g=(t,n)=>(r,i,a=!0)=>new Promise((o,s)=>{let c=n.register(o,s);t.postMessage(JSON.stringify({action:e.POSTFORMDATA_REQUEST,url:r,id:c,payload:i,createNewTab:a}))}),_=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.PROMPT_REQUEST,id:o,config:r}))}),v=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.DYNAMIC_PROMPT_REQUEST,id:o,config:r}))}),y=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.UPLOADFILE_REQUEST,id:o,payload:r}))}),b=(t,n)=>(r,i)=>new Promise((a,o)=>{let s=n.register(a,o);t.postMessage(JSON.stringify({action:e.INSTALL_THIRD_PARTY_SCRIPT_REQUEST,url:r,id:s,args:i}))}),x=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.REFRESH_ENTITY,id:o,entityId:r}))}),S=(t,n)=>r=>new Promise((i,a)=>{let o=n.register(i,a);t.postMessage(JSON.stringify({action:e.OPEN_CREATE_RECORD_MODAL_REQUEST,id:o,entityId:r}))}),C=(t,n)=>(r,i)=>new Promise((a,o)=>{let s=n.register(a,o);t.postMessage(JSON.stringify({action:e.OPEN_CREATE_RELATED_RECORD_MODAL_REQUEST,id:s,objectId:r,relatedEntityId:i}))}),w=(e,n,r)=>{switch(e){case t.QUERY_RESPONSE:{let{id:e,data:t,error:i}=JSON.parse(n.data);i?r.reject(e,i):r.resolve(e,t);break}case t.POSTFORMDATA_RESPONSE:{let{id:e,success:t}=JSON.parse(n.data);t?r.resolve(e):r.reject(e);break}case t.UPLOADFILE_RESPONSE:{let{id:e,data:t,error:i}=JSON.parse(n.data);t?r.resolve(e,t):r.reject(e,i);break}case t.INSTALL_THIRD_PARTY_SCRIPT_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);t.success?r.resolve(e,t):r.reject(e);break}case t.PROMPT_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.CREATE_RECORD_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.CREATE_RELATED_RECORD_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);r.resolve(e,t);break}case t.REFRESH_ENTITY_RESPONSE:{let{id:e,data:t}=JSON.parse(n.data);t.success?r.resolve(e,!0):r.reject(e);break}}},T=`integration:${n.RUN_FRAME_SCRIPT}`,E=class{instance;constructor(e){this.instance=e}runFrameScript(t,r,i){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.RUN_FRAME_SCRIPT,eventName:T,recipient:{frame:t,script:r},args:i}))}sendMessageToOwnFrame(t,r){this.instance.postMessage(JSON.stringify({action:e.COMMUNICATE,type:n.SEND_MESSAGE_TO_FRAME,args:{payload:t,path:r}}))}},D=async e=>{let t=null;try{t=await e.json()}catch{}return{status:e.status,statusText:e.statusText,body:t}},O=(e,t,n={},r=``)=>`(function() { ${r}
|
|
19
|
+
return ${`(${e.toString()})({ state: {{${t}}}, args: ${JSON.stringify(n)}, utils: __kizen_utils })`}; })()`,k=class{user;teamMember;business;clientObject;appPath;dataCache=new Map;queryOptions={};api;postFormData;executionTimer=0;setupExecutions=0;cleanupExecutions=0;isDebug=!1;scriptBody;internalState={indicator:`none`};console=console;instance;breakOnException=!1;args;communicate;shouldPreserve=!1;uploadFileHandler;internalSessionData;pluginComponentId;installThirdPartyScriptHandler;promptHandler;dynamicPromptHandler;refreshEntityHandler;openCreateRecordHandler;openCreateRelatedRecordHandler;runnerType;pluginApiName;tempPromptState={};partialLocation;constructor({user:e,teamMember:t,business:n,clientObject:r,appPath:i,isDebug:a,kizenRequest:o,postFormData:s,scriptBody:c,instance:l,args:u,uploadFile:d,sessionData:f,pluginComponentId:p,installThirdPartyScript:m,prompt:h,refreshEntity:g,openCreateRecord:_,openCreateRelatedRecord:v,pluginApiName:y,dynamicPrompt:b,location:x}){this.user=e,this.teamMember=t,this.business=n,this.clientObject=r,this.partialLocation=x,this.appPath=i,this.isDebug=a??!1,this.api={get:o(`get`),post:o(`post`),put:o(`put`),delete:o(`delete`),patch:o(`patch`)},this.postFormData=s,this.scriptBody=c,this.instance=l,this.communicate=new E(l),this.uploadFileHandler=d,this.internalSessionData=f??{},this.pluginComponentId=p,this.installThirdPartyScriptHandler=m,this.promptHandler=h,this.refreshEntityHandler=g,this.openCreateRecordHandler=_,this.openCreateRelatedRecordHandler=v,this.runnerType=`base`,this.pluginApiName=y,this.dynamicPromptHandler=b;try{this.args=JSON.parse(u??`{}`)}catch{this.args={}}}onError(e){if(this.breakOnException)debugger;this.instance.postMessage(JSON.stringify({action:t.ERROR,error:e?.message}))}set debug(e){this.isDebug=e,this.breakOnException=e}set preserve(e){this.shouldPreserve=e}get preserve(){return this.shouldPreserve}parseDate(e){return e.split(`-`)}parsePhone(e){return e.replace(/\+/g,``)}openWindow(t,n=`_blank`){this.instance.postMessage(JSON.stringify({action:e.OPEN_WINDOW,url:t,target:n,features:`noopener noreferrer`}))}authorize(t,n={}){if(!t)throw Error(`Service name is required to authorize`);this.instance.postMessage(JSON.stringify({action:e.AUTHORIZE,serviceName:t,config:{successRedirectPath:n.successRedirectPath??`/marketplace/${this.pluginApiName}/auth`,errorRedirectPath:n.errorRedirectPath??`/marketplace/${this.pluginApiName}/auth`}}))}getServiceUrl(e,t){if(!e)throw Error(`Service name is required to get a service url`);let n=`/external-integrations/proxy/${this.pluginApiName}/${e}`;return t.startsWith(`/`)?`${n}${t}`:`${n}/${t}`}get currentBusiness(){return this.business}get applicationPath(){return this.appPath}get currentUser(){return{profile:{id:this.teamMember?.id??``,full_name:this.teamMember?.full_name??``,first_name:this.teamMember?.first_name??``,last_name:this.teamMember?.last_name??``,email:this.teamMember?.email??``,phone:this.teamMember?.phone??``,created:this.teamMember?.created??``,crm_client_id:this.user?.crm_client_id??``}}}get sessionData(){return this.internalSessionData}get config(){return this.args.__kizen_clean_config?new Proxy(this.args.__kizen_clean_config??{},{get:(e,t)=>{if(Reflect.has(e,t))return Reflect.get(e,t)}}):{}}get location(){return new Proxy(this.partialLocation,{get:(e,t)=>{if(t===`toJSON`)return()=>this.partialLocation;if(Reflect.has(e,t))return Reflect.get(e,t);throw Error(`Property ${String(t)} is not available on location object for plugin apps`)}})}get userConfig(){let e=this.args.__kizen_user_config?.__kizen_clean_config;return e?new Proxy(e,{get:(e,t)=>{if(Reflect.has(e,t))return Reflect.get(e,t)}}):{}}setSessionData(t){if(typeof t!=`object`)throw Error(`Invalid session update with type ${typeof t}`);if(Array.isArray(t))throw Error(`Invalid session update with type array`);this.internalSessionData={...this.internalSessionData,...t},this.instance.postMessage(JSON.stringify({action:e.UPDATE_SESSION_DATA,update:t}))}async get(e,t){try{if(this.isRelativeUrl(e)){let n=this.dataCache.get(e);if(n&&!t?.ignoreCache)return t?.returnErrors?[n.data,null]:n.data;let{data:r}=await this.api.get(e,{...this.queryOptions,headers:this.buildHeaders(t?.headers)});return this.dataCache.set(e,{ts:Date.now(),data:r}),t?.returnErrors?[r,null]:r}else{let n=await fetch(e,{method:`GET`,headers:new Headers(t?.headers),credentials:t?.credentials??`same-origin`});if(!n.ok)throw await D(n);let r=await n.json();return t?.returnErrors?[r,null]:r}}catch(e){if(t?.returnErrors)return[null,e];this.onError(e)}}async getWithErrors(e,t){return this.get(e,{...t,returnErrors:!0})}async getUserConfig(){if(!this.args.pluginId||!this.pluginComponentId)throw Error(`User config is not available for scripts not associated to a plugin or plugin component`);return(await this.get(`/employee/mine/configs/plugins/${this.args.pluginId}`,{ignoreCache:!0})).config?.[this.pluginComponentId]??{}}async setUserConfig(e){if(!this.args.pluginId||!this.pluginComponentId)throw Error(`User config is not available for scripts not associated to a plugin or plugin component`);let t=await this.get(`/employee/mine/configs/plugins/${this.args.pluginId}`,{ignoreCache:!0});return await this.post(`/employee/mine/configs/plugins/${this.args.pluginId}`,{config:{...t?.config,[this.pluginComponentId]:{...t?.config?.[this.pluginComponentId],...e}}})}async patch(e,t,n){try{if(this.isRelativeUrl(e)){let{data:r}=await this.api.patch(e,t,{...this.queryOptions,headers:n?.headers});return n?.returnErrors?[r,null]:r}else{let r=await fetch(e,{method:`PATCH`,body:t?JSON.stringify(t):null,headers:new Headers(n?.headers),credentials:n?.credentials??`same-origin`});if(!r.ok)throw await D(r);let i=await r.json();return n?.returnErrors?[i,null]:i}}catch(e){if(n?.returnErrors)return[null,e];this.onError(e)}}async patchWithErrors(e,t,n){return this.patch(e,t,{...n,returnErrors:!0})}async post(e,t,n){try{if(this.isRelativeUrl(e)){let{data:r}=await this.api.post(e,t,{...this.queryOptions,headers:this.buildHeaders(n?.headers)});return n?.returnErrors?[r,null]:r}else{let r=await fetch(e,{method:`POST`,body:t?JSON.stringify(t):null,headers:new Headers(n?.headers),credentials:n?.credentials??`same-origin`});if(!r.ok)throw await D(r);let i=await r.json();return n?.returnErrors?[i,null]:i}}catch(e){if(n?.returnErrors)return[null,e];this.onError(e)}}async postWithErrors(e,t,n){return this.post(e,t,{...n,returnErrors:!0})}async delete(e,t){try{if(this.isRelativeUrl(e)){let{data:n}=await this.api.delete(e,{...this.queryOptions,headers:this.buildHeaders(t?.headers)});return t?.returnErrors?[n,null]:n}else{let n=await fetch(e,{method:`DELETE`,headers:new Headers(t?.headers),credentials:t?.credentials??`same-origin`});if(!n.ok)throw await D(n);let r=null;return n.status!==204&&(r=await n.json()),t?.returnErrors?[r,null]:r}}catch(e){if(t?.returnErrors)return[null,e];this.onError(e)}}async deleteWithErrors(e,t){return this.delete(e,{...t,returnErrors:!0})}async openCreateRecordModal(e){return this.openCreateRecordHandler(e)}async openCreateRelatedRecordModal(e,t){return this.openCreateRelatedRecordHandler(e,t)}showToast(t,n){this.instance.postMessage(JSON.stringify({action:e.SHOW_TOAST,message:t,toastOptions:n}))}clearToasts(){this.instance.postMessage(JSON.stringify({action:e.CLEAR_TOASTS}))}outputUI(t){this.instance.postMessage(JSON.stringify({action:e.UI_OUTPUT,markup:t}))}prompt(e){return this.promptHandler(e)}async dynamicPrompt(e){let t=`__kizen_state`,n=`const __kizen_utils = {};
|
|
20
|
+
`;if(e.registerUtils){let t=Object.keys(e.registerUtils);n+=t.map(t=>{let n=e.registerUtils?.[t];if(typeof n!=`function`)throw Error(`Registered util ${t} is not a function, got ${typeof n}`);return`__kizen_utils["${t}"] = (${n.toString()});`}).join(`
|
|
21
|
+
`)}let r=e.content?.map(e=>{let r=``;`optionMapper`in e&&(r=O(e.optionMapper,t,e.args,n));let i=``;`getFetchUrl`in e&&(i=O(e.getFetchUrl,t,e.args,n));let a=``;`getHeaders`in e&&(a=O(e.getHeaders,t,e.args,n));let o=``;return`getBody`in e&&(o=O(e.getBody,t,e.args,n)),{...e,optionMapper:r,getFetchUrl:i,getHeaders:a,getBody:o}}),i={...e,content:r},a={fields:i.content},o=await this.dynamicPromptHandler(i),s=m(a,o.values);return{...o,values:s}}outputIframe(t,n,r){this.instance.postMessage(JSON.stringify({action:e.IFRAME_OUTPUT,url:t,allow:n,sandbox:r,preserve:this.preserve}))}getBase64EncodedBlob(e){return new Promise((t,n)=>{let r=new FileReader;r.readAsDataURL(e),r.onload=()=>{t(r.result)},r.onerror=e=>{n(e)}})}async uploadFile(e,t,n=!1){let r=await this.getBase64EncodedBlob(e);return await this.uploadFileHandler({file:r,fileName:t??`file_`+String(Date.now()),isPublic:n})}afterSetup(){}__setup(){if(this.setupExecutions!==0)throw Error(`Setup must be called exactly once, and should never be called by a script directly.`);if(this.cleanupExecutions!==0)throw Error(`Setup was called after cleanup`);this.isDebug&&this.console.log(`Running script:
|
|
22
|
+
|
|
23
|
+
${this.scriptBody}`),this.setupExecutions++,this.executionTimer=performance.now(),this.afterSetup()}__cleanup(e){if(this.cleanupExecutions!==0)throw Error(`Cleanup must be called exactly once, and should never be called by a script directly.`);if(this.setupExecutions!==1)throw Error(`Cleanup was called before setup`);this.cleanupExecutions++,this.setIndicator(`none`);let t=performance.now();this.isDebug&&this.console.log(`Script execution took ${String(t-this.executionTimer)}ms`),this.done(this.preserve,e)}setIndicator(e=`none`){this.internalState.indicator=e,this.setState({indicator:e})}wait(e){return new Promise(t=>setTimeout(t,e))}done(t,n){this.instance.postMessage(JSON.stringify({action:e.DONE,result:n,preserve:t}))}setState(t){this.instance.postMessage(JSON.stringify({action:e.SETSTATE,state:t}))}isRelativeUrl(e){return e.startsWith(`/`)}buildHeaders(e={}){return{...e,"X-Request-Type":`kizen-ui-scripting-api`}}refreshTimelineForId(t){t&&this.instance.postMessage(JSON.stringify({action:e.REFRESH_TIMELINE,entityId:t}))}refreshEntityForId(e){if(e)return this.refreshEntityHandler(e)}async installThirdPartyScript(e){try{let t=await this.installThirdPartyScriptHandler(e,this.args);return new s(this.instance,t.url)}catch{this.onError(Error(`Third party script ${e} could not be installed.`))}}releaseBlockingScript(){this.instance.postMessage(JSON.stringify({action:e.RELEASE_BLOCKING_SCRIPT}))}copyToClipboard(t){this.instance.postMessage(JSON.stringify({action:e.COPY_TO_CLIPBOARD,text:t}))}createDateObject(e){if(typeof e!=`string`)throw Error(`Invalid date string ${String(e)}`);if(!/^\d{4}-\d{2}-\d{2}$/.test(e))throw Error(`Date string ${e} is not in the format YYYY-MM-DD`);let t=e.split(`-`).map(e=>parseInt(e,10));if(t.length<3)throw Error(`Date string ${e} could not be parsed into valid date parts`);return new Date(t[0],t[1]-1,t[2])}formatDateForResponse(e){return e.getTime()}},A=new d({isDebug:!1}),j=null;self.onmessage=async t=>{let{action:n,script:r,setup:i,args:a,sessionData:o={},pluginComponentId:s,pluginApiName:c,location:l}=JSON.parse(t.data);if(n===e.RUN&&i&&r){let{fn:e,functionBody:t}=u(r);j=new k({user:i.user,teamMember:i.teamMember,business:i.business,clientObject:i.clientObject,isDebug:i.isDebug,appPath:i.appPath,scriptBody:r,functionBody:t,instance:self,kizenRequest:h(self,A),postFormData:g(self,A),uploadFile:y(self,A),installThirdPartyScript:b(self,A),args:a??``,sessionData:o,pluginComponentId:s,prompt:_(self,A),dynamicPrompt:v(self,A),refreshEntity:x(self,A),openCreateRecord:S(self,A),openCreateRelatedRecord:C(self,A),pluginApiName:c,location:l}),await e.bind(j)()}else w(n,t,A)}})();
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, Menlo, Consolas, "Liberation Mono", monospace;--color-red-100:oklch(93.6% .032 17.717);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-700:oklch(50.5% .213 27.518);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-700:oklch(55.5% .163 48.998);--color-yellow-100:oklch(97.3% .071 103.193);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-700:oklch(55.4% .135 66.442);--color-green-100:oklch(96.2% .044 156.743);--color-green-400:oklch(79.2% .209 151.711);--color-green-700:oklch(52.7% .154 150.069);--color-blue-400:oklch(70.7% .165 254.624);--color-neutral-50:oklch(98.5% 0 0);--color-neutral-100:oklch(97% 0 0);--color-neutral-200:oklch(92.2% 0 0);--color-neutral-300:oklch(87% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-widest:.1em;--radius-lg:.5rem;--radius-xl:.75rem;--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.top-0{top:calc(var(--spacing) * 0)}.top-4{top:calc(var(--spacing) * 4)}.top-full{top:100%}.bottom-0{bottom:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-\[99999\]{z-index:99999}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing) * 0)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.block{display:block}.flex{display:flex}.hidden{display:none}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-6{height:calc(var(--spacing) * 6)}.h-10{height:calc(var(--spacing) * 10)}.h-24{height:calc(var(--spacing) * 24)}.h-48{height:calc(var(--spacing) * 48)}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-\[60vh\]{max-height:60vh}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[200px\]{min-height:200px}.min-h-screen{min-height:100vh}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-6{width:calc(var(--spacing) * 6)}.w-10{width:calc(var(--spacing) * 10)}.w-28{width:calc(var(--spacing) * 28)}.w-64{width:calc(var(--spacing) * 64)}.w-\[26rem\]{width:26rem}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-black\/8{border-color:#00000014}@supports (color:color-mix(in lab, red, red)){.border-black\/8{border-color:color-mix(in oklab, var(--color-black) 8%, transparent)}}.border-black\/10{border-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.border-black\/10{border-color:color-mix(in oklab, var(--color-black) 10%, transparent)}}.border-black\/20{border-color:#0003}@supports (color:color-mix(in lab, red, red)){.border-black\/20{border-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.border-neutral-300{border-color:var(--color-neutral-300)}.border-neutral-700{border-color:var(--color-neutral-700)}.border-neutral-800{border-color:var(--color-neutral-800)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-black\/30{background-color:#0000004d}@supports (color:color-mix(in lab, red, red)){.bg-black\/30{background-color:color-mix(in oklab, var(--color-black) 30%, transparent)}}.bg-green-100{background-color:var(--color-green-100)}.bg-green-400\/60{background-color:#05df7299}@supports (color:color-mix(in lab, red, red)){.bg-green-400\/60{background-color:color-mix(in oklab, var(--color-green-400) 60%, transparent)}}.bg-neutral-50{background-color:var(--color-neutral-50)}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-neutral-800{background-color:var(--color-neutral-800)}.bg-neutral-800\/40{background-color:#26262666}@supports (color:color-mix(in lab, red, red)){.bg-neutral-800\/40{background-color:color-mix(in oklab, var(--color-neutral-800) 40%, transparent)}}.bg-neutral-900{background-color:var(--color-neutral-900)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-400\/60{background-color:#ff656899}@supports (color:color-mix(in lab, red, red)){.bg-red-400\/60{background-color:color-mix(in oklab, var(--color-red-400) 60%, transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/70{background-color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){.bg-white\/70{background-color:color-mix(in oklab, var(--color-white) 70%, transparent)}}.bg-white\/80{background-color:#fffc}@supports (color:color-mix(in lab, red, red)){.bg-white\/80{background-color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.bg-white\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-white\/85{background-color:color-mix(in oklab, var(--color-white) 85%, transparent)}}.bg-yellow-100{background-color:var(--color-yellow-100)}.bg-yellow-400\/60{background-color:#fac80099}@supports (color:color-mix(in lab, red, red)){.bg-yellow-400\/60{background-color:color-mix(in oklab, var(--color-yellow-400) 60%, transparent)}}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-12{padding-block:calc(var(--spacing) * 12)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.whitespace-pre{white-space:pre}.text-amber-700{color:var(--color-amber-700)}.text-blue-400{color:var(--color-blue-400)}.text-green-700{color:var(--color-green-700)}.text-neutral-100{color:var(--color-neutral-100)}.text-neutral-200{color:var(--color-neutral-200)}.text-neutral-300{color:var(--color-neutral-300)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-600{color:var(--color-neutral-600)}.text-neutral-700{color:var(--color-neutral-700)}.text-neutral-800{color:var(--color-neutral-800)}.text-neutral-900{color:var(--color-neutral-900)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-700{color:var(--color-yellow-700)}.uppercase{text-transform:uppercase}.accent-neutral-800{accent-color:var(--color-neutral-800)}.opacity-30{opacity:.3}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.hover\:bg-black\/5:hover{background-color:#0000000d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-black\/5:hover{background-color:color-mix(in oklab, var(--color-black) 5%, transparent)}}.hover\:bg-neutral-100:hover{background-color:var(--color-neutral-100)}.hover\:bg-neutral-700:hover{background-color:var(--color-neutral-700)}.hover\:bg-neutral-800\/50:hover{background-color:#26262680}@supports (color:color-mix(in lab, red, red)){.hover\:bg-neutral-800\/50:hover{background-color:color-mix(in oklab, var(--color-neutral-800) 50%, transparent)}}.hover\:text-neutral-200:hover{color:var(--color-neutral-200)}.hover\:text-neutral-600:hover{color:var(--color-neutral-600)}.hover\:text-neutral-700:hover{color:var(--color-neutral-700)}.hover\:text-neutral-900:hover{color:var(--color-neutral-900)}}.focus\:border-neutral-400:focus{border-color:var(--color-neutral-400)}.focus\:border-neutral-500:focus{border-color:var(--color-neutral-500)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-neutral-400:focus{--tw-ring-color:var(--color-neutral-400)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:opacity-50:disabled{opacity:.5}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
|