@eclipse-docks/core 0.7.111 → 0.7.112
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/api/index.js +2 -2
- package/dist/{api--wFgOEHp.js → api-BWhUdgQ_.js} +2 -2
- package/dist/{api--wFgOEHp.js.map → api-BWhUdgQ_.js.map} +1 -1
- package/dist/core/apploader.d.ts.map +1 -1
- package/dist/core/extensionregistry.d.ts +5 -0
- package/dist/core/extensionregistry.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/parts/index.js +1 -1
- package/dist/{parts-Da1O57F2.js → parts-D1n2XZVE.js} +31 -14
- package/dist/parts-D1n2XZVE.js.map +1 -0
- package/dist/vite-plugin-resolve-deps.d.ts +6 -0
- package/dist/vite-plugin-resolve-deps.d.ts.map +1 -1
- package/dist/vite-plugin-resolve-deps.js +48 -11
- package/dist/vite-plugin-resolve-deps.js.map +1 -1
- package/package.json +1 -1
- package/src/core/apploader.ts +7 -8
- package/src/core/extensionregistry.ts +33 -10
- package/src/vite-plugin-resolve-deps.ts +68 -12
- package/dist/parts-Da1O57F2.js.map +0 -1
|
@@ -49,5 +49,11 @@ export type ExtensionSideEffectsListOptions = {
|
|
|
49
49
|
pattern: RegExp;
|
|
50
50
|
};
|
|
51
51
|
export declare function listExtensionSideEffectPackages(dependencies: Record<string, string>, sideEffects: ExtensionSideEffectsListOptions): string[];
|
|
52
|
+
/**
|
|
53
|
+
* Walks extension package.json `dependencies` to collect transitive extension-* packages
|
|
54
|
+
* (e.g. extension-utils → extension-python-runtime → extension-terminal).
|
|
55
|
+
*/
|
|
56
|
+
export declare function collectTransitiveExtensionPackages(appRoot: string, seeds: string[], sideEffects: ExtensionSideEffectsListOptions): string[];
|
|
57
|
+
export declare function resolveExtensionSideEffectPackages(appRoot: string, dependencies: Record<string, string>, sideEffects: ExtensionSideEffectsListOptions): string[];
|
|
52
58
|
export declare function resolveDepVersionsPlugin(options?: ResolveDepVersionsPluginOptions): Plugin;
|
|
53
59
|
//# sourceMappingURL=vite-plugin-resolve-deps.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-resolve-deps.d.ts","sourceRoot":"","sources":["../src/vite-plugin-resolve-deps.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;CACnC;
|
|
1
|
+
{"version":3,"file":"vite-plugin-resolve-deps.d.ts","sourceRoot":"","sources":["../src/vite-plugin-resolve-deps.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;CACnC;AA8DD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,sBAAsB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7C,mBAAmB,GAAG,IAAI,CAkB5B;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,sBAAsB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGxB;AAID,8GAA8G;AAC9G,eAAO,MAAM,yBAAyB,4CAA4C,CAAC;AAanF,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC5C,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,GAAG,2BAA2B,CAAC;CAC9D,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,+BAA+B,GAAG;IAC5C,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAqBF,wBAAgB,+BAA+B,CAC7C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,WAAW,EAAE,+BAA+B,GAC3C,MAAM,EAAE,CAQV;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EAAE,EACf,WAAW,EAAE,+BAA+B,GAC3C,MAAM,EAAE,CAqBV;AAED,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,WAAW,EAAE,+BAA+B,GAC3C,MAAM,EAAE,CAQV;AAED,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,+BAA+B,GACxC,MAAM,CA0ER"}
|
|
@@ -1,25 +1,33 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
//#region src/vite-plugin-resolve-deps.ts
|
|
4
|
-
function
|
|
5
|
-
const segments =
|
|
4
|
+
function packageJsonPath(appRoot, packageName) {
|
|
5
|
+
const segments = packageName.startsWith("@") ? packageName.split("/") : [packageName];
|
|
6
6
|
const relativePath = path.join("node_modules", ...segments, "package.json");
|
|
7
7
|
let dir = path.resolve(appRoot);
|
|
8
8
|
const root = path.parse(dir).root;
|
|
9
9
|
while (true) {
|
|
10
10
|
const pkgPath = path.join(dir, relativePath);
|
|
11
|
-
if (existsSync(pkgPath))
|
|
12
|
-
try {
|
|
13
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
14
|
-
if (typeof pkg.version === "string") return pkg.version;
|
|
15
|
-
} catch {}
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
11
|
+
if (existsSync(pkgPath)) return pkgPath;
|
|
18
12
|
if (dir === root) break;
|
|
19
13
|
dir = path.dirname(dir);
|
|
20
14
|
}
|
|
21
15
|
return null;
|
|
22
16
|
}
|
|
17
|
+
function readPackageJson(appRoot, packageName) {
|
|
18
|
+
const pkgPath = packageJsonPath(appRoot, packageName);
|
|
19
|
+
if (!pkgPath) return null;
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function findPackageVersion(appRoot, depName) {
|
|
27
|
+
const pkg = readPackageJson(appRoot, depName);
|
|
28
|
+
if (typeof pkg?.version === "string") return pkg.version;
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
23
31
|
function resolveDepVersionsFromPkg(appRoot, pkg, options) {
|
|
24
32
|
const deps = { ...pkg.dependencies };
|
|
25
33
|
if (options?.includeDevDependencies && pkg.devDependencies) Object.assign(deps, pkg.devDependencies);
|
|
@@ -77,6 +85,34 @@ function listExtensionSideEffectPackages(dependencies, sideEffects) {
|
|
|
77
85
|
const rest = names.filter((n) => !prioritySet.has(n)).sort((a, b) => a.localeCompare(b));
|
|
78
86
|
return [...first, ...rest];
|
|
79
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Walks extension package.json `dependencies` to collect transitive extension-* packages
|
|
90
|
+
* (e.g. extension-utils → extension-python-runtime → extension-terminal).
|
|
91
|
+
*/
|
|
92
|
+
function collectTransitiveExtensionPackages(appRoot, seeds, sideEffects) {
|
|
93
|
+
const found = /* @__PURE__ */ new Set();
|
|
94
|
+
const queue = [...seeds];
|
|
95
|
+
const visited = /* @__PURE__ */ new Set();
|
|
96
|
+
while (queue.length > 0) {
|
|
97
|
+
const name = queue.shift();
|
|
98
|
+
if (visited.has(name)) continue;
|
|
99
|
+
visited.add(name);
|
|
100
|
+
const pkg = readPackageJson(appRoot, name);
|
|
101
|
+
if (!pkg?.dependencies) continue;
|
|
102
|
+
for (const dep of Object.keys(pkg.dependencies)) {
|
|
103
|
+
if (!sideEffects.pattern.test(dep) || sideEffects.exclude.has(dep)) continue;
|
|
104
|
+
found.add(dep);
|
|
105
|
+
queue.push(dep);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return [...found];
|
|
109
|
+
}
|
|
110
|
+
function resolveExtensionSideEffectPackages(appRoot, dependencies, sideEffects) {
|
|
111
|
+
const direct = listExtensionSideEffectPackages(dependencies, sideEffects);
|
|
112
|
+
const transitive = collectTransitiveExtensionPackages(appRoot, direct, sideEffects);
|
|
113
|
+
const allNames = [...new Set([...direct, ...transitive])];
|
|
114
|
+
return listExtensionSideEffectPackages(Object.fromEntries(allNames.map((name) => [name, "*"])), sideEffects);
|
|
115
|
+
}
|
|
80
116
|
function resolveDepVersionsPlugin(options) {
|
|
81
117
|
let appRoot = process.cwd();
|
|
82
118
|
let extensionSideEffectsActive = false;
|
|
@@ -101,7 +137,8 @@ function resolveDepVersionsPlugin(options) {
|
|
|
101
137
|
extensionImportPackages = [];
|
|
102
138
|
return;
|
|
103
139
|
}
|
|
104
|
-
|
|
140
|
+
const info = resolvePackageInfo(appRoot, options);
|
|
141
|
+
extensionImportPackages = resolveExtensionSideEffectPackages(appRoot, info?.dependencies ?? {}, normalized);
|
|
105
142
|
},
|
|
106
143
|
resolveId(id) {
|
|
107
144
|
if (id === "virtual:eclipse-docks-extension-imports") return RESOLVED_VIRTUAL_EXTENSION_IMPORTS;
|
|
@@ -125,6 +162,6 @@ function resolveDepVersionsPlugin(options) {
|
|
|
125
162
|
};
|
|
126
163
|
}
|
|
127
164
|
//#endregion
|
|
128
|
-
export { VIRTUAL_EXTENSION_IMPORTS, listExtensionSideEffectPackages, resolveDepVersions, resolveDepVersionsPlugin, resolvePackageInfo };
|
|
165
|
+
export { VIRTUAL_EXTENSION_IMPORTS, collectTransitiveExtensionPackages, listExtensionSideEffectPackages, resolveDepVersions, resolveDepVersionsPlugin, resolveExtensionSideEffectPackages, resolvePackageInfo };
|
|
129
166
|
|
|
130
167
|
//# sourceMappingURL=vite-plugin-resolve-deps.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-resolve-deps.js","names":[],"sources":["../src/vite-plugin-resolve-deps.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'fs';\nimport path from 'path';\nimport type { Plugin } from 'vite';\n\nexport interface ResolvedPackageInfo {\n name: string;\n version: string;\n description?: string;\n dependencies: Record<string, string>;\n marketplaceCatalogUrls?: string[];\n}\n\ninterface PackageJson {\n name?: string;\n version?: string;\n description?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nfunction findPackageVersion(appRoot: string, depName: string): string | null {\n const segments = depName.startsWith('@')\n ? depName.split('/')\n : [depName];\n const relativePath = path.join('node_modules', ...segments, 'package.json');\n let dir = path.resolve(appRoot);\n const root = path.parse(dir).root;\n\n while (true) {\n const pkgPath = path.join(dir, relativePath);\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;\n if (typeof pkg.version === 'string') return pkg.version;\n } catch {\n // ignore parse errors\n }\n return null;\n }\n if (dir === root) break;\n dir = path.dirname(dir);\n }\n return null;\n}\n\nfunction resolveDepVersionsFromPkg(\n appRoot: string,\n pkg: PackageJson,\n options?: { includeDevDependencies?: boolean }\n): Record<string, string> {\n const deps = { ...pkg.dependencies };\n if (options?.includeDevDependencies && pkg.devDependencies) {\n Object.assign(deps, pkg.devDependencies);\n }\n const result: Record<string, string> = {};\n for (const [name, specifier] of Object.entries(deps)) {\n const version = findPackageVersion(appRoot, name);\n result[name] = version ?? specifier;\n }\n return result;\n}\n\nexport function resolvePackageInfo(\n appRoot: string,\n options?: { includeDevDependencies?: boolean }\n): ResolvedPackageInfo | null {\n const pkgPath = path.join(appRoot, 'package.json');\n if (!existsSync(pkgPath)) return null;\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;\n } catch {\n return null;\n }\n\n const name = typeof pkg.name === 'string' ? pkg.name : '';\n const version = typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n const description = typeof pkg.description === 'string' ? pkg.description : undefined;\n const dependencies = resolveDepVersionsFromPkg(appRoot, pkg, options);\n const marketplaceCatalogUrls = (pkg as { marketplace?: { catalogUrls?: string[] } }).marketplace?.catalogUrls;\n\n return { name, version, description, dependencies, marketplaceCatalogUrls };\n}\n\nexport function resolveDepVersions(\n appRoot: string,\n options?: { includeDevDependencies?: boolean }\n): Record<string, string> {\n const info = resolvePackageInfo(appRoot, options);\n return info?.dependencies ?? {};\n}\n\nconst RESOLVED_PACKAGE_INFO_KEY = '__RESOLVED_PACKAGE_INFO__';\n\n/** Virtual module id; injected into `index.html` before `main.ts` when extension side-effects are enabled. */\nexport const VIRTUAL_EXTENSION_IMPORTS = 'virtual:eclipse-docks-extension-imports';\n\nconst RESOLVED_VIRTUAL_EXTENSION_IMPORTS = `\\0${VIRTUAL_EXTENSION_IMPORTS}`;\n\n/** Unscoped `extension-*` or scoped `@namespace/extension-*` (any npm scope). */\nconst DEFAULT_EXTENSION_PATTERN = /^(?:@[^/]+\\/)?extension-/;\n\nconst DEFAULT_PRIORITY_FIRST = ['@eclipse-docks/extension-pwa', 'extension-pwa'];\n\n/** Matches Vite’s default app entry in index.html. */\nconst MAIN_TS_SCRIPT_RE =\n /<script\\b[^>]*\\btype\\s*=\\s*[\"']module[\"'][^>]*\\bsrc\\s*=\\s*[\"'][^\"']*\\/src\\/main\\.ts[\"'][^>]*>\\s*<\\/script>/i;\n\nexport interface ExtensionSideEffectsOptions {\n /**\n * When false, disables automatic extension side-effect imports. Omitted or true keeps them on.\n */\n enabled?: boolean;\n /** Dependency names to skip (even if they match `packageNamePattern`). */\n exclude?: string[];\n /**\n * Packages to load first, in order (only those present in dependencies are imported).\n * Default includes PWA so `beforeinstallprompt` can register early.\n */\n priorityFirst?: string[];\n /**\n * Which direct `dependencies` keys qualify as Docks-style extensions (`extension-*`, with an optional npm scope).\n * @default /^(?:@[^/]+\\/)?extension-/\n */\n packageNamePattern?: RegExp;\n}\n\nexport type ResolveDepVersionsPluginOptions = {\n includeDevDependencies?: boolean;\n /**\n * By default, registers a virtual module that side-effect-imports every matching direct\n * `dependencies` entry (see `ExtensionSideEffectsOptions`), and injects\n * `import 'virtual:eclipse-docks-extension-imports'` into `index.html` **before** `/src/main.ts`.\n * Pass `false` or `{ enabled: false }` to disable.\n */\n extensionSideEffects?: boolean | ExtensionSideEffectsOptions;\n};\n\n/** Normalized match options for {@link listExtensionSideEffectPackages}. */\nexport type ExtensionSideEffectsListOptions = {\n exclude: Set<string>;\n priorityFirst: string[];\n pattern: RegExp;\n};\n\nfunction normalizeExtensionSideEffects(\n opt: boolean | ExtensionSideEffectsOptions | undefined,\n): ExtensionSideEffectsListOptions | null {\n if (opt === false) return null;\n if (opt === undefined || opt === true) {\n return {\n exclude: new Set(),\n priorityFirst: [...DEFAULT_PRIORITY_FIRST],\n pattern: DEFAULT_EXTENSION_PATTERN,\n };\n }\n if (opt.enabled === false) return null;\n return {\n exclude: new Set(opt.exclude ?? []),\n priorityFirst: opt.priorityFirst ?? [...DEFAULT_PRIORITY_FIRST],\n pattern: opt.packageNamePattern ?? DEFAULT_EXTENSION_PATTERN,\n };\n}\n\nexport function listExtensionSideEffectPackages(\n dependencies: Record<string, string>,\n sideEffects: ExtensionSideEffectsListOptions,\n): string[] {\n const names = Object.keys(dependencies).filter(\n (name) => sideEffects.pattern.test(name) && !sideEffects.exclude.has(name),\n );\n const prioritySet = new Set(sideEffects.priorityFirst);\n const first = sideEffects.priorityFirst.filter((p) => names.includes(p));\n const rest = names.filter((n) => !prioritySet.has(n)).sort((a, b) => a.localeCompare(b));\n return [...first, ...rest];\n}\n\nexport function resolveDepVersionsPlugin(\n options?: ResolveDepVersionsPluginOptions,\n): Plugin {\n let appRoot = process.cwd();\n let extensionSideEffectsActive = false;\n let extensionImportPackages: string[] = [];\n\n return {\n name: 'resolve-dep-versions',\n config(config) {\n const root = config.root ? path.resolve(config.root) : process.cwd();\n const info = resolvePackageInfo(root, options);\n const value =\n info ?? {\n name: '',\n version: '0.0.0',\n description: undefined,\n dependencies: {},\n marketplaceCatalogUrls: undefined,\n };\n return {\n define: {\n [RESOLVED_PACKAGE_INFO_KEY]: JSON.stringify(value),\n },\n };\n },\n configResolved(config) {\n appRoot = path.resolve(config.root ?? process.cwd());\n const normalized = normalizeExtensionSideEffects(options?.extensionSideEffects);\n extensionSideEffectsActive = normalized !== null;\n if (!normalized) {\n extensionImportPackages = [];\n return;\n }\n const info = resolvePackageInfo(appRoot, options);\n extensionImportPackages = listExtensionSideEffectPackages(\n info?.dependencies ?? {},\n normalized,\n );\n },\n resolveId(id) {\n if (id === VIRTUAL_EXTENSION_IMPORTS) {\n return RESOLVED_VIRTUAL_EXTENSION_IMPORTS;\n }\n return undefined;\n },\n load(id) {\n if (id !== RESOLVED_VIRTUAL_EXTENSION_IMPORTS) {\n return null;\n }\n if (extensionImportPackages.length === 0) {\n return 'export {};\\n';\n }\n return extensionImportPackages.map((pkg) => `import ${JSON.stringify(pkg)};\\n`).join('');\n },\n transformIndexHtml: {\n order: 'pre',\n handler(html) {\n if (!extensionSideEffectsActive) {\n return html;\n }\n if (extensionImportPackages.length === 0) {\n return html;\n }\n if (html.includes(VIRTUAL_EXTENSION_IMPORTS)) {\n return html;\n }\n if (!MAIN_TS_SCRIPT_RE.test(html)) {\n return html;\n }\n const inject = `<script type=\"module\">import ${JSON.stringify(VIRTUAL_EXTENSION_IMPORTS)};</script>\\n`;\n return html.replace(MAIN_TS_SCRIPT_RE, (match) => `${inject}${match}`);\n },\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vite-plugin-resolve-deps.js","names":[],"sources":["../src/vite-plugin-resolve-deps.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'fs';\nimport path from 'path';\nimport type { Plugin } from 'vite';\n\nexport interface ResolvedPackageInfo {\n name: string;\n version: string;\n description?: string;\n dependencies: Record<string, string>;\n marketplaceCatalogUrls?: string[];\n}\n\ninterface PackageJson {\n name?: string;\n version?: string;\n description?: string;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nfunction packageJsonPath(appRoot: string, packageName: string): string | null {\n const segments = packageName.startsWith('@')\n ? packageName.split('/')\n : [packageName];\n const relativePath = path.join('node_modules', ...segments, 'package.json');\n let dir = path.resolve(appRoot);\n const root = path.parse(dir).root;\n\n while (true) {\n const pkgPath = path.join(dir, relativePath);\n if (existsSync(pkgPath)) {\n return pkgPath;\n }\n if (dir === root) break;\n dir = path.dirname(dir);\n }\n return null;\n}\n\nfunction readPackageJson(appRoot: string, packageName: string): PackageJson | null {\n const pkgPath = packageJsonPath(appRoot, packageName);\n if (!pkgPath) return null;\n try {\n return JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;\n } catch {\n return null;\n }\n}\n\nfunction findPackageVersion(appRoot: string, depName: string): string | null {\n const pkg = readPackageJson(appRoot, depName);\n if (typeof pkg?.version === 'string') return pkg.version;\n return null;\n}\n\nfunction resolveDepVersionsFromPkg(\n appRoot: string,\n pkg: PackageJson,\n options?: { includeDevDependencies?: boolean }\n): Record<string, string> {\n const deps = { ...pkg.dependencies };\n if (options?.includeDevDependencies && pkg.devDependencies) {\n Object.assign(deps, pkg.devDependencies);\n }\n const result: Record<string, string> = {};\n for (const [name, specifier] of Object.entries(deps)) {\n const version = findPackageVersion(appRoot, name);\n result[name] = version ?? specifier;\n }\n return result;\n}\n\nexport function resolvePackageInfo(\n appRoot: string,\n options?: { includeDevDependencies?: boolean }\n): ResolvedPackageInfo | null {\n const pkgPath = path.join(appRoot, 'package.json');\n if (!existsSync(pkgPath)) return null;\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;\n } catch {\n return null;\n }\n\n const name = typeof pkg.name === 'string' ? pkg.name : '';\n const version = typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n const description = typeof pkg.description === 'string' ? pkg.description : undefined;\n const dependencies = resolveDepVersionsFromPkg(appRoot, pkg, options);\n const marketplaceCatalogUrls = (pkg as { marketplace?: { catalogUrls?: string[] } }).marketplace?.catalogUrls;\n\n return { name, version, description, dependencies, marketplaceCatalogUrls };\n}\n\nexport function resolveDepVersions(\n appRoot: string,\n options?: { includeDevDependencies?: boolean }\n): Record<string, string> {\n const info = resolvePackageInfo(appRoot, options);\n return info?.dependencies ?? {};\n}\n\nconst RESOLVED_PACKAGE_INFO_KEY = '__RESOLVED_PACKAGE_INFO__';\n\n/** Virtual module id; injected into `index.html` before `main.ts` when extension side-effects are enabled. */\nexport const VIRTUAL_EXTENSION_IMPORTS = 'virtual:eclipse-docks-extension-imports';\n\nconst RESOLVED_VIRTUAL_EXTENSION_IMPORTS = `\\0${VIRTUAL_EXTENSION_IMPORTS}`;\n\n/** Unscoped `extension-*` or scoped `@namespace/extension-*` (any npm scope). */\nconst DEFAULT_EXTENSION_PATTERN = /^(?:@[^/]+\\/)?extension-/;\n\nconst DEFAULT_PRIORITY_FIRST = ['@eclipse-docks/extension-pwa', 'extension-pwa'];\n\n/** Matches Vite’s default app entry in index.html. */\nconst MAIN_TS_SCRIPT_RE =\n /<script\\b[^>]*\\btype\\s*=\\s*[\"']module[\"'][^>]*\\bsrc\\s*=\\s*[\"'][^\"']*\\/src\\/main\\.ts[\"'][^>]*>\\s*<\\/script>/i;\n\nexport interface ExtensionSideEffectsOptions {\n /**\n * When false, disables automatic extension side-effect imports. Omitted or true keeps them on.\n */\n enabled?: boolean;\n /** Dependency names to skip (even if they match `packageNamePattern`). */\n exclude?: string[];\n /**\n * Packages to load first, in order (only those present in dependencies are imported).\n * Default includes PWA so `beforeinstallprompt` can register early.\n */\n priorityFirst?: string[];\n /**\n * Which direct `dependencies` keys qualify as Docks-style extensions (`extension-*`, with an optional npm scope).\n * @default /^(?:@[^/]+\\/)?extension-/\n */\n packageNamePattern?: RegExp;\n}\n\nexport type ResolveDepVersionsPluginOptions = {\n includeDevDependencies?: boolean;\n /**\n * By default, registers a virtual module that side-effect-imports every matching direct\n * `dependencies` entry (see `ExtensionSideEffectsOptions`), and injects\n * `import 'virtual:eclipse-docks-extension-imports'` into `index.html` **before** `/src/main.ts`.\n * Pass `false` or `{ enabled: false }` to disable.\n */\n extensionSideEffects?: boolean | ExtensionSideEffectsOptions;\n};\n\n/** Normalized match options for {@link listExtensionSideEffectPackages}. */\nexport type ExtensionSideEffectsListOptions = {\n exclude: Set<string>;\n priorityFirst: string[];\n pattern: RegExp;\n};\n\nfunction normalizeExtensionSideEffects(\n opt: boolean | ExtensionSideEffectsOptions | undefined,\n): ExtensionSideEffectsListOptions | null {\n if (opt === false) return null;\n if (opt === undefined || opt === true) {\n return {\n exclude: new Set(),\n priorityFirst: [...DEFAULT_PRIORITY_FIRST],\n pattern: DEFAULT_EXTENSION_PATTERN,\n };\n }\n if (opt.enabled === false) return null;\n return {\n exclude: new Set(opt.exclude ?? []),\n priorityFirst: opt.priorityFirst ?? [...DEFAULT_PRIORITY_FIRST],\n pattern: opt.packageNamePattern ?? DEFAULT_EXTENSION_PATTERN,\n };\n}\n\nexport function listExtensionSideEffectPackages(\n dependencies: Record<string, string>,\n sideEffects: ExtensionSideEffectsListOptions,\n): string[] {\n const names = Object.keys(dependencies).filter(\n (name) => sideEffects.pattern.test(name) && !sideEffects.exclude.has(name),\n );\n const prioritySet = new Set(sideEffects.priorityFirst);\n const first = sideEffects.priorityFirst.filter((p) => names.includes(p));\n const rest = names.filter((n) => !prioritySet.has(n)).sort((a, b) => a.localeCompare(b));\n return [...first, ...rest];\n}\n\n/**\n * Walks extension package.json `dependencies` to collect transitive extension-* packages\n * (e.g. extension-utils → extension-python-runtime → extension-terminal).\n */\nexport function collectTransitiveExtensionPackages(\n appRoot: string,\n seeds: string[],\n sideEffects: ExtensionSideEffectsListOptions,\n): string[] {\n const found = new Set<string>();\n const queue = [...seeds];\n const visited = new Set<string>();\n\n while (queue.length > 0) {\n const name = queue.shift()!;\n if (visited.has(name)) continue;\n visited.add(name);\n\n const pkg = readPackageJson(appRoot, name);\n if (!pkg?.dependencies) continue;\n\n for (const dep of Object.keys(pkg.dependencies)) {\n if (!sideEffects.pattern.test(dep) || sideEffects.exclude.has(dep)) continue;\n found.add(dep);\n queue.push(dep);\n }\n }\n\n return [...found];\n}\n\nexport function resolveExtensionSideEffectPackages(\n appRoot: string,\n dependencies: Record<string, string>,\n sideEffects: ExtensionSideEffectsListOptions,\n): string[] {\n const direct = listExtensionSideEffectPackages(dependencies, sideEffects);\n const transitive = collectTransitiveExtensionPackages(appRoot, direct, sideEffects);\n const allNames = [...new Set([...direct, ...transitive])];\n return listExtensionSideEffectPackages(\n Object.fromEntries(allNames.map((name) => [name, '*'])),\n sideEffects,\n );\n}\n\nexport function resolveDepVersionsPlugin(\n options?: ResolveDepVersionsPluginOptions,\n): Plugin {\n let appRoot = process.cwd();\n let extensionSideEffectsActive = false;\n let extensionImportPackages: string[] = [];\n\n return {\n name: 'resolve-dep-versions',\n config(config) {\n const root = config.root ? path.resolve(config.root) : process.cwd();\n const info = resolvePackageInfo(root, options);\n const value =\n info ?? {\n name: '',\n version: '0.0.0',\n description: undefined,\n dependencies: {},\n marketplaceCatalogUrls: undefined,\n };\n return {\n define: {\n [RESOLVED_PACKAGE_INFO_KEY]: JSON.stringify(value),\n },\n };\n },\n configResolved(config) {\n appRoot = path.resolve(config.root ?? process.cwd());\n const normalized = normalizeExtensionSideEffects(options?.extensionSideEffects);\n extensionSideEffectsActive = normalized !== null;\n if (!normalized) {\n extensionImportPackages = [];\n return;\n }\n const info = resolvePackageInfo(appRoot, options);\n extensionImportPackages = resolveExtensionSideEffectPackages(\n appRoot,\n info?.dependencies ?? {},\n normalized,\n );\n },\n resolveId(id) {\n if (id === VIRTUAL_EXTENSION_IMPORTS) {\n return RESOLVED_VIRTUAL_EXTENSION_IMPORTS;\n }\n return undefined;\n },\n load(id) {\n if (id !== RESOLVED_VIRTUAL_EXTENSION_IMPORTS) {\n return null;\n }\n if (extensionImportPackages.length === 0) {\n return 'export {};\\n';\n }\n return extensionImportPackages.map((pkg) => `import ${JSON.stringify(pkg)};\\n`).join('');\n },\n transformIndexHtml: {\n order: 'pre',\n handler(html) {\n if (!extensionSideEffectsActive) {\n return html;\n }\n if (extensionImportPackages.length === 0) {\n return html;\n }\n if (html.includes(VIRTUAL_EXTENSION_IMPORTS)) {\n return html;\n }\n if (!MAIN_TS_SCRIPT_RE.test(html)) {\n return html;\n }\n const inject = `<script type=\"module\">import ${JSON.stringify(VIRTUAL_EXTENSION_IMPORTS)};</script>\\n`;\n return html.replace(MAIN_TS_SCRIPT_RE, (match) => `${inject}${match}`);\n },\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/core/apploader.ts
CHANGED
|
@@ -416,14 +416,8 @@ class AppLoaderService {
|
|
|
416
416
|
this.systemRequiredExtensions.forEach(extId => extensionsSet.add(extId));
|
|
417
417
|
app.extensions = Array.from(extensionsSet);
|
|
418
418
|
|
|
419
|
-
//
|
|
420
|
-
//
|
|
421
|
-
// load any extensions that are marked as enabled in settings (including
|
|
422
|
-
// persisted external extensions).
|
|
423
|
-
this.dispatchLoadProgress('Loading extensions…');
|
|
424
|
-
await extensionRegistry.loadEnabledExtensions();
|
|
425
|
-
|
|
426
|
-
// Enable and load app extensions so commands/contributions are registered before UI is shown
|
|
419
|
+
// Enable and load app extensions first so declared dependencies
|
|
420
|
+
// are loaded before persisted settings extensions run.
|
|
427
421
|
if (app.extensions.length > 0) {
|
|
428
422
|
this.dispatchLoadProgress('Enabling extensions…');
|
|
429
423
|
await Promise.all(
|
|
@@ -435,6 +429,11 @@ class AppLoaderService {
|
|
|
435
429
|
);
|
|
436
430
|
}
|
|
437
431
|
|
|
432
|
+
// Load any additional extensions marked as enabled in settings (including
|
|
433
|
+
// persisted external extensions).
|
|
434
|
+
this.dispatchLoadProgress('Loading extensions…');
|
|
435
|
+
await extensionRegistry.loadEnabledExtensions();
|
|
436
|
+
|
|
438
437
|
// Initialize new app
|
|
439
438
|
if (app.initialize) {
|
|
440
439
|
this.dispatchLoadProgress('Initializing…');
|
|
@@ -301,6 +301,24 @@ class ExtensionRegistry {
|
|
|
301
301
|
* await extensionRegistry.load('@eclipse-docks/extension-notebook')
|
|
302
302
|
* ```
|
|
303
303
|
*/
|
|
304
|
+
/**
|
|
305
|
+
* Extension ids match npm package names. When a dependency was not side-effect-imported
|
|
306
|
+
* (e.g. only a transitive package.json dependency), importing the package registers it.
|
|
307
|
+
*/
|
|
308
|
+
private async ensureExtensionRegistered(extensionId: string): Promise<void> {
|
|
309
|
+
if (this.extensions[extensionId]) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
await import(/* @vite-ignore */ extensionId);
|
|
314
|
+
} catch (error) {
|
|
315
|
+
logger.debug(`Could not side-effect import extension package ${extensionId}: ${error}`);
|
|
316
|
+
}
|
|
317
|
+
if (!this.extensions[extensionId]) {
|
|
318
|
+
throw new Error("Extension not found: " + extensionId);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
304
322
|
public async load(extensionId: string, loadingChain: string[] = []): Promise<void> {
|
|
305
323
|
// Already loaded, return immediately
|
|
306
324
|
if (this.loadedExtensions.has(extensionId)) {
|
|
@@ -321,15 +339,20 @@ class ExtensionRegistry {
|
|
|
321
339
|
|
|
322
340
|
const extension = this.extensions[extensionId]
|
|
323
341
|
if (!extension) {
|
|
342
|
+
await this.ensureExtensionRegistered(extensionId);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const resolvedExtension = this.extensions[extensionId]
|
|
346
|
+
if (!resolvedExtension) {
|
|
324
347
|
throw new Error("Extension not found: " + extensionId)
|
|
325
348
|
}
|
|
326
349
|
|
|
327
350
|
const loadingPromise = (async () => {
|
|
328
351
|
try {
|
|
329
352
|
logger.debug(`Loading extension: ${extensionId}`);
|
|
330
|
-
if (
|
|
353
|
+
if (resolvedExtension.dependencies && resolvedExtension.dependencies.length > 0) {
|
|
331
354
|
const newChain = [...loadingChain, extensionId]
|
|
332
|
-
for (const depId of
|
|
355
|
+
for (const depId of resolvedExtension.dependencies) {
|
|
333
356
|
await this.load(depId, newChain)
|
|
334
357
|
// Enable the dependency if it's not already enabled
|
|
335
358
|
if (!this.isEnabled(depId)) {
|
|
@@ -339,14 +362,14 @@ class ExtensionRegistry {
|
|
|
339
362
|
}
|
|
340
363
|
}
|
|
341
364
|
|
|
342
|
-
const module = await taskService.runAsync("Loading extension: " +
|
|
343
|
-
if (
|
|
344
|
-
return
|
|
345
|
-
} else if (
|
|
346
|
-
let finalUrl =
|
|
347
|
-
if (esmShService.isSourceIdentifier(
|
|
348
|
-
finalUrl = esmShService.normalizeToEsmSh(
|
|
349
|
-
logger.debug(`Normalized extension URL: ${
|
|
365
|
+
const module = await taskService.runAsync("Loading extension: " + resolvedExtension.name, async () => {
|
|
366
|
+
if (resolvedExtension.loader) {
|
|
367
|
+
return resolvedExtension.loader()
|
|
368
|
+
} else if (resolvedExtension.url) {
|
|
369
|
+
let finalUrl = resolvedExtension.url;
|
|
370
|
+
if (esmShService.isSourceIdentifier(resolvedExtension.url)) {
|
|
371
|
+
finalUrl = esmShService.normalizeToEsmSh(resolvedExtension.url);
|
|
372
|
+
logger.debug(`Normalized extension URL: ${resolvedExtension.url} -> ${finalUrl}`);
|
|
350
373
|
}
|
|
351
374
|
return import(/* @vite-ignore */ finalUrl)
|
|
352
375
|
}
|
|
@@ -18,10 +18,10 @@ interface PackageJson {
|
|
|
18
18
|
devDependencies?: Record<string, string>;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
function
|
|
22
|
-
const segments =
|
|
23
|
-
?
|
|
24
|
-
: [
|
|
21
|
+
function packageJsonPath(appRoot: string, packageName: string): string | null {
|
|
22
|
+
const segments = packageName.startsWith('@')
|
|
23
|
+
? packageName.split('/')
|
|
24
|
+
: [packageName];
|
|
25
25
|
const relativePath = path.join('node_modules', ...segments, 'package.json');
|
|
26
26
|
let dir = path.resolve(appRoot);
|
|
27
27
|
const root = path.parse(dir).root;
|
|
@@ -29,13 +29,7 @@ function findPackageVersion(appRoot: string, depName: string): string | null {
|
|
|
29
29
|
while (true) {
|
|
30
30
|
const pkgPath = path.join(dir, relativePath);
|
|
31
31
|
if (existsSync(pkgPath)) {
|
|
32
|
-
|
|
33
|
-
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;
|
|
34
|
-
if (typeof pkg.version === 'string') return pkg.version;
|
|
35
|
-
} catch {
|
|
36
|
-
// ignore parse errors
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
32
|
+
return pkgPath;
|
|
39
33
|
}
|
|
40
34
|
if (dir === root) break;
|
|
41
35
|
dir = path.dirname(dir);
|
|
@@ -43,6 +37,22 @@ function findPackageVersion(appRoot: string, depName: string): string | null {
|
|
|
43
37
|
return null;
|
|
44
38
|
}
|
|
45
39
|
|
|
40
|
+
function readPackageJson(appRoot: string, packageName: string): PackageJson | null {
|
|
41
|
+
const pkgPath = packageJsonPath(appRoot, packageName);
|
|
42
|
+
if (!pkgPath) return null;
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function findPackageVersion(appRoot: string, depName: string): string | null {
|
|
51
|
+
const pkg = readPackageJson(appRoot, depName);
|
|
52
|
+
if (typeof pkg?.version === 'string') return pkg.version;
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
46
56
|
function resolveDepVersionsFromPkg(
|
|
47
57
|
appRoot: string,
|
|
48
58
|
pkg: PackageJson,
|
|
@@ -176,6 +186,51 @@ export function listExtensionSideEffectPackages(
|
|
|
176
186
|
return [...first, ...rest];
|
|
177
187
|
}
|
|
178
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Walks extension package.json `dependencies` to collect transitive extension-* packages
|
|
191
|
+
* (e.g. extension-utils → extension-python-runtime → extension-terminal).
|
|
192
|
+
*/
|
|
193
|
+
export function collectTransitiveExtensionPackages(
|
|
194
|
+
appRoot: string,
|
|
195
|
+
seeds: string[],
|
|
196
|
+
sideEffects: ExtensionSideEffectsListOptions,
|
|
197
|
+
): string[] {
|
|
198
|
+
const found = new Set<string>();
|
|
199
|
+
const queue = [...seeds];
|
|
200
|
+
const visited = new Set<string>();
|
|
201
|
+
|
|
202
|
+
while (queue.length > 0) {
|
|
203
|
+
const name = queue.shift()!;
|
|
204
|
+
if (visited.has(name)) continue;
|
|
205
|
+
visited.add(name);
|
|
206
|
+
|
|
207
|
+
const pkg = readPackageJson(appRoot, name);
|
|
208
|
+
if (!pkg?.dependencies) continue;
|
|
209
|
+
|
|
210
|
+
for (const dep of Object.keys(pkg.dependencies)) {
|
|
211
|
+
if (!sideEffects.pattern.test(dep) || sideEffects.exclude.has(dep)) continue;
|
|
212
|
+
found.add(dep);
|
|
213
|
+
queue.push(dep);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return [...found];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function resolveExtensionSideEffectPackages(
|
|
221
|
+
appRoot: string,
|
|
222
|
+
dependencies: Record<string, string>,
|
|
223
|
+
sideEffects: ExtensionSideEffectsListOptions,
|
|
224
|
+
): string[] {
|
|
225
|
+
const direct = listExtensionSideEffectPackages(dependencies, sideEffects);
|
|
226
|
+
const transitive = collectTransitiveExtensionPackages(appRoot, direct, sideEffects);
|
|
227
|
+
const allNames = [...new Set([...direct, ...transitive])];
|
|
228
|
+
return listExtensionSideEffectPackages(
|
|
229
|
+
Object.fromEntries(allNames.map((name) => [name, '*'])),
|
|
230
|
+
sideEffects,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
179
234
|
export function resolveDepVersionsPlugin(
|
|
180
235
|
options?: ResolveDepVersionsPluginOptions,
|
|
181
236
|
): Plugin {
|
|
@@ -211,7 +266,8 @@ export function resolveDepVersionsPlugin(
|
|
|
211
266
|
return;
|
|
212
267
|
}
|
|
213
268
|
const info = resolvePackageInfo(appRoot, options);
|
|
214
|
-
extensionImportPackages =
|
|
269
|
+
extensionImportPackages = resolveExtensionSideEffectPackages(
|
|
270
|
+
appRoot,
|
|
215
271
|
info?.dependencies ?? {},
|
|
216
272
|
normalized,
|
|
217
273
|
);
|