@dsh-plugin/dsh-loader 1.0.0 → 1.1.0-dev.32278873528
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.md +251 -226
- package/{README.zh-CN.md → README.zh_CN.md} +227 -202
- package/bin/dshloader.mjs +42 -42
- package/cordis.patch.yml +8 -8
- package/dist/adapters/dsh-1-x.d.ts +23 -0
- package/dist/adapters/dsh-1-x.js +223 -0
- package/dist/adapters/dsh-1-x.js.map +1 -0
- package/dist/adapters/index.d.ts +22 -0
- package/dist/adapters/index.js +57 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/api.d.ts +13 -0
- package/dist/api.js +46 -0
- package/dist/api.js.map +1 -0
- package/dist/client.d.ts +157 -0
- package/dist/client.js +295 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +35 -0
- package/dist/registry.js +229 -0
- package/dist/registry.js.map +1 -0
- package/dist/services/services.d.ts +4 -0
- package/dist/services/services.js +28 -0
- package/dist/services/services.js.map +1 -0
- package/dist/services/settings.d.ts +41 -0
- package/dist/services/settings.js +161 -0
- package/dist/services/settings.js.map +1 -0
- package/dist/services/web.d.ts +10 -0
- package/dist/services/web.js +63 -0
- package/dist/services/web.js.map +1 -0
- package/dist/setup.d.ts +32 -0
- package/dist/setup.js +119 -0
- package/dist/setup.js.map +1 -0
- package/dist/types.d.ts +111 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/{src → dist}/version.js +5 -5
- package/dist/version.js.map +1 -0
- package/lib/client.js +283 -0
- package/lib/client.js.map +1 -0
- package/package.json +74 -59
- package/src/stable/agent.d.ts +1 -1
- package/src/stable/agent.js +2 -2
- package/src/stable/llm.d.ts +1 -1
- package/src/stable/llm.js +2 -2
- package/src/stable/runtime.d.ts +1 -1
- package/src/stable/runtime.js +5 -5
- package/src/stable/schema-form.d.ts +1 -1
- package/src/stable/schema-form.js +2 -2
- package/src/stable/settings.d.ts +1 -1
- package/src/stable/settings.js +2 -2
- package/src/stable/tools.d.ts +1 -1
- package/src/stable/tools.js +5 -5
- package/src/stable/ui-primitives.d.ts +4 -4
- package/src/stable/ui-primitives.js +6 -6
- package/src/stable/ui-settings.d.ts +6 -6
- package/src/stable/ui-settings.js +4 -4
- package/src/stable/ui-slots.d.ts +1 -1
- package/src/stable/ui-slots.js +2 -2
- package/src/stable/web-react.d.ts +1 -1
- package/src/stable/web-react.js +2 -2
- package/src/adapters/dsh-1-x.js +0 -236
- package/src/adapters/index.js +0 -59
- package/src/api.js +0 -56
- package/src/client.js +0 -330
- package/src/index.js +0 -105
- package/src/registry.js +0 -242
- package/src/services/services.js +0 -28
- package/src/services/settings.js +0 -174
- package/src/services/web.js +0 -71
- package/src/setup.mjs +0 -125
package/dist/setup.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// One-shot profile injection script (design.md §3.6 / §6 / M6).
|
|
2
|
+
//
|
|
3
|
+
// `dshloader setup <profile>`:
|
|
4
|
+
// - adds `@dsh-plugin/dsh-loader` to the profile package.json dependencies
|
|
5
|
+
// (if missing);
|
|
6
|
+
// - appends the dshloader `insert` entry to cordis.patch.yml (if missing);
|
|
7
|
+
// - does NOT reorder the insert list — cordis is reactive DI, so position
|
|
8
|
+
// does not affect whether service aliases / module redirects take effect
|
|
9
|
+
// (design.md §1.2 / §6.2).
|
|
10
|
+
//
|
|
11
|
+
// `dshloader dump-config <profile>`: best-effort validation that runs
|
|
12
|
+
// `dsh --profile <name> --dump-config` when the dsh CLI is available.
|
|
13
|
+
//
|
|
14
|
+
// `dshloader info [profile]`: prints dshloader version, detected dsh version,
|
|
15
|
+
// selected adapter, and registered aliases (AC-OB-03, P2 — minimal).
|
|
16
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { join, resolve } from 'node:path';
|
|
18
|
+
import { spawnSync } from 'node:child_process';
|
|
19
|
+
import { LOADER_VERSION, LOG_PREFIX } from './version.js';
|
|
20
|
+
import { detectDshVersion, AdapterRegistry } from './registry.js';
|
|
21
|
+
import { registerHostAdapters } from './adapters/index.js';
|
|
22
|
+
const LOADER_PKG = '@dsh-plugin/dsh-loader';
|
|
23
|
+
const PATCH_ENTRY = `- id: dsh-loader\n name: '${LOADER_PKG}'`;
|
|
24
|
+
export function dshHome() {
|
|
25
|
+
const env = process.env.DSH_HOME?.trim();
|
|
26
|
+
return env ? resolve(env) : join(process.env.HOME ?? '~', '.dsh');
|
|
27
|
+
}
|
|
28
|
+
export function profileDir(profileName) {
|
|
29
|
+
return join(dshHome(), 'profiles', profileName);
|
|
30
|
+
}
|
|
31
|
+
function readJson(path) {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function writeJson(path, data) {
|
|
40
|
+
writeFileSync(path, JSON.stringify(data, undefined, 2) + '\n');
|
|
41
|
+
}
|
|
42
|
+
/** Ensure dshloader is listed in the profile package.json dependencies. */
|
|
43
|
+
export function injectDependency(pkgPath) {
|
|
44
|
+
const manifest = readJson(pkgPath) ?? { name: '', dependencies: {} };
|
|
45
|
+
manifest.dependencies = manifest.dependencies ?? {};
|
|
46
|
+
if (manifest.dependencies[LOADER_PKG] === undefined) {
|
|
47
|
+
manifest.dependencies[LOADER_PKG] = '^' + LOADER_VERSION;
|
|
48
|
+
writeJson(pkgPath, manifest);
|
|
49
|
+
return { added: true, manifest };
|
|
50
|
+
}
|
|
51
|
+
return { added: false, manifest };
|
|
52
|
+
}
|
|
53
|
+
/** Ensure the dshloader insert entry exists in cordis.patch.yml (no reorder). */
|
|
54
|
+
export function injectPatch(patchPath) {
|
|
55
|
+
let text = '';
|
|
56
|
+
try {
|
|
57
|
+
text = readFileSync(patchPath, 'utf8');
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
text = '';
|
|
61
|
+
}
|
|
62
|
+
if (text.includes('id: dsh-loader')) {
|
|
63
|
+
return { added: false, text };
|
|
64
|
+
}
|
|
65
|
+
const insertion = `- insert:\n ${PATCH_ENTRY}\n`;
|
|
66
|
+
const next = text.length === 0 ? insertion : text.endsWith('\n') ? text + insertion : text + '\n' + insertion;
|
|
67
|
+
writeFileSync(patchPath, next);
|
|
68
|
+
return { added: true, text: next };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Run `dshloader setup <profile>`.
|
|
72
|
+
* @param profileName
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
export function setupProfile(profileName) {
|
|
76
|
+
const dir = profileDir(profileName);
|
|
77
|
+
if (!existsSync(dir)) {
|
|
78
|
+
throw new Error(`${LOG_PREFIX} profile directory not found: ${dir}`);
|
|
79
|
+
}
|
|
80
|
+
const pkgPath = join(dir, 'package.json');
|
|
81
|
+
const patchPath = join(dir, 'cordis.patch.yml');
|
|
82
|
+
const dep = injectDependency(pkgPath);
|
|
83
|
+
const patch = injectPatch(patchPath);
|
|
84
|
+
console.log(`${LOG_PREFIX} setup ${profileName}: dependency ${dep.added ? 'added' : 'already present'}, patch ${patch.added ? 'appended' : 'already present'}`);
|
|
85
|
+
console.log(`${LOG_PREFIX} note: insert position is irrelevant — cordis reactive DI resolves aliases regardless of order (design.md §6.2)`);
|
|
86
|
+
return { profileDir: dir, dependencyAdded: dep.added, patchAdded: patch.added };
|
|
87
|
+
}
|
|
88
|
+
/** Best-effort dump-config validation. Returns { ok, output } (never throws). */
|
|
89
|
+
export function dumpConfig(profileName) {
|
|
90
|
+
const dir = profileDir(profileName);
|
|
91
|
+
if (!existsSync(dir)) {
|
|
92
|
+
return { ok: false, output: `${LOG_PREFIX} profile directory not found: ${dir}` };
|
|
93
|
+
}
|
|
94
|
+
const result = spawnSync('dsh', ['--profile', profileName, '--dump-config'], {
|
|
95
|
+
encoding: 'utf8',
|
|
96
|
+
timeout: 60_000,
|
|
97
|
+
});
|
|
98
|
+
const output = (result.stdout ?? '') + (result.stderr ?? '');
|
|
99
|
+
return { ok: result.status === 0, output };
|
|
100
|
+
}
|
|
101
|
+
/** Print dshloader status for a profile (AC-OB-03, minimal). */
|
|
102
|
+
export function info(profileName) {
|
|
103
|
+
console.log(`${LOG_PREFIX} version ${LOADER_VERSION}`);
|
|
104
|
+
const dir = profileName ? profileDir(profileName) : undefined;
|
|
105
|
+
const dshVersion = detectDshVersion(dir ? { profileDir: dir } : {});
|
|
106
|
+
console.log(`${LOG_PREFIX} detected dsh version: ${dshVersion ?? '<unknown>'}`);
|
|
107
|
+
if (dshVersion) {
|
|
108
|
+
try {
|
|
109
|
+
const reg = registerHostAdapters(new AdapterRegistry());
|
|
110
|
+
const { factory, mode } = reg.select(dshVersion);
|
|
111
|
+
console.log(`${LOG_PREFIX} selected adapter: ${factory.name} (supports ${factory.supports}, mode ${mode})`);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.log(`${LOG_PREFIX} adapter selection: ${error instanceof Error ? error.message : String(error)}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return { loaderVersion: LOADER_VERSION, dshVersion };
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared TypeScript types for dshloader (host + client).
|
|
3
|
+
*
|
|
4
|
+
* These describe only the shapes dshloader itself relies on from the cordis
|
|
5
|
+
* runtime, the real dsh settings/web services, and the browser client
|
|
6
|
+
* environment. The real dsh services are intentionally typed loosely (`any`)
|
|
7
|
+
* because dshloader's whole job is to absorb dsh's internal shape changes
|
|
8
|
+
* behind a stable API — pinning them here would defeat the compatibility
|
|
9
|
+
* shim's purpose.
|
|
10
|
+
*/
|
|
11
|
+
/** Minimal cordis context surface dshloader uses. */
|
|
12
|
+
export interface CordisContext {
|
|
13
|
+
get(name: string): any;
|
|
14
|
+
reflect: {
|
|
15
|
+
provide(name: string, value: any): void;
|
|
16
|
+
};
|
|
17
|
+
effect(fn: () => void | (() => void) | Promise<void | (() => void)>, label?: string): void;
|
|
18
|
+
}
|
|
19
|
+
/** dshloader host adapter factory. */
|
|
20
|
+
export interface AdapterFactory {
|
|
21
|
+
supports: string;
|
|
22
|
+
name: string;
|
|
23
|
+
create(ctx: CordisContext, config?: HostAdapterConfig): HostAdapter;
|
|
24
|
+
}
|
|
25
|
+
/** An instantiated host adapter. */
|
|
26
|
+
export interface HostAdapter {
|
|
27
|
+
supports: string;
|
|
28
|
+
name: string;
|
|
29
|
+
apply?: () => Promise<void> | void;
|
|
30
|
+
dispose?: () => void;
|
|
31
|
+
/** Adapter-provided overrides for the stable API capabilities. */
|
|
32
|
+
settings?: any;
|
|
33
|
+
web?: any;
|
|
34
|
+
services?: any;
|
|
35
|
+
}
|
|
36
|
+
/** Config passed to an adapter's create(). */
|
|
37
|
+
export interface HostAdapterConfig {
|
|
38
|
+
exposeAllNamespaces?: boolean;
|
|
39
|
+
hostPackageAliases?: Record<string, string>;
|
|
40
|
+
}
|
|
41
|
+
/** Result of AdapterRegistry.select(). */
|
|
42
|
+
export interface AdapterSelection {
|
|
43
|
+
factory: AdapterFactory;
|
|
44
|
+
mode: 'exact' | 'range' | 'fallback';
|
|
45
|
+
}
|
|
46
|
+
/** dshloader host API exposed as `ctx.dshLoader`. */
|
|
47
|
+
export interface HostAPI {
|
|
48
|
+
version: string;
|
|
49
|
+
dshVersion?: string;
|
|
50
|
+
adapterVersion?: string;
|
|
51
|
+
settings: SettingsAPI;
|
|
52
|
+
web: WebAPI;
|
|
53
|
+
services: ServicesAPI;
|
|
54
|
+
registerPackageAlias(oldName: string, newName: string): void;
|
|
55
|
+
}
|
|
56
|
+
/** Settings stable API. */
|
|
57
|
+
export interface SettingsAPI {
|
|
58
|
+
exposeAllNamespaces: boolean;
|
|
59
|
+
register(ns: string, schema: any, options?: any): any;
|
|
60
|
+
describe(options?: {
|
|
61
|
+
redactSecrets?: boolean;
|
|
62
|
+
}): any[];
|
|
63
|
+
update(ns: string, section?: any, expectedRevision?: number): Promise<SettingsResult>;
|
|
64
|
+
replace(ns: string, section?: any, expectedRevision?: number): Promise<SettingsResult>;
|
|
65
|
+
mutate(ns: string, ops?: any, expectedRevision?: number): Promise<SettingsResult>;
|
|
66
|
+
}
|
|
67
|
+
/** Settings write result shape. */
|
|
68
|
+
export interface SettingsResult {
|
|
69
|
+
ok: boolean;
|
|
70
|
+
value?: NamespaceView;
|
|
71
|
+
code?: string;
|
|
72
|
+
message?: string;
|
|
73
|
+
details?: Record<string, any>;
|
|
74
|
+
}
|
|
75
|
+
/** Official NamespaceView wire shape. */
|
|
76
|
+
export interface NamespaceView {
|
|
77
|
+
ns: string;
|
|
78
|
+
schema: any;
|
|
79
|
+
value: any;
|
|
80
|
+
base?: any;
|
|
81
|
+
user?: any;
|
|
82
|
+
applies?: any;
|
|
83
|
+
secrets: {
|
|
84
|
+
path: string[];
|
|
85
|
+
set?: any;
|
|
86
|
+
}[];
|
|
87
|
+
revision?: any;
|
|
88
|
+
}
|
|
89
|
+
/** Web stable API. */
|
|
90
|
+
export interface WebAPI {
|
|
91
|
+
register(prefix: string, handler: any): () => void;
|
|
92
|
+
get(path: string, handler: any): () => void;
|
|
93
|
+
post(path: string, handler: any): () => void;
|
|
94
|
+
use(middleware: any): () => void;
|
|
95
|
+
registerUpgrade(route: {
|
|
96
|
+
path: string;
|
|
97
|
+
handler: (req: any, socket: any, head: Buffer) => void;
|
|
98
|
+
}): () => void;
|
|
99
|
+
}
|
|
100
|
+
/** Services stable API. */
|
|
101
|
+
export interface ServicesAPI {
|
|
102
|
+
get(name: string): any;
|
|
103
|
+
alias(from: string, to: string): void;
|
|
104
|
+
}
|
|
105
|
+
/** Selectable adapter entry exposed for CLI/tests. */
|
|
106
|
+
export interface AdapterSelectionResult {
|
|
107
|
+
registry: import('./registry.js').AdapterRegistry;
|
|
108
|
+
factory: AdapterFactory;
|
|
109
|
+
mode: AdapterSelection['mode'];
|
|
110
|
+
dshVersion: string;
|
|
111
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared TypeScript types for dshloader (host + client).
|
|
3
|
+
*
|
|
4
|
+
* These describe only the shapes dshloader itself relies on from the cordis
|
|
5
|
+
* runtime, the real dsh settings/web services, and the browser client
|
|
6
|
+
* environment. The real dsh services are intentionally typed loosely (`any`)
|
|
7
|
+
* because dshloader's whole job is to absorb dsh's internal shape changes
|
|
8
|
+
* behind a stable API — pinning them here would defeat the compatibility
|
|
9
|
+
* shim's purpose.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|
package/{src → dist}/version.js
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// dshloader version — keep in sync with package.json.
|
|
2
|
-
export const LOADER_VERSION = '1.0.0';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
// dshloader version — keep in sync with package.json.
|
|
2
|
+
export const LOADER_VERSION = '1.0.0';
|
|
3
|
+
// Prefix used in every console log / error so users can grep dshloader output.
|
|
4
|
+
export const LOG_PREFIX = '[dshloader]';
|
|
5
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC"}
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@dsh-plugin/dsh-loader",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
//#region src/version.ts
|
|
8
|
+
const LOADER_VERSION = "1.0.0";
|
|
9
|
+
const LOG_PREFIX = "[dshloader]";
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/adapters/dsh-1-x.ts
|
|
12
|
+
const supports = ">=0.1.0-rc.1 <2.0.0";
|
|
13
|
+
const name$1 = "dsh-1-x";
|
|
14
|
+
const BRIDGE_PREFIX = "/api/dshloader";
|
|
15
|
+
const clientAdapters = [{
|
|
16
|
+
supports,
|
|
17
|
+
name: name$1,
|
|
18
|
+
moduleAliases: {
|
|
19
|
+
"@deepseek-ai/dsh-client-runtime/src/client/sessions/context-provenance.ts": "@deepseek-ai/dsh-client-runtime/client",
|
|
20
|
+
"dsh/runtime/context-provenance": "@deepseek-ai/dsh-client-runtime/client"
|
|
21
|
+
},
|
|
22
|
+
packageAliases: {
|
|
23
|
+
"@dsh-plugin/dsh-loader/ui-primitives": "@deepseek-ai/dsh-client-ui-primitives",
|
|
24
|
+
"@dsh-plugin/dsh-loader/ui-slots": "@deepseek-ai/dsh-client-ui-slots",
|
|
25
|
+
"@dsh-plugin/dsh-loader/web-react": "@deepseek-ai/dsh-client-web-react",
|
|
26
|
+
"@dsh-plugin/dsh-loader/schema-form": "@deepseek-ai/dsh-client-schema-form",
|
|
27
|
+
"@dsh-plugin/dsh-loader/ui-settings": "@deepseek-ai/dsh-client-ui-settings/client",
|
|
28
|
+
"@dsh-plugin/dsh-loader/runtime": "@deepseek-ai/dsh-client-runtime/client"
|
|
29
|
+
}
|
|
30
|
+
}];
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/client.ts
|
|
33
|
+
var ModuleNotFoundError = class extends Error {
|
|
34
|
+
specifier;
|
|
35
|
+
constructor(specifier) {
|
|
36
|
+
super(`${LOG_PREFIX} module not found: ${specifier}`);
|
|
37
|
+
this.name = "ModuleNotFoundError";
|
|
38
|
+
this.specifier = specifier;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Pick the client adapter for the given dsh version. v1 ships a single
|
|
43
|
+
* client adapter (dsh 1.x); when more are added, swap this for a semver-based
|
|
44
|
+
* selection mirroring the host AdapterRegistry.
|
|
45
|
+
*/
|
|
46
|
+
function pickClientAdapter(dshVersion) {
|
|
47
|
+
return clientAdapters[0];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Build the `window.__dshLoader__` API object.
|
|
51
|
+
*/
|
|
52
|
+
function createClientAPI(opts = {}) {
|
|
53
|
+
const aliases = new Map(Object.entries(opts.moduleAliases ?? {}));
|
|
54
|
+
const requireImpl = opts.requireImpl ?? ((spec) => {
|
|
55
|
+
throw new ModuleNotFoundError(spec);
|
|
56
|
+
});
|
|
57
|
+
const clientCtx = opts.clientCtx;
|
|
58
|
+
const packageAliases = opts.packageAliases instanceof Map ? opts.packageAliases : new Map(Object.entries(opts.packageAliases ?? {}));
|
|
59
|
+
return {
|
|
60
|
+
version: LOADER_VERSION,
|
|
61
|
+
dshVersion: opts.dshVersion,
|
|
62
|
+
adapterVersion: opts.adapterVersion,
|
|
63
|
+
require(specifier) {
|
|
64
|
+
if (typeof specifier !== "string") throw new ModuleNotFoundError(String(specifier));
|
|
65
|
+
const target = aliases.get(specifier);
|
|
66
|
+
if (target === void 0) throw new ModuleNotFoundError(specifier);
|
|
67
|
+
return requireImpl(target);
|
|
68
|
+
},
|
|
69
|
+
registerModuleAlias(alias, target) {
|
|
70
|
+
aliases.set(alias, target);
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* Register a package-name alias for the client module loader's
|
|
74
|
+
* require(). When a plugin's bundle calls require('@old/pkg-name'),
|
|
75
|
+
* the loader's wrapped require remaps it to '@new/pkg-name' before
|
|
76
|
+
* hitting the module table. This lets dsh rename client packages
|
|
77
|
+
* across versions without forcing plugin bundles to rebuild.
|
|
78
|
+
*/
|
|
79
|
+
registerPackageAlias(oldName, newName) {
|
|
80
|
+
packageAliases.set(oldName, newName);
|
|
81
|
+
},
|
|
82
|
+
/**
|
|
83
|
+
* Read a client-side cordis service by name.
|
|
84
|
+
* Proxies to `clientCtx.get(name)` — the same ctx.get plugins use
|
|
85
|
+
* inside their client `apply(ctx)`, but exposed through the stable
|
|
86
|
+
* dshloader surface so plugins don't depend on the cordis context
|
|
87
|
+
* shape directly.
|
|
88
|
+
*
|
|
89
|
+
* Only available when dshloader's client apply() received a ctx
|
|
90
|
+
* (cordis client boot). Returns undefined when ctx is not wired.
|
|
91
|
+
*/
|
|
92
|
+
services: { get(name) {
|
|
93
|
+
if (clientCtx === void 0 || typeof clientCtx.get !== "function") return void 0;
|
|
94
|
+
return clientCtx.get(name);
|
|
95
|
+
} },
|
|
96
|
+
rpc: opts.fetchBridge ? { settings: {
|
|
97
|
+
describe: () => opts.fetchBridge.describe(),
|
|
98
|
+
update: (ns, section) => opts.fetchBridge.write("update", {
|
|
99
|
+
ns,
|
|
100
|
+
section
|
|
101
|
+
}),
|
|
102
|
+
replace: (ns, section) => opts.fetchBridge.write("replace", {
|
|
103
|
+
ns,
|
|
104
|
+
section
|
|
105
|
+
}),
|
|
106
|
+
mutate: (ns, ops) => opts.fetchBridge.write("mutate", {
|
|
107
|
+
ns,
|
|
108
|
+
ops
|
|
109
|
+
})
|
|
110
|
+
} } : void 0
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Install dshloader into a browser-like environment.
|
|
115
|
+
*/
|
|
116
|
+
function installClient(opts = {}) {
|
|
117
|
+
const win = opts.window ?? (typeof window !== "undefined" ? window : void 0);
|
|
118
|
+
if (win === void 0) return void 0;
|
|
119
|
+
const dshVersion = opts.dshVersion ?? win.__DSHLOADER_VERSION__;
|
|
120
|
+
const adapter = pickClientAdapter(dshVersion);
|
|
121
|
+
const moduleAliases = { ...adapter.moduleAliases ?? {} };
|
|
122
|
+
const packageAliases = new Map(Object.entries(adapter.packageAliases ?? {}));
|
|
123
|
+
if (opts.packageAliases) for (const [k, v] of Object.entries(opts.packageAliases)) packageAliases.set(k, v);
|
|
124
|
+
const exposeAllNamespaces = Boolean(opts.exposeAllNamespaces ?? win.__DSHLOADER_CONFIG__?.exposeAllNamespaces);
|
|
125
|
+
const bridgePrefix = opts.hostBridgePrefix ?? "/api/dshloader";
|
|
126
|
+
const fetchBridge = exposeAllNamespaces ? {
|
|
127
|
+
describe: () => win.fetch(`${bridgePrefix}/settings/describe`, { headers: { accept: "application/json" } }).then((r) => r.json()),
|
|
128
|
+
write: (mode, payload) => win.fetch(`${bridgePrefix}/settings/${mode}`, {
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: { "content-type": "application/json" },
|
|
131
|
+
body: JSON.stringify(payload)
|
|
132
|
+
}).then((r) => r.json())
|
|
133
|
+
} : void 0;
|
|
134
|
+
const api = createClientAPI({
|
|
135
|
+
dshVersion,
|
|
136
|
+
adapterVersion: adapter.supports,
|
|
137
|
+
moduleAliases,
|
|
138
|
+
packageAliases,
|
|
139
|
+
requireImpl: opts.requireImpl ?? ((spec) => win.__dshNativeRequire__?.(spec)),
|
|
140
|
+
fetchBridge,
|
|
141
|
+
clientCtx: opts.clientCtx
|
|
142
|
+
});
|
|
143
|
+
win.__dshLoader__ = api;
|
|
144
|
+
const loader = win.__ModuleLoader__;
|
|
145
|
+
if (loader && typeof loader.load === "function") {
|
|
146
|
+
const originalLoad = loader.load.bind(loader);
|
|
147
|
+
loader.load = function dshloaderLoad(handoff) {
|
|
148
|
+
const wrappedFactory = (require$1) => {
|
|
149
|
+
const aliasedRequire = (spec) => {
|
|
150
|
+
return require$1(packageAliases.get(spec) ?? spec);
|
|
151
|
+
};
|
|
152
|
+
return handoff.factory(aliasedRequire);
|
|
153
|
+
};
|
|
154
|
+
return originalLoad({
|
|
155
|
+
id: handoff.id,
|
|
156
|
+
factory: wrappedFactory
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (loader && typeof loader.load === "function") for (const [aliasId, target] of Object.entries(moduleAliases)) loader.load({
|
|
161
|
+
id: aliasId,
|
|
162
|
+
factory: (require$2) => {
|
|
163
|
+
const mod = require$2(target);
|
|
164
|
+
if (aliasId.endsWith("context-provenance.ts") || aliasId.endsWith("context-provenance")) return { contextProvenance: mod.contextProvenance };
|
|
165
|
+
return mod;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
if (exposeAllNamespaces) {
|
|
169
|
+
installSettingsFetchInterceptor(win, bridgePrefix);
|
|
170
|
+
console.warn(`${LOG_PREFIX} exposeAllNamespaces enabled: bypassing official settings whitelist`);
|
|
171
|
+
}
|
|
172
|
+
return api;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Fetch interceptor for settings namespace whitelist bypass (fix 5, path 2).
|
|
176
|
+
* Mirrors dsh-upstream-fixes/lib/client.js (127-223).
|
|
177
|
+
*
|
|
178
|
+
* - /api/settings.describe: merge non-whitelisted namespaces from the host
|
|
179
|
+
* bridge into the official response (rpcId/official fields preserved).
|
|
180
|
+
* - /api/settings.{update,mutate,replace}: route writes for namespaces the
|
|
181
|
+
* official proxy does NOT expose through the host bridge, and rebuild the
|
|
182
|
+
* response envelope as `{ type: 'server-response', rpcId, result }` so the
|
|
183
|
+
* official client can correlate the response with the request.
|
|
184
|
+
*/
|
|
185
|
+
function installSettingsFetchInterceptor(win, bridgePrefix = BRIDGE_PREFIX) {
|
|
186
|
+
if (typeof win.fetch !== "function") return () => {};
|
|
187
|
+
const originalFetch = win.fetch;
|
|
188
|
+
/** Namespaces the official proxy itself exposed (learned from describe). */
|
|
189
|
+
const officialExposed = /* @__PURE__ */ new Set();
|
|
190
|
+
win.fetch = async function dshloaderFetch(input, init) {
|
|
191
|
+
let pathname = "";
|
|
192
|
+
try {
|
|
193
|
+
const urlLike = typeof input === "string" ? input : input.url;
|
|
194
|
+
pathname = new URL(urlLike, win.location?.origin ?? "http://localhost").pathname;
|
|
195
|
+
} catch {
|
|
196
|
+
pathname = String(input).split("?")[0];
|
|
197
|
+
}
|
|
198
|
+
const method = (init?.method ?? "GET").toUpperCase();
|
|
199
|
+
if (pathname === "/api/settings.describe") {
|
|
200
|
+
const response = await originalFetch.call(this, input, init);
|
|
201
|
+
try {
|
|
202
|
+
const body = await response.clone().json();
|
|
203
|
+
const namespaces = body?.result?.value?.namespaces;
|
|
204
|
+
if (!Array.isArray(namespaces)) return response;
|
|
205
|
+
for (const row of namespaces) if (typeof row?.ns === "string") officialExposed.add(row.ns);
|
|
206
|
+
const extraBody = await (await originalFetch.call(this, `${bridgePrefix}/settings/describe`, { headers: { accept: "application/json" } })).json();
|
|
207
|
+
if (extraBody?.ok !== true || !Array.isArray(extraBody.namespaces)) return response;
|
|
208
|
+
const seen = new Set(namespaces.map((row) => row.ns));
|
|
209
|
+
const merged = [...namespaces, ...extraBody.namespaces.filter((row) => !seen.has(row.ns))];
|
|
210
|
+
const ResponseCtor = win.Response;
|
|
211
|
+
return new ResponseCtor(JSON.stringify({
|
|
212
|
+
...body,
|
|
213
|
+
result: {
|
|
214
|
+
...body.result,
|
|
215
|
+
value: {
|
|
216
|
+
...body.result.value,
|
|
217
|
+
namespaces: merged
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}), {
|
|
221
|
+
status: 200,
|
|
222
|
+
headers: { "content-type": "application/json" }
|
|
223
|
+
});
|
|
224
|
+
} catch {
|
|
225
|
+
return response;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if ((pathname === "/api/settings.update" || pathname === "/api/settings.mutate" || pathname === "/api/settings.replace") && method === "POST") {
|
|
229
|
+
let rpcId = null;
|
|
230
|
+
let payload = null;
|
|
231
|
+
try {
|
|
232
|
+
const parsed = JSON.parse(String(init?.body ?? "{}"));
|
|
233
|
+
rpcId = parsed.rpcId;
|
|
234
|
+
payload = parsed.payload;
|
|
235
|
+
} catch {}
|
|
236
|
+
const ns = typeof payload?.ns === "string" ? payload.ns : "";
|
|
237
|
+
if (rpcId !== null && ns !== "" && officialExposed.size > 0 && !officialExposed.has(ns)) try {
|
|
238
|
+
const mode = pathname.slice(14);
|
|
239
|
+
const body = await (await originalFetch.call(this, `${bridgePrefix}/settings/${mode}`, {
|
|
240
|
+
method: "POST",
|
|
241
|
+
headers: { "content-type": "application/json" },
|
|
242
|
+
body: JSON.stringify(payload)
|
|
243
|
+
})).json();
|
|
244
|
+
if (body?.result) {
|
|
245
|
+
const ResponseCtor = win.Response;
|
|
246
|
+
return new ResponseCtor(JSON.stringify({
|
|
247
|
+
type: "server-response",
|
|
248
|
+
rpcId,
|
|
249
|
+
result: body.result
|
|
250
|
+
}), {
|
|
251
|
+
status: 200,
|
|
252
|
+
headers: { "content-type": "application/json" }
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
} catch {}
|
|
256
|
+
}
|
|
257
|
+
return originalFetch.call(this, input, init);
|
|
258
|
+
};
|
|
259
|
+
return () => {
|
|
260
|
+
win.fetch = originalFetch;
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
const name = "@dsh-plugin/dsh-loader";
|
|
264
|
+
const inject = [];
|
|
265
|
+
function apply(ctx) {
|
|
266
|
+
if (typeof window !== "undefined") installClient({
|
|
267
|
+
window,
|
|
268
|
+
clientCtx: ctx
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
272
|
+
exports.ModuleNotFoundError = ModuleNotFoundError;
|
|
273
|
+
exports.apply = apply;
|
|
274
|
+
exports.createClientAPI = createClientAPI;
|
|
275
|
+
exports.inject = inject;
|
|
276
|
+
exports.installClient = installClient;
|
|
277
|
+
exports.installSettingsFetchInterceptor = installSettingsFetchInterceptor;
|
|
278
|
+
exports.name = name;
|
|
279
|
+
return module.exports;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
//# sourceMappingURL=client.js.map
|