@kosdev-code/kos-ui-cli 2.1.38 → 3.0.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/package.json +5 -6
- package/src/lib/cli.mjs +34 -10
- package/src/lib/generators/component/index.mjs +1230 -27
- package/src/lib/generators/component/index.mjs.map +7 -0
- package/src/lib/generators/model/add-future.mjs +1449 -43
- package/src/lib/generators/model/add-future.mjs.map +7 -0
- package/src/lib/generators/model/companion.mjs +1465 -56
- package/src/lib/generators/model/companion.mjs.map +7 -0
- package/src/lib/generators/model/container.mjs +1234 -45
- package/src/lib/generators/model/container.mjs.map +7 -0
- package/src/lib/generators/model/context.mjs +1102 -35
- package/src/lib/generators/model/context.mjs.map +7 -0
- package/src/lib/generators/model/hook.mjs +1097 -33
- package/src/lib/generators/model/hook.mjs.map +7 -0
- package/src/lib/generators/model/model.mjs +1411 -39
- package/src/lib/generators/model/model.mjs.map +7 -0
- package/src/lib/generators/plugin/index.mjs +1275 -74
- package/src/lib/generators/plugin/index.mjs.map +7 -0
- package/src/lib/generators/project/splash.mjs +691 -21
- package/src/lib/generators/project/splash.mjs.map +7 -0
- package/src/lib/utils/dev-config.mjs +7 -12
- package/src/lib/utils/nx-context.mjs +584 -170
- package/src/lib/utils/nx-context.mjs.map +7 -0
- package/README.md +0 -484
- package/src/index.d.ts +0 -2
- package/src/index.d.ts.map +0 -1
- package/src/index.js +0 -1
- package/src/index.js.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../packages/kos-ui-cli/src/lib/utils/nx-context.mjs", "../../../../../../packages/kos-ui-cli/src/lib/utils/cache.mjs", "../../../../../../packages/kos-codegen-core/src/lib/generate-files.ts", "../../../../../../packages/kos-codegen-core/src/lib/logger.ts", "../../../../../../packages/kos-codegen-core/src/lib/project-discovery.ts", "../../../../../../packages/kos-codegen-core/src/lib/format-files.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/update-model-index.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/types.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/base.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/control-pour-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/cui-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/custom-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/default-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/nav-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/setting-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/setup-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/trouble-action-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/utility-handler.ts", "../../../../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/factory.ts"],
|
|
4
|
+
"sourcesContent": ["// utils/nx-context.mjs\nimport { existsSync, readFileSync, readdirSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getCached, setCached } from \"./cache.mjs\";\nimport { discoverProjects, findProjectByName } from \"@kosdev-code/kos-codegen-core\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nfunction findKosJsonFiles(dir = process.cwd(), files = []) {\n try {\n const entries = readdirSync(dir);\n \n for (const entry of entries) {\n // Skip common directories that won't have .kos.json files\n // BUT don't skip .kos.json files themselves!\n if (entry === 'node_modules' || entry === '.git' || entry === '.nx' || \n entry === 'dist' || entry === 'coverage' || entry === '.vscode' ||\n entry === '.idea' || (entry.startsWith('.') && entry !== '.kos.json')) {\n continue;\n }\n \n const fullPath = path.join(dir, entry);\n \n try {\n const stat = statSync(fullPath);\n \n if (stat.isFile() && entry === '.kos.json') {\n files.push(fullPath);\n } else if (stat.isDirectory()) {\n // Only recurse into directories that might contain projects\n // Skip common build/temp directories\n if (entry !== 'tmp' && entry !== 'temp' && entry !== 'build') {\n findKosJsonFiles(fullPath, files);\n }\n }\n } catch (error) {\n // Skip files/directories we can't access\n continue;\n }\n }\n } catch (error) {\n // Skip directories we can't read\n }\n \n return files;\n}\n\nlet _workspaceDetected;\n\nexport async function detectWorkspace(startDir = process.cwd()) {\n if (_workspaceDetected !== undefined) return _workspaceDetected;\n\n let dir = startDir;\n while (dir !== path.dirname(dir)) {\n if (existsSync(path.join(dir, \"nx.json\"))) {\n _workspaceDetected = true;\n return true;\n }\n dir = path.dirname(dir);\n }\n\n _workspaceDetected = false;\n return false;\n}\nexport async function getAllProjects() {\n const cached = getCached(\"allProjects\");\n if (cached) return cached;\n\n const projectMap = discoverProjects(process.cwd());\n const projects = Array.from(projectMap.keys());\n setCached(\"allProjects\", projects);\n return projects;\n}\n\nexport async function getLibraryProjects() {\n const cached = getCached(\"libraryProjects\");\n if (cached) return cached;\n\n const projectMap = discoverProjects(process.cwd());\n const projects = Array.from(projectMap.values())\n .filter((p) => p.projectType === \"library\")\n .map((p) => p.name);\n setCached(\"libraryProjects\", projects);\n return projects;\n}\n\nexport async function getPluginProjects() {\n const cached = getCached(\"pluginProjects\");\n if (cached) return cached;\n\n const all = await getAllProjects();\n const filtered = all.filter(\n (p) => p.includes(\"plugin\") || p.includes(\"extension\")\n );\n setCached(\"pluginProjects\", filtered);\n return filtered;\n}\n\nexport async function getAllKosProjects() {\n const cached = getCached(\"allKosProjects\");\n if (cached) return cached;\n\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] Discovering KOS projects by scanning .kos.json files...`);\n }\n \n // In an NX workspace, focus on common project directories first\n const projectDirs = ['apps', 'libs', 'packages'];\n const kosJsonFiles = [];\n const workspaceRoot = process.cwd();\n \n // First scan common project directories\n for (const dir of projectDirs) {\n const dirPath = path.join(workspaceRoot, dir);\n if (existsSync(dirPath)) {\n findKosJsonFiles(dirPath, kosJsonFiles);\n }\n }\n \n // Also check the workspace root for any .kos.json files\n const rootKosJson = path.join(workspaceRoot, '.kos.json');\n if (existsSync(rootKosJson)) {\n kosJsonFiles.push(rootKosJson);\n }\n \n // If we didn't find any in the common directories, fall back to full scan\n if (kosJsonFiles.length === 0) {\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] No .kos.json files found in common directories, performing full workspace scan...`);\n }\n findKosJsonFiles(workspaceRoot, kosJsonFiles);\n }\n \n const kosProjects = [];\n\n for (const kosJsonPath of kosJsonFiles) {\n try {\n const kosConfig = JSON.parse(readFileSync(kosJsonPath, \"utf-8\"));\n const projectDir = path.dirname(kosJsonPath);\n \n // Try to determine the project name by looking for project.json\n let projectName = null;\n const projectJsonPath = path.join(projectDir, 'project.json');\n \n if (existsSync(projectJsonPath)) {\n try {\n const projectJson = JSON.parse(readFileSync(projectJsonPath, \"utf-8\"));\n projectName = projectJson.name;\n } catch (error) {\n // If we can't read project.json, use directory name as fallback\n projectName = path.basename(projectDir);\n }\n } else {\n // Use directory name as fallback\n projectName = path.basename(projectDir);\n }\n\n // Skip root-type configurations as they are not projects\n if (kosConfig.type === 'root') {\n continue;\n }\n\n kosProjects.push({\n name: projectName,\n path: projectDir,\n kosJsonPath,\n config: kosConfig,\n projectType: kosConfig.generator?.projectType\n });\n } catch (error) {\n console.warn(`[kos-cli] Error reading ${kosJsonPath}: ${error.message}`);\n }\n }\n\n setCached(\"allKosProjects\", kosProjects);\n return kosProjects;\n}\n\nexport async function getProjectsByType(targetType) {\n const cacheKey = `projectsByType:${targetType}`;\n const cached = getCached(cacheKey);\n if (cached) return cached;\n\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] Filtering projects for ${targetType} projectType...`);\n }\n const allKosProjects = await getAllKosProjects();\n const filteredProjects = [];\n\n for (const kosProject of allKosProjects) {\n const projectType = kosProject.projectType;\n \n // Handle both string and array formats for projectType\n const hasTargetType = Array.isArray(projectType) \n ? projectType.includes(targetType)\n : projectType === targetType;\n \n if (hasTargetType) {\n filteredProjects.push(kosProject.name);\n }\n }\n\n setCached(cacheKey, filteredProjects);\n return filteredProjects;\n}\n\nexport async function getModelProjects() {\n return await getProjectsByType(\"model\");\n}\n\nexport async function getUIProjects() {\n return await getProjectsByType(\"ui\");\n}\n\nexport async function getModelComponentProjects() {\n return await getProjectsByType(\"model-component\");\n}\n\nexport async function getI18nProjects() {\n return await getProjectsByType(\"i18n\");\n}\n\n\nexport async function getProjectsByTypeWithFallback(targetType, fallbackFunction = getLibraryProjects) {\n const filteredProjects = await getProjectsByType(targetType);\n \n if (filteredProjects.length > 0) {\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] Found ${filteredProjects.length} ${targetType} projects`);\n }\n return filteredProjects;\n } else {\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] No ${targetType} projects found, showing fallback projects`);\n }\n return await fallbackFunction();\n }\n}\n\nexport async function getModelProjectsWithFallback() {\n return await getProjectsByTypeWithFallback(\"model\", getLibraryProjects);\n}\n\nexport async function getModelComponentProjectsWithFallback() {\n return await getProjectsByTypeWithFallback(\"model-component\", getAllProjects);\n}\n\nexport async function getProjectsByMultipleTypes(targetTypes) {\n const cacheKey = `projectsByMultipleTypes:${targetTypes.join(',')}`;\n const cached = getCached(cacheKey);\n if (cached) return cached;\n\n console.warn(`[kos-cli] Filtering projects for projectTypes: ${targetTypes.join(', ')}...`);\n const allKosProjects = await getAllKosProjects();\n const filteredProjects = [];\n\n for (const kosProject of allKosProjects) {\n const projectType = kosProject.projectType;\n \n // Handle both string and array formats for projectType\n const hasAnyTargetType = targetTypes.some(targetType => {\n return Array.isArray(projectType) \n ? projectType.includes(targetType)\n : projectType === targetType;\n });\n \n if (hasAnyTargetType) {\n filteredProjects.push(kosProject.name);\n }\n }\n\n setCached(cacheKey, filteredProjects);\n return filteredProjects;\n}\n\nexport async function getComponentCompatibleProjects() {\n return await getProjectsByMultipleTypes([\"ui\", \"splash\", \"model-component\"]);\n}\n\nexport async function getComponentCompatibleProjectsWithFallback() {\n const componentProjects = await getComponentCompatibleProjects();\n \n if (componentProjects.length > 0) {\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] Found ${componentProjects.length} component-compatible projects`);\n }\n return componentProjects;\n } else {\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] No component-compatible projects found, showing all projects`);\n }\n return await getAllProjects();\n }\n}\n\nexport async function getI18nProjectsWithFallback() {\n return await getProjectsByTypeWithFallback(\"i18n\", getAllProjects);\n}\n\nexport async function getPluginProjectsWithFallback() {\n // First try type-based filtering\n const pluginProjectsByType = await getProjectsByType(\"plugin\");\n if (pluginProjectsByType.length > 0) {\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] Found ${pluginProjectsByType.length} plugin projects by type`);\n }\n return pluginProjectsByType;\n }\n \n // Fall back to existing name-based filtering\n const pluginProjectsByName = await getPluginProjects();\n if (pluginProjectsByName.length > 0) {\n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] Found ${pluginProjectsByName.length} plugin projects by name`);\n }\n return pluginProjectsByName;\n }\n \n // Final fallback to all projects\n console.warn(`[kos-cli] No plugin projects found, showing all projects`);\n return await getAllProjects();\n}\n\nexport async function getAllModels() {\n const cached = getCached(\"allModels\");\n if (cached) return cached;\n \n if (process.env.KOS_CLI_QUIET !== \"true\") {\n console.warn(`[kos-cli] Scanning for models in KOS projects...`);\n }\n const allKosProjects = await getAllKosProjects();\n const models = [];\n\n for (const kosProject of allKosProjects) {\n if (kosProject.config.models) {\n Object.keys(kosProject.config.models).forEach((model) => {\n models.push({ model: model, project: kosProject.name });\n });\n }\n }\n\n // Sort models by project name first, then by model name\n models.sort((a, b) => {\n if (a.project === b.project) {\n return a.model.localeCompare(b.model);\n } else {\n return a.project.localeCompare(b.project);\n }\n });\n\n setCached(\"allModels\", models);\n return models;\n}\n\nexport async function getWorkspaceDefaults() {\n const cached = getCached(\"workspaceDefaults\");\n if (cached) return cached;\n\n const workspaceRoot = process.cwd();\n const rootKosJsonPath = path.join(workspaceRoot, '.kos.json');\n \n if (existsSync(rootKosJsonPath)) {\n try {\n const rootConfig = JSON.parse(readFileSync(rootKosJsonPath, \"utf-8\"));\n if (rootConfig.type === 'root' && rootConfig.generator?.defaults) {\n setCached(\"workspaceDefaults\", rootConfig.generator.defaults);\n return rootConfig.generator.defaults;\n }\n } catch (error) {\n console.warn(`[kos-cli] Error reading workspace defaults: ${error.message}`);\n }\n }\n \n setCached(\"workspaceDefaults\", {});\n return {};\n}\n\nexport async function getDefaultProjectForType(projectType) {\n const defaults = await getWorkspaceDefaults();\n return defaults[projectType] || null;\n}\n\nexport async function getProjectDetails(projectName) {\n const cacheKey = `projectDetails:${projectName}`;\n const cached = getCached(cacheKey);\n if (cached) return cached;\n\n const details = findProjectByName(process.cwd(), projectName);\n if (!details) {\n throw new Error(`Project \"${projectName}\" not found in workspace`);\n }\n setCached(cacheKey, details);\n return details;\n}\n", "// utils/cache.mjs\nimport crypto from \"crypto\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\n\n// Default to project-local cache; can swap to global using `getGlobalCachePath()`\nconst CACHE_PATH = path.resolve(\".nx/cli-cache.json\");\nconst CACHE_TTL = 600 * 1000;\nconst ARGS = process.argv;\nconst DISABLE_CACHE =\n process.env.DISABLE_CACHE === \"true\" || process.env.REFRESH === \"true\";\n\nlet _cache = {}; // in-memory cache\nlet _loaded = false;\n\nconst DEFAULT_TRACKED_FILES = [\n \"workspace.json\",\n \"nx.json\",\n \"project.json\",\n \"tsconfig.base.json\",\n \"package.json\",\n];\n\nfunction ensureCacheDir() {\n const dir = path.dirname(CACHE_PATH);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n}\n\nfunction loadCacheFromDisk() {\n if (_loaded) return;\n _loaded = true;\n try {\n if (fs.existsSync(CACHE_PATH)) {\n const data = fs.readFileSync(CACHE_PATH, \"utf-8\");\n _cache = JSON.parse(data);\n }\n } catch (err) {\n console.warn(\"Failed to load CLI cache:\", err);\n _cache = {};\n }\n}\n\nfunction saveCacheToDisk() {\n try {\n ensureCacheDir();\n fs.writeFileSync(CACHE_PATH, JSON.stringify(_cache, null, 2));\n } catch (err) {\n console.warn(\"Failed to save CLI cache:\", err);\n }\n}\n\nfunction isFresh(entry, ttl = CACHE_TTL) {\n if (!entry || !entry.timestamp) return false;\n return Date.now() - entry.timestamp < ttl;\n}\n\nexport function getCached(key, ttl = CACHE_TTL) {\n if (DISABLE_CACHE) return null;\n loadCacheFromDisk();\n const entry = _cache[key];\n if (isFresh(entry, ttl)) return entry.data;\n return null;\n}\n\nexport function setCached(key, data) {\n loadCacheFromDisk();\n _cache[key] = {\n data,\n timestamp: Date.now(),\n };\n saveCacheToDisk();\n}\n\nexport function clearCache(key) {\n loadCacheFromDisk();\n if (key) {\n delete _cache[key];\n } else {\n _cache = {};\n }\n saveCacheToDisk();\n}\n\nexport function getGlobalCachePath() {\n return path.join(os.homedir(), \".kos-cli-cache.json\");\n}\n\nexport function hashFiles(filePaths = DEFAULT_TRACKED_FILES) {\n const hash = crypto.createHash(\"sha256\");\n for (const file of filePaths) {\n if (fs.existsSync(file)) {\n hash.update(fs.readFileSync(file));\n }\n }\n return hash.digest(\"hex\");\n}\n\nexport function getHashedCache(key, filePaths = DEFAULT_TRACKED_FILES) {\n if (DISABLE_CACHE) return null;\n loadCacheFromDisk();\n const entry = _cache[key];\n const currentHash = hashFiles(filePaths);\n if (entry && entry.hash === currentHash) {\n return entry.data;\n }\n return null;\n}\n\nexport function setHashedCache(key, data, filePaths = DEFAULT_TRACKED_FILES) {\n loadCacheFromDisk();\n const hash = hashFiles(filePaths);\n _cache[key] = { data, hash, timestamp: Date.now() };\n saveCacheToDisk();\n}\n\nexport function markCacheDirty(reason = \"manual\") {\n _loaded = false;\n _cache = {};\n if (fs.existsSync(CACHE_PATH)) {\n fs.unlinkSync(CACHE_PATH);\n console.debug(`Cache invalidated due to ${reason}: ${CACHE_PATH} deleted`);\n }\n}\n\nexport function shouldInvalidateFromMeta(metadata = {}) {\n return metadata?.invalidateCache === true;\n}\n", "/**\n * EJS-based file generation \u2014 replaces @nx/devkit generateFiles().\n *\n * Walks a source template directory, processes each file through EJS,\n * interpolates __var__ tokens in filenames, strips .template suffixes,\n * and writes results via a CodegenFileSystem.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as ejs from \"ejs\";\nimport type { CodegenFileSystem } from \"./codegen-filesystem\";\nimport { getCodegenLogger } from \"./logger\";\n\n/**\n * Generate files from a template directory into a destination path.\n *\n * Behavior matches @nx/devkit generateFiles():\n * - Walks `srcFolder` recursively\n * - For each file, replaces `__propName__` in the filename using `substitutions`\n * - Strips `.template` suffix from filenames\n * - Processes file contents through EJS with `substitutions` as data\n * - Writes the result to `destFolder` (relative to fs.root) via the CodegenFileSystem\n *\n * @param codegenFs - Target filesystem abstraction\n * @param srcFolder - Absolute path to the template directory\n * @param destFolder - Destination path relative to the filesystem root\n * @param substitutions - Key-value pairs for EJS and filename interpolation\n */\nexport function generateFilesFromTemplates(\n codegenFs: CodegenFileSystem,\n srcFolder: string,\n destFolder: string,\n substitutions: Record<string, any>\n): void {\n const logger = getCodegenLogger();\n const templateFiles = walkTemplateDir(srcFolder);\n\n for (const templateFile of templateFiles) {\n const relPath = path.relative(srcFolder, templateFile);\n\n // Interpolate __var__ tokens in the path segments\n let destRelPath = interpolateFilename(relPath, substitutions);\n\n // Strip .template suffix\n if (destRelPath.endsWith(\".template\")) {\n destRelPath = destRelPath.slice(0, -\".template\".length);\n }\n\n const destPath = path.join(destFolder, destRelPath);\n\n // Templates are read from the real filesystem (package assets),\n // while outputs are written through CodegenFileSystem.\n const rawContent = fs.readFileSync(templateFile, \"utf-8\");\n const rendered = ejs.render(rawContent, substitutions, {\n filename: templateFile, // for EJS error messages and includes\n });\n\n logger.debug(`Generating ${destPath}`);\n codegenFs.write(destPath, rendered);\n }\n}\n\n/**\n * Replace `__propName__` tokens in a file path with values from substitutions.\n * E.g., `__nameDashCase__-model.ts` with `{ nameDashCase: \"my-widget\" }` becomes\n * `my-widget-model.ts`.\n */\nfunction interpolateFilename(\n filePath: string,\n substitutions: Record<string, any>\n): string {\n return filePath.replace(/__([^_]+)__/g, (match, key: string) => {\n if (key in substitutions) {\n return String(substitutions[key]);\n }\n return match; // leave unmatched tokens as-is\n });\n}\n\nfunction walkTemplateDir(dir: string): string[] {\n const results: string[] = [];\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...walkTemplateDir(full));\n } else {\n results.push(full);\n }\n }\n return results;\n}\n", "/**\n * Settable logger interface for kos-codegen-core.\n *\n * Consumers (CLI, VS Code extension, Nx adapter) set their own logger\n * via setCodegenLogger(). Defaults to silent no-op.\n */\nexport interface CodegenLogger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nconst noopLogger: CodegenLogger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\nlet activeLogger: CodegenLogger = noopLogger;\n\nexport function setCodegenLogger(logger: CodegenLogger): void {\n activeLogger = logger;\n}\n\nexport function getCodegenLogger(): CodegenLogger {\n return activeLogger;\n}\n", "/**\n * Nx-free project discovery \u2014 scans for project.json files in the workspace.\n *\n * Replaces @nx/devkit readProjectConfiguration, getProjects, readNxJson.\n * Based on the pattern in kos-model-extension/src/utils/workspace-scanner.ts.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport fg from \"fast-glob\";\nimport { getCodegenLogger } from \"./logger\";\n\nexport interface ProjectConfiguration {\n name: string;\n root: string;\n sourceRoot: string;\n projectType?: \"library\" | \"application\";\n targets?: Record<string, unknown>;\n tags?: string[];\n}\n\n/**\n * Discover all projects in the workspace by scanning for project.json files.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @returns Map of project name to ProjectConfiguration\n */\nexport function discoverProjects(\n workspaceRoot: string\n): Map<string, ProjectConfiguration> {\n const logger = getCodegenLogger();\n const projects = new Map<string, ProjectConfiguration>();\n\n const projectJsonPaths = fg.sync(\"**/project.json\", {\n cwd: workspaceRoot,\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/.git/**\"],\n absolute: false,\n });\n\n for (const relPath of projectJsonPaths) {\n const absPath = path.join(workspaceRoot, relPath);\n try {\n const raw = fs.readFileSync(absPath, \"utf-8\");\n const json = JSON.parse(raw);\n const projectRoot = path.dirname(relPath);\n const name = json.name ?? path.basename(projectRoot);\n\n const config: ProjectConfiguration = {\n name,\n root: projectRoot,\n sourceRoot: json.sourceRoot ?? path.join(projectRoot, \"src\"),\n projectType: json.projectType,\n targets: json.targets,\n tags: json.tags,\n };\n\n projects.set(name, config);\n logger.debug(`Discovered project: ${name} at ${projectRoot}`);\n } catch (err) {\n logger.warn(`Failed to parse ${absPath}: ${err}`);\n }\n }\n\n logger.info(`Discovered ${projects.size} projects`);\n return projects;\n}\n\n/**\n * Find a single project by name.\n *\n * Note: This rescans the workspace on every call. If you need to look up\n * multiple projects, call discoverProjects() once and query the returned Map.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @param projectName - The project name to look up\n * @param projects - Optional pre-computed project map (avoids rescan)\n * @returns ProjectConfiguration or undefined if not found\n */\nexport function findProjectByName(\n workspaceRoot: string,\n projectName: string,\n projects?: Map<string, ProjectConfiguration>\n): ProjectConfiguration | undefined {\n const map = projects ?? discoverProjects(workspaceRoot);\n return map.get(projectName);\n}\n\n/**\n * Find the project that contains a given file path.\n * Walks up from the file path looking for the nearest project.json.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @param filePath - Absolute path to a file within the workspace\n * @returns ProjectConfiguration or undefined if not within any project\n */\nexport function findProjectForPath(\n workspaceRoot: string,\n filePath: string\n): ProjectConfiguration | undefined {\n const resolved = path.resolve(workspaceRoot);\n let dir = path.dirname(path.resolve(filePath));\n\n while (dir.startsWith(resolved) && dir !== resolved) {\n const projectJsonPath = path.join(dir, \"project.json\");\n if (fs.existsSync(projectJsonPath)) {\n try {\n const raw = fs.readFileSync(projectJsonPath, \"utf-8\");\n const json = JSON.parse(raw);\n const projectRoot = path.relative(resolved, dir);\n const name = json.name ?? path.basename(dir);\n\n return {\n name,\n root: projectRoot,\n sourceRoot: json.sourceRoot ?? path.join(projectRoot, \"src\"),\n projectType: json.projectType,\n targets: json.targets,\n tags: json.tags,\n };\n } catch {\n return undefined;\n }\n }\n dir = path.dirname(dir);\n }\n\n return undefined;\n}\n\n/**\n * Read the workspace-level nx.json configuration.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @returns Parsed nx.json contents, or empty object if not found\n */\nexport function readNxJson(\n workspaceRoot: string\n): Record<string, unknown> {\n const nxJsonPath = path.join(workspaceRoot, \"nx.json\");\n try {\n const raw = fs.readFileSync(nxJsonPath, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return {};\n }\n}\n", "/**\n * Format files using Prettier \u2014 replaces @nx/devkit formatFiles().\n *\n * Resolves the Prettier config from the workspace root and formats\n * all files tracked by a CodegenFileSystem that match supported extensions.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport prettier from \"prettier\";\nimport { getCodegenLogger } from \"./logger\";\n\nconst FORMATTABLE_EXTENSIONS = new Set([\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".css\",\n \".scss\",\n \".md\",\n \".yaml\",\n \".yml\",\n \".html\",\n]);\n\n/**\n * Format files at the given paths using Prettier.\n *\n * @param workspaceRoot - Absolute path to the workspace root (for Prettier config resolution)\n * @param filePaths - Absolute paths of files to format\n */\nexport async function formatFiles(\n workspaceRoot: string,\n filePaths: string[]\n): Promise<void> {\n const logger = getCodegenLogger();\n\n for (const filePath of filePaths) {\n const ext = path.extname(filePath);\n if (!FORMATTABLE_EXTENSIONS.has(ext)) {\n continue;\n }\n\n try {\n const content = fs.readFileSync(filePath, \"utf-8\");\n const options = await prettier.resolveConfig(filePath, {\n editorconfig: true,\n });\n const formatted = await prettier.format(content, {\n ...options,\n filepath: filePath,\n });\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n logger.debug(`Formatted ${path.relative(workspaceRoot, filePath)}`);\n } catch (err) {\n logger.warn(`Failed to format ${filePath}: ${err}`);\n }\n }\n}\n", "/**\n * TypeScript AST-based index.ts updater.\n *\n * Adds `export * from './path'` declarations to a barrel file using\n * the TypeScript compiler API for proper AST manipulation.\n *\n * Ported from kos-nx-plugin/src/generators/kos-model/lib/utils/ts-visitor.ts.\n */\nimport * as ts from \"typescript\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { getCodegenLogger } from \"../logger\";\n\n/**\n * Add an export-all declaration to an index.ts file using TS AST.\n *\n * @param codegenFs - Filesystem abstraction\n * @param indexPath - Path to the index.ts file (relative to root)\n * @param modelPath - Relative path to export (e.g. 'models/my-model')\n */\nexport function updateModelIndex(\n codegenFs: CodegenFileSystem,\n indexPath: string,\n modelPath: string\n): void {\n const logger = getCodegenLogger();\n\n if (!indexPath) return;\n\n const content = codegenFs.read(indexPath);\n if (content === null) {\n logger.warn(`Index file not found: ${indexPath}`);\n return;\n }\n\n logger.info(`Updating ${indexPath} \u2014 adding export for ${modelPath}`);\n\n const sourceFile = ts.createSourceFile(\n indexPath,\n content,\n ts.ScriptTarget.Latest,\n true\n );\n\n const exportDeclaration = ts.factory.createExportDeclaration(\n undefined,\n false,\n undefined,\n ts.factory.createStringLiteral(`./${modelPath}`)\n );\n\n const updatedSourceFile = ts.factory.updateSourceFile(sourceFile, [\n ...sourceFile.statements,\n exportDeclaration,\n ]);\n\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n const newContents = printer.printFile(updatedSourceFile);\n\n codegenFs.write(indexPath, newContents);\n}\n", "/**\n * Type definitions for KOS Component Generator\n */\n\n// Plugin type constants\nexport const PLUGIN_TYPES = {\n CUI: \"cui\",\n UTILITY: \"utility\",\n TROUBLE_ACTION: \"troubleAction\",\n SETUP: \"setup\",\n SETTING: \"setting\",\n NAV: \"nav\",\n CONTROL_POUR: \"controlPour\",\n CUSTOM: \"custom\",\n} as const;\n\nexport type PluginType = (typeof PLUGIN_TYPES)[keyof typeof PLUGIN_TYPES];\n\n// Contribution type mapping\nexport const CONTRIBUTION_TYPE_MAP: Record<string, string> = {\n [PLUGIN_TYPES.SETUP]: \"setup\",\n [PLUGIN_TYPES.CUI]: \"cui\",\n [PLUGIN_TYPES.UTILITY]: \"utility\",\n [PLUGIN_TYPES.SETTING]: \"setting\",\n [PLUGIN_TYPES.NAV]: \"nav\",\n [PLUGIN_TYPES.TROUBLE_ACTION]: \"trouble-action\",\n [PLUGIN_TYPES.CONTROL_POUR]: \"control-pour\",\n [PLUGIN_TYPES.CUSTOM]: \"custom\",\n};\n\n// Plugin types that require localization\nexport const LOCALIZED_PLUGIN_TYPES: ReadonlySet<string> = new Set([\n PLUGIN_TYPES.CUI,\n PLUGIN_TYPES.UTILITY,\n PLUGIN_TYPES.SETUP,\n PLUGIN_TYPES.SETTING,\n PLUGIN_TYPES.NAV,\n PLUGIN_TYPES.CONTROL_POUR,\n PLUGIN_TYPES.TROUBLE_ACTION,\n PLUGIN_TYPES.CUSTOM,\n]);\n\n// Configuration interfaces\nexport interface ExperienceConfig {\n id: string;\n component: string;\n location: string;\n}\n\nexport interface PluginContribution {\n id: string;\n title: string;\n namespace: string;\n experienceId?: string;\n [key: string]: any; // Allow plugin-specific properties\n}\n\nexport interface PluginConfiguration {\n contributions: Record<string, PluginContribution[]>;\n experiences: Record<string, ExperienceConfig>;\n views?: Record<string, any[]>;\n}\n\nexport interface NormalizedComponentOptions {\n name: string;\n nameDashCase: string;\n nameCamelCase: string;\n namePascalCase: string;\n nameLowerCase: string;\n appProject: string;\n group?: string;\n pluginType?: string;\n type: string;\n appDirectory: string;\n useEmotionCss?: boolean;\n contributionKey?: string; // User-specified contribution key for custom plugins\n}\n\n// Component generator input options\nexport interface ComponentOptions {\n name: string;\n type: \"components\" | \"features\";\n useEmotionCss: boolean;\n appProject: string;\n appDirectory: string;\n modelDirectory: string;\n group?: string;\n pluginType?: string;\n contributionKey?: string;\n registrationProject?: string;\n skipRegistration?: boolean;\n companion?: boolean;\n companionModel?: string;\n companionModelProject?: string;\n companionPattern?: \"composition\" | \"decorator\";\n}\n\n// JSON path constants for .kos.json structure\nexport const KOS_JSON_PATHS = {\n PLUGIN_ROOT: \"kosdev.ddk.ncui.plugin\",\n CONTRIBUTES: \"kosdev.ddk.ncui.plugin.contributes\",\n EXPERIENCES: \"kosdev.ddk.ncui.plugin.contributes.experiences\",\n VIEWS: \"kosdev.ddk.ncui.plugin.contributes.views\",\n TAB_VIEW: \"ddk.ncui.settings.tabView\",\n} as const;\n", "import {\n ExperienceConfig,\n NormalizedComponentOptions,\n PluginConfiguration,\n PluginContribution,\n} from \"../types\";\n\n/**\n * Base interface for plugin-specific handlers\n */\nexport interface PluginHandler {\n /**\n * Creates the plugin-specific configuration\n */\n createConfiguration(options: NormalizedComponentOptions): PluginConfiguration;\n\n /**\n * Returns the contribution key for this plugin type\n */\n getContributionKey(): string;\n\n /**\n * Checks if this plugin type requires localization\n */\n requiresLocalization(): boolean;\n\n /**\n * Gets the template source path for this plugin type\n */\n getTemplatePath(): string;\n}\n\n/**\n * Base implementation with common functionality\n */\nexport abstract class BasePluginHandler implements PluginHandler {\n protected abstract pluginType: string;\n protected abstract contributionKey: string;\n protected abstract requiresI18n: boolean;\n\n abstract createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration;\n\n getContributionKey(): string {\n return this.contributionKey;\n }\n\n requiresLocalization(): boolean {\n return this.requiresI18n;\n }\n\n getTemplatePath(): string {\n return this.contributionKey;\n }\n\n /**\n * Helper to create experience configuration\n */\n protected createExperience(\n options: NormalizedComponentOptions,\n experienceId: string\n ): ExperienceConfig {\n const compPath = this.getComponentPath(options);\n\n return {\n id: experienceId,\n component: options.namePascalCase,\n location: `./src/${compPath}`,\n };\n }\n\n /**\n * Helper to get component path\n */\n protected getComponentPath(options: NormalizedComponentOptions): string {\n return `${options.appDirectory}/${this.contributionKey}/${options.nameDashCase}/${options.nameDashCase}.tsx`;\n }\n\n /**\n * Helper to create config prefix\n */\n protected getConfigPrefix(options: NormalizedComponentOptions): string {\n return `${options.appProject}.${options.nameCamelCase}`;\n }\n}\n", "import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class ControlPourPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CONTROL_POUR;\n protected contributionKey = \"control-pour\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.controlPour.experience`;\n\n const contribution = {\n id: `${configPrefix}.controlPour`,\n title: `${configPrefix}.controlPour.title`,\n namespace: options.appProject,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n controlPour: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n", "import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class CuiPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CUI;\n protected contributionKey = \"cui\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.cui.experience`;\n\n const contribution = {\n id: configPrefix,\n title: `${configPrefix}.cui.title`,\n namespace: options.appProject,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n cui: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n", "import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class CustomPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CUSTOM;\n protected contributionKey = \"custom\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.${\n options.contributionKey || \"custom\"\n }.experience`;\n\n // Get the user-specified contribution key or default to 'custom'\n const userContributionKey = options.contributionKey || \"custom\";\n\n const contribution = {\n id: configPrefix,\n title: `${configPrefix}.${userContributionKey}.title`,\n namespace: options.appProject,\n experienceId,\n // TODO: Add additional fields as required by the plugin-explorer specification\n // Refer to the plugin-explorer documentation for your specific contribution type\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n [userContributionKey]: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n\n override getTemplatePath(): string {\n // Use the generic 'custom' template path\n return this.contributionKey || \"custom\";\n }\n\n protected override getComponentPath(options: NormalizedComponentOptions): string {\n // Use the user-specified contribution key for the path if available\n const pathKey = options.contributionKey || \"custom\";\n return `${options.appDirectory}/${pathKey}/${options.nameDashCase}/${options.nameDashCase}.tsx`;\n }\n}\n", "import { NormalizedComponentOptions, PluginConfiguration } from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\n/**\n * Default handler for non-plugin components\n */\nexport class DefaultComponentHandler extends BasePluginHandler {\n protected pluginType = \"component\";\n protected contributionKey = \"components\";\n protected requiresI18n = false;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const compPath = this.getComponentPath(options);\n\n const viewConfig = {\n id: `${options.appProject}.${options.nameCamelCase}`,\n title: \"ddk.ncui.config.title\",\n namespace: options.appProject,\n component: options.namePascalCase,\n location: `./src/${compPath}`,\n };\n\n return {\n contributions: {},\n experiences: {},\n views: {\n [this.getTabViewKey()]: [viewConfig],\n },\n };\n }\n\n private getTabViewKey(): string {\n return \"ddk.ncui.settings.tabView\";\n }\n\n override getTemplatePath(): string {\n return \"files\"; // Default template path\n }\n}\n", "import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class NavPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.NAV;\n protected contributionKey = \"nav\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.nav.experience`;\n\n const contribution = {\n id: `${configPrefix}.nav`,\n title: `${configPrefix}.nav.title`,\n namespace: options.appProject,\n navDescriptor: options.nameLowerCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n navViews: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n", "import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class SettingPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.SETTING;\n protected contributionKey = \"setting\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.settings.experience`;\n\n const contribution = {\n id: `${configPrefix}.setting`,\n title: `${configPrefix}.setting.title`,\n namespace: options.appProject,\n settingsGroup: options.group || \"general\",\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n settings: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n", "import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class SetupPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.SETUP;\n protected contributionKey = \"setup\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.setup.experience`;\n\n const contribution = {\n id: `${configPrefix}.setup`,\n title: `${configPrefix}.setup.title`,\n namespace: options.appProject,\n setupDescriptor: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n setupStep: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n", "import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class TroubleActionPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.TROUBLE_ACTION;\n protected contributionKey = \"trouble-action\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.troubleAction.experience`;\n\n const contribution = {\n id: `${configPrefix}.troubleAction`,\n title: `${configPrefix}.troubleAction.title`,\n namespace: options.appProject,\n troubleType: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n troubleActions: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n", "import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class UtilityPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.UTILITY;\n protected contributionKey = \"utility\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.util.experience`;\n\n const contribution = {\n id: `${configPrefix}.util`,\n title: `${configPrefix}.utility.title`,\n namespace: options.appProject,\n utilDescriptor: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n utilities: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n", "import { PLUGIN_TYPES } from \"../types\";\nimport { PluginHandler } from \"./base\";\nimport { ControlPourPluginHandler } from \"./control-pour-handler\";\nimport { CuiPluginHandler } from \"./cui-handler\";\nimport { CustomPluginHandler } from \"./custom-handler\";\nimport { DefaultComponentHandler } from \"./default-handler\";\nimport { NavPluginHandler } from \"./nav-handler\";\nimport { SettingPluginHandler } from \"./setting-handler\";\nimport { SetupPluginHandler } from \"./setup-handler\";\nimport { TroubleActionPluginHandler } from \"./trouble-action-handler\";\nimport { UtilityPluginHandler } from \"./utility-handler\";\n\n/**\n * Factory for creating plugin-specific handlers\n */\nexport class PluginHandlerFactory {\n private static handlers: Map<string, new () => PluginHandler> = new Map<\n string,\n new () => PluginHandler\n >([\n [PLUGIN_TYPES.CUI, CuiPluginHandler],\n [PLUGIN_TYPES.UTILITY, UtilityPluginHandler],\n [PLUGIN_TYPES.SETTING, SettingPluginHandler],\n [PLUGIN_TYPES.SETUP, SetupPluginHandler],\n [PLUGIN_TYPES.NAV, NavPluginHandler],\n [PLUGIN_TYPES.CONTROL_POUR, ControlPourPluginHandler],\n [PLUGIN_TYPES.TROUBLE_ACTION, TroubleActionPluginHandler],\n [PLUGIN_TYPES.CUSTOM, CustomPluginHandler],\n ]);\n\n static createHandler(pluginType?: string): PluginHandler {\n if (!pluginType) {\n return new DefaultComponentHandler();\n }\n\n const HandlerClass = this.handlers.get(pluginType);\n\n if (!HandlerClass) {\n console.warn(\n `No handler found for plugin type: ${pluginType}. Using default handler.`\n );\n return new DefaultComponentHandler();\n }\n\n return new HandlerClass();\n }\n\n static isValidPluginType(type: string): boolean {\n return this.handlers.has(type);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["existsSync", "readFileSync", "path", "fs", "path", "__dirname", "path", "existsSync", "readFileSync"]
|
|
7
|
+
}
|
package/README.md
DELETED
|
@@ -1,484 +0,0 @@
|
|
|
1
|
-
# KOS UI CLI
|
|
2
|
-
|
|
3
|
-
Command-line interface for KOS workspace management and code generation.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The KOS UI CLI (`kosui`) provides tools for:
|
|
8
|
-
|
|
9
|
-
- Generating KOS models with proper architecture patterns
|
|
10
|
-
- Creating OpenAPI type definitions and service wrappers from device APIs
|
|
11
|
-
- Comparing API versions for breaking change detection
|
|
12
|
-
- Managing workspace configurations
|
|
13
|
-
- Scaffolding new KOS projects
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
The CLI is installed as part of the KOS SDK workspace:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install @kosdev-code/kos-ui-cli
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
Or use directly via npx:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npx @kosdev-code/kos-ui-cli <command>
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Quick Reference
|
|
30
|
-
|
|
31
|
-
| Command | Description | Example |
|
|
32
|
-
|---------|-------------|---------|
|
|
33
|
-
| `model` | Generate KOS models | `kosui model UserProfile` |
|
|
34
|
-
| `api:generate` | Generate API types from OpenAPI | `kosui api:generate --project my-app` |
|
|
35
|
-
| `api:compare` | Compare API versions for compatibility | `kosui api:compare --project my-app --app kos --base v1.8.0 --target v1.9.0` |
|
|
36
|
-
| `workspace` | Workspace utilities | `kosui workspace:list-models` |
|
|
37
|
-
|
|
38
|
-
## Commands
|
|
39
|
-
|
|
40
|
-
### kosui api:generate
|
|
41
|
-
|
|
42
|
-
Generate TypeScript types and service wrappers from OpenAPI specifications.
|
|
43
|
-
|
|
44
|
-
Automatically creates type-safe API clients from your device's OpenAPI spec, including:
|
|
45
|
-
- TypeScript type definitions for all endpoints
|
|
46
|
-
- Service wrapper functions with proper error handling
|
|
47
|
-
- Full IntelliSense support for paths, parameters, and responses
|
|
48
|
-
- Filtered output by app namespace
|
|
49
|
-
|
|
50
|
-
#### Options
|
|
51
|
-
|
|
52
|
-
**Required:**
|
|
53
|
-
- `--project <name>` - Target project name (must exist in workspace)
|
|
54
|
-
|
|
55
|
-
**Optional:**
|
|
56
|
-
- `--host <url>` - API host URL (default: inherited from project.json or http://127.0.0.1:8081)
|
|
57
|
-
- `--apps <apps>` - Comma-separated app filters to include specific namespaces (e.g., 'kos,dispense')
|
|
58
|
-
- `--output <path>` - Output path relative to sourceRoot (default: inherited from project.json or 'utils')
|
|
59
|
-
- `--default-version <version>` - Default version for service exports (default: inherited from project.json)
|
|
60
|
-
- `--all-apps-version <version>` - Override all apps to use specific version
|
|
61
|
-
|
|
62
|
-
**Advanced:**
|
|
63
|
-
- `--alias <json>` - Custom export aliases as JSON (e.g., '{"kos":"KOS"}')
|
|
64
|
-
- `--app-version <json>` - Custom versions per app as JSON (e.g., '{"kos":"v2"}')
|
|
65
|
-
|
|
66
|
-
**Note:** Options can be configured in `project.json` under `targets.api.options` and will be inherited if not specified on command line. CLI arguments take precedence over project configuration.
|
|
67
|
-
|
|
68
|
-
#### Examples
|
|
69
|
-
|
|
70
|
-
**Basic usage with project configuration:**
|
|
71
|
-
```bash
|
|
72
|
-
kosui api:generate --project my-device-models
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**Override host and filter by apps:**
|
|
76
|
-
```bash
|
|
77
|
-
kosui api:generate \
|
|
78
|
-
--project my-device-models \
|
|
79
|
-
--host http://device.local:8081 \
|
|
80
|
-
--apps kos,dispense
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
**Custom output path and version:**
|
|
84
|
-
```bash
|
|
85
|
-
kosui api:generate \
|
|
86
|
-
--project my-device-models \
|
|
87
|
-
--output api/types \
|
|
88
|
-
--default-version v2
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**Force all apps to specific version:**
|
|
92
|
-
```bash
|
|
93
|
-
kosui api:generate \
|
|
94
|
-
--project my-device-models \
|
|
95
|
-
--all-apps-version v1
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
#### What Gets Generated
|
|
99
|
-
|
|
100
|
-
For each app namespace (e.g., `kos`, `dispense`, `freestyle`):
|
|
101
|
-
|
|
102
|
-
1. **Type definitions** - `utils/services/{app}/{version}/openapi.d.ts`
|
|
103
|
-
- TypeScript types for all endpoints
|
|
104
|
-
- Request/response schemas
|
|
105
|
-
- Path parameter types
|
|
106
|
-
|
|
107
|
-
2. **Service wrapper** - `utils/services/{app}/{version}/service.ts`
|
|
108
|
-
- Typed `kosServiceRequest` decorator
|
|
109
|
-
- Typed API client
|
|
110
|
-
- Type aliases for IntelliSense
|
|
111
|
-
|
|
112
|
-
3. **Index files**
|
|
113
|
-
- `utils/openapi-index.ts` - Aggregated type exports
|
|
114
|
-
- `utils/services-index.ts` - Aggregated service exports
|
|
115
|
-
|
|
116
|
-
**Core SDK services** (`kos`, `vfs`, `dispense`, `freestyle`, `handle`, `kosdev.ddk`) are automatically excluded when generating for third-party projects since they're already available in published SDKs.
|
|
117
|
-
|
|
118
|
-
#### Integration with Project Configuration
|
|
119
|
-
|
|
120
|
-
Add default configuration to your project's `project.json`:
|
|
121
|
-
|
|
122
|
-
```json
|
|
123
|
-
{
|
|
124
|
-
"targets": {
|
|
125
|
-
"api": {
|
|
126
|
-
"executor": "nx:run-commands",
|
|
127
|
-
"options": {
|
|
128
|
-
"command": "kosui api:generate --project my-project",
|
|
129
|
-
"host": "http://127.0.0.1:8081",
|
|
130
|
-
"outputPath": "utils",
|
|
131
|
-
"defaultVersion": "v1",
|
|
132
|
-
"serviceExportAliases": {
|
|
133
|
-
"kos": "KOS",
|
|
134
|
-
"dispense": "DISPENSE"
|
|
135
|
-
},
|
|
136
|
-
"appVersions": {
|
|
137
|
-
"kos": "v2",
|
|
138
|
-
"dispense": "v1"
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Then run simply:
|
|
147
|
-
```bash
|
|
148
|
-
npx nx run my-project:api
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
#### Using Generated Types
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
import { kosServiceRequest, type ApiResponse } from './utils/services/kos/v1/service';
|
|
155
|
-
import { DependencyLifecycle } from '@kosdev-code/kos-ui-sdk';
|
|
156
|
-
|
|
157
|
-
// Path constant with type safety
|
|
158
|
-
const PATH_DEVICE_STATUS = '/api/kos/device/status';
|
|
159
|
-
|
|
160
|
-
// Service function with tuple-based error handling
|
|
161
|
-
async function getDeviceStatus(): Promise<ApiResponse<typeof PATH_DEVICE_STATUS, 'get'>> {
|
|
162
|
-
// ... implementation
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Using in a model with decorator
|
|
166
|
-
@kosServiceRequest({
|
|
167
|
-
path: PATH_DEVICE_STATUS,
|
|
168
|
-
method: 'get',
|
|
169
|
-
lifecycle: DependencyLifecycle.LOAD
|
|
170
|
-
})
|
|
171
|
-
private onDeviceStatusLoaded(ctx: ExecutionContext<typeof PATH_DEVICE_STATUS>): void {
|
|
172
|
-
const [error, data] = ctx.result;
|
|
173
|
-
if (error) {
|
|
174
|
-
console.error('Failed to load device status:', error);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
this.status = data.status;
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### kosui api:compare
|
|
182
|
-
|
|
183
|
-
Compare OpenAPI versions to detect breaking changes and API compatibility issues.
|
|
184
|
-
|
|
185
|
-
Analyzes two generated API type definitions to identify:
|
|
186
|
-
- Removed endpoints or HTTP methods
|
|
187
|
-
- New or removed parameters
|
|
188
|
-
- Parameter requirement changes
|
|
189
|
-
- Request body modifications
|
|
190
|
-
|
|
191
|
-
#### Prerequisites
|
|
192
|
-
|
|
193
|
-
Generate types for both versions before comparing:
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
# Connect to base version device and generate types
|
|
197
|
-
kosui api:generate --project my-models --apps kos
|
|
198
|
-
|
|
199
|
-
# Connect to target version device and generate types
|
|
200
|
-
kosui api:generate --project my-models --apps kos
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
#### Options
|
|
204
|
-
|
|
205
|
-
**Required:**
|
|
206
|
-
- `--project <name>` - Project containing generated API types
|
|
207
|
-
- `--app <name>` - App namespace to compare (kos, dispense, freestyle)
|
|
208
|
-
- `--base <version>` - Base version to compare from
|
|
209
|
-
- `--target <version>` - Target version to compare to
|
|
210
|
-
|
|
211
|
-
**Optional:**
|
|
212
|
-
- `--format <format>` - Output format: console (default), json, markdown
|
|
213
|
-
- `--output <file>` - Write output to file instead of stdout
|
|
214
|
-
- `--apps <apps>` - Compare multiple apps (comma-separated)
|
|
215
|
-
|
|
216
|
-
#### Examples
|
|
217
|
-
|
|
218
|
-
**Basic comparison:**
|
|
219
|
-
```bash
|
|
220
|
-
kosui api:compare \
|
|
221
|
-
--project device-models \
|
|
222
|
-
--app kos \
|
|
223
|
-
--base v1.8.0 \
|
|
224
|
-
--target v1.9.0
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
**Generate markdown release notes:**
|
|
228
|
-
```bash
|
|
229
|
-
kosui api:compare \
|
|
230
|
-
--project device-models \
|
|
231
|
-
--app kos \
|
|
232
|
-
--base v1.8.0 \
|
|
233
|
-
--target v1.9.0 \
|
|
234
|
-
--format markdown \
|
|
235
|
-
--output CHANGELOG-API.md
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
**JSON output for automation:**
|
|
239
|
-
```bash
|
|
240
|
-
kosui api:compare \
|
|
241
|
-
--project device-models \
|
|
242
|
-
--app kos \
|
|
243
|
-
--base v1.8.0 \
|
|
244
|
-
--target v1.9.0 \
|
|
245
|
-
--format json
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**Compare multiple apps:**
|
|
249
|
-
```bash
|
|
250
|
-
kosui api:compare \
|
|
251
|
-
--project device-models \
|
|
252
|
-
--apps kos,dispense,freestyle \
|
|
253
|
-
--base v1.8.0 \
|
|
254
|
-
--target v1.9.0
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
#### Output Formats
|
|
258
|
-
|
|
259
|
-
**Console (default):**
|
|
260
|
-
- Colored terminal output with compatibility status
|
|
261
|
-
- Summary statistics (added/removed/modified endpoints)
|
|
262
|
-
- Breaking changes highlighted
|
|
263
|
-
- Recommendations for safe upgrade
|
|
264
|
-
|
|
265
|
-
**JSON:**
|
|
266
|
-
- Machine-readable format for automation
|
|
267
|
-
- Complete comparison data structure
|
|
268
|
-
- Suitable for CI/CD pipelines
|
|
269
|
-
|
|
270
|
-
**Markdown:**
|
|
271
|
-
- Ready for release notes and documentation
|
|
272
|
-
- Organized sections for breaking/non-breaking changes
|
|
273
|
-
- Suitable for commit messages or changelogs
|
|
274
|
-
|
|
275
|
-
#### Exit Codes
|
|
276
|
-
|
|
277
|
-
The command uses exit codes for automation:
|
|
278
|
-
|
|
279
|
-
- **Exit 0** - Versions are backward compatible
|
|
280
|
-
- **Exit 1** - Breaking changes detected
|
|
281
|
-
|
|
282
|
-
Example CI/CD usage:
|
|
283
|
-
```bash
|
|
284
|
-
kosui api:compare --project models --app kos --base v1 --target v2
|
|
285
|
-
if [ $? -eq 0 ]; then
|
|
286
|
-
echo "Safe to upgrade"
|
|
287
|
-
else
|
|
288
|
-
echo "Breaking changes detected"
|
|
289
|
-
fi
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
#### Integration with Build Process
|
|
293
|
-
|
|
294
|
-
Add comparison target to `project.json`:
|
|
295
|
-
|
|
296
|
-
```json
|
|
297
|
-
{
|
|
298
|
-
"targets": {
|
|
299
|
-
"api:compare": {
|
|
300
|
-
"executor": "nx:run-commands",
|
|
301
|
-
"options": {
|
|
302
|
-
"command": "kosui api:compare --project device-models --app kos --base ${BASE} --target ${TARGET}"
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
Run via Nx:
|
|
310
|
-
```bash
|
|
311
|
-
BASE=v1.8.0 TARGET=v1.9.0 npx nx run device-models:api:compare
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### kosui model
|
|
315
|
-
|
|
316
|
-
Generate KOS models with proper architecture patterns.
|
|
317
|
-
|
|
318
|
-
*For detailed model generation documentation, see the KOS UI SDK documentation.*
|
|
319
|
-
|
|
320
|
-
### kosui workspace
|
|
321
|
-
|
|
322
|
-
Workspace utilities for managing KOS projects.
|
|
323
|
-
|
|
324
|
-
*For workspace command documentation, see the KOS UI SDK documentation.*
|
|
325
|
-
|
|
326
|
-
## Advanced Usage
|
|
327
|
-
|
|
328
|
-
### Argument Formats
|
|
329
|
-
|
|
330
|
-
The CLI supports multiple argument formats:
|
|
331
|
-
|
|
332
|
-
**Boolean flags:**
|
|
333
|
-
```bash
|
|
334
|
-
--singleton # true
|
|
335
|
-
--singleton=false # explicit false
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
**String values:**
|
|
339
|
-
```bash
|
|
340
|
-
--name MyModel
|
|
341
|
-
--name=my-model
|
|
342
|
-
--name="My Model"
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
**Array values:**
|
|
346
|
-
```bash
|
|
347
|
-
--apps kos,dispense,network
|
|
348
|
-
--apps=kos,dispense
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
**JSON values:**
|
|
352
|
-
```bash
|
|
353
|
-
--alias '{"kos":"KOS","dispense":"DISPENSE"}'
|
|
354
|
-
--app-version '{"kos":"v2"}'
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
### Help System
|
|
358
|
-
|
|
359
|
-
Get contextual help for any command:
|
|
360
|
-
|
|
361
|
-
```bash
|
|
362
|
-
kosui --help # General help
|
|
363
|
-
kosui api:generate --help # Command-specific help
|
|
364
|
-
kosui model -h # Shorthand
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
The help system shows:
|
|
368
|
-
- Command description and purpose
|
|
369
|
-
- Available options with types and defaults
|
|
370
|
-
- Examples for common use cases
|
|
371
|
-
|
|
372
|
-
## Configuration
|
|
373
|
-
|
|
374
|
-
### Project-Level Configuration
|
|
375
|
-
|
|
376
|
-
Configure defaults in your project's `project.json` to avoid repeating options:
|
|
377
|
-
|
|
378
|
-
```json
|
|
379
|
-
{
|
|
380
|
-
"targets": {
|
|
381
|
-
"api": {
|
|
382
|
-
"executor": "nx:run-commands",
|
|
383
|
-
"options": {
|
|
384
|
-
"command": "kosui api:generate --project ${projectName}",
|
|
385
|
-
"host": "http://127.0.0.1:8081",
|
|
386
|
-
"outputPath": "utils",
|
|
387
|
-
"defaultVersion": "v1"
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
Then run via Nx:
|
|
395
|
-
```bash
|
|
396
|
-
npx nx run my-project:api
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
CLI arguments always override project configuration.
|
|
400
|
-
|
|
401
|
-
### Workspace-Level Configuration
|
|
402
|
-
|
|
403
|
-
For monorepo-wide settings, consider creating a shared configuration file that projects can reference.
|
|
404
|
-
|
|
405
|
-
## Troubleshooting
|
|
406
|
-
|
|
407
|
-
### Command Not Found
|
|
408
|
-
|
|
409
|
-
Ensure the package is installed and available in your PATH:
|
|
410
|
-
```bash
|
|
411
|
-
npm install @kosdev-code/kos-ui-cli
|
|
412
|
-
# or
|
|
413
|
-
npm link # if developing locally
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
### OpenAPI Generation Fails
|
|
417
|
-
|
|
418
|
-
**Check device connectivity:**
|
|
419
|
-
```bash
|
|
420
|
-
curl http://127.0.0.1:8081/api/kos/openapi/api
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
**Verify project name:**
|
|
424
|
-
```bash
|
|
425
|
-
npx nx list # List all projects
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
**Check project.json configuration:**
|
|
429
|
-
- Ensure `sourceRoot` is correctly set
|
|
430
|
-
- Verify target configuration if using `inherit` mode
|
|
431
|
-
|
|
432
|
-
### Generated Types Have Errors
|
|
433
|
-
|
|
434
|
-
**Regenerate with latest spec:**
|
|
435
|
-
```bash
|
|
436
|
-
kosui api:generate --project my-project --host http://device.local:8081
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
**Check for breaking changes in OpenAPI spec:**
|
|
440
|
-
- Compare previous and current OpenAPI specs
|
|
441
|
-
- Update service function signatures as needed
|
|
442
|
-
|
|
443
|
-
### Version Conflicts
|
|
444
|
-
|
|
445
|
-
When working with multiple API versions:
|
|
446
|
-
|
|
447
|
-
1. Use `--all-apps-version` to force specific version
|
|
448
|
-
2. Configure `appVersions` in project.json for per-app versions
|
|
449
|
-
3. Check `defaultVersion` setting for export aliases
|
|
450
|
-
|
|
451
|
-
## Development
|
|
452
|
-
|
|
453
|
-
### Building
|
|
454
|
-
|
|
455
|
-
```bash
|
|
456
|
-
npx nx run @kosdev-code/kos-ui-cli:build
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
### Testing
|
|
460
|
-
|
|
461
|
-
The CLI is tested through manual integration testing:
|
|
462
|
-
|
|
463
|
-
```bash
|
|
464
|
-
# Link for local development
|
|
465
|
-
npm link
|
|
466
|
-
|
|
467
|
-
# Test commands
|
|
468
|
-
kosui --help
|
|
469
|
-
kosui api:generate --project test-project
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
### Contributing
|
|
473
|
-
|
|
474
|
-
See the main [CONTRIBUTING.md](../../../CONTRIBUTING.md) for development guidelines.
|
|
475
|
-
|
|
476
|
-
## Related Documentation
|
|
477
|
-
|
|
478
|
-
- [KOS UI SDK Documentation](../kos-ui-sdk/README.md)
|
|
479
|
-
- [CODING_STANDARDS.md](../../../CODING_STANDARDS.md)
|
|
480
|
-
- [Workspace Documentation](../../../README.md)
|
|
481
|
-
|
|
482
|
-
## Support
|
|
483
|
-
|
|
484
|
-
For issues, questions, or feature requests, please refer to the main KOS monorepo documentation.
|
package/src/index.d.ts
DELETED
package/src/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/sdk/kos-ui-cli/src/index.js"],"names":[],"mappings":""}
|
package/src/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/src/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/sdk/kos-ui-cli/src/index.js"],"names":[],"mappings":""}
|