git mv per the regrouping RFC: the five human-collaboration seams and tui join packages/interaction/, app-boot becomes packages/boot/, and jsonrpc joins the renamed scaffold/ (formerly sdk/) as its server half beside client/protocol/create-sdk/helper/scripts/telemetry, whose folders drop the legacy sdk- prefix. Three new group README triplets replace the ui/ and sdk/ ones; tsconfig references/paths/globs, knip keys, vitest globs, gate scripts, catalogs, docs, and the lockfile follow. Adds the four settled FIXME rename markers (dsh-sdk-server, dsh-sdk-telemetry, dsh-sdk-helper, dsh-sdk-scripts). The scaffold folders diverge from their npm names until those renames land, so tsconfig.base.json maps the three affected names explicitly beside the group wildcard. Also repairs two pre-existing stale-path classes the strengthened sweep surfaced: docs/web-styling.md's retired web-ui host package and type-model spec fixture-literal joins. app-boot's three Loader-composition specs time out at the default 5s under full-suite parallel load on this filesystem (pre-existing; pass isolated with --testTimeout=30000); interaction/scaffold/boot suites otherwise green (687 passed).
98 lines
3.0 KiB
TypeScript
98 lines
3.0 KiB
TypeScript
/**
|
|
* Resource vocabulary contributed by builtin SDK features.
|
|
*
|
|
* @module @deepseek-ai/dsh-helper/features/resources
|
|
*/
|
|
|
|
import type { CordisConfigEntry } from '../documents/cordis-yaml-file.ts'
|
|
import type { ProjectFile } from '../documents/project-file.ts'
|
|
import type { ResourceKey } from '../ids.ts'
|
|
|
|
/** Runtime or development NPM dependency contribution. */
|
|
export interface NpmDependencyResource {
|
|
kind: 'npm-dependency'
|
|
key: ResourceKey
|
|
name: string
|
|
section: 'dependencies' | 'devDependencies'
|
|
}
|
|
|
|
/** Feature-owned package script. */
|
|
export interface PackageScriptResource {
|
|
kind: 'package-script'
|
|
key: ResourceKey
|
|
name: string
|
|
command: string
|
|
removeOnlyWhenUnchanged: boolean
|
|
}
|
|
|
|
/** Owned Cordis config entry plus the config keys safe to update in place. */
|
|
export interface CordisConfigEntryResource {
|
|
kind: 'cordis-config-entry'
|
|
key: ResourceKey
|
|
entry: CordisConfigEntry
|
|
ownedConfigKeys: readonly string[]
|
|
commentedExample?: string
|
|
validateConfig?: (config: Readonly<Record<string, unknown>>) => readonly string[]
|
|
}
|
|
|
|
/** Environment variable reference and dotenv material. */
|
|
export interface EnvironmentResource {
|
|
kind: 'environment'
|
|
key: ResourceKey
|
|
name: string
|
|
value?: string
|
|
exampleValue: string
|
|
comment?: string
|
|
}
|
|
|
|
/** Feature-exclusive complete file. */
|
|
export interface OwnedFileResource {
|
|
kind: 'owned-file'
|
|
key: ResourceKey
|
|
document: ProjectFile
|
|
removeOnlyWhenUnchanged: boolean
|
|
}
|
|
|
|
/** Any resource a feature can add to a project. */
|
|
export type ProjectResource =
|
|
| NpmDependencyResource
|
|
| PackageScriptResource
|
|
| CordisConfigEntryResource
|
|
| EnvironmentResource
|
|
| OwnedFileResource
|
|
|
|
/** Complete resource contribution for one selected feature state. */
|
|
export class ProjectContribution {
|
|
readonly resources: readonly ProjectResource[]
|
|
|
|
/** Validate and retain one feature-owned resource set. */
|
|
constructor(resources: readonly ProjectResource[]) {
|
|
const seen = new Set<ResourceKey>()
|
|
for (const resource of resources) {
|
|
if (seen.has(resource.key)) throw new Error(`duplicate contribution resource key: ${resource.key}`)
|
|
seen.add(resource.key)
|
|
}
|
|
this.resources = resources
|
|
}
|
|
|
|
/** Merge base and option contributions by stable key. */
|
|
static merge(...contributions: readonly ProjectContribution[]): ProjectContribution {
|
|
const resources = new Map<ResourceKey, ProjectResource>()
|
|
for (const contribution of contributions) {
|
|
for (const resource of contribution.resources) {
|
|
const previous = resources.get(resource.key)
|
|
if (previous && JSON.stringify(previous) !== JSON.stringify(resource)) {
|
|
throw new Error(`resource ${resource.key} has conflicting definitions inside one feature`)
|
|
}
|
|
resources.set(resource.key, resource)
|
|
}
|
|
}
|
|
return new ProjectContribution([...resources.values()])
|
|
}
|
|
|
|
/** Index resources by stable key. */
|
|
byKey(): ReadonlyMap<ResourceKey, ProjectResource> {
|
|
return new Map(this.resources.map(resource => [resource.key, resource]))
|
|
}
|
|
}
|