@kosdev-code/kos-ui-cli 2.1.39 → 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/action-factory.mjs", "../../../../../../../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/codegen-filesystem.ts", "../../../../../../../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/name-utils.ts", "../../../../../../../packages/kos-codegen-core/src/lib/normalize-values.ts", "../../../../../../../packages/kos-codegen-core/src/lib/kos-config.ts", "../../../../../../../packages/kos-codegen-core/src/lib/generators/update-model-index.ts", "../../../../../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/normalize-options.ts", "../../../../../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/model-transformer.ts", "../../../../../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/service-transformer.ts", "../../../../../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/registration-transformer.ts", "../../../../../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/generate-add-future-to-model.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", "../../../../../../../packages/kos-ui-cli/src/lib/utils/prompts.mjs", "../../../../../../../packages/kos-ui-cli/src/lib/generators/model/add-future.mjs"],
|
|
4
|
+
"sourcesContent": ["export const actionFactory = (action, metadata) => {\n return () => {\n const _actions = [{ type: action }];\n if (metadata.invalidateCache) {\n _actions.push({ type: \"clearCache\" });\n }\n return _actions;\n };\n};\n", "// 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", "import * as fs from \"fs\";\nimport * as path from \"path\";\n\n/**\n * Abstraction over a filesystem for code generation.\n *\n * Mirrors the subset of the Nx Tree API that generators actually use,\n * enabling the same generator logic to run against the real filesystem\n * (CLI, VS Code extension) or an in-memory tree (Nx adapter).\n */\nexport interface CodegenFileSystem {\n /** Workspace root directory (absolute path). */\n readonly root: string;\n\n /** Read a file relative to the workspace root. Returns null if not found. */\n read(filePath: string): string | null;\n\n /** Write a file relative to the workspace root. Creates parent dirs as needed. */\n write(filePath: string, content: string): void;\n\n /** Check whether a file exists relative to the workspace root. */\n exists(filePath: string): boolean;\n\n /** Delete a file relative to the workspace root. No-op if not found. */\n delete(filePath: string): void;\n\n /** List all files under a directory (relative to root), returned as root-relative paths. */\n listFiles(dirPath: string): string[];\n}\n\n/**\n * CodegenFileSystem wrapper that records absolute paths of every file written.\n * Wrap any CodegenFileSystem to collect written paths for post-generation steps\n * such as formatting.\n *\n * @example\n * const fs = new TrackingFileSystem(new DirectFileSystem(cwd));\n * generateModel({ codegenFs: fs, ... });\n * await formatFiles(fs.root, fs.writtenPaths);\n */\nexport class TrackingFileSystem implements CodegenFileSystem {\n private readonly inner: CodegenFileSystem;\n private readonly _writtenPaths: string[] = [];\n\n constructor(inner: CodegenFileSystem) {\n this.inner = inner;\n }\n\n get root(): string {\n return this.inner.root;\n }\n\n get writtenPaths(): string[] {\n return [...this._writtenPaths];\n }\n\n read(filePath: string): string | null {\n return this.inner.read(filePath);\n }\n\n write(filePath: string, content: string): void {\n this.inner.write(filePath, content);\n this._writtenPaths.push(\n path.isAbsolute(filePath) ? filePath : path.join(this.inner.root, filePath)\n );\n }\n\n exists(filePath: string): boolean {\n return this.inner.exists(filePath);\n }\n\n delete(filePath: string): void {\n this.inner.delete(filePath);\n }\n\n listFiles(dirPath: string): string[] {\n return this.inner.listFiles(dirPath);\n }\n}\n\n/**\n * CodegenFileSystem backed by the real Node.js filesystem.\n * All paths passed to interface methods are relative to the workspace root.\n */\nexport class DirectFileSystem implements CodegenFileSystem {\n readonly root: string;\n\n constructor(workspaceRoot: string) {\n this.root = path.resolve(workspaceRoot);\n }\n\n read(filePath: string): string | null {\n const abs = this.resolve(filePath);\n try {\n return fs.readFileSync(abs, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n write(filePath: string, content: string): void {\n const abs = this.resolve(filePath);\n fs.mkdirSync(path.dirname(abs), { recursive: true });\n fs.writeFileSync(abs, content, \"utf-8\");\n }\n\n exists(filePath: string): boolean {\n return fs.existsSync(this.resolve(filePath));\n }\n\n delete(filePath: string): void {\n const abs = this.resolve(filePath);\n try {\n fs.unlinkSync(abs);\n } catch {\n // no-op if file doesn't exist\n }\n }\n\n listFiles(dirPath: string): string[] {\n const abs = this.resolve(dirPath);\n if (!fs.existsSync(abs)) {\n return [];\n }\n return this.walkDir(abs).map((file) => path.relative(this.root, file));\n }\n\n private resolve(filePath: string): string {\n if (path.isAbsolute(filePath)) {\n return filePath;\n }\n return path.join(this.root, filePath);\n }\n\n private walkDir(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(...this.walkDir(full));\n } else {\n results.push(full);\n }\n }\n return results;\n }\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 * String case-conversion utilities.\n *\n * Pure functions with no external dependencies.\n * Ported from kos-nx-plugin/src/utils/name-utils.ts (minus the logger calls).\n */\n\nexport function dashCase(input: string): string {\n return input\n .replace(/\\s+/g, \"-\")\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n}\n\nexport function camelCase(input: string): string {\n if (input.length === 0) return \"\";\n const words = input.split(/-|\\s+/);\n if (words.length > 0 && words[0].length > 0) {\n words[0] = words[0].charAt(0).toLowerCase() + words[0].slice(1);\n }\n for (let i = 1; i < words.length; i++) {\n words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);\n }\n return words.join(\"\");\n}\n\nexport function pascalCase(input: string): string {\n if (input.length === 0) return \"\";\n const cc = camelCase(input);\n return cc[0].toUpperCase() + cc.slice(1);\n}\n\nexport function properCase(input: string): string {\n const words = input\n .toLowerCase()\n .replaceAll(\"-\", \" \")\n .split(\" \")\n .filter(Boolean);\n for (let i = 0; i < words.length; i++) {\n words[i] = words[i][0].toUpperCase() + words[i].slice(1);\n }\n return words.join(\"\");\n}\n\n/**\n * Convert to CONSTANT_CASE. Expects space-separated or dash-separated input.\n * camelCase input is not split (e.g. \"myWidget\" becomes \"MYWIDGET\").\n */\nexport function constantCase(input: string): string {\n if (input.length === 0) return \"\";\n return input\n .toUpperCase()\n .split(/[\\s-]+/)\n .filter(Boolean)\n .join(\"_\");\n}\n", "/**\n * Option normalization \u2014 generates all case variants for every string property.\n *\n * Given `{ name: \"my-widget\" }`, produces:\n * ```\n * {\n * name: \"my-widget\",\n * nameCamelCase: \"myWidget\",\n * namePascalCase: \"MyWidget\",\n * nameDashCase: \"my-widget\",\n * nameProperCase: \"MyWidget\",\n * nameConstantCase: \"MY_WIDGET\",\n * nameLowerCase: \"my-widget\",\n * }\n * ```\n *\n * Ported from kos-nx-plugin/src/utils/normalize-value.ts.\n */\nimport {\n camelCase,\n constantCase,\n dashCase,\n pascalCase,\n properCase,\n} from \"./name-utils\";\n\ntype NormalizedFunctions =\n | \"CamelCase\"\n | \"ConstantCase\"\n | \"DashCase\"\n | \"PascalCase\"\n | \"ProperCase\"\n | \"LowerCase\";\n\ntype NormalizedValue<Type extends Record<string, string>> = {\n [k in Type as `${Extract<keyof Type, string>}${NormalizedFunctions}`]: string;\n};\n\ntype Normalized<T extends string> = {\n [k in T as `${T}${NormalizedFunctions}`]: string;\n};\n\nconst normalizeValue = <T extends string>(\n optionsName: T,\n value: string\n): Normalized<T> & { [k in T]: string } =>\n ({\n [`${camelCase(optionsName)}CamelCase`]: camelCase(value),\n [`${camelCase(optionsName)}ConstantCase`]: constantCase(value),\n [`${camelCase(optionsName)}DashCase`]: dashCase(value),\n [`${camelCase(optionsName)}PascalCase`]: pascalCase(value),\n [`${camelCase(optionsName)}ProperCase`]: properCase(value),\n [`${camelCase(optionsName)}LowerCase`]: value.toLowerCase(),\n [`${optionsName}`]: value,\n }) as Normalized<T> & { [k in T]: string };\n\nexport const normalizeAllValues = <T extends Record<string, any>>(\n options: T\n): NormalizedValue<T> & T => {\n let normalizedValues = {} as NormalizedValue<T> & T;\n for (const key in options) {\n if (Object.prototype.hasOwnProperty.call(options, key)) {\n const element = options[key];\n const newOptions =\n typeof element !== \"string\" || element === \"\"\n ? { [key]: element }\n : normalizeValue(key, element);\n\n normalizedValues = {\n ...normalizedValues,\n ...newOptions,\n };\n }\n }\n return normalizedValues;\n};\n", "/**\n * KOS project and model configuration utilities.\n *\n * Reads and writes .kos.json files through CodegenFileSystem.\n * Ported from kos-nx-plugin/src/utils/project-utils.ts.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"./codegen-filesystem\";\nimport {\n findProjectByName,\n findProjectForPath,\n type ProjectConfiguration,\n} from \"./project-discovery\";\nimport { readJson, updateJson } from \"./json-utils\";\nimport { dashCase } from \"./name-utils\";\nimport { getCodegenLogger } from \"./logger\";\n\nexport interface KosModelConfiguration {\n name: string;\n type: string;\n singleton: boolean;\n container?: boolean;\n}\n\nexport interface KosProjectConfiguration {\n name: string;\n type: string;\n version: string;\n models: Record<string, KosModelConfiguration>;\n generator?: {\n internal?: boolean;\n defaults?: {\n model?: { folder?: string };\n components?: { folder?: string };\n };\n };\n}\n\nexport function getCurrentDirectoryName(cwd: string): string | undefined {\n return cwd.split(\"/\").pop();\n}\n\n/**\n * Find the project that contains the given working directory.\n */\nexport function getProject(\n codegenFs: CodegenFileSystem,\n cwd: string\n): ProjectConfiguration | undefined {\n return findProjectForPath(codegenFs.root, cwd);\n}\n\n/**\n * Read .kos.json for a project, creating a default if it doesn't exist.\n */\nexport function getKosProjectConfiguration(\n codegenFs: CodegenFileSystem,\n projectName: string,\n projects?: Map<string, ProjectConfiguration>\n): KosProjectConfiguration | undefined {\n const project = findProjectByName(codegenFs.root, projectName, projects);\n if (!project) return undefined;\n\n const configPath = path.join(project.root, \".kos.json\");\n if (!codegenFs.exists(configPath)) {\n const defaultConfig: KosProjectConfiguration = {\n name: `${dashCase(projectName)}-model`,\n type: \"kos.model\",\n version: \"0.1.0\",\n models: {},\n generator: { defaults: { model: { folder: \"\" } } },\n };\n codegenFs.write(configPath, JSON.stringify(defaultConfig, null, 2));\n }\n\n const content = codegenFs.read(configPath);\n return content ? JSON.parse(content) : undefined;\n}\n\n/**\n * Read a specific model's configuration from .kos.json.\n */\nexport function getKosModelConfiguration(\n codegenFs: CodegenFileSystem,\n projectName: string,\n modelName: string,\n projects?: Map<string, ProjectConfiguration>\n): KosModelConfiguration | undefined {\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n projectName,\n projects\n );\n return kosConfig?.models?.[modelName];\n}\n\n/**\n * Read a specific property from a model's configuration.\n */\nexport function getKosModelConfigProp(params: {\n codegenFs: CodegenFileSystem;\n project: string;\n modelName: string;\n prop: string;\n projects?: Map<string, ProjectConfiguration>;\n}): any {\n const config = getKosModelConfiguration(\n params.codegenFs,\n params.project,\n params.modelName,\n params.projects\n );\n return config ? (config as any)[params.prop] : undefined;\n}\n\n/**\n * Add a model entry to a project's .kos.json.\n */\nexport function addKosModelConfiguration(params: {\n codegenFs: CodegenFileSystem;\n projectName: string;\n projectRoot: string;\n modelName: string;\n singleton: boolean;\n container?: boolean;\n}): void {\n const logger = getCodegenLogger();\n const kosConfigPath = path.join(params.projectRoot, \".kos.json\");\n\n if (!params.codegenFs.exists(kosConfigPath)) {\n logger.info(`Creating .kos.json in ${params.projectRoot}`);\n const defaultConfig = {\n name: params.projectName,\n type: \"kos.model\",\n version: \"0.1.0\",\n models: {},\n generator: { defaults: { model: { folder: \"\" } } },\n };\n params.codegenFs.write(\n kosConfigPath,\n JSON.stringify(defaultConfig, null, 2) + \"\\n\"\n );\n }\n\n updateJson(params.codegenFs, kosConfigPath, (json: any) => {\n json.models = {\n ...json.models,\n [params.modelName]: {\n name: params.modelName,\n type: `${params.modelName}-model`,\n singleton: !!params.singleton,\n container: !!params.container,\n },\n };\n return json;\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 * Option normalization for the add-future-to-model generator.\n *\n * Resolves project configuration, computes name case variants,\n * and determines file paths for model, services, and registration files.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../project-discovery\";\nimport { getKosProjectConfiguration } from \"../../kos-config\";\nimport { normalizeAllValues } from \"../../normalize-values\";\nimport type {\n AddFutureToModelOptions,\n NormalizedAddFutureToModelOptions,\n} from \"./types\";\n\nexport function normalizeAddFutureOptions(\n codegenFs: CodegenFileSystem,\n options: AddFutureToModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): NormalizedAddFutureToModelOptions {\n const projectConfiguration = findProjectByName(\n codegenFs.root,\n options.modelProject,\n projects\n );\n\n if (!projectConfiguration) {\n throw new Error(\n `Project not found: ${options.modelProject}. Ensure a project.json exists for this project.`\n );\n }\n\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n options.modelProject,\n projects\n );\n const internal = !!kosConfig?.generator?.internal;\n\n // Normalize name variations\n const normalizedValues = normalizeAllValues({\n modelName: options.modelName,\n });\n\n const nameDashCase = normalizedValues.modelNameDashCase;\n const nameProperCase = normalizedValues.modelNameProperCase;\n const nameCamelCase = normalizedValues.modelNameCamelCase;\n const namePascalCase = normalizedValues.modelNamePascalCase;\n const nameConstantCase = normalizedValues.modelNameConstantCase;\n const nameLowerCase = normalizedValues.modelNameLowerCase;\n\n const projectRoot = projectConfiguration.root;\n const sourceRoot =\n projectConfiguration.sourceRoot || path.join(projectRoot, \"src\");\n\n // Determine model file path\n const modelLocation = kosConfig?.generator?.defaults?.model?.folder || \"\";\n const modelDirectory = path.join(sourceRoot, modelLocation, nameDashCase);\n const modelFilePath = path.join(modelDirectory, `${nameDashCase}-model.ts`);\n\n // Determine services file path\n const servicesDirectory = path.join(modelDirectory, \"services\");\n const servicesFilePath = codegenFs.exists(servicesDirectory)\n ? path.join(servicesDirectory, `${nameDashCase}-services.ts`)\n : undefined;\n\n // Determine registration file path\n const registrationFilePath = path.join(\n modelDirectory,\n `${nameDashCase}-registration.ts`\n );\n\n return {\n ...options,\n nameDashCase,\n nameProperCase,\n nameCamelCase,\n namePascalCase,\n nameConstantCase,\n nameLowerCase,\n projectRoot,\n sourceRoot,\n modelFilePath,\n servicesFilePath,\n registrationFilePath: codegenFs.exists(registrationFilePath)\n ? registrationFilePath\n : undefined,\n internal,\n };\n}\n", "/**\n * Transformer that updates existing models to use the new @kosFutureAware\n * decorator pattern with TypeScript interface merging for type safety.\n *\n * Ported from kos-nx-plugin to use CodegenFileSystem instead of Nx Tree.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\n\nexport class ModelFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n transform(): void {\n const { modelFilePath } = this.options;\n\n if (!this.codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n let content = this.codegenFs.read(modelFilePath)!;\n\n content = this.addESLintDisable(content);\n content = this.addImports(content);\n content = this.addServiceImport(content);\n content = this.addInterfaceMerging(content);\n content = this.addDecorator(content);\n content = this.updatePublicType(content);\n content = this.removeLegacySetup(content);\n content = this.addFutureMethod(content);\n\n if (this.options.futureType === \"complete\") {\n content = this.addOnFutureUpdateMethod(content);\n }\n\n this.codegenFs.write(modelFilePath, content);\n }\n\n private addESLintDisable(content: string): string {\n // Check if ESLint disable comment already exists\n if (content.includes(\"@typescript-eslint/no-unsafe-declaration-merging\")) {\n return content;\n }\n\n // Add the ESLint disable comment at the top of the file\n const eslintDisable =\n \"/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */\\n\";\n return eslintDisable + content;\n }\n\n private addImports(content: string): string {\n const { internal, futureType } = this.options;\n const isComplete = futureType === \"complete\";\n\n // Find the kosModel import line\n const kosModelImportRegex = internal\n ? /import\\s*{\\s*([^}]*kosModel[^}]*)\\s*}\\s*from\\s*\"\\.\\.\\/\\.\\.\\/\\.\\.\\/core\\/core\\/decorators\"/\n : /import\\s*{\\s*([^}]*kosModel[^}]*)\\s*}\\s*from\\s*\"@kosdev-code\\/kos-ui-sdk\"/;\n\n const kosModelMatch = content.match(kosModelImportRegex);\n if (kosModelMatch) {\n const existingImportsStr = kosModelMatch[1] || \"\";\n const newImports = [\n \"kosFuture\",\n \"kosFutureAware\",\n isComplete ? \"KosFutureAwareFull\" : \"KosFutureAwareMinimal\",\n ];\n\n // Parse existing imports and add new ones\n const existingImports = existingImportsStr\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n // Remove old setup functions if they exist\n const importsToRemove = [\n \"setupCompleteFutureSupport\",\n \"setupMinimalFutureSupport\",\n ];\n\n const cleanedImports = existingImports.filter(\n (imp) => !importsToRemove.includes(imp)\n );\n\n // Only add imports that don't already exist\n const importsToAdd = newImports.filter(\n (imp) => !cleanedImports.includes(imp)\n );\n const allImports = [...cleanedImports, ...importsToAdd];\n\n const newImportLine = internal\n ? `import { ${allImports.join(\n \", \"\n )} } from \"../../../core/core/decorators\"`\n : `import { ${allImports.join(\", \")} } from \"@kosdev-code/kos-ui-sdk\"`;\n\n content = content.replace(kosModelImportRegex, newImportLine);\n }\n\n // Add type imports\n const typeImportsBase = internal\n ? \"../../../models/types/future-interfaces\"\n : \"@kosdev-code/kos-ui-sdk\";\n\n const futureTypeImports = [\"ExternalFutureInterface\", \"IFutureModel\"];\n\n // Find existing type import or add new one\n const typeImportRegex = internal\n ? /import type {([^}]*)} from \"\\.\\.\\/\\.\\.\\/\\.\\.\\/models\\/types\\/future-interfaces\"/\n : /import type {([^}]*)} from \"@kosdev-code\\/kos-ui-sdk\"/;\n\n const typeImportMatch = content.match(typeImportRegex);\n if (typeImportMatch) {\n // Update existing import\n const existingTypes = typeImportMatch[1] || \"\";\n const existingTypesList = existingTypes\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n // Remove old types that are no longer needed\n const typesToRemove = [\n \"FutureAwareContainer\",\n \"FutureHandlerContainer\",\n \"FutureStateAccessor\",\n \"FutureUpdateHandler\",\n ];\n\n const cleanedTypes = existingTypesList.filter(\n (type) => !typesToRemove.includes(type)\n );\n\n const typesToAdd = futureTypeImports.filter(\n (type) => !cleanedTypes.includes(type)\n );\n\n const allTypes = [...cleanedTypes, ...typesToAdd].join(\", \");\n\n const newTypeImport = `import type { ${allTypes} } from \"${typeImportsBase}\"`;\n content = content.replace(typeImportRegex, newTypeImport);\n } else {\n // Add new type import after other imports\n const importLines = content.split(\"\\n\");\n const lastImportIndex = importLines.findLastIndex((line) =>\n line.trim().startsWith(\"import\")\n );\n\n if (lastImportIndex >= 0) {\n const newTypeImport = `import type { ${futureTypeImports.join(\n \", \"\n )} } from \"${typeImportsBase}\";`;\n importLines.splice(lastImportIndex + 1, 0, newTypeImport);\n content = importLines.join(\"\\n\");\n }\n }\n\n return content;\n }\n\n private addServiceImport(content: string): string {\n const { nameProperCase, updateServices } = this.options;\n\n // If updateServices is false, we don't need to import the progress type\n if (!updateServices) {\n return content;\n }\n\n // Check if progress type is already imported\n if (content.includes(`${nameProperCase}OperationProgress`)) {\n return content;\n }\n\n // Look for existing \"./services\" import\n const servicesImportRegex =\n /import\\s*{([^}]*)}\\s*from\\s*[\"']\\.\\/services[\"'];?/s;\n const servicesMatch = content.match(servicesImportRegex);\n\n if (servicesMatch) {\n // Add to existing services import\n const existingImports = servicesMatch[1];\n const cleanedImports = existingImports\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n cleanedImports.push(`${nameProperCase}OperationProgress`);\n\n const newImport = `import { ${cleanedImports.join(\n \", \"\n )} } from \"./services\";`;\n content = content.replace(servicesImportRegex, newImport);\n } else {\n // Add new services import after types import\n const typesImportRegex =\n /import\\s+type\\s+{[^}]*}\\s+from\\s+[\"']\\.\\/types[\"'];?/;\n const typesMatch = content.match(typesImportRegex);\n\n if (typesMatch) {\n const newImport = `\\nimport type { ${nameProperCase}OperationProgress } from \"./services\";`;\n content = content.replace(typesMatch[0], typesMatch[0] + newImport);\n }\n }\n\n return content;\n }\n\n private addInterfaceMerging(content: string): string {\n const { nameProperCase, futureType } = this.options;\n const isComplete = futureType === \"complete\";\n const interfaceType = isComplete\n ? \"KosFutureAwareFull\"\n : \"KosFutureAwareMinimal\";\n const progressType = this.options.updateServices\n ? `${nameProperCase}OperationProgress`\n : \"Record<string, unknown>\";\n\n // Find the class declaration\n const classRegex = new RegExp(\n `(@kosModel[^\\\\n]*\\\\n)([^\\\\n]*export\\\\s+class\\\\s+${nameProperCase}ModelImpl)`,\n \"m\"\n );\n\n const classMatch = content.match(classRegex);\n if (classMatch) {\n // Check if interface merging already exists\n const interfaceRegex = new RegExp(\n `interface\\\\s+${nameProperCase}ModelImpl\\\\s+extends`\n );\n\n if (!content.match(interfaceRegex)) {\n // Add interface merging before the class declaration\n const interfaceMerging = `\\n// Interface merging for Future Container type safety\\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\\nexport interface ${nameProperCase}ModelImpl extends ${interfaceType}<${progressType}> {}\\n\\n`;\n\n content = content.replace(\n classMatch[0],\n interfaceMerging + classMatch[0]\n );\n }\n }\n\n return content;\n }\n\n private addDecorator(content: string): string {\n const { nameProperCase, futureType } = this.options;\n const isComplete = futureType === \"complete\";\n\n // Find the class declaration with existing decorators\n const classRegex = new RegExp(\n `(@kosModel[^\\\\n]*\\\\n)((?:@[^\\\\n]*\\\\n)*)([^\\\\n]*export\\\\s+class\\\\s+${nameProperCase}ModelImpl)`,\n \"m\"\n );\n\n const classMatch = content.match(classRegex);\n if (classMatch) {\n // Check if @kosFutureAware already exists\n if (!classMatch[2].includes(\"@kosFutureAware\")) {\n const decoratorOptions = isComplete ? \"\" : \"{ mode: 'minimal' }\";\n const futureDecorator = `@kosFutureAware(${decoratorOptions})\\n`;\n\n content = content.replace(\n classMatch[0],\n classMatch[1] + classMatch[2] + futureDecorator + classMatch[3]\n );\n }\n }\n\n return content;\n }\n\n private updatePublicType(content: string): string {\n const { nameProperCase, updateServices } = this.options;\n const progressType = updateServices\n ? `${nameProperCase}OperationProgress`\n : \"Record<string, unknown>\";\n\n // Find the public type declaration\n const typeRegex = new RegExp(\n `export\\\\s+type\\\\s+${nameProperCase}Model\\\\s*=\\\\s*PublicModelInterface<${nameProperCase}ModelImpl>([^;]*);`,\n \"s\"\n );\n\n const typeMatch = content.match(typeRegex);\n if (typeMatch) {\n // Check if ExternalFutureInterface is already added\n if (!typeMatch[1].includes(\"ExternalFutureInterface\")) {\n const newType = `export type ${nameProperCase}Model = PublicModelInterface<${nameProperCase}ModelImpl> & ExternalFutureInterface<${progressType}>;`;\n content = content.replace(typeMatch[0], newType);\n }\n }\n\n return content;\n }\n\n private removeLegacySetup(content: string): string {\n // Remove old setup function calls from constructor\n const setupRegex = /\\s*setup(Complete|Minimal)FutureSupport\\(this\\);?\\s*/g;\n content = content.replace(setupRegex, \"\");\n\n // Remove old property declarations\n const propertyRegex =\n /\\s*(public|private|protected)?\\s*(declare\\s+)?futureHandler[!?]?:\\s*FutureAwareContainer[^;]*;\\s*/g;\n content = content.replace(propertyRegex, \"\");\n\n const futurePropertyRegex =\n /\\s*(public|private|protected)?\\s*(declare\\s+)?future\\??:\\s*IFutureModel[^;]*;\\s*/g;\n content = content.replace(futurePropertyRegex, \"\");\n\n // Remove old interface implementations\n const implementsRegex = new RegExp(\n `(implements\\\\s+[^{]*?)\\\\s*,?\\\\s*(FutureUpdateHandler|FutureHandlerContainer|FutureStateAccessor)`,\n \"g\"\n );\n content = content.replace(implementsRegex, \"$1\");\n\n // Clean up duplicate commas in implements clause\n content = content.replace(/,\\s*,/g, \",\");\n content = content.replace(/implements\\s*,/g, \"implements\");\n\n return content;\n }\n\n private addFutureMethod(content: string): string {\n const { nameProperCase } = this.options;\n\n // Check if a @kosFuture method already exists\n if (content.includes(\"@kosFuture()\")) {\n return content;\n }\n\n // Find the end of the class to add the method\n const classRegex = new RegExp(\n `class\\\\s+${nameProperCase}ModelImpl[^{]*{([\\\\s\\\\S]*)}\\\\s*$`,\n \"m\"\n );\n\n const classMatch = content.match(classRegex);\n if (classMatch) {\n const methodCode = `\n /**\n * Placeholder method for Future operations\n * Replace this with your actual long-running operation\n */\n @kosFuture()\n async performLongRunningOperation(): Promise<void> {\n // TODO: Implement your long-running operation here\n // This method should use a service that returns a Future for progress tracking\n\n this.logger.debug(\\`Starting long-running operation for \\${this.id}\\`);\n\n // Example implementation pattern using services:\n // import { perform${nameProperCase}Operation } from './services';\n //\n // const future = await perform${nameProperCase}Operation();\n // return this.futureHandler.setFuture(future);\n\n // Placeholder that doesn't actually do anything\n await new Promise(resolve => setTimeout(resolve, 1000));\n\n this.logger.debug(\\`Completed long-running operation for \\${this.id}\\`);\n }\n`;\n\n // Insert before the closing brace\n const classContent = classMatch[1];\n const lastBraceIndex = classContent.lastIndexOf(\"}\");\n\n if (lastBraceIndex >= 0) {\n const updatedContent =\n classContent.slice(0, lastBraceIndex) +\n methodCode +\n classContent.slice(lastBraceIndex);\n\n content = content.replace(\n classMatch[0],\n `class ${nameProperCase}ModelImpl${\n classMatch[0].match(/[^{]*/)?.[0]\n }{${updatedContent}}`\n );\n }\n }\n\n return content;\n }\n\n private addOnFutureUpdateMethod(content: string): string {\n const { nameProperCase, updateServices } = this.options;\n const progressType = updateServices\n ? `${nameProperCase}OperationProgress`\n : \"Record<string, unknown>\";\n\n // Check if onFutureUpdate already exists\n if (content.includes(\"onFutureUpdate\")) {\n return content;\n }\n\n // Find a good place to add the method (after performLongRunningOperation if it exists)\n const futureMethodRegex = /@kosFuture\\(\\)[^}]*}/s;\n const futureMethodMatch = content.match(futureMethodRegex);\n\n if (futureMethodMatch) {\n const methodCode = `\n\n /**\n * Optional: Custom Future update handling\n * Called whenever the Future state changes (progress, status, completion, etc.)\n */\n onFutureUpdate?(update: IFutureModel<${progressType}>): void {\n // Add custom Future update logic here\n // Examples:\n // - Log progress milestones\n // - Update derived state based on progress\n // - Handle specific error conditions\n // - Trigger notifications at certain thresholds\n\n this.logger.debug(\\`Future update for \\${this.id}:\\`, {\n progress: update.progress,\n status: update.status,\n endState: update.endState,\n clientData: update.clientData\n });\n }`;\n\n content = content.replace(\n futureMethodMatch[0],\n futureMethodMatch[0] + methodCode\n );\n }\n\n return content;\n }\n}\n", "/**\n * Transformer that updates or creates service files with Future operation support.\n *\n * Adds FutureResponse imports, a placeholder future service function,\n * and progress/result type definitions.\n *\n * Ported from kos-nx-plugin to use CodegenFileSystem instead of Nx Tree.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\n\nexport class ServiceFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n transform(): void {\n const { servicesFilePath } = this.options;\n\n if (!servicesFilePath || !this.codegenFs.exists(servicesFilePath)) {\n // Create services file if it doesn't exist\n this.createServicesFile();\n return;\n }\n\n let content = this.codegenFs.read(servicesFilePath)!;\n\n content = this.addFutureImports(content);\n content = this.addFutureService(content);\n content = this.addProgressTypes(content);\n\n this.codegenFs.write(servicesFilePath, content);\n }\n\n private createServicesFile(): void {\n const { servicesFilePath, nameProperCase, nameDashCase, nameLowerCase } =\n this.options;\n\n if (!servicesFilePath) {\n return;\n }\n\n const content = `import {\n KosLog,\n type ClientResponse,\n type DeepRequired,\n type ElementType,\n type ServiceResponse,\n type FutureResponse\n} from '@kosdev-code/kos-ui-sdk';\n\nimport API, { type KosApi, type ApiPath } from '../../../utils/service';\n\nconst log = KosLog.createLogger({name: \"${nameDashCase}-service\", group: \"Services\"});\n\nconst SERVICE_PATH: ApiPath = \"ENTER_SERVICE_PATH\"\nexport type ${nameProperCase}ClientResponse = ClientResponse<\n KosApi,\n typeof SERVICE_PATH,\n 'get'\n>;\nexport type ${nameProperCase}Response = DeepRequired<${nameProperCase}ClientResponse>;\n\n/**\n * @category Service\n * Retrieves the initial ${nameLowerCase} data.\n */\nexport const get${nameProperCase} = async (): Promise<ServiceResponse<${nameProperCase}Response>> => {\n log.debug('sending GET for ${nameLowerCase}');\n return await API.get(SERVICE_PATH);\n};\n\n/**\n * @category Service - Future Operation\n * Placeholder for a long-running operation that returns a Future for progress tracking\n *\n * Replace this with your actual long-running service operation\n */\nexport const perform${nameProperCase}Operation = async (): Promise<FutureResponse> => {\n // TODO: Implement your long-running service operation here\n // This should return a Future that can be tracked for progress\n\n log.debug('starting long-running ${nameLowerCase} operation');\n\n // Example pattern:\n // return API.post(OPERATION_SERVICE_PATH, {\n // // operation parameters\n // });\n\n // Placeholder - replace with actual implementation\n throw new Error('perform${nameProperCase}Operation not yet implemented');\n};\n\n// Additional Future-aware service types (add as needed)\nexport type ${nameProperCase}OperationProgress = {\n // Define your progress data structure here\n stage: string;\n percentComplete: number;\n currentItem?: string;\n totalItems?: number;\n};\n\nexport type ${nameProperCase}OperationResult = {\n // Define your operation result structure here\n success: boolean;\n message?: string;\n data?: any;\n};\n`;\n\n this.codegenFs.write(servicesFilePath, content);\n }\n\n private addFutureImports(content: string): string {\n // Check if FutureResponse is already imported\n if (content.includes(\"FutureResponse\")) {\n return content;\n }\n\n // Add FutureResponse to existing import\n const importRegex =\n /import {\\s*([^}]*)\\s*} from '@kosdev-code\\/kos-ui-sdk';/;\n const importMatch = content.match(importRegex);\n\n if (importMatch) {\n const existingImports = importMatch[1];\n if (existingImports.includes(\"FutureResponse\")) {\n return content; // Already imported\n }\n\n // Clean up existing imports and add FutureResponse\n const cleanedImports = existingImports.trim().replace(/,\\s*$/, \"\"); // Remove trailing comma\n const newImports = cleanedImports\n ? `${cleanedImports},\\n type FutureResponse`\n : `type FutureResponse`;\n\n const newImportStatement = `import {\\n ${newImports}\\n} from '@kosdev-code/kos-ui-sdk';`;\n return content.replace(importMatch[0], newImportStatement);\n }\n\n return content;\n }\n\n private addFutureService(content: string): string {\n const { nameProperCase, nameLowerCase } = this.options;\n\n // Check if Future service already exists\n if (content.includes(`perform${nameProperCase}Operation`)) {\n return content;\n }\n\n const futureService = `\n/**\n * @category Service - Future Operation\n * Placeholder for a long-running operation that returns a Future for progress tracking\n *\n * Replace this with your actual long-running service operation\n */\nexport const perform${nameProperCase}Operation = async (): Promise<FutureResponse> => {\n // TODO: Implement your long-running service operation here\n // This should return a Future that can be tracked for progress\n\n log.debug('starting long-running ${nameLowerCase} operation');\n\n // Example pattern:\n // return API.post(OPERATION_SERVICE_PATH, {\n // // operation parameters\n // });\n\n // Placeholder - replace with actual implementation\n throw new Error('perform${nameProperCase}Operation not yet implemented');\n};`;\n\n // Add at the end of the file\n return content + \"\\n\" + futureService;\n }\n\n private addProgressTypes(content: string): string {\n const { nameProperCase } = this.options;\n\n // Check if progress types already exist\n if (content.includes(`${nameProperCase}OperationProgress`)) {\n return content;\n }\n\n const progressTypes = `\n// Additional Future-aware service types (add as needed)\nexport type ${nameProperCase}OperationProgress = {\n // Define your progress data structure here\n stage: string;\n percentComplete: number;\n currentItem?: string;\n totalItems?: number;\n};\n\nexport type ${nameProperCase}OperationResult = {\n // Define your operation result structure here\n success: boolean;\n message?: string;\n data?: any;\n};`;\n\n // Add at the end of the file\n return content + \"\\n\" + progressTypes;\n }\n}\n", "/**\n * Transformer that updates registration files to support Future-enabled models.\n *\n * Adds type casts and documentation for Future capabilities.\n *\n * Ported from kos-nx-plugin to use CodegenFileSystem instead of Nx Tree.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport { getCodegenLogger } from \"../../logger\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\n\nexport class RegistrationFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n transform(): void {\n const logger = getCodegenLogger();\n const { registrationFilePath } = this.options;\n\n if (\n !registrationFilePath ||\n !this.codegenFs.exists(registrationFilePath)\n ) {\n logger.warn(\n \"Registration file not found, skipping registration updates\"\n );\n return;\n }\n\n let content = this.codegenFs.read(registrationFilePath)!;\n\n content = this.addTypeCast(content);\n content = this.updateDocumentation(content);\n\n this.codegenFs.write(registrationFilePath, content);\n }\n\n private addTypeCast(content: string): string {\n const { nameProperCase } = this.options;\n\n // Find the registration factory instantiation and add type cast\n const factoryRegex = new RegExp(`class: ${nameProperCase}ModelImpl,`);\n\n const replacement = `class: ${nameProperCase}ModelImpl as any, // Type cast needed for Future intersection`;\n\n return content.replace(factoryRegex, replacement);\n }\n\n private updateDocumentation(content: string): string {\n const { nameProperCase, futureType } = this.options;\n\n // Add Future support documentation after the main description\n const descriptionRegex = new RegExp(\n `(\\\\* The registration bean includes convenience methods for creating and working with ${nameProperCase}Model instances\\\\.)`\n );\n\n const futureDocumentation = `$1\n *\n * ## Future Support\n * This model includes ${futureType} Future support for tracking long-running operations with:\n * - Progress tracking (0-1) with reactive updates\n * - Status messages during operation\n * - Cancellation support with bi-directional AbortController integration\n * - Reactive integration for UI updates${\n futureType === \"complete\"\n ? \"\\n * - Internal access to Future state for custom logic and computed properties\"\n : \"\"\n }`;\n\n if (content.match(descriptionRegex)) {\n content = content.replace(descriptionRegex, futureDocumentation);\n }\n\n // Add Future usage examples to factory documentation\n const factoryExampleRegex = /(\\*\\s+\\}\\);?\\s*\\*\\s+```)/;\n\n const futureExample = `$1\n *\n * // Example: Accessing Future state (when a Future is active)\n * const isRunning = model.futureIsRunning;\n * const progress = model.futureProgress; // 0-1\n * const status = model.futureStatus; // Current status message\n * \\`\\`\\``;\n\n if (content.match(factoryExampleRegex)) {\n content = content.replace(factoryExampleRegex, futureExample);\n }\n\n // Add Future capabilities to predicate examples\n const predicateExampleRegex =\n /(\\*\\s+model\\.updateAvailability\\(false\\);?\\s*\\*\\s+\\})/;\n\n const predicateFutureExample = `$1\n *\n * // Future capabilities are also available\n * const isRunning = model.futureIsRunning;\n * const progress = model.futureProgress;\n * }`;\n\n if (content.match(predicateExampleRegex)) {\n content = content.replace(predicateExampleRegex, predicateFutureExample);\n }\n\n return content;\n }\n}\n", "/**\n * Framework-agnostic core logic for the add-future-to-model generator.\n *\n * Adds Future (long-running operation) support to an existing KOS model\n * by transforming model, service, and registration files. Works through\n * the CodegenFileSystem abstraction so it can run in any environment\n * (CLI, VS Code, Nx).\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { normalizeAddFutureOptions } from \"./normalize-options\";\nimport { ModelFileTransformer } from \"./model-transformer\";\nimport { ServiceFileTransformer } from \"./service-transformer\";\nimport { RegistrationFileTransformer } from \"./registration-transformer\";\nimport type { AddFutureToModelOptions } from \"./types\";\n\nexport function addFutureToModel(\n codegenFs: CodegenFileSystem,\n options: AddFutureToModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n const logger = getCodegenLogger();\n const normalized = normalizeAddFutureOptions(codegenFs, options, projects);\n\n logger.info(\n `Adding ${normalized.futureType} Future support to model: ${normalized.modelName}`\n );\n\n // Validate that model file exists\n if (!codegenFs.exists(normalized.modelFilePath)) {\n throw new Error(`Model file not found: ${normalized.modelFilePath}`);\n }\n\n if (options.dryRun) {\n logger.info(\"DRY RUN - No files will be modified\");\n logger.info(`Would modify model file: ${normalized.modelFilePath}`);\n if (normalized.servicesFilePath) {\n logger.info(\n `Would modify/create services file: ${normalized.servicesFilePath}`\n );\n }\n if (normalized.registrationFilePath) {\n logger.info(\n `Would modify registration file: ${normalized.registrationFilePath}`\n );\n }\n return;\n }\n\n try {\n // Transform model file\n logger.info(`Transforming model file: ${normalized.modelFilePath}`);\n const modelTransformer = new ModelFileTransformer(codegenFs, normalized);\n modelTransformer.transform();\n\n // Transform or create services file\n if (normalized.updateServices) {\n logger.info(\n `Transforming services file: ${\n normalized.servicesFilePath || \"creating new\"\n }`\n );\n const serviceTransformer = new ServiceFileTransformer(\n codegenFs,\n normalized\n );\n serviceTransformer.transform();\n }\n\n // Transform registration file\n if (normalized.registrationFilePath) {\n logger.info(\n `Transforming registration file: ${normalized.registrationFilePath}`\n );\n const registrationTransformer = new RegistrationFileTransformer(\n codegenFs,\n normalized\n );\n registrationTransformer.transform();\n }\n\n logger.info(\n `Successfully added ${normalized.futureType} Future support to ${normalized.modelName}`\n );\n logger.info(\"\");\n logger.info(\"Next steps:\");\n logger.info(\n \"1. Review the generated @kosFuture method and implement your actual operation\"\n );\n logger.info(\n \"2. Update the service method to return a proper FutureResponse\"\n );\n logger.info(\"3. Define your specific progress and result types\");\n if (normalized.futureType === \"complete\") {\n logger.info(\n \"4. Customize the onFutureUpdate method for your specific needs\"\n );\n }\n } catch (error) {\n logger.error(`Failed to add Future support: ${error}`);\n throw error;\n }\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", "// utils/prompts.mjs\n\nexport const DEFAULT_PROMPTS = [\n {\n type: \"confirm\",\n name: \"interactive\",\n message: \"Use interactive mode?\",\n default: false,\n when: false,\n },\n {\n type: \"confirm\",\n name: \"dryRun\",\n message: \"Dry run the command?\",\n default: false,\n when: false,\n },\n];\n\nexport const MODEL_PROMPTS = [\n {\n type: \"confirm\",\n name: \"container\",\n message: \"Requires container model?\",\n default: false,\n },\n {\n type: \"confirm\",\n name: \"parentAware\",\n message: \"Aware of parent container?\",\n default: false,\n },\n {\n type: \"confirm\",\n name: \"singleton\",\n message: \"Is singleton?\",\n default: false,\n },\n {\n type: \"confirm\",\n name: \"dataServices\",\n message: \"Create data services?\",\n default: true,\n },\n {\n type: \"list\",\n name: \"futureAware\",\n message: \"Include Future-aware capabilities?\",\n choices: [\n { name: \"No Future support\", value: \"none\" },\n { name: \"Minimal (external access only)\", value: \"minimal\" },\n { name: \"Complete (internal + external access)\", value: \"complete\" },\n ],\n default: \"none\",\n },\n];\n\nexport const COMPANION_PROMPTS = [\n {\n type: \"list\",\n name: \"companionPattern\",\n message: \"Which companion pattern to use?\",\n choices: [\n {\n name: \"Composition (recommended) - explicit parent access via this.parent\",\n value: \"composition\",\n },\n {\n name: \"Decorator - transparent parent access, drop-in replacement\",\n value: \"decorator\",\n },\n ],\n default: \"composition\",\n },\n];\n", "// generators/model/add-future.mjs\nimport { actionFactory } from \"../../utils/action-factory.mjs\";\nimport { getAllModels } from \"../../utils/nx-context.mjs\";\nimport { DEFAULT_PROMPTS } from \"../../utils/prompts.mjs\";\nimport { DirectFileSystem, addFutureToModel } from \"@kosdev-code/kos-codegen-core\";\n\nexport const metadata = {\n key: \"add-future\",\n name: \"Add Future Support to Model\",\n invalidateCache: true,\n namedArguments: {\n modelName: \"modelName\",\n project: \"modelProject\",\n modelProject: \"modelProject\",\n futureType: \"futureType\",\n updateServices: \"updateServices\",\n dryRun: \"dryRun\",\n interactive: \"interactive\",\n },\n};\n\nexport default async function (plop) {\n // Check if we're in interactive mode by looking at process args\n const isInteractive = process.argv.includes('-i') || process.argv.includes('--interactive');\n \n // For interactive mode, use lazy loading. For non-interactive, load immediately.\n let modelChoices;\n if (isInteractive) {\n modelChoices = async () => {\n const allModels = await getAllModels();\n return allModels.map((m) => ({\n name: `${m.model} (${m.project})`,\n value: m.model,\n }));\n };\n } else {\n const allModels = await getAllModels();\n modelChoices = allModels.map((m) => ({\n name: `${m.model} (${m.project})`,\n value: m.model,\n }));\n }\n\n plop.setActionType(\"addFutureToModel\", async function (answers) {\n const cwd = process.cwd();\n const codegenFs = new DirectFileSystem(cwd);\n\n const allModels = await getAllModels();\n const modelProject = allModels.find((m) => m.model === answers.modelName)?.project;\n\n addFutureToModel(codegenFs, {\n modelName: answers.modelName,\n modelProject: modelProject,\n futureType: answers.futureType,\n updateServices: !!answers.updateServices,\n dryRun: !!answers.dryRun,\n });\n\n return `Future support (${answers.futureType}) added to model ${answers.modelName} in ${modelProject}`;\n });\n\n plop.setGenerator(\"add-future\", {\n description: \"Add Future support to an existing KOS Model\",\n prompts: [\n ...DEFAULT_PROMPTS,\n {\n type: \"list\",\n name: \"modelName\",\n message: \"Which model do you want to add Future support to?\",\n choices: modelChoices,\n },\n {\n type: \"list\",\n name: \"futureType\",\n message: \"What type of Future support?\",\n choices: [\n { name: \"Minimal (external access only)\", value: \"minimal\" },\n { name: \"Complete (internal + external access)\", value: \"complete\" },\n ],\n default: \"minimal\",\n },\n {\n type: \"confirm\",\n name: \"updateServices\",\n message: \"Update/create services file with Future operations?\",\n default: true,\n },\n ],\n\n actions: actionFactory(\"addFutureToModel\", metadata),\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["metadata", "existsSync", "readFileSync", "readdirSync", "path", "fs", "path", "fs", "path", "path", "path", "__dirname", "path", "readdirSync", "path", "existsSync", "readFileSync"]
|
|
7
|
+
}
|