@agimon-ai/doompi-build 0.0.1-alpha.2 → 0.0.1-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants/contributions.cjs +1 -1
- package/dist/constants/contributions.cjs.map +1 -1
- package/dist/constants/contributions.mjs +1 -1
- package/dist/constants/contributions.mjs.map +1 -1
- package/dist/constants/layout.cjs +1 -1
- package/dist/constants/layout.cjs.map +1 -1
- package/dist/constants/layout.d.mts.map +1 -1
- package/dist/constants/layout.mjs +1 -1
- package/dist/constants/layout.mjs.map +1 -1
- package/dist/services/generate/index.cjs +1 -1
- package/dist/services/generate/index.cjs.map +1 -1
- package/dist/services/generate/index.d.mts.map +1 -1
- package/dist/services/generate/index.mjs +1 -1
- package/dist/services/generate/index.mjs.map +1 -1
- package/dist/services/generate/type.d.mts +2 -0
- package/dist/services/generate/type.d.mts.map +1 -1
- package/dist/services/renderClient/index.cjs +1 -1
- package/dist/services/renderClient/index.cjs.map +1 -1
- package/dist/services/renderClient/index.mjs +1 -1
- package/dist/services/renderClient/index.mjs.map +1 -1
- package/dist/services/renderEntry/index.cjs +4 -3
- package/dist/services/renderEntry/index.cjs.map +1 -1
- package/dist/services/renderEntry/index.d.mts.map +1 -1
- package/dist/services/renderEntry/index.mjs +4 -3
- package/dist/services/renderEntry/index.mjs.map +1 -1
- package/dist/services/renderEntry/type.d.mts +2 -0
- package/dist/services/renderEntry/type.d.mts.map +1 -1
- package/dist/services/renderMcpWidgets/index.cjs +3 -0
- package/dist/services/renderMcpWidgets/index.cjs.map +1 -0
- package/dist/services/renderMcpWidgets/index.mjs +3 -0
- package/dist/services/renderMcpWidgets/index.mjs.map +1 -0
- package/dist/services/resolveTarget/index.cjs +1 -1
- package/dist/services/resolveTarget/index.cjs.map +1 -1
- package/dist/services/resolveTarget/index.d.mts.map +1 -1
- package/dist/services/resolveTarget/index.mjs +1 -1
- package/dist/services/resolveTarget/index.mjs.map +1 -1
- package/dist/services/resolveTarget/type.d.mts +2 -2
- package/dist/services/scan/index.cjs +1 -1
- package/dist/services/scan/index.cjs.map +1 -1
- package/dist/services/scan/index.mjs +1 -1
- package/dist/services/scan/index.mjs.map +1 -1
- package/dist/services/syncManifest/index.cjs +1 -1
- package/dist/services/syncManifest/index.cjs.map +1 -1
- package/dist/services/syncManifest/index.d.mts.map +1 -1
- package/dist/services/syncManifest/index.mjs +1 -1
- package/dist/services/syncManifest/index.mjs.map +1 -1
- package/dist/services/tsdownPreset/index.cjs +1 -1
- package/dist/services/tsdownPreset/index.cjs.map +1 -1
- package/dist/services/tsdownPreset/index.d.mts +24 -5
- package/dist/services/tsdownPreset/index.d.mts.map +1 -1
- package/dist/services/tsdownPreset/index.mjs +1 -1
- package/dist/services/tsdownPreset/index.mjs.map +1 -1
- package/package.json +5 -5
- package/dist/browserFile.d.cts +0 -2
- package/dist/constants/layout.d.cts +0 -59
- package/dist/constants/layout.d.cts.map +0 -1
- package/dist/index.d.cts +0 -16
- package/dist/services/browserFile/index.d.cts +0 -28
- package/dist/services/browserFile/index.d.cts.map +0 -1
- package/dist/services/filename/index.d.cts +0 -29
- package/dist/services/filename/index.d.cts.map +0 -1
- package/dist/services/generate/index.d.cts +0 -15
- package/dist/services/generate/index.d.cts.map +0 -1
- package/dist/services/generate/type.d.cts +0 -26
- package/dist/services/generate/type.d.cts.map +0 -1
- package/dist/services/renderEntry/index.d.cts +0 -24
- package/dist/services/renderEntry/index.d.cts.map +0 -1
- package/dist/services/renderEntry/type.d.cts +0 -14
- package/dist/services/renderEntry/type.d.cts.map +0 -1
- package/dist/services/resolveTarget/index.d.cts +0 -16
- package/dist/services/resolveTarget/index.d.cts.map +0 -1
- package/dist/services/resolveTarget/type.d.cts +0 -34
- package/dist/services/resolveTarget/type.d.cts.map +0 -1
- package/dist/services/scan/index.d.cts +0 -19
- package/dist/services/scan/index.d.cts.map +0 -1
- package/dist/services/scan/type.d.cts +0 -25
- package/dist/services/scan/type.d.cts.map +0 -1
- package/dist/services/segments/index.d.cts +0 -26
- package/dist/services/segments/index.d.cts.map +0 -1
- package/dist/services/syncManifest/index.d.cts +0 -21
- package/dist/services/syncManifest/index.d.cts.map +0 -1
- package/dist/services/syncManifest/type.d.cts +0 -15
- package/dist/services/syncManifest/type.d.cts.map +0 -1
- package/dist/services/tsdownPreset/index.d.cts +0 -63
- package/dist/services/tsdownPreset/index.d.cts.map +0 -1
- package/dist/services/writeGenerated/index.d.cts +0 -23
- package/dist/services/writeGenerated/index.d.cts.map +0 -1
- package/dist/tsdown.d.cts +0 -2
- package/dist/types/extensionGraph.d.cts +0 -75
- package/dist/types/extensionGraph.d.cts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["path","fs","toKebab","GENERATED_DIR","generateExtension","writeManifest"],"sources":["../../../src/services/tsdownPreset/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { GENERATED_DIR } from '../../constants/layout';\nimport { generateExtension } from '../generate';\nimport type { GenerateOptions } from '../generate/type';\nimport { toKebab } from '../identity';\nimport { writeManifest } from '../syncManifest';\n\ninterface EmittedFile {\n readonly type: 'asset' | 'chunk';\n readonly id?: string;\n readonly name: string;\n readonly source?: Buffer;\n}\n\ninterface QueryAssetPlugin {\n readonly name: string;\n resolveId(source: string, importer: string | undefined): string | undefined;\n load(this: { emitFile(file: EmittedFile): string }, id: string): string | undefined;\n}\n\n/** The shape a tsdown config needs from this preset, without importing tsdown's types. */\ninterface BrowserPresetConfig {\n entry: Record<string, string>;\n clean: boolean;\n dts: false;\n exports: boolean;\n format: 'esm'[];\n platform: 'browser';\n fixedExtension: boolean;\n external: (id: string) => boolean;\n plugins: QueryAssetPlugin[];\n sourcemap: boolean;\n unbundle: boolean;\n}\n\ninterface PresetConfig {\n entry: Record<string, string>;\n clean: boolean;\n dts: { incremental: boolean; parallel: boolean; eager: boolean };\n exports: boolean;\n format: ('esm' | 'cjs')[];\n platform: 'node';\n sourcemap: boolean;\n unbundle: boolean;\n hooks: { 'build:done': () => void };\n}\n\nconst DEFAULT_EXPORTS_DIR = 'src/exports';\n\n/** `src/exports/apiContracts.ts` becomes the `api-contracts` entry; index keeps its name. */\nfunction exportEntries(packageDir: string, exportsDir: string): Record<string, string> {\n const absolute = path.join(packageDir, exportsDir);\n if (!fs.existsSync(absolute)) return {};\n const entries: Record<string, string> = {};\n for (const file of fs.readdirSync(absolute)) {\n if (!file.endsWith('.ts') || file.endsWith('.d.ts')) continue;\n const stem = file.slice(0, -'.ts'.length);\n entries[stem === 'index' ? 'index' : toKebab(stem)] = `${exportsDir}/${file}`;\n }\n return entries;\n}\n\n/**\n * One tsdown config for a folder-routed extension.\n *\n * Entries come from the tree rather than a hand-written list, and the manifest\n * blocks that restate the tree are written after the build rather than kept in\n * step by hand. Browser contributions are emitted through a second bundled\n * config because their routed source is not published.\n */\nexport interface ExtensionPresetOptions extends GenerateOptions {\n /** Extra tsdown entries beyond the derived ones. */\n readonly entry?: Record<string, string>;\n /** Public export modules, package-relative. Defaults to `src/exports`. */\n readonly exportsDir?: string;\n}\n\n/**\n * Implements the Vite query imports extension browser code already uses.\n *\n * `?url` copies an opaque asset and `?worker&url` emits a separately bundled\n * worker chunk. Rolldown then replaces its file reference with an URL relative\n * to the extension bundle, which remains valid when the cockpit composes it.\n */\nfunction queryAssetPlugin(): QueryAssetPlugin {\n return {\n name: 'doompi-query-assets',\n resolveId(source, importer) {\n const queryAt = source.indexOf('?');\n if (queryAt < 0 || importer === undefined || !source.startsWith('.')) return undefined;\n const importerFile = importer.split('?')[0] as string;\n return `${path.resolve(path.dirname(importerFile), source.slice(0, queryAt))}${source.slice(queryAt)}`;\n },\n load(id) {\n const queryAt = id.indexOf('?');\n if (queryAt < 0) return undefined;\n const file = id.slice(0, queryAt);\n const query = new URLSearchParams(id.slice(queryAt + 1));\n if (!query.has('url')) return undefined;\n const worker = query.has('worker');\n const reference = this.emitFile(\n worker\n ? { type: 'chunk', id: file, name: path.basename(file, path.extname(file)) }\n : { type: 'asset', name: path.basename(file), source: fs.readFileSync(file) },\n );\n return `export default import.meta.ROLLUP_FILE_URL_${reference};`;\n },\n };\n}\n\n/** The separately bundled browser half of a routed extension. */\nfunction browserConfig(): BrowserPresetConfig {\n return {\n entry: { 'extensions/web': `${GENERATED_DIR}/web.ts` },\n clean: false,\n // No declarations. Nothing imports this as a typed module: it has no\n // export subpath, and the cockpit consumes it as a bundle. The browser\n // half is still typechecked, by tsconfig.web.json in the typecheck script.\n dts: false,\n exports: false,\n format: ['esm'],\n platform: 'browser',\n // platform browser turns tsdown's fixedExtension off, which would emit\n // .js. The manifest names .mjs like the other two entries, so ask for it.\n fixedExtension: true,\n // Every bare specifier stays external and the cockpit resolves it, which\n // is what keeps one React and one store in the page no matter how many\n // plugins are installed. An allowlist would have to be kept in step with\n // the cockpit's; this cannot drift.\n //\n // A predicate rather than a pattern: rolldown tests `external` against the\n // resolved id, so /^[^.]/ also matches the absolute path of this package's\n // own routed file and would leave a dangling import to unbuilt .tsx.\n external: (id: string) => !id.startsWith('.') && !path.isAbsolute(id),\n plugins: [queryAssetPlugin()],\n sourcemap: true,\n // Bundled, unlike the node half. Unbundling would emit an import to the\n // routed source file, which is not published and is .tsx besides. One\n // module with only bare specifiers external is what the cockpit wants.\n unbundle: false,\n };\n}\n\nexport function doompiExtension(\n options: ExtensionPresetOptions = { packageDir: process.cwd() },\n): PresetConfig | (PresetConfig | BrowserPresetConfig)[] {\n const packageDir = options.packageDir ?? process.cwd();\n const result = generateExtension({ ...options, packageDir, check: options.check ?? false });\n\n for (const notice of result.notices) process.stderr.write(`[doompi-build] ${notice.path}: ${notice.message}\\n`);\n\n const entry: Record<string, string> = {\n ...exportEntries(packageDir, options.exportsDir ?? DEFAULT_EXPORTS_DIR),\n ...(result.targets.includes('cli') ? { 'extensions/pi': `${GENERATED_DIR}/pi.ts` } : {}),\n ...(result.targets.includes('server') ? { 'extensions/server': `${GENERATED_DIR}/server.ts` } : {}),\n ...options.entry,\n };\n\n const node: PresetConfig = {\n entry,\n clean: true,\n dts: { incremental: true, parallel: false, eager: true },\n exports: true,\n format: ['esm', 'cjs'],\n // No minify. This is a library build, and a mangled stack trace inside a\n // published extension is far more expensive than the bytes it saves.\n // Node output uses fixed extensions, so pi.extensions and doompiServer.dist\n // both land on the .mjs filenames their hosts require.\n platform: 'node',\n sourcemap: true,\n unbundle: true,\n hooks: {\n 'build:done': () =>\n void writeManifest({\n packageDir,\n manifest: JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as Record<\n string,\n unknown\n >,\n graph: result.graph,\n targets: result.targets,\n pluginId: result.pluginId,\n }),\n },\n };\n\n return result.targets.includes('web') ? [node, browserConfig()] : node;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["path","fs","GENERATED_DIR","generateExtension","renderMcpWidgets"],"sources":["../../../src/services/tsdownPreset/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { GENERATED_DIR } from '../../constants/layout';\nimport { generateExtension } from '../generate';\nimport type { GenerateOptions } from '../generate/type';\nimport { renderMcpWidgets } from '../renderMcpWidgets';\nimport { writeManifest, writeMcpManifest } from '../syncManifest';\n\ninterface EmittedFile {\n readonly type: 'asset' | 'chunk';\n readonly id?: string;\n readonly name: string;\n readonly source?: Buffer;\n}\n\ninterface QueryAssetPlugin {\n readonly name: string;\n resolveId(source: string, importer: string | undefined): string | undefined;\n load(this: { emitFile(file: EmittedFile): string }, id: string): string | undefined;\n}\n\n/** The shape a tsdown config needs from this preset, without importing tsdown's types. */\ninterface BrowserPresetConfig {\n entry: Record<string, string>;\n clean: boolean;\n dts: false;\n exports: boolean;\n format: 'esm'[];\n platform: 'browser';\n fixedExtension: boolean;\n external: (id: string) => boolean;\n plugins: QueryAssetPlugin[];\n sourcemap: boolean;\n unbundle: boolean;\n tsconfig: string;\n}\n\ninterface GeneratedExports {\n customExports: (exports: Record<string, unknown>) => Record<string, unknown>;\n}\n\ninterface BasePresetConfig {\n entry: Record<string, string>;\n clean: boolean;\n dts: false | { incremental: boolean; parallel: boolean; eager: boolean };\n write?: false;\n plugins?: QueryAssetPlugin[];\n exports: boolean | GeneratedExports;\n format: { esm: Record<string, never>; cjs: { dts: false } };\n platform: 'node';\n sourcemap: boolean;\n unbundle: boolean;\n outExtensions: ({ format }: { format: string }) => {\n js: string;\n dts: string;\n };\n}\n\ninterface PresetConfig extends BasePresetConfig {\n hooks?: { 'build:done': () => void };\n}\n\nconst DEFAULT_EXPORTS_DIR = 'src/exports';\nconst API_CONTRACTS_ENTRY = 'apiContracts';\n\n/** `src/exports/apiContracts.ts` becomes the `apiContracts` entry; index keeps its name. */\nfunction exportEntries(packageDir: string, exportsDir: string): Record<string, string> {\n const absolute = path.join(packageDir, exportsDir);\n if (!fs.existsSync(absolute)) return {};\n const entries: Record<string, string> = {};\n for (const file of fs.readdirSync(absolute)) {\n if (!file.endsWith('.ts') || file.endsWith('.d.ts')) continue;\n const stem = file.slice(0, -'.ts'.length);\n entries[stem] = `${exportsDir}/${file}`;\n }\n return entries;\n}\n\n/** Static resources receive package export entries without becoming tsdown inputs. */\nfunction resourceEntries(\n packageDir: string,\n directory: string,\n matches: (relative: string) => boolean,\n): Record<string, string> {\n const root = path.join(packageDir, directory);\n if (!fs.existsSync(root)) return {};\n const entries: Record<string, string> = {};\n for (const relative of fs.readdirSync(root, { encoding: 'utf8', recursive: true })) {\n if (!matches(relative)) continue;\n const normalized = relative.split(path.sep).join('/');\n entries[`./${directory}/${normalized}`] = `./${directory}/${normalized}`;\n }\n return entries;\n}\n\n/** Preserves declared resources and discovers default skill and theme resource exports. */\nfunction staticExports(packageDir: string): Record<string, unknown> {\n const manifest = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as Record<\n string,\n unknown\n >;\n const declared =\n manifest.exports !== null && typeof manifest.exports === 'object' && !Array.isArray(manifest.exports)\n ? Object.fromEntries(Object.entries(manifest.exports).filter(([, target]) => typeof target === 'string'))\n : {};\n return {\n ...resourceEntries(packageDir, 'skills', (relative) => path.basename(relative) === 'SKILL.md'),\n ...resourceEntries(packageDir, 'themes', (relative) => relative.endsWith('.json')),\n ...declared,\n };\n}\n/**\n * One tsdown config for a folder-routed extension.\n *\n * Entries come from the tree rather than a hand-written list, and the manifest\n * blocks that restate the tree are written after the build rather than kept in\n * step by hand. Browser contributions are emitted through a second bundled\n * config because their routed source is not published.\n */\nexport interface ExtensionPresetOptions extends GenerateOptions {\n /** Extra tsdown entries beyond the derived ones. */\n readonly entry?: Record<string, string>;\n /** Public export modules, package-relative. Defaults to `src/exports`. */\n readonly exportsDir?: string;\n}\n\n/**\n * Implements the Vite query imports extension browser code already uses.\n *\n * `?url` copies an opaque asset and `?worker&url` emits a separately bundled\n * worker chunk. Rolldown then replaces its file reference with an URL relative\n * to the extension bundle, which remains valid when the cockpit composes it.\n */\nfunction queryAssetPlugin(): QueryAssetPlugin {\n return {\n name: 'doompi-query-assets',\n resolveId(source, importer) {\n const queryAt = source.indexOf('?');\n if (queryAt < 0 || importer === undefined || !source.startsWith('.')) return undefined;\n const importerFile = importer.split('?')[0] as string;\n return `${path.resolve(path.dirname(importerFile), source.slice(0, queryAt))}${source.slice(queryAt)}`;\n },\n load(id) {\n const queryAt = id.indexOf('?');\n if (queryAt < 0) return undefined;\n const file = id.slice(0, queryAt);\n const query = new URLSearchParams(id.slice(queryAt + 1));\n if (!query.has('url')) return undefined;\n const worker = query.has('worker');\n const reference = this.emitFile(\n worker\n ? { type: 'chunk', id: file, name: path.basename(file, path.extname(file)) }\n : { type: 'asset', name: path.basename(file), source: fs.readFileSync(file) },\n );\n return `export default import.meta.ROLLUP_FILE_URL_${reference};`;\n },\n };\n}\n\n/** The separately bundled browser half of a routed extension. */\nfunction browserConfig(target: 'web' | 'mcp-ui' = 'web'): BrowserPresetConfig {\n return {\n entry: { [`extensions/${target}`]: `${GENERATED_DIR}/${target}.ts` },\n clean: false,\n // No declarations. Nothing imports this as a typed module: it has no\n // export subpath, and the cockpit consumes it as a bundle. The browser\n // half is still typechecked, by tsconfig.web.json in the typecheck script.\n dts: false,\n exports: false,\n format: ['esm'],\n platform: 'browser',\n // platform browser turns tsdown's fixedExtension off, which would emit\n // .js. The manifest names .mjs like the other two entries, so ask for it.\n fixedExtension: true,\n // Every bare specifier stays external and the cockpit resolves it, which\n // is what keeps one React and one store in the page no matter how many\n // plugins are installed. An allowlist would have to be kept in step with\n // the cockpit's; this cannot drift.\n //\n // A predicate rather than a pattern: rolldown tests `external` against the\n // resolved id, so /^[^.]/ also matches the absolute path of this package's\n // own routed file and would leave a dangling import to unbuilt .tsx.\n external: (id: string) => !id.startsWith('.') && !path.isAbsolute(id),\n plugins: [queryAssetPlugin()],\n sourcemap: true,\n // Bundled, unlike the node half. Unbundling would emit an import to the\n // routed source file, which is not published and is .tsx besides. One\n // module with only bare specifiers external is what the cockpit wants.\n unbundle: false,\n // Browser routes are excluded from the node tsconfig. Every browser-capable\n // extension owns this focused config for its matching typecheck.\n tsconfig: target === 'web' ? 'tsconfig.web.json' : 'tsconfig.mcp.json',\n };\n}\n\n/** Removes only filenames owned by the isolated MCP build, including obsolete declarations. */\nfunction cleanMcpOutput(packageDir: string): void {\n const dist = path.join(packageDir, 'dist');\n if (!fs.existsSync(dist)) return;\n for (const relative of fs.readdirSync(dist, { recursive: true, encoding: 'utf8' })) {\n const normalized = relative.split(path.sep).join('/');\n if (!/^(?:extensions\\/mcp(?:-ui)?|.+\\.mcp)\\.(?:mjs|cjs|d\\.mts|d\\.cts)(?:\\.map)?$/u.test(normalized)) continue;\n const absolute = path.join(dist, relative);\n if (fs.lstatSync(absolute).isFile()) fs.rmSync(absolute);\n }\n}\n\nexport function doompiExtension(\n options: ExtensionPresetOptions = { packageDir: process.cwd() },\n): PresetConfig | (PresetConfig | BrowserPresetConfig)[] {\n const packageDir = options.packageDir ?? process.cwd();\n const result = generateExtension({ ...options, packageDir, check: options.check ?? false });\n\n for (const notice of result.notices) process.stderr.write(`[doompi-build] ${notice.path}: ${notice.message}\\n`);\n\n const mcpOnly = options.target === 'mcp';\n if (mcpOnly && !options.check) cleanMcpOutput(packageDir);\n const emptyMcp = mcpOnly && !result.targets.includes('mcp');\n const emptyEntry = '\\0doompi-empty-mcp';\n if (emptyMcp && !options.check) writeMcpManifest(packageDir, false);\n const entry: Record<string, string> = mcpOnly\n ? result.targets.includes('mcp')\n ? { 'extensions/mcp': `${GENERATED_DIR}/mcp.ts` }\n : { 'extensions/mcp': emptyEntry }\n : {\n ...exportEntries(packageDir, options.exportsDir ?? DEFAULT_EXPORTS_DIR),\n ...(result.targets.includes('cli') ? { 'extensions/pi': `${GENERATED_DIR}/pi.ts` } : {}),\n ...(result.targets.includes('server') ? { 'extensions/server': `${GENERATED_DIR}/server.ts` } : {}),\n ...options.entry,\n };\n\n const baseNode: Omit<BasePresetConfig, 'entry' | 'unbundle'> = {\n // MCP shares dist/ with the normal build, so neither build may erase the other.\n clean: false,\n dts: emptyMcp ? false : { incremental: true, parallel: false, eager: true },\n // tsdown rejects both an empty entry and an empty config array. A virtual\n // input completes its normal lifecycle without publishing an empty facet.\n ...(emptyMcp\n ? {\n write: false as const,\n plugins: [\n {\n name: 'doompi-empty-mcp',\n resolveId: (source: string) => (source === emptyEntry ? emptyEntry : undefined),\n load: (id: string) => (id === emptyEntry ? 'export {};' : undefined),\n },\n ],\n }\n : {}),\n exports: mcpOnly\n ? false\n : {\n customExports: (generated) => ({ ...staticExports(packageDir), ...generated }),\n },\n // CommonJS keeps its JavaScript but emits no declarations. Every export map\n // resolves types through .d.mts, and a CJS declaration build would rerun\n // the same whole-program tsgo emit a second time.\n format: { esm: {}, cjs: { dts: false } },\n // No minify. This is a library build, and a mangled stack trace inside a\n // published extension is far more expensive than the bytes it saves.\n // Node output uses fixed extensions, so pi.extensions and doompiServer.dist\n // both land on the .mjs filenames their hosts require.\n platform: 'node',\n outExtensions: ({ format }) => ({\n js: format === 'es' ? '.mjs' : '.cjs',\n dts: format === 'es' ? '.d.mts' : '.d.cts',\n }),\n sourcemap: true,\n };\n\n // Contract bundles are published as a self-contained graph. Normal extension\n // entries remain unbundled for routed runtime resources, while MCP remains\n // isolated from the shared dist directory.\n const node = (entries: Record<string, string>, _unbundle: boolean): PresetConfig => ({\n ...baseNode,\n entry: entries,\n // Public entry facades must remain bundled. Otherwise their relative\n // imports target unbundled implementation chunks, which Vite treats as\n // source files when resolving a workspace package.\n unbundle: false,\n hooks: {\n 'build:done': () => {\n if (mcpOnly) {\n writeMcpManifest(\n packageDir,\n result.targets.includes('mcp'),\n renderMcpWidgets(result.graph, result.packageName, GENERATED_DIR).names,\n );\n return;\n }\n writeManifest({\n packageDir,\n manifest: JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as Record<\n string,\n unknown\n >,\n graph: result.graph,\n targets: result.targets,\n pluginId: result.pluginId,\n });\n },\n },\n });\n const unsyncedNode = (entries: Record<string, string>, unbundle: boolean): PresetConfig => ({\n ...baseNode,\n entry: entries,\n unbundle,\n });\n const configs =\n !mcpOnly && API_CONTRACTS_ENTRY in entry\n ? [\n unsyncedNode({ [API_CONTRACTS_ENTRY]: entry[API_CONTRACTS_ENTRY] }, false),\n node(Object.fromEntries(Object.entries(entry).filter(([name]) => name !== API_CONTRACTS_ENTRY)), true),\n ]\n : [node(entry, !mcpOnly)];\n if (mcpOnly && result.files.has(`${GENERATED_DIR}/mcp-ui.ts`)) return [...configs, browserConfig('mcp-ui')];\n if (!mcpOnly && result.targets.includes('web')) return [...configs, browserConfig()];\n return configs.length === 1 ? configs[0]! : configs;\n}\n"],"mappings":"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"}
|
|
@@ -26,21 +26,40 @@ interface BrowserPresetConfig {
|
|
|
26
26
|
plugins: QueryAssetPlugin[];
|
|
27
27
|
sourcemap: boolean;
|
|
28
28
|
unbundle: boolean;
|
|
29
|
+
tsconfig: string;
|
|
29
30
|
}
|
|
30
|
-
interface
|
|
31
|
+
interface GeneratedExports {
|
|
32
|
+
customExports: (exports: Record<string, unknown>) => Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
interface BasePresetConfig {
|
|
31
35
|
entry: Record<string, string>;
|
|
32
36
|
clean: boolean;
|
|
33
|
-
dts: {
|
|
37
|
+
dts: false | {
|
|
34
38
|
incremental: boolean;
|
|
35
39
|
parallel: boolean;
|
|
36
40
|
eager: boolean;
|
|
37
41
|
};
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
write?: false;
|
|
43
|
+
plugins?: QueryAssetPlugin[];
|
|
44
|
+
exports: boolean | GeneratedExports;
|
|
45
|
+
format: {
|
|
46
|
+
esm: Record<string, never>;
|
|
47
|
+
cjs: {
|
|
48
|
+
dts: false;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
40
51
|
platform: 'node';
|
|
41
52
|
sourcemap: boolean;
|
|
42
53
|
unbundle: boolean;
|
|
43
|
-
|
|
54
|
+
outExtensions: ({ format }: {
|
|
55
|
+
format: string;
|
|
56
|
+
}) => {
|
|
57
|
+
js: string;
|
|
58
|
+
dts: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
interface PresetConfig extends BasePresetConfig {
|
|
62
|
+
hooks?: {
|
|
44
63
|
'build:done': () => void;
|
|
45
64
|
};
|
|
46
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/tsdownPreset/index.ts"],"mappings":";;UASU;WACC;WACA;WACA;WACA,SAAS;;UAGV;WACC;EACT,UAAU,gBAAgB;EAC1B,KAAK;IAAQ,SAAS,MAAM;KAAwB;;;UAI5C;EACR,OAAO;EACP;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX,SAAS;EACT;EACA;;UAGQ;EACR,OAAO;EACP;EACA;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/services/tsdownPreset/index.ts"],"mappings":";;UASU;WACC;WACA;WACA;WACA,SAAS;;UAGV;WACC;EACT,UAAU,gBAAgB;EAC1B,KAAK;IAAQ,SAAS,MAAM;KAAwB;;;UAI5C;EACR,OAAO;EACP;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX,SAAS;EACT;EACA;EACA;;UAGQ;EACR,gBAAgB,SAAS,4BAA4B;;UAG7C;EACR,OAAO;EACP;EACA;IAAe;IAAsB;IAAmB;;EACxD;EACA,UAAU;EACV,mBAAmB;EACnB;IAAU,KAAK;IAAuB;MAAO;;;EAC7C;EACA;EACA;EACA,kBAAkB;IAAY;;IAC5B;IACA;;;UAIM,qBAAqB;EAC7B;IAAU;;;;;;;;;;;iBA4DK,+BAA+B;;WAErC,QAAQ;;WAER;;wBAoFK,gBACd,UAAS,yBACR,gBAAgB,eAAe"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{GENERATED_DIR as e}from"../../constants/layout.mjs";import{
|
|
1
|
+
import{GENERATED_DIR as e}from"../../constants/layout.mjs";import{renderMcpWidgets as t}from"../renderMcpWidgets/index.mjs";import{generateExtension as n}from"../generate/index.mjs";import{writeManifest as r,writeMcpManifest as i}from"../syncManifest/index.mjs";import a from"node:fs";import o from"node:path";const s=`apiContracts`;function c(e,t){let n=o.join(e,t);if(!a.existsSync(n))return{};let r={};for(let e of a.readdirSync(n)){if(!e.endsWith(`.ts`)||e.endsWith(`.d.ts`))continue;let n=e.slice(0,-3);r[n]=`${t}/${e}`}return r}function l(e,t,n){let r=o.join(e,t);if(!a.existsSync(r))return{};let i={};for(let e of a.readdirSync(r,{encoding:`utf8`,recursive:!0})){if(!n(e))continue;let r=e.split(o.sep).join(`/`);i[`./${t}/${r}`]=`./${t}/${r}`}return i}function u(e){let t=JSON.parse(a.readFileSync(o.join(e,`package.json`),`utf8`)),n=t.exports!==null&&typeof t.exports==`object`&&!Array.isArray(t.exports)?Object.fromEntries(Object.entries(t.exports).filter(([,e])=>typeof e==`string`)):{};return{...l(e,`skills`,e=>o.basename(e)===`SKILL.md`),...l(e,`themes`,e=>e.endsWith(`.json`)),...n}}function d(){return{name:`doompi-query-assets`,resolveId(e,t){let n=e.indexOf(`?`);if(n<0||t===void 0||!e.startsWith(`.`))return;let r=t.split(`?`)[0];return`${o.resolve(o.dirname(r),e.slice(0,n))}${e.slice(n)}`},load(e){let t=e.indexOf(`?`);if(t<0)return;let n=e.slice(0,t),r=new URLSearchParams(e.slice(t+1));if(!r.has(`url`))return;let i=r.has(`worker`);return`export default import.meta.ROLLUP_FILE_URL_${this.emitFile(i?{type:`chunk`,id:n,name:o.basename(n,o.extname(n))}:{type:`asset`,name:o.basename(n),source:a.readFileSync(n)})};`}}}function f(t=`web`){return{entry:{[`extensions/${t}`]:`${e}/${t}.ts`},clean:!1,dts:!1,exports:!1,format:[`esm`],platform:`browser`,fixedExtension:!0,external:e=>!e.startsWith(`.`)&&!o.isAbsolute(e),plugins:[d()],sourcemap:!0,unbundle:!1,tsconfig:t===`web`?`tsconfig.web.json`:`tsconfig.mcp.json`}}function p(e){let t=o.join(e,`dist`);if(a.existsSync(t))for(let e of a.readdirSync(t,{recursive:!0,encoding:`utf8`})){let n=e.split(o.sep).join(`/`);if(!/^(?:extensions\/mcp(?:-ui)?|.+\.mcp)\.(?:mjs|cjs|d\.mts|d\.cts)(?:\.map)?$/u.test(n))continue;let r=o.join(t,e);a.lstatSync(r).isFile()&&a.rmSync(r)}}function m(l={packageDir:process.cwd()}){let d=l.packageDir??process.cwd(),m=n({...l,packageDir:d,check:l.check??!1});for(let e of m.notices)process.stderr.write(`[doompi-build] ${e.path}: ${e.message}\n`);let h=l.target===`mcp`;h&&!l.check&&p(d);let g=h&&!m.targets.includes(`mcp`),_=`\0doompi-empty-mcp`;g&&!l.check&&i(d,!1);let v=h?m.targets.includes(`mcp`)?{"extensions/mcp":`${e}/mcp.ts`}:{"extensions/mcp":_}:{...c(d,l.exportsDir??`src/exports`),...m.targets.includes(`cli`)?{"extensions/pi":`${e}/pi.ts`}:{},...m.targets.includes(`server`)?{"extensions/server":`${e}/server.ts`}:{},...l.entry},y={clean:!1,dts:!g&&{incremental:!0,parallel:!1,eager:!0},...g?{write:!1,plugins:[{name:`doompi-empty-mcp`,resolveId:e=>e===_?_:void 0,load:e=>e===_?`export {};`:void 0}]}:{},exports:!h&&{customExports:e=>({...u(d),...e})},format:{esm:{},cjs:{dts:!1}},platform:`node`,outExtensions:({format:e})=>({js:e===`es`?`.mjs`:`.cjs`,dts:e===`es`?`.d.mts`:`.d.cts`}),sourcemap:!0},b=(n,s)=>({...y,entry:n,unbundle:!1,hooks:{"build:done":()=>{if(h){i(d,m.targets.includes(`mcp`),t(m.graph,m.packageName,e).names);return}r({packageDir:d,manifest:JSON.parse(a.readFileSync(o.join(d,`package.json`),`utf8`)),graph:m.graph,targets:m.targets,pluginId:m.pluginId})}}}),x=!h&&s in v?[((e,t)=>({...y,entry:e,unbundle:t}))({[s]:v[s]},!1),b(Object.fromEntries(Object.entries(v).filter(([e])=>e!==s)),!0)]:[b(v,!h)];return h&&m.files.has(`generated/mcp-ui.ts`)?[...x,f(`mcp-ui`)]:!h&&m.targets.includes(`web`)?[...x,f()]:x.length===1?x[0]:x}export{m as doompiExtension};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/tsdownPreset/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { GENERATED_DIR } from '../../constants/layout';\nimport { generateExtension } from '../generate';\nimport type { GenerateOptions } from '../generate/type';\nimport { toKebab } from '../identity';\nimport { writeManifest } from '../syncManifest';\n\ninterface EmittedFile {\n readonly type: 'asset' | 'chunk';\n readonly id?: string;\n readonly name: string;\n readonly source?: Buffer;\n}\n\ninterface QueryAssetPlugin {\n readonly name: string;\n resolveId(source: string, importer: string | undefined): string | undefined;\n load(this: { emitFile(file: EmittedFile): string }, id: string): string | undefined;\n}\n\n/** The shape a tsdown config needs from this preset, without importing tsdown's types. */\ninterface BrowserPresetConfig {\n entry: Record<string, string>;\n clean: boolean;\n dts: false;\n exports: boolean;\n format: 'esm'[];\n platform: 'browser';\n fixedExtension: boolean;\n external: (id: string) => boolean;\n plugins: QueryAssetPlugin[];\n sourcemap: boolean;\n unbundle: boolean;\n}\n\ninterface PresetConfig {\n entry: Record<string, string>;\n clean: boolean;\n dts: { incremental: boolean; parallel: boolean; eager: boolean };\n exports: boolean;\n format: ('esm' | 'cjs')[];\n platform: 'node';\n sourcemap: boolean;\n unbundle: boolean;\n hooks: { 'build:done': () => void };\n}\n\nconst DEFAULT_EXPORTS_DIR = 'src/exports';\n\n/** `src/exports/apiContracts.ts` becomes the `api-contracts` entry; index keeps its name. */\nfunction exportEntries(packageDir: string, exportsDir: string): Record<string, string> {\n const absolute = path.join(packageDir, exportsDir);\n if (!fs.existsSync(absolute)) return {};\n const entries: Record<string, string> = {};\n for (const file of fs.readdirSync(absolute)) {\n if (!file.endsWith('.ts') || file.endsWith('.d.ts')) continue;\n const stem = file.slice(0, -'.ts'.length);\n entries[stem === 'index' ? 'index' : toKebab(stem)] = `${exportsDir}/${file}`;\n }\n return entries;\n}\n\n/**\n * One tsdown config for a folder-routed extension.\n *\n * Entries come from the tree rather than a hand-written list, and the manifest\n * blocks that restate the tree are written after the build rather than kept in\n * step by hand. Browser contributions are emitted through a second bundled\n * config because their routed source is not published.\n */\nexport interface ExtensionPresetOptions extends GenerateOptions {\n /** Extra tsdown entries beyond the derived ones. */\n readonly entry?: Record<string, string>;\n /** Public export modules, package-relative. Defaults to `src/exports`. */\n readonly exportsDir?: string;\n}\n\n/**\n * Implements the Vite query imports extension browser code already uses.\n *\n * `?url` copies an opaque asset and `?worker&url` emits a separately bundled\n * worker chunk. Rolldown then replaces its file reference with an URL relative\n * to the extension bundle, which remains valid when the cockpit composes it.\n */\nfunction queryAssetPlugin(): QueryAssetPlugin {\n return {\n name: 'doompi-query-assets',\n resolveId(source, importer) {\n const queryAt = source.indexOf('?');\n if (queryAt < 0 || importer === undefined || !source.startsWith('.')) return undefined;\n const importerFile = importer.split('?')[0] as string;\n return `${path.resolve(path.dirname(importerFile), source.slice(0, queryAt))}${source.slice(queryAt)}`;\n },\n load(id) {\n const queryAt = id.indexOf('?');\n if (queryAt < 0) return undefined;\n const file = id.slice(0, queryAt);\n const query = new URLSearchParams(id.slice(queryAt + 1));\n if (!query.has('url')) return undefined;\n const worker = query.has('worker');\n const reference = this.emitFile(\n worker\n ? { type: 'chunk', id: file, name: path.basename(file, path.extname(file)) }\n : { type: 'asset', name: path.basename(file), source: fs.readFileSync(file) },\n );\n return `export default import.meta.ROLLUP_FILE_URL_${reference};`;\n },\n };\n}\n\n/** The separately bundled browser half of a routed extension. */\nfunction browserConfig(): BrowserPresetConfig {\n return {\n entry: { 'extensions/web': `${GENERATED_DIR}/web.ts` },\n clean: false,\n // No declarations. Nothing imports this as a typed module: it has no\n // export subpath, and the cockpit consumes it as a bundle. The browser\n // half is still typechecked, by tsconfig.web.json in the typecheck script.\n dts: false,\n exports: false,\n format: ['esm'],\n platform: 'browser',\n // platform browser turns tsdown's fixedExtension off, which would emit\n // .js. The manifest names .mjs like the other two entries, so ask for it.\n fixedExtension: true,\n // Every bare specifier stays external and the cockpit resolves it, which\n // is what keeps one React and one store in the page no matter how many\n // plugins are installed. An allowlist would have to be kept in step with\n // the cockpit's; this cannot drift.\n //\n // A predicate rather than a pattern: rolldown tests `external` against the\n // resolved id, so /^[^.]/ also matches the absolute path of this package's\n // own routed file and would leave a dangling import to unbuilt .tsx.\n external: (id: string) => !id.startsWith('.') && !path.isAbsolute(id),\n plugins: [queryAssetPlugin()],\n sourcemap: true,\n // Bundled, unlike the node half. Unbundling would emit an import to the\n // routed source file, which is not published and is .tsx besides. One\n // module with only bare specifiers external is what the cockpit wants.\n unbundle: false,\n };\n}\n\nexport function doompiExtension(\n options: ExtensionPresetOptions = { packageDir: process.cwd() },\n): PresetConfig | (PresetConfig | BrowserPresetConfig)[] {\n const packageDir = options.packageDir ?? process.cwd();\n const result = generateExtension({ ...options, packageDir, check: options.check ?? false });\n\n for (const notice of result.notices) process.stderr.write(`[doompi-build] ${notice.path}: ${notice.message}\\n`);\n\n const entry: Record<string, string> = {\n ...exportEntries(packageDir, options.exportsDir ?? DEFAULT_EXPORTS_DIR),\n ...(result.targets.includes('cli') ? { 'extensions/pi': `${GENERATED_DIR}/pi.ts` } : {}),\n ...(result.targets.includes('server') ? { 'extensions/server': `${GENERATED_DIR}/server.ts` } : {}),\n ...options.entry,\n };\n\n const node: PresetConfig = {\n entry,\n clean: true,\n dts: { incremental: true, parallel: false, eager: true },\n exports: true,\n format: ['esm', 'cjs'],\n // No minify. This is a library build, and a mangled stack trace inside a\n // published extension is far more expensive than the bytes it saves.\n // Node output uses fixed extensions, so pi.extensions and doompiServer.dist\n // both land on the .mjs filenames their hosts require.\n platform: 'node',\n sourcemap: true,\n unbundle: true,\n hooks: {\n 'build:done': () =>\n void writeManifest({\n packageDir,\n manifest: JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as Record<\n string,\n unknown\n >,\n graph: result.graph,\n targets: result.targets,\n pluginId: result.pluginId,\n }),\n },\n };\n\n return result.targets.includes('web') ? [node, browserConfig()] : node;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/services/tsdownPreset/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { GENERATED_DIR } from '../../constants/layout';\nimport { generateExtension } from '../generate';\nimport type { GenerateOptions } from '../generate/type';\nimport { renderMcpWidgets } from '../renderMcpWidgets';\nimport { writeManifest, writeMcpManifest } from '../syncManifest';\n\ninterface EmittedFile {\n readonly type: 'asset' | 'chunk';\n readonly id?: string;\n readonly name: string;\n readonly source?: Buffer;\n}\n\ninterface QueryAssetPlugin {\n readonly name: string;\n resolveId(source: string, importer: string | undefined): string | undefined;\n load(this: { emitFile(file: EmittedFile): string }, id: string): string | undefined;\n}\n\n/** The shape a tsdown config needs from this preset, without importing tsdown's types. */\ninterface BrowserPresetConfig {\n entry: Record<string, string>;\n clean: boolean;\n dts: false;\n exports: boolean;\n format: 'esm'[];\n platform: 'browser';\n fixedExtension: boolean;\n external: (id: string) => boolean;\n plugins: QueryAssetPlugin[];\n sourcemap: boolean;\n unbundle: boolean;\n tsconfig: string;\n}\n\ninterface GeneratedExports {\n customExports: (exports: Record<string, unknown>) => Record<string, unknown>;\n}\n\ninterface BasePresetConfig {\n entry: Record<string, string>;\n clean: boolean;\n dts: false | { incremental: boolean; parallel: boolean; eager: boolean };\n write?: false;\n plugins?: QueryAssetPlugin[];\n exports: boolean | GeneratedExports;\n format: { esm: Record<string, never>; cjs: { dts: false } };\n platform: 'node';\n sourcemap: boolean;\n unbundle: boolean;\n outExtensions: ({ format }: { format: string }) => {\n js: string;\n dts: string;\n };\n}\n\ninterface PresetConfig extends BasePresetConfig {\n hooks?: { 'build:done': () => void };\n}\n\nconst DEFAULT_EXPORTS_DIR = 'src/exports';\nconst API_CONTRACTS_ENTRY = 'apiContracts';\n\n/** `src/exports/apiContracts.ts` becomes the `apiContracts` entry; index keeps its name. */\nfunction exportEntries(packageDir: string, exportsDir: string): Record<string, string> {\n const absolute = path.join(packageDir, exportsDir);\n if (!fs.existsSync(absolute)) return {};\n const entries: Record<string, string> = {};\n for (const file of fs.readdirSync(absolute)) {\n if (!file.endsWith('.ts') || file.endsWith('.d.ts')) continue;\n const stem = file.slice(0, -'.ts'.length);\n entries[stem] = `${exportsDir}/${file}`;\n }\n return entries;\n}\n\n/** Static resources receive package export entries without becoming tsdown inputs. */\nfunction resourceEntries(\n packageDir: string,\n directory: string,\n matches: (relative: string) => boolean,\n): Record<string, string> {\n const root = path.join(packageDir, directory);\n if (!fs.existsSync(root)) return {};\n const entries: Record<string, string> = {};\n for (const relative of fs.readdirSync(root, { encoding: 'utf8', recursive: true })) {\n if (!matches(relative)) continue;\n const normalized = relative.split(path.sep).join('/');\n entries[`./${directory}/${normalized}`] = `./${directory}/${normalized}`;\n }\n return entries;\n}\n\n/** Preserves declared resources and discovers default skill and theme resource exports. */\nfunction staticExports(packageDir: string): Record<string, unknown> {\n const manifest = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as Record<\n string,\n unknown\n >;\n const declared =\n manifest.exports !== null && typeof manifest.exports === 'object' && !Array.isArray(manifest.exports)\n ? Object.fromEntries(Object.entries(manifest.exports).filter(([, target]) => typeof target === 'string'))\n : {};\n return {\n ...resourceEntries(packageDir, 'skills', (relative) => path.basename(relative) === 'SKILL.md'),\n ...resourceEntries(packageDir, 'themes', (relative) => relative.endsWith('.json')),\n ...declared,\n };\n}\n/**\n * One tsdown config for a folder-routed extension.\n *\n * Entries come from the tree rather than a hand-written list, and the manifest\n * blocks that restate the tree are written after the build rather than kept in\n * step by hand. Browser contributions are emitted through a second bundled\n * config because their routed source is not published.\n */\nexport interface ExtensionPresetOptions extends GenerateOptions {\n /** Extra tsdown entries beyond the derived ones. */\n readonly entry?: Record<string, string>;\n /** Public export modules, package-relative. Defaults to `src/exports`. */\n readonly exportsDir?: string;\n}\n\n/**\n * Implements the Vite query imports extension browser code already uses.\n *\n * `?url` copies an opaque asset and `?worker&url` emits a separately bundled\n * worker chunk. Rolldown then replaces its file reference with an URL relative\n * to the extension bundle, which remains valid when the cockpit composes it.\n */\nfunction queryAssetPlugin(): QueryAssetPlugin {\n return {\n name: 'doompi-query-assets',\n resolveId(source, importer) {\n const queryAt = source.indexOf('?');\n if (queryAt < 0 || importer === undefined || !source.startsWith('.')) return undefined;\n const importerFile = importer.split('?')[0] as string;\n return `${path.resolve(path.dirname(importerFile), source.slice(0, queryAt))}${source.slice(queryAt)}`;\n },\n load(id) {\n const queryAt = id.indexOf('?');\n if (queryAt < 0) return undefined;\n const file = id.slice(0, queryAt);\n const query = new URLSearchParams(id.slice(queryAt + 1));\n if (!query.has('url')) return undefined;\n const worker = query.has('worker');\n const reference = this.emitFile(\n worker\n ? { type: 'chunk', id: file, name: path.basename(file, path.extname(file)) }\n : { type: 'asset', name: path.basename(file), source: fs.readFileSync(file) },\n );\n return `export default import.meta.ROLLUP_FILE_URL_${reference};`;\n },\n };\n}\n\n/** The separately bundled browser half of a routed extension. */\nfunction browserConfig(target: 'web' | 'mcp-ui' = 'web'): BrowserPresetConfig {\n return {\n entry: { [`extensions/${target}`]: `${GENERATED_DIR}/${target}.ts` },\n clean: false,\n // No declarations. Nothing imports this as a typed module: it has no\n // export subpath, and the cockpit consumes it as a bundle. The browser\n // half is still typechecked, by tsconfig.web.json in the typecheck script.\n dts: false,\n exports: false,\n format: ['esm'],\n platform: 'browser',\n // platform browser turns tsdown's fixedExtension off, which would emit\n // .js. The manifest names .mjs like the other two entries, so ask for it.\n fixedExtension: true,\n // Every bare specifier stays external and the cockpit resolves it, which\n // is what keeps one React and one store in the page no matter how many\n // plugins are installed. An allowlist would have to be kept in step with\n // the cockpit's; this cannot drift.\n //\n // A predicate rather than a pattern: rolldown tests `external` against the\n // resolved id, so /^[^.]/ also matches the absolute path of this package's\n // own routed file and would leave a dangling import to unbuilt .tsx.\n external: (id: string) => !id.startsWith('.') && !path.isAbsolute(id),\n plugins: [queryAssetPlugin()],\n sourcemap: true,\n // Bundled, unlike the node half. Unbundling would emit an import to the\n // routed source file, which is not published and is .tsx besides. One\n // module with only bare specifiers external is what the cockpit wants.\n unbundle: false,\n // Browser routes are excluded from the node tsconfig. Every browser-capable\n // extension owns this focused config for its matching typecheck.\n tsconfig: target === 'web' ? 'tsconfig.web.json' : 'tsconfig.mcp.json',\n };\n}\n\n/** Removes only filenames owned by the isolated MCP build, including obsolete declarations. */\nfunction cleanMcpOutput(packageDir: string): void {\n const dist = path.join(packageDir, 'dist');\n if (!fs.existsSync(dist)) return;\n for (const relative of fs.readdirSync(dist, { recursive: true, encoding: 'utf8' })) {\n const normalized = relative.split(path.sep).join('/');\n if (!/^(?:extensions\\/mcp(?:-ui)?|.+\\.mcp)\\.(?:mjs|cjs|d\\.mts|d\\.cts)(?:\\.map)?$/u.test(normalized)) continue;\n const absolute = path.join(dist, relative);\n if (fs.lstatSync(absolute).isFile()) fs.rmSync(absolute);\n }\n}\n\nexport function doompiExtension(\n options: ExtensionPresetOptions = { packageDir: process.cwd() },\n): PresetConfig | (PresetConfig | BrowserPresetConfig)[] {\n const packageDir = options.packageDir ?? process.cwd();\n const result = generateExtension({ ...options, packageDir, check: options.check ?? false });\n\n for (const notice of result.notices) process.stderr.write(`[doompi-build] ${notice.path}: ${notice.message}\\n`);\n\n const mcpOnly = options.target === 'mcp';\n if (mcpOnly && !options.check) cleanMcpOutput(packageDir);\n const emptyMcp = mcpOnly && !result.targets.includes('mcp');\n const emptyEntry = '\\0doompi-empty-mcp';\n if (emptyMcp && !options.check) writeMcpManifest(packageDir, false);\n const entry: Record<string, string> = mcpOnly\n ? result.targets.includes('mcp')\n ? { 'extensions/mcp': `${GENERATED_DIR}/mcp.ts` }\n : { 'extensions/mcp': emptyEntry }\n : {\n ...exportEntries(packageDir, options.exportsDir ?? DEFAULT_EXPORTS_DIR),\n ...(result.targets.includes('cli') ? { 'extensions/pi': `${GENERATED_DIR}/pi.ts` } : {}),\n ...(result.targets.includes('server') ? { 'extensions/server': `${GENERATED_DIR}/server.ts` } : {}),\n ...options.entry,\n };\n\n const baseNode: Omit<BasePresetConfig, 'entry' | 'unbundle'> = {\n // MCP shares dist/ with the normal build, so neither build may erase the other.\n clean: false,\n dts: emptyMcp ? false : { incremental: true, parallel: false, eager: true },\n // tsdown rejects both an empty entry and an empty config array. A virtual\n // input completes its normal lifecycle without publishing an empty facet.\n ...(emptyMcp\n ? {\n write: false as const,\n plugins: [\n {\n name: 'doompi-empty-mcp',\n resolveId: (source: string) => (source === emptyEntry ? emptyEntry : undefined),\n load: (id: string) => (id === emptyEntry ? 'export {};' : undefined),\n },\n ],\n }\n : {}),\n exports: mcpOnly\n ? false\n : {\n customExports: (generated) => ({ ...staticExports(packageDir), ...generated }),\n },\n // CommonJS keeps its JavaScript but emits no declarations. Every export map\n // resolves types through .d.mts, and a CJS declaration build would rerun\n // the same whole-program tsgo emit a second time.\n format: { esm: {}, cjs: { dts: false } },\n // No minify. This is a library build, and a mangled stack trace inside a\n // published extension is far more expensive than the bytes it saves.\n // Node output uses fixed extensions, so pi.extensions and doompiServer.dist\n // both land on the .mjs filenames their hosts require.\n platform: 'node',\n outExtensions: ({ format }) => ({\n js: format === 'es' ? '.mjs' : '.cjs',\n dts: format === 'es' ? '.d.mts' : '.d.cts',\n }),\n sourcemap: true,\n };\n\n // Contract bundles are published as a self-contained graph. Normal extension\n // entries remain unbundled for routed runtime resources, while MCP remains\n // isolated from the shared dist directory.\n const node = (entries: Record<string, string>, _unbundle: boolean): PresetConfig => ({\n ...baseNode,\n entry: entries,\n // Public entry facades must remain bundled. Otherwise their relative\n // imports target unbundled implementation chunks, which Vite treats as\n // source files when resolving a workspace package.\n unbundle: false,\n hooks: {\n 'build:done': () => {\n if (mcpOnly) {\n writeMcpManifest(\n packageDir,\n result.targets.includes('mcp'),\n renderMcpWidgets(result.graph, result.packageName, GENERATED_DIR).names,\n );\n return;\n }\n writeManifest({\n packageDir,\n manifest: JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf8')) as Record<\n string,\n unknown\n >,\n graph: result.graph,\n targets: result.targets,\n pluginId: result.pluginId,\n });\n },\n },\n });\n const unsyncedNode = (entries: Record<string, string>, unbundle: boolean): PresetConfig => ({\n ...baseNode,\n entry: entries,\n unbundle,\n });\n const configs =\n !mcpOnly && API_CONTRACTS_ENTRY in entry\n ? [\n unsyncedNode({ [API_CONTRACTS_ENTRY]: entry[API_CONTRACTS_ENTRY] }, false),\n node(Object.fromEntries(Object.entries(entry).filter(([name]) => name !== API_CONTRACTS_ENTRY)), true),\n ]\n : [node(entry, !mcpOnly)];\n if (mcpOnly && result.files.has(`${GENERATED_DIR}/mcp-ui.ts`)) return [...configs, browserConfig('mcp-ui')];\n if (!mcpOnly && result.targets.includes('web')) return [...configs, browserConfig()];\n return configs.length === 1 ? configs[0]! : configs;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-build",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.21",
|
|
4
4
|
"description": "Folder-convention scanner and build presets for DoomPi extensions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"import": "./dist/index.mjs",
|
|
38
38
|
"require": "./dist/index.cjs"
|
|
39
39
|
},
|
|
40
|
-
"./
|
|
40
|
+
"./browserFile": {
|
|
41
41
|
"types": "./dist/browserFile.d.mts",
|
|
42
42
|
"import": "./dist/browserFile.mjs",
|
|
43
43
|
"require": "./dist/browserFile.cjs"
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"access": "public"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@types/node": "26.
|
|
57
|
-
"@vitest/coverage-v8": "5.0.
|
|
56
|
+
"@types/node": "26.6.2",
|
|
57
|
+
"@vitest/coverage-v8": "5.0.1",
|
|
58
58
|
"tsdown": "0.23.0",
|
|
59
59
|
"typescript": "7.0.2",
|
|
60
|
-
"vitest": "5.0.
|
|
60
|
+
"vitest": "5.0.1"
|
|
61
61
|
},
|
|
62
62
|
"engines": {
|
|
63
63
|
"node": ">=22.19.0"
|
package/dist/browserFile.d.cts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
//#region src/constants/layout.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* The folder-convention vocabulary, in one place.
|
|
4
|
-
*
|
|
5
|
-
* Every name here is part of the authoring contract in
|
|
6
|
-
* docs/extension-layout.md. Adding a surface means adding it to both.
|
|
7
|
-
*/
|
|
8
|
-
/** Where the scan starts, package-relative. */
|
|
9
|
-
export declare const DEFAULT_ROUTING_ROOT = "src/extensions";
|
|
10
|
-
/** Accepted spelling of the same root, for packages that prefer the singular. */
|
|
11
|
-
export declare const ROUTING_ROOT_ALIAS = "src/extension";
|
|
12
|
-
/** Gate folders. Each is followed by exactly one id segment. */
|
|
13
|
-
export declare const GATE_SEGMENTS: readonly string[];
|
|
14
|
-
/** The leaf filename of an HTTP route, as Next.js spells it. */
|
|
15
|
-
export declare const ROUTE_FILE_NAME = "route";
|
|
16
|
-
/**
|
|
17
|
-
* Where generated entries are written, package-relative.
|
|
18
|
-
*
|
|
19
|
-
* Not `src`. That directory is authored code, and a build that writes into it
|
|
20
|
-
* makes every package carry output its author did not write and must not edit.
|
|
21
|
-
* This one is gitignored per package, and the repository's formatter already
|
|
22
|
-
* skips a directory by this name.
|
|
23
|
-
*/
|
|
24
|
-
export declare const GENERATED_DIR = "generated";
|
|
25
|
-
/**
|
|
26
|
-
* Platform suffixes, scoped to their side. A target may not reuse one of these words.
|
|
27
|
-
*
|
|
28
|
-
* Every public routed file names one of these, so which host reads it is read
|
|
29
|
-
* off the filename rather than inferred. A file that names none is a notice.
|
|
30
|
-
*
|
|
31
|
-
* `cli` appears on both sides, because the interactive host has both. Its
|
|
32
|
-
* backend files hold a tool's `execute` and its services; its frontend files
|
|
33
|
-
* hold the TUI that draws them. A terminal is a frontend that happens not to
|
|
34
|
-
* be a browser, which is why the side axis is logic against presentation
|
|
35
|
-
* rather than Node against browser.
|
|
36
|
-
*/
|
|
37
|
-
export declare const BACKEND_PLATFORMS: readonly string[];
|
|
38
|
-
export declare const FRONTEND_PLATFORMS: readonly string[];
|
|
39
|
-
/**
|
|
40
|
-
* Surfaces that produce contributions on the backend side.
|
|
41
|
-
*
|
|
42
|
-
* `mode` is absent on purpose: it is a gate folder, so it is consumed before
|
|
43
|
-
* the surface check and its declaration file synthesises the surface instead.
|
|
44
|
-
*/
|
|
45
|
-
export declare const BACKEND_SURFACES: readonly string[];
|
|
46
|
-
/**
|
|
47
|
-
* Surfaces that produce contributions on the frontend side.
|
|
48
|
-
*
|
|
49
|
-
* `message` is terminal-only today: the cockpit renders a timeline entry
|
|
50
|
-
* through a tool renderer or a fill, while the TUI has a separate registry
|
|
51
|
-
* keyed by custom message type.
|
|
52
|
-
*/
|
|
53
|
-
export declare const FRONTEND_SURFACES: readonly string[];
|
|
54
|
-
/** Surfaces whose filename carries a relationship target. */
|
|
55
|
-
export declare const TARGETED_SURFACES: readonly string[];
|
|
56
|
-
/** Surfaces whose folders below the surface spell a route path. */
|
|
57
|
-
export declare const ROUTED_SURFACES: readonly string[];
|
|
58
|
-
//#endregion
|
|
59
|
-
//# sourceMappingURL=layout.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"layout.d.cts","names":[],"sources":["../../src/constants/layout.ts"],"mappings":";;;;;;;;qBAQa;;qBAEA;;qBAWA;;qBAGA;;;;;;;;;qBAoBA;;;;;;;;;;;;;qBAoDA;qBACA;;;;;;;qBAWA;;;;;;;;qBAoBA;;qBAwBA;;qBAGA"}
|
package/dist/index.d.cts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ExtensionEntry, ExtensionGate, ExtensionGraph, ExtensionNotice, ExtensionScope, ExtensionSide, RouteParam, RouteSegment } from "./types/extensionGraph.cjs";
|
|
2
|
-
import { Segment, classifySegment } from "./services/segments/index.cjs";
|
|
3
|
-
import { ParsedFilename, parseFilename } from "./services/filename/index.cjs";
|
|
4
|
-
import { ScanOptions } from "./services/scan/type.cjs";
|
|
5
|
-
import { resolveRoutingRoot, scanExtensions } from "./services/scan/index.cjs";
|
|
6
|
-
import { BuildTarget, ResolvedContribution, TargetResolution } from "./services/resolveTarget/type.cjs";
|
|
7
|
-
import { resolveTarget } from "./services/resolveTarget/index.cjs";
|
|
8
|
-
import { BACKEND_PLATFORMS, BACKEND_SURFACES, DEFAULT_ROUTING_ROOT, FRONTEND_PLATFORMS, FRONTEND_SURFACES, GATE_SEGMENTS, GENERATED_DIR, ROUTED_SURFACES, ROUTE_FILE_NAME, ROUTING_ROOT_ALIAS, TARGETED_SURFACES } from "./constants/layout.cjs";
|
|
9
|
-
import { GenerateOptions, GenerateResult } from "./services/generate/type.cjs";
|
|
10
|
-
import { defaultPluginId, generateExtension } from "./services/generate/index.cjs";
|
|
11
|
-
import { RenderOptions } from "./services/renderEntry/type.cjs";
|
|
12
|
-
import { renderCliEntry, renderServerEntry, renderWebEntry } from "./services/renderEntry/index.cjs";
|
|
13
|
-
import { StaleGeneratedError, WriteResult, writeGenerated } from "./services/writeGenerated/index.cjs";
|
|
14
|
-
import { ManifestSync } from "./services/syncManifest/type.cjs";
|
|
15
|
-
import { syncManifest, writeManifest } from "./services/syncManifest/index.cjs";
|
|
16
|
-
export { BACKEND_PLATFORMS, BACKEND_SURFACES, type BuildTarget, DEFAULT_ROUTING_ROOT, type ExtensionEntry, type ExtensionGate, type ExtensionGraph, type ExtensionNotice, type ExtensionScope, type ExtensionSide, FRONTEND_PLATFORMS, FRONTEND_SURFACES, GATE_SEGMENTS, GENERATED_DIR, type GenerateOptions, type GenerateResult, type ManifestSync, type ParsedFilename, ROUTED_SURFACES, ROUTE_FILE_NAME, ROUTING_ROOT_ALIAS, type RenderOptions, type ResolvedContribution, type RouteParam, type RouteSegment, type ScanOptions, type Segment, StaleGeneratedError, TARGETED_SURFACES, type TargetResolution, type WriteResult, classifySegment, defaultPluginId, generateExtension, parseFilename, renderCliEntry, renderServerEntry, renderWebEntry, resolveRoutingRoot, resolveTarget, scanExtensions, syncManifest, writeGenerated, writeManifest };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
//#region src/services/browserFile/index.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Whether a package-relative path holds code the cockpit bundles.
|
|
4
|
-
*
|
|
5
|
-
* Browser-bound is narrower than `(frontend)`. That side carries both
|
|
6
|
-
* presentations, and the terminal's half legitimately imports src/services and
|
|
7
|
-
* pi-tui, so treating the whole side as browser would reject every one of those
|
|
8
|
-
* imports. Two things separate the halves, in this order:
|
|
9
|
-
*
|
|
10
|
-
* - a surface the CLI frontend table names and the web table does not is
|
|
11
|
-
* terminal-only, whatever the filename says;
|
|
12
|
-
* - on a surface both hosts share, the platform in the filename decides, which
|
|
13
|
-
* is what tells `tool/x.cli.tsx` from `tool/x.web.tsx`.
|
|
14
|
-
*
|
|
15
|
-
* Everything else under `(frontend)` is browser, including the private folders
|
|
16
|
-
* colocated beside a surface, and a private folder at the side root, which
|
|
17
|
-
* names no surface to read.
|
|
18
|
-
*
|
|
19
|
-
* That default is why a private terminal helper carries `.cli` even though the
|
|
20
|
-
* scan never routes it: on a shared surface such as `tool/`, the folder says
|
|
21
|
-
* nothing about which host draws the file, so `_lib/bashRender.cli.ts` is the
|
|
22
|
-
* only thing distinguishing a TUI renderer from a cockpit one sitting beside it.
|
|
23
|
-
*
|
|
24
|
-
* Path in, answer out: nothing here reads the file or the filesystem.
|
|
25
|
-
*/
|
|
26
|
-
export declare function isBrowserFile(relativePath: string): boolean;
|
|
27
|
-
//#endregion
|
|
28
|
-
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/browserFile/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;wBA0DgB,cAAc"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
//#region src/services/filename/index.d.ts
|
|
2
|
-
/** One filename split into the four things the grammar encodes. */
|
|
3
|
-
export interface ParsedFilename {
|
|
4
|
-
/** The contribution's identity. */
|
|
5
|
-
readonly name: string;
|
|
6
|
-
/** The relationship target, such as the slot a fill names. */
|
|
7
|
-
readonly target: string | undefined;
|
|
8
|
-
/** The platform this file serves, or undefined when the filename names none. */
|
|
9
|
-
readonly platform: string | undefined;
|
|
10
|
-
readonly extension: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Parses `{name}[.{target}][.{platform}].{ext}`.
|
|
14
|
-
*
|
|
15
|
-
* Right to left, because the platform set is closed and the target is not: a
|
|
16
|
-
* dotted slot name such as `task.detail` would otherwise be ambiguous. A file
|
|
17
|
-
* whose extension is not a source extension, or that carries an excluded
|
|
18
|
-
* infix, returns undefined rather than an entry the caller has to filter.
|
|
19
|
-
*
|
|
20
|
-
* The one word a target may not be is a platform name for its own side, since
|
|
21
|
-
* the last segment is read as a platform whenever it matches.
|
|
22
|
-
*
|
|
23
|
-
* A filename that names no platform still parses, with `platform: undefined`.
|
|
24
|
-
* Requiring one is the scan's job, since only the scan knows whether the file
|
|
25
|
-
* is public: a private `_lib` helper and an `api/` route sibling name none.
|
|
26
|
-
*/
|
|
27
|
-
export declare function parseFilename(fileName: string, platforms: readonly string[]): ParsedFilename | undefined;
|
|
28
|
-
//#endregion
|
|
29
|
-
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/filename/index.ts"],"mappings":";;iBAGiB;;WAEN;;WAEA;;WAEA;WACA;;;;;;;;;;;;;;;;;wBAkBK,cAAc,kBAAkB,+BAA+B"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { GenerateOptions, GenerateResult } from "./type.cjs";
|
|
2
|
-
//#region src/services/generate/index.d.ts
|
|
3
|
-
/** `@agimon-ai/doompi-plan` becomes `plan`. */
|
|
4
|
-
export declare function defaultPluginId(packageName: string): string;
|
|
5
|
-
/**
|
|
6
|
-
* Scans a package and renders every entry its tree calls for.
|
|
7
|
-
*
|
|
8
|
-
* A target with nothing in it produces no file, so a backend-only package
|
|
9
|
-
* never grows an empty cockpit entry. Notices from the scan and from each
|
|
10
|
-
* resolution are gathered rather than thrown: an unrecognised folder costs
|
|
11
|
-
* that folder, never the build.
|
|
12
|
-
*/
|
|
13
|
-
export declare function generateExtension(options: GenerateOptions): GenerateResult;
|
|
14
|
-
//#endregion
|
|
15
|
-
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/generate/index.ts"],"mappings":";;;wBAqBgB,gBAAgB;;;;;;;;;wBA6BhB,kBAAkB,SAAS,kBAAkB"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { ExtensionGraph, ExtensionNotice } from "../../types/extensionGraph.cjs";
|
|
2
|
-
import { ScanOptions } from "../scan/type.cjs";
|
|
3
|
-
import { BuildTarget } from "../resolveTarget/type.cjs";
|
|
4
|
-
//#region src/services/generate/type.d.ts
|
|
5
|
-
export interface GenerateOptions extends ScanOptions {
|
|
6
|
-
/** Defaults to the name in the package's own package.json. */
|
|
7
|
-
readonly packageName?: string;
|
|
8
|
-
/** Defaults to the package name without its scope and `doompi-` prefix. */
|
|
9
|
-
readonly pluginId?: string;
|
|
10
|
-
/** Throw on stale output instead of writing it. */
|
|
11
|
-
readonly check?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export interface GenerateResult {
|
|
14
|
-
readonly graph: ExtensionGraph;
|
|
15
|
-
readonly packageName: string;
|
|
16
|
-
readonly pluginId: string;
|
|
17
|
-
/** Package-relative path to rendered source, for every entry the tree calls for. */
|
|
18
|
-
readonly files: ReadonlyMap<string, string>;
|
|
19
|
-
/** Package-relative paths whose contents changed. */
|
|
20
|
-
readonly changed: readonly string[];
|
|
21
|
-
readonly notices: readonly ExtensionNotice[];
|
|
22
|
-
/** The hosts this package contributes to. */
|
|
23
|
-
readonly targets: readonly BuildTarget[];
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
//# sourceMappingURL=type.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.cts","names":[],"sources":["../../../src/services/generate/type.ts"],"mappings":";;;;iBAIiB,wBAAwB;;WAE9B;;WAEA;;WAEA;;iBAGM;WACN,OAAO;WACP;WACA;;WAEA,OAAO;;WAEP;WACA,kBAAkB;;WAElB,kBAAkB"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { TargetResolution } from "../resolveTarget/type.cjs";
|
|
2
|
-
import { RenderOptions } from "./type.cjs";
|
|
3
|
-
//#region src/services/renderEntry/index.d.ts
|
|
4
|
-
/** The interactive terminal entry. One mount, so every backend contribution lands in it. */
|
|
5
|
-
export declare function renderCliEntry(resolution: TargetResolution, options: RenderOptions): string;
|
|
6
|
-
/**
|
|
7
|
-
* The headless entry, one declaration per scope.
|
|
8
|
-
*
|
|
9
|
-
* Contributions cascade downward here because the server does not do it
|
|
10
|
-
* itself: a facet reads exactly one `plugin[host.scope]` and nothing from the
|
|
11
|
-
* scopes above it. Emitting the repetition is what lets an author declare a
|
|
12
|
-
* channel once and have it mount at all three scopes.
|
|
13
|
-
*/
|
|
14
|
-
export declare function renderServerEntry(resolution: TargetResolution, options: RenderOptions): string;
|
|
15
|
-
/**
|
|
16
|
-
* The cockpit entry, one contributions object per scope.
|
|
17
|
-
*
|
|
18
|
-
* No cascade here, unlike the server: the registry already folds global into
|
|
19
|
-
* workspace into session before install, so repeating a contribution would
|
|
20
|
-
* install it twice.
|
|
21
|
-
*/
|
|
22
|
-
export declare function renderWebEntry(resolution: TargetResolution, options: RenderOptions): string;
|
|
23
|
-
//#endregion
|
|
24
|
-
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/renderEntry/index.ts"],"mappings":";;;;wBA2jBgB,eAAe,YAAY,kBAAkB,SAAS;;;;;;;;;wBAmDtD,kBAAkB,YAAY,kBAAkB,SAAS;;;;;;;;wBA6DzD,eAAe,YAAY,kBAAkB,SAAS"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
//#region src/services/renderEntry/type.d.ts
|
|
2
|
-
/** What the renderers need beyond the resolved contributions themselves. */
|
|
3
|
-
export interface RenderOptions {
|
|
4
|
-
/** The package's npm name, used as the extension and facet name. */
|
|
5
|
-
readonly packageName: string;
|
|
6
|
-
/** The cockpit plugin id. */
|
|
7
|
-
readonly pluginId: string;
|
|
8
|
-
/** Routing root, package-relative. */
|
|
9
|
-
readonly root: string;
|
|
10
|
-
/** Where the generated entry is written, package-relative, so its imports can be made relative to it. */
|
|
11
|
-
readonly entryDir: string;
|
|
12
|
-
}
|
|
13
|
-
//#endregion
|
|
14
|
-
//# sourceMappingURL=type.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.cts","names":[],"sources":["../../../src/services/renderEntry/type.ts"],"mappings":";;iBACiB;;WAEN;;WAEA;;WAEA;;WAEA"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ExtensionGraph } from "../../types/extensionGraph.cjs";
|
|
2
|
-
import { BuildTarget, TargetResolution } from "./type.cjs";
|
|
3
|
-
//#region src/services/resolveTarget/index.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Picks the winning file per logical contribution for one host.
|
|
6
|
-
*
|
|
7
|
-
* Metro and Expo semantics: a file naming this platform replaces a sibling
|
|
8
|
-
* that names none, and a file naming none serves every platform on its side
|
|
9
|
-
* that has no more specific sibling. The scan reports the unnamed one, so this
|
|
10
|
-
* is a fallback rather than a supported way to author. Two files naming the
|
|
11
|
-
* same platform for the same contribution is an authoring mistake, so the
|
|
12
|
-
* first wins and the second becomes a notice rather than silently disappearing.
|
|
13
|
-
*/
|
|
14
|
-
export declare function resolveTarget(graph: ExtensionGraph, target: BuildTarget): TargetResolution;
|
|
15
|
-
//#endregion
|
|
16
|
-
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/resolveTarget/index.ts"],"mappings":";;;;;;;;;;;;;wBAsHgB,cAAc,OAAO,gBAAgB,QAAQ,cAAc"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { ExtensionEntry, ExtensionNotice } from "../../types/extensionGraph.cjs";
|
|
2
|
-
//#region src/services/resolveTarget/type.d.ts
|
|
3
|
-
/** The three hosts an entry can be generated for. */
|
|
4
|
-
export type BuildTarget = 'cli' | 'server' | 'web';
|
|
5
|
-
/** One file and the host contribution array it belongs in. */
|
|
6
|
-
export interface ResolvedContribution {
|
|
7
|
-
/** The winning file for this logical contribution on this host. */
|
|
8
|
-
readonly entry: ExtensionEntry;
|
|
9
|
-
/** The host contribution array this belongs in. */
|
|
10
|
-
readonly field: string;
|
|
11
|
-
/**
|
|
12
|
-
* A presentation file folded into this contribution rather than emitted
|
|
13
|
-
* beside it. Only the terminal has one: its tool renderers are fields of the
|
|
14
|
-
* tool declaration, so the pair becomes a single registration.
|
|
15
|
-
*/
|
|
16
|
-
readonly renderers?: ExtensionEntry;
|
|
17
|
-
}
|
|
18
|
-
/** Everything one host needs generated, plus anything skipped on the way. */
|
|
19
|
-
export interface TargetResolution {
|
|
20
|
-
readonly target: BuildTarget;
|
|
21
|
-
readonly contributions: readonly ResolvedContribution[];
|
|
22
|
-
/** Escape-hatch files whose raw contributions are merged in wholesale. */
|
|
23
|
-
readonly escapeHatches: readonly ExtensionEntry[];
|
|
24
|
-
/**
|
|
25
|
-
* Scope constructors, outermost first.
|
|
26
|
-
*
|
|
27
|
-
* Each one runs before the contributions beneath it and its value joins
|
|
28
|
-
* their mount context, so the order is the nesting order and nothing else.
|
|
29
|
-
*/
|
|
30
|
-
readonly roots: readonly ExtensionEntry[];
|
|
31
|
-
readonly notices: readonly ExtensionNotice[];
|
|
32
|
-
}
|
|
33
|
-
//#endregion
|
|
34
|
-
//# sourceMappingURL=type.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.cts","names":[],"sources":["../../../src/services/resolveTarget/type.ts"],"mappings":";;;YAGY;;iBAGK;;WAEN,OAAO;;WAEP;;;;;;WAMA,YAAY;;;iBAIN;WACN,QAAQ;WACR,wBAAwB;;WAExB,wBAAwB;;;;;;;WAOxB,gBAAgB;WAChB,kBAAkB"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ExtensionGraph } from "../../types/extensionGraph.cjs";
|
|
2
|
-
import { ScanOptions } from "./type.cjs";
|
|
3
|
-
//#region src/services/scan/index.d.ts
|
|
4
|
-
/** Resolves the routing root, accepting the singular alias when only it exists. */
|
|
5
|
-
export declare function resolveRoutingRoot(packageDir: string, root: string | undefined): string | undefined;
|
|
6
|
-
/**
|
|
7
|
-
* Reads one package's routing root into a description of what it declares.
|
|
8
|
-
*
|
|
9
|
-
* Filesystem in, data out. No globbing, which is what keeps parenthesised
|
|
10
|
-
* group folders safe: tsdown's globber would read a bare `(name)` as an
|
|
11
|
-
* extglob group, and a directory walk never sees a pattern at all.
|
|
12
|
-
*
|
|
13
|
-
* Nothing here throws. A folder the convention does not recognise becomes a
|
|
14
|
-
* notice and its subtree is skipped, so one bad directory never costs a
|
|
15
|
-
* package its other contributions.
|
|
16
|
-
*/
|
|
17
|
-
export declare function scanExtensions(options: ScanOptions): ExtensionGraph;
|
|
18
|
-
//#endregion
|
|
19
|
-
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/services/scan/index.ts"],"mappings":";;;;wBA+EgB,mBAAmB,oBAAoB;;;;;;;;;;;;wBAgBvC,eAAe,SAAS,cAAc"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
//#region src/services/scan/type.d.ts
|
|
2
|
-
/** What the scan needs to know before it walks a package. */
|
|
3
|
-
export interface ScanOptions {
|
|
4
|
-
/** Absolute path of the package being scanned. */
|
|
5
|
-
readonly packageDir: string;
|
|
6
|
-
/**
|
|
7
|
-
* Routing root, package-relative. Defaults to `src/extensions`, falling back
|
|
8
|
-
* to `src/extension` when only that one exists.
|
|
9
|
-
*/
|
|
10
|
-
readonly root?: string;
|
|
11
|
-
/** Group folder names that select a build side. */
|
|
12
|
-
readonly sides?: {
|
|
13
|
-
readonly backend?: string;
|
|
14
|
-
readonly frontend?: string;
|
|
15
|
-
};
|
|
16
|
-
/** Recognised platform suffixes per side. */
|
|
17
|
-
readonly platforms?: {
|
|
18
|
-
readonly backend?: readonly string[];
|
|
19
|
-
readonly frontend?: readonly string[];
|
|
20
|
-
};
|
|
21
|
-
/** Base names of the generated entries at the root, which the scan skips. */
|
|
22
|
-
readonly generatedEntries?: readonly string[];
|
|
23
|
-
}
|
|
24
|
-
//#endregion
|
|
25
|
-
//# sourceMappingURL=type.d.cts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.cts","names":[],"sources":["../../../src/services/scan/type.ts"],"mappings":";;iBACiB;;WAEN;;;;;WAKA;;WAEA;aAAmB;aAA2B;;;WAE9C;aAAuB;aAAsC;;;WAE7D"}
|