@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.
Files changed (73) hide show
  1. package/README.i18n.yaml +4 -4
  2. package/README.md +4 -2
  3. package/README.zh.md +4 -2
  4. package/lib/index.js +37 -17
  5. package/lib/types/bundle-platform.d.ts +4 -2
  6. package/lib/types/bundle-platform.d.ts.map +1 -0
  7. package/lib/types/bundle-platform.js.map +1 -0
  8. package/lib/types/compatibility-preflight.d.ts.map +1 -0
  9. package/lib/types/compatibility-preflight.js.map +1 -0
  10. package/lib/types/config-schema/collect.d.ts.map +1 -0
  11. package/lib/types/config-schema/collect.js.map +1 -0
  12. package/lib/types/config-schema/document.d.ts.map +1 -0
  13. package/lib/types/config-schema/document.js.map +1 -0
  14. package/lib/types/config-schema/index.d.ts.map +1 -0
  15. package/lib/types/config-schema/index.js.map +1 -0
  16. package/lib/types/config-schema/native.d.ts.map +1 -0
  17. package/lib/types/config-schema/native.js.map +1 -0
  18. package/lib/types/config-schema/pattern.d.ts.map +1 -0
  19. package/lib/types/config-schema/pattern.js.map +1 -0
  20. package/lib/types/config-schema/projector.d.ts.map +1 -0
  21. package/lib/types/config-schema/projector.js.map +1 -0
  22. package/lib/types/config-schema/types.d.ts.map +1 -0
  23. package/lib/types/config-schema/types.js.map +1 -0
  24. package/lib/types/index.d.ts +1 -1
  25. package/lib/types/index.d.ts.map +1 -0
  26. package/lib/types/index.js.map +1 -0
  27. package/lib/types/package-meta.d.ts.map +1 -0
  28. package/lib/types/package-meta.js.map +1 -0
  29. package/lib/types/plugin-compatibility.d.ts.map +1 -0
  30. package/lib/types/plugin-compatibility.js.map +1 -0
  31. package/lib/types/profile-compatibility.d.ts.map +1 -0
  32. package/lib/types/profile-compatibility.js.map +1 -0
  33. package/lib/types/profile-context.d.ts.map +1 -0
  34. package/lib/types/profile-context.js.map +1 -0
  35. package/lib/types/profile-plugins.d.ts.map +1 -0
  36. package/lib/types/profile-plugins.js.map +1 -0
  37. package/lib/types/profile-resolution/legacy-links.d.ts.map +1 -0
  38. package/lib/types/profile-resolution/legacy-links.js.map +1 -0
  39. package/lib/types/profile-resolution/resolver.d.ts.map +1 -0
  40. package/lib/types/profile-resolution/resolver.js.map +1 -0
  41. package/lib/types/profile-resolution/service.d.ts.map +1 -0
  42. package/lib/types/profile-resolution/service.js.map +1 -0
  43. package/lib/types/profile-resolution/worker-bootstrap.d.ts.map +1 -0
  44. package/lib/types/profile-resolution/worker-bootstrap.js.map +1 -0
  45. package/lib/types/profile-sanitize.d.ts.map +1 -0
  46. package/lib/types/profile-sanitize.js.map +1 -0
  47. package/lib/types/profile.d.ts.map +1 -0
  48. package/lib/types/profile.js.map +1 -0
  49. package/lib/types/startup-diagnostics.d.ts.map +1 -0
  50. package/lib/types/startup-diagnostics.js.map +1 -0
  51. package/package.json +15 -11
  52. package/src/bundle-platform.ts +35 -0
  53. package/src/compatibility-preflight.ts +187 -0
  54. package/src/config-schema/collect.ts +249 -0
  55. package/src/config-schema/document.ts +169 -0
  56. package/src/config-schema/index.ts +36 -0
  57. package/src/config-schema/native.ts +16 -0
  58. package/src/config-schema/pattern.ts +62 -0
  59. package/src/config-schema/projector.ts +455 -0
  60. package/src/config-schema/types.ts +95 -0
  61. package/src/index.ts +1286 -0
  62. package/src/package-meta.ts +200 -0
  63. package/src/plugin-compatibility.ts +117 -0
  64. package/src/profile-compatibility.ts +141 -0
  65. package/src/profile-context.ts +85 -0
  66. package/src/profile-plugins.ts +133 -0
  67. package/src/profile-resolution/legacy-links.ts +33 -0
  68. package/src/profile-resolution/resolver.ts +1072 -0
  69. package/src/profile-resolution/service.ts +148 -0
  70. package/src/profile-resolution/worker-bootstrap.ts +12 -0
  71. package/src/profile-sanitize.ts +34 -0
  72. package/src/profile.ts +762 -0
  73. 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
+ }