@deepseek-ai/dsh-app-boot 0.2.2-rc.1 → 0.2.2-rc.3
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/README.i18n.yaml +4 -4
- package/README.md +4 -2
- package/README.zh.md +4 -2
- package/lib/index.js +37 -17
- package/lib/types/bundle-platform.d.ts +4 -2
- package/lib/types/bundle-platform.d.ts.map +1 -0
- package/lib/types/bundle-platform.js.map +1 -0
- package/lib/types/compatibility-preflight.d.ts.map +1 -0
- package/lib/types/compatibility-preflight.js.map +1 -0
- package/lib/types/config-schema/collect.d.ts.map +1 -0
- package/lib/types/config-schema/collect.js.map +1 -0
- package/lib/types/config-schema/document.d.ts.map +1 -0
- package/lib/types/config-schema/document.js.map +1 -0
- package/lib/types/config-schema/index.d.ts.map +1 -0
- package/lib/types/config-schema/index.js.map +1 -0
- package/lib/types/config-schema/native.d.ts.map +1 -0
- package/lib/types/config-schema/native.js.map +1 -0
- package/lib/types/config-schema/pattern.d.ts.map +1 -0
- package/lib/types/config-schema/pattern.js.map +1 -0
- package/lib/types/config-schema/projector.d.ts.map +1 -0
- package/lib/types/config-schema/projector.js.map +1 -0
- package/lib/types/config-schema/types.d.ts.map +1 -0
- package/lib/types/config-schema/types.js.map +1 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/package-meta.d.ts.map +1 -0
- package/lib/types/package-meta.js.map +1 -0
- package/lib/types/plugin-compatibility.d.ts.map +1 -0
- package/lib/types/plugin-compatibility.js.map +1 -0
- package/lib/types/profile-compatibility.d.ts.map +1 -0
- package/lib/types/profile-compatibility.js.map +1 -0
- package/lib/types/profile-context.d.ts.map +1 -0
- package/lib/types/profile-context.js.map +1 -0
- package/lib/types/profile-plugins.d.ts.map +1 -0
- package/lib/types/profile-plugins.js.map +1 -0
- package/lib/types/profile-resolution/legacy-links.d.ts.map +1 -0
- package/lib/types/profile-resolution/legacy-links.js.map +1 -0
- package/lib/types/profile-resolution/resolver.d.ts.map +1 -0
- package/lib/types/profile-resolution/resolver.js.map +1 -0
- package/lib/types/profile-resolution/service.d.ts.map +1 -0
- package/lib/types/profile-resolution/service.js.map +1 -0
- package/lib/types/profile-resolution/worker-bootstrap.d.ts.map +1 -0
- package/lib/types/profile-resolution/worker-bootstrap.js.map +1 -0
- package/lib/types/profile-sanitize.d.ts.map +1 -0
- package/lib/types/profile-sanitize.js.map +1 -0
- package/lib/types/profile.d.ts.map +1 -0
- package/lib/types/profile.js.map +1 -0
- package/lib/types/startup-diagnostics.d.ts.map +1 -0
- package/lib/types/startup-diagnostics.js.map +1 -0
- package/package.json +15 -11
- package/src/bundle-platform.ts +35 -0
- package/src/compatibility-preflight.ts +187 -0
- package/src/config-schema/collect.ts +249 -0
- package/src/config-schema/document.ts +169 -0
- package/src/config-schema/index.ts +36 -0
- package/src/config-schema/native.ts +16 -0
- package/src/config-schema/pattern.ts +62 -0
- package/src/config-schema/projector.ts +455 -0
- package/src/config-schema/types.ts +95 -0
- package/src/index.ts +1286 -0
- package/src/package-meta.ts +200 -0
- package/src/plugin-compatibility.ts +117 -0
- package/src/profile-compatibility.ts +141 -0
- package/src/profile-context.ts +85 -0
- package/src/profile-plugins.ts +133 -0
- package/src/profile-resolution/legacy-links.ts +33 -0
- package/src/profile-resolution/resolver.ts +1072 -0
- package/src/profile-resolution/service.ts +148 -0
- package/src/profile-resolution/worker-bootstrap.ts +12 -0
- package/src/profile-sanitize.ts +34 -0
- package/src/profile.ts +762 -0
- package/src/startup-diagnostics.ts +104 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/** Installed profile dependencies and their bundle activation after package-manager operations. */
|
|
2
|
+
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
import { assertBundlePlatform } from './bundle-platform.ts'
|
|
5
|
+
import { readProfileManifest, resolveBundleDir, writeProfileManifest, type ProfileManifest } from './profile.ts'
|
|
6
|
+
|
|
7
|
+
/** Profile directory and installation used by the shared bundle resolver. */
|
|
8
|
+
export interface ProfilePluginLocation {
|
|
9
|
+
/** Diagnostic prefix for profile manifest failures. */
|
|
10
|
+
readonly binName: string
|
|
11
|
+
/** Profile package directory managed by pnpm. */
|
|
12
|
+
readonly profileDir: string
|
|
13
|
+
/** Absolute package.json path of the owning dsh installation. */
|
|
14
|
+
readonly installAnchor: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** One dependency under its package-manager key, including npm aliases. */
|
|
18
|
+
export interface ProfilePluginDependency {
|
|
19
|
+
/** Dependency key used in package.json and the bundle list. */
|
|
20
|
+
readonly name: string
|
|
21
|
+
/** Installed version, or the dependency spec when installed metadata is unavailable. */
|
|
22
|
+
readonly version: string
|
|
23
|
+
/** Whether the package selected by the bundle resolver declares a patch. */
|
|
24
|
+
readonly bundle: boolean
|
|
25
|
+
/** Whether the dependency appears in the profile's active bundle list. */
|
|
26
|
+
readonly enabled: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Profile manifest and dependencies in manifest order. */
|
|
30
|
+
export interface ProfilePluginInventory {
|
|
31
|
+
readonly manifest: ProfileManifest
|
|
32
|
+
readonly dependencies: readonly ProfilePluginDependency[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Result of reconciling bundle activation after a successful package operation. */
|
|
36
|
+
export interface ProfilePluginReconciliation {
|
|
37
|
+
readonly plugins: ProfilePluginInventory
|
|
38
|
+
/** Newly added ordinary dependencies, for optional caller-owned diagnostics. */
|
|
39
|
+
readonly addedPlainDependencies: readonly string[]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Unavailable installed metadata must not prevent listing or removing dependencies. */
|
|
43
|
+
function optionalManifest(binName: string, packageDir: string): ProfileManifest | undefined {
|
|
44
|
+
try { return readProfileManifest(binName, packageDir) } catch { return undefined }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Resolve activation metadata with the same installation precedence as profile loading. */
|
|
48
|
+
function bundleManifest(location: ProfilePluginLocation, name: string): ProfileManifest | undefined {
|
|
49
|
+
let packageDir: string
|
|
50
|
+
try {
|
|
51
|
+
packageDir = resolveBundleDir(location.binName, name, location.installAnchor, location.profileDir)
|
|
52
|
+
} catch {
|
|
53
|
+
// An unresolved dependency remains visible as an ordinary package.
|
|
54
|
+
return undefined
|
|
55
|
+
}
|
|
56
|
+
return optionalManifest(location.binName, packageDir)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Read installed versions and bundle declarations without requiring loadable plugin code.
|
|
61
|
+
* Missing or unreadable installed metadata leaves the dependency visible for repair or removal.
|
|
62
|
+
* @param location - profile and installation resolution inputs.
|
|
63
|
+
* @returns dependency records in package.json order and the profile manifest.
|
|
64
|
+
*/
|
|
65
|
+
export function readProfilePlugins(location: ProfilePluginLocation): ProfilePluginInventory {
|
|
66
|
+
const manifest = readProfileManifest(location.binName, location.profileDir)
|
|
67
|
+
const bundles = manifest.dsh?.profile?.bundles ?? []
|
|
68
|
+
const dependencies = Object.entries(manifest.dependencies ?? {}).map(([name, spec]) => {
|
|
69
|
+
const installed = optionalManifest(location.binName, join(location.profileDir, 'node_modules', name))
|
|
70
|
+
return {
|
|
71
|
+
name,
|
|
72
|
+
version: typeof installed?.version === 'string' ? installed.version : spec,
|
|
73
|
+
bundle: bundleManifest(location, name)?.dsh?.bundle?.patch !== undefined,
|
|
74
|
+
enabled: bundles.includes(name),
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
return { manifest, dependencies }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Write a bundle list while preserving the supplied profile's other metadata.
|
|
82
|
+
* @param profileDir - directory whose package.json is updated.
|
|
83
|
+
* @param manifest - current profile manifest, read after the package operation when applicable.
|
|
84
|
+
* @param bundles - ordered active bundle names, including any template entries.
|
|
85
|
+
* @returns the written manifest.
|
|
86
|
+
*/
|
|
87
|
+
export function writeProfileBundles(
|
|
88
|
+
profileDir: string, manifest: ProfileManifest, bundles: readonly string[],
|
|
89
|
+
): ProfileManifest {
|
|
90
|
+
const updated = { ...manifest, dsh: { ...manifest.dsh, profile: { ...manifest.dsh?.profile, bundles: [...bundles] } } }
|
|
91
|
+
writeProfileManifest(profileDir, updated)
|
|
92
|
+
return updated
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Reconcile installed bundle declarations after a successful package-manager operation.
|
|
97
|
+
* Dependency-managed entries disappear when removed or when their package loses its declaration;
|
|
98
|
+
* template entries retain their order and duplicates. New bundle dependencies activate automatically.
|
|
99
|
+
* @param options - location, inventory captured before pnpm, and whether explicitly disabled bundles remain disabled.
|
|
100
|
+
* @returns updated inventory and newly added ordinary dependencies for caller-owned warnings.
|
|
101
|
+
* @throws If a new selection has invalid platform metadata or excludes the Host. Installed dependencies
|
|
102
|
+
* remain; no bundle selection changes are written.
|
|
103
|
+
*/
|
|
104
|
+
export function reconcileProfilePlugins(options: ProfilePluginLocation & {
|
|
105
|
+
readonly before: ProfilePluginInventory
|
|
106
|
+
readonly preserveDisabled: boolean
|
|
107
|
+
}): ProfilePluginReconciliation {
|
|
108
|
+
const after = readProfilePlugins(options)
|
|
109
|
+
const beforeNames = new Set(options.before.dependencies.map(dependency => dependency.name))
|
|
110
|
+
const afterNames = new Set(after.dependencies.map(dependency => dependency.name))
|
|
111
|
+
const bundleNames = new Set(after.dependencies.filter(dependency => dependency.bundle).map(dependency => dependency.name))
|
|
112
|
+
const disabled = new Set(options.preserveDisabled
|
|
113
|
+
? options.before.dependencies.filter(dependency => dependency.bundle && !dependency.enabled).map(dependency => dependency.name)
|
|
114
|
+
: [])
|
|
115
|
+
const previous = after.manifest.dsh?.profile?.bundles ?? []
|
|
116
|
+
const bundles = previous.filter(name => !(beforeNames.has(name) || afterNames.has(name)) || bundleNames.has(name))
|
|
117
|
+
for (const dependency of after.dependencies) {
|
|
118
|
+
if (dependency.bundle && !disabled.has(dependency.name) && !bundles.includes(dependency.name)) {
|
|
119
|
+
assertBundlePlatform(bundleManifest(options, dependency.name)?.dsh?.bundle?.platforms, process.platform)
|
|
120
|
+
bundles.push(dependency.name)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const changed = bundles.length !== previous.length || bundles.some((name, index) => name !== previous[index])
|
|
124
|
+
const manifest = changed ? writeProfileBundles(options.profileDir, after.manifest, bundles) : after.manifest
|
|
125
|
+
return {
|
|
126
|
+
plugins: {
|
|
127
|
+
manifest,
|
|
128
|
+
dependencies: after.dependencies.map(dependency => ({ ...dependency, enabled: bundles.includes(dependency.name) })),
|
|
129
|
+
},
|
|
130
|
+
addedPlainDependencies: after.dependencies.filter(dependency => !dependency.bundle && !beforeNames.has(dependency.name))
|
|
131
|
+
.map(dependency => dependency.name),
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Package directory and resource canonicalization through the active runtime carrier's filesystem. */
|
|
2
|
+
|
|
3
|
+
import { lstatSync, realpathSync } from 'node:fs'
|
|
4
|
+
import { basename, dirname, join } from 'node:path'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Return whether the process reads application modules from pkg's virtual filesystem.
|
|
8
|
+
* @returns whether pkg owns the module filesystem.
|
|
9
|
+
*/
|
|
10
|
+
function isPackagedExecutable(): boolean {
|
|
11
|
+
return (process as NodeJS.Process & { pkg?: unknown }).pkg !== undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a directory through the active carrier's filesystem implementation.
|
|
16
|
+
* @param path - directory path to canonicalize.
|
|
17
|
+
* @returns the canonical directory path.
|
|
18
|
+
*/
|
|
19
|
+
export function realModuleDirectory(path: string): string {
|
|
20
|
+
return isPackagedExecutable() ? realpathSync(path) : realpathSync.native(path)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Canonicalize a module resource, preserving physical file aliases.
|
|
24
|
+
* SEA archive files are symlink-free and support stat and reads, while their containing directories support realpath.
|
|
25
|
+
* @param path Existing module resource path.
|
|
26
|
+
* @returns Canonical resource path under the active carrier's filesystem.
|
|
27
|
+
* @throws When the resource or its directory cannot be inspected or resolved.
|
|
28
|
+
*/
|
|
29
|
+
export function realModuleFile(path: string): string {
|
|
30
|
+
return !isPackagedExecutable() || lstatSync(path).isSymbolicLink()
|
|
31
|
+
? realpathSync(path)
|
|
32
|
+
: join(realModuleDirectory(dirname(path)), basename(path))
|
|
33
|
+
}
|