@eclipse-docks/core 0.7.132 → 0.7.134
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.d.ts +3 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +3 -3
- package/dist/api/services.d.ts +2 -0
- package/dist/api/services.d.ts.map +1 -1
- package/dist/api/types.d.ts +3 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/{api-DImisUWV.js → api-DNLFdSfp.js} +128 -24
- package/dist/api-DNLFdSfp.js.map +1 -0
- package/dist/components/npm-packages.d.ts +5 -1
- package/dist/components/npm-packages.d.ts.map +1 -1
- package/dist/contributions/default-attributions-contributions.d.ts +2 -0
- package/dist/contributions/default-attributions-contributions.d.ts.map +1 -0
- package/dist/contributions/index.d.ts.map +1 -1
- package/dist/core/apploader.d.ts +11 -5
- package/dist/core/apploader.d.ts.map +1 -1
- package/dist/core/contribution-names.d.ts +1 -0
- package/dist/core/contribution-names.d.ts.map +1 -1
- package/dist/core/license-attribution.d.ts +13 -0
- package/dist/core/license-attribution.d.ts.map +1 -0
- package/dist/core/resolved-package-info.d.ts +10 -0
- package/dist/core/resolved-package-info.d.ts.map +1 -0
- package/dist/index.js +3 -3
- package/dist/parts/index.js +1 -1
- package/dist/{parts-DQRktiiR.js → parts-VwCbRGd_.js} +5 -2
- package/dist/parts-VwCbRGd_.js.map +1 -0
- package/dist/vite-plugin-resolve-deps.d.ts +18 -8
- package/dist/vite-plugin-resolve-deps.d.ts.map +1 -1
- package/dist/vite-plugin-resolve-deps.js +140 -21
- package/dist/vite-plugin-resolve-deps.js.map +1 -1
- package/package.json +1 -1
- package/src/api/index.ts +10 -1
- package/src/api/services.ts +2 -0
- package/src/api/types.ts +10 -1
- package/src/commands/global.ts +1 -1
- package/src/components/npm-packages.ts +103 -11
- package/src/contributions/default-attributions-contributions.ts +34 -0
- package/src/contributions/default-ui-contributions.ts +1 -14
- package/src/contributions/index.ts +1 -0
- package/src/core/apploader.ts +20 -11
- package/src/core/contribution-names.ts +1 -0
- package/src/core/license-attribution.ts +45 -0
- package/src/core/resolved-package-info.ts +15 -0
- package/src/vite-env.d.ts +11 -2
- package/src/vite-plugin-resolve-deps.ts +231 -31
- package/dist/api-DImisUWV.js.map +0 -1
- package/dist/parts-DQRktiiR.js.map +0 -1
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
|
+
import { ResolvedDependencyInfo, ResolvedDependencyMap } from './core/resolved-package-info';
|
|
3
|
+
export type { ResolvedDependencyInfo, ResolvedDependencyMap };
|
|
2
4
|
export interface ResolvedPackageInfo {
|
|
3
5
|
name: string;
|
|
4
6
|
version: string;
|
|
5
7
|
description?: string;
|
|
6
|
-
dependencies:
|
|
8
|
+
dependencies: ResolvedDependencyMap;
|
|
9
|
+
/** Direct app `package.json` dependencies, in declaration order. */
|
|
10
|
+
directDependencies: string[];
|
|
11
|
+
/** Third-party runtime packages nested under a direct @eclipse-docks/core or extension-* dependency. */
|
|
12
|
+
nestedDependencies: Record<string, string[]>;
|
|
7
13
|
marketplaceCatalogUrls?: string[];
|
|
8
14
|
}
|
|
9
|
-
export
|
|
15
|
+
export type ResolvePackageInfoOptions = {
|
|
10
16
|
includeDevDependencies?: boolean;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
/**
|
|
18
|
+
* When true (default), list each direct `@eclipse-docks/core` and `extension-*`
|
|
19
|
+
* dependency's own third-party `package.json` dependencies in the About tree.
|
|
20
|
+
*/
|
|
21
|
+
includeExtensionRuntimeDependencies?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare function resolveDependencyInfo(appRoot: string, depName: string): ResolvedDependencyInfo;
|
|
24
|
+
export declare function resolvePackageInfo(appRoot: string, options?: ResolvePackageInfoOptions): ResolvedPackageInfo | null;
|
|
25
|
+
export declare function resolveDepVersions(appRoot: string, options?: ResolvePackageInfoOptions): Record<string, string>;
|
|
15
26
|
/** Virtual module id; prepended to `src/main.ts` when extension side-effects are enabled. */
|
|
16
27
|
export declare const VIRTUAL_EXTENSION_IMPORTS = "virtual:eclipse-docks-extension-imports";
|
|
17
28
|
/** Prepends the virtual extension side-effect import when not already present. */
|
|
@@ -34,8 +45,7 @@ export interface ExtensionSideEffectsOptions {
|
|
|
34
45
|
*/
|
|
35
46
|
packageNamePattern?: RegExp;
|
|
36
47
|
}
|
|
37
|
-
export type ResolveDepVersionsPluginOptions = {
|
|
38
|
-
includeDevDependencies?: boolean;
|
|
48
|
+
export type ResolveDepVersionsPluginOptions = ResolvePackageInfoOptions & {
|
|
39
49
|
/**
|
|
40
50
|
* By default, registers a virtual module that side-effect-imports every matching direct
|
|
41
51
|
* `dependencies` entry (see `ExtensionSideEffectsOptions`), and prepends
|
|
@@ -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;
|
|
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;AACnC,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAElG,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;AAE9D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,qBAAqB,CAAC;IACpC,oEAAoE;IACpE,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,wGAAwG;IACxG,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;CACnC;AAkBD,MAAM,MAAM,yBAAyB,GAAG;IACtC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,mCAAmC,CAAC,EAAE,OAAO,CAAC;CAC/C,CAAC;AA4HF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,sBAAsB,CASxB;AA0DD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,yBAAyB,GAClC,mBAAmB,GAAG,IAAI,CA+B5B;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,yBAAyB,GAClC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBxB;AAID,6FAA6F;AAC7F,eAAO,MAAM,yBAAyB,4CAA4C,CAAC;AASnF,kFAAkF;AAClF,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrE;AAID,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,yBAAyB,GAAG;IACxE;;;;;;OAMG;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;AAUD,wBAAgB,wBAAwB,CACtC,OAAO,CAAC,EAAE,+BAA+B,GACxC,MAAM,CAuER"}
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
//#region src/vite-plugin-resolve-deps.ts
|
|
4
|
+
var RUNTIME_SKIP_PATTERN = /^@types\//;
|
|
5
|
+
var RUNTIME_SKIP_PACKAGES = /* @__PURE__ */ new Set([
|
|
6
|
+
"typescript",
|
|
7
|
+
"vite",
|
|
8
|
+
"vitest",
|
|
9
|
+
"jsdom",
|
|
10
|
+
"playwright",
|
|
11
|
+
"rolldown",
|
|
12
|
+
"fake-indexeddb",
|
|
13
|
+
"@vitest/coverage-v8",
|
|
14
|
+
"vite-plugin-dts",
|
|
15
|
+
"vite-plugin-cross-origin-isolation",
|
|
16
|
+
"vite-plugin-mkcert",
|
|
17
|
+
"vite-plugin-pwa"
|
|
18
|
+
]);
|
|
4
19
|
function packageJsonPath(appRoot, packageName) {
|
|
5
20
|
const segments = packageName.startsWith("@") ? packageName.split("/") : [packageName];
|
|
6
21
|
const relativePath = path.join("node_modules", ...segments, "package.json");
|
|
@@ -14,26 +29,105 @@ function packageJsonPath(appRoot, packageName) {
|
|
|
14
29
|
}
|
|
15
30
|
return null;
|
|
16
31
|
}
|
|
32
|
+
function readWorkspacePackageJson(appRoot, depName) {
|
|
33
|
+
if (!depName.startsWith("@eclipse-docks/")) return null;
|
|
34
|
+
const folder = depName === "@eclipse-docks/core" ? "core" : depName.slice(15);
|
|
35
|
+
let dir = path.resolve(appRoot);
|
|
36
|
+
const root = path.parse(dir).root;
|
|
37
|
+
while (dir !== root) {
|
|
38
|
+
const workspacePkgPath = path.join(dir, "packages", folder, "package.json");
|
|
39
|
+
if (existsSync(workspacePkgPath)) try {
|
|
40
|
+
return JSON.parse(readFileSync(workspacePkgPath, "utf8"));
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
dir = path.dirname(dir);
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
17
48
|
function readPackageJson(appRoot, packageName) {
|
|
18
49
|
const pkgPath = packageJsonPath(appRoot, packageName);
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
|
|
50
|
+
let pkg = null;
|
|
51
|
+
if (pkgPath) try {
|
|
52
|
+
pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
22
53
|
} catch {
|
|
23
|
-
|
|
54
|
+
pkg = null;
|
|
24
55
|
}
|
|
56
|
+
const workspacePkg = readWorkspacePackageJson(appRoot, packageName);
|
|
57
|
+
if (workspacePkg) pkg = {
|
|
58
|
+
...workspacePkg,
|
|
59
|
+
...pkg,
|
|
60
|
+
description: pkg?.description ?? workspacePkg.description,
|
|
61
|
+
license: pkg?.license ?? workspacePkg.license,
|
|
62
|
+
homepage: pkg?.homepage ?? workspacePkg.homepage,
|
|
63
|
+
repository: pkg?.repository ?? workspacePkg.repository
|
|
64
|
+
};
|
|
65
|
+
return pkg;
|
|
66
|
+
}
|
|
67
|
+
function normalizeLicense(license) {
|
|
68
|
+
if (!license) return void 0;
|
|
69
|
+
if (typeof license === "string") return license;
|
|
70
|
+
if (Array.isArray(license)) {
|
|
71
|
+
const parts = license.map((entry) => typeof entry === "string" ? entry : entry.type ?? "").filter(Boolean);
|
|
72
|
+
return parts.length > 0 ? parts.join(" AND ") : void 0;
|
|
73
|
+
}
|
|
74
|
+
return license.type;
|
|
75
|
+
}
|
|
76
|
+
function normalizeRepository(repository) {
|
|
77
|
+
if (!repository) return void 0;
|
|
78
|
+
const raw = typeof repository === "string" ? repository : repository.url;
|
|
79
|
+
if (!raw) return void 0;
|
|
80
|
+
return raw.replace(/^git\+/, "").replace(/^git:\/\//, "https://").replace(/\.git$/, "");
|
|
81
|
+
}
|
|
82
|
+
function shouldSkipRuntimePackage(name) {
|
|
83
|
+
if (RUNTIME_SKIP_PATTERN.test(name)) return true;
|
|
84
|
+
if (RUNTIME_SKIP_PACKAGES.has(name)) return true;
|
|
85
|
+
if (name.startsWith("vite-plugin-")) return true;
|
|
86
|
+
return false;
|
|
25
87
|
}
|
|
26
|
-
|
|
88
|
+
/** Unscoped `extension-*` or scoped `@namespace/extension-*` (any npm scope). */
|
|
89
|
+
var DEFAULT_EXTENSION_PATTERN = /^(?:@[^/]+\/)?extension-/;
|
|
90
|
+
function isEclipseDocksPlatformPackage(name) {
|
|
91
|
+
return name === "@eclipse-docks/core" || DEFAULT_EXTENSION_PATTERN.test(name);
|
|
92
|
+
}
|
|
93
|
+
function resolveDependencyInfo(appRoot, depName) {
|
|
27
94
|
const pkg = readPackageJson(appRoot, depName);
|
|
28
|
-
|
|
29
|
-
|
|
95
|
+
return {
|
|
96
|
+
license: normalizeLicense(pkg?.license),
|
|
97
|
+
homepage: typeof pkg?.homepage === "string" ? pkg.homepage : void 0,
|
|
98
|
+
repository: normalizeRepository(pkg?.repository),
|
|
99
|
+
description: typeof pkg?.description === "string" ? pkg.description : void 0
|
|
100
|
+
};
|
|
30
101
|
}
|
|
31
|
-
function
|
|
102
|
+
function collectDirectDependencyEntries(pkg, options) {
|
|
32
103
|
const deps = { ...pkg.dependencies };
|
|
33
104
|
if (options?.includeDevDependencies && pkg.devDependencies) Object.assign(deps, pkg.devDependencies);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
105
|
+
return Object.entries(deps);
|
|
106
|
+
}
|
|
107
|
+
/** Direct third-party runtime dependencies declared in `seed`'s package.json. */
|
|
108
|
+
function collectDirectThirdPartyDependencies(appRoot, seed) {
|
|
109
|
+
const pkg = readPackageJson(appRoot, seed);
|
|
110
|
+
if (!pkg?.dependencies) return [];
|
|
111
|
+
return Object.keys(pkg.dependencies).filter((dep) => !shouldSkipRuntimePackage(dep)).filter((dep) => !isEclipseDocksPlatformPackage(dep)).sort((a, b) => a.localeCompare(b));
|
|
112
|
+
}
|
|
113
|
+
function resolveDependenciesFromPkg(appRoot, pkg, options) {
|
|
114
|
+
const depEntries = collectDirectDependencyEntries(pkg, options);
|
|
115
|
+
const directDependencies = depEntries.map(([name]) => name);
|
|
116
|
+
const dependencies = {};
|
|
117
|
+
for (const [name] of depEntries) dependencies[name] = resolveDependencyInfo(appRoot, name);
|
|
118
|
+
const nestedDependencies = {};
|
|
119
|
+
if (options?.includeExtensionRuntimeDependencies !== false) for (const name of directDependencies) {
|
|
120
|
+
if (!isEclipseDocksPlatformPackage(name)) continue;
|
|
121
|
+
const thirdParty = collectDirectThirdPartyDependencies(appRoot, name);
|
|
122
|
+
if (thirdParty.length === 0) continue;
|
|
123
|
+
nestedDependencies[name] = thirdParty;
|
|
124
|
+
for (const dep of thirdParty) if (!dependencies[dep]) dependencies[dep] = resolveDependencyInfo(appRoot, dep);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
dependencies,
|
|
128
|
+
directDependencies,
|
|
129
|
+
nestedDependencies
|
|
130
|
+
};
|
|
37
131
|
}
|
|
38
132
|
function resolvePackageInfo(appRoot, options) {
|
|
39
133
|
const pkgPath = path.join(appRoot, "package.json");
|
|
@@ -44,16 +138,36 @@ function resolvePackageInfo(appRoot, options) {
|
|
|
44
138
|
} catch {
|
|
45
139
|
return null;
|
|
46
140
|
}
|
|
141
|
+
const name = typeof pkg.name === "string" ? pkg.name : "";
|
|
142
|
+
const version = typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
143
|
+
const description = typeof pkg.description === "string" ? pkg.description : void 0;
|
|
144
|
+
const { dependencies, directDependencies, nestedDependencies } = resolveDependenciesFromPkg(appRoot, pkg, options);
|
|
47
145
|
return {
|
|
48
|
-
name
|
|
49
|
-
version
|
|
50
|
-
description
|
|
51
|
-
dependencies
|
|
146
|
+
name,
|
|
147
|
+
version,
|
|
148
|
+
description,
|
|
149
|
+
dependencies,
|
|
150
|
+
directDependencies,
|
|
151
|
+
nestedDependencies,
|
|
52
152
|
marketplaceCatalogUrls: pkg.marketplace?.catalogUrls
|
|
53
153
|
};
|
|
54
154
|
}
|
|
55
155
|
function resolveDepVersions(appRoot, options) {
|
|
56
|
-
|
|
156
|
+
const pkgPath = path.join(appRoot, "package.json");
|
|
157
|
+
if (!existsSync(pkgPath)) return {};
|
|
158
|
+
let pkg;
|
|
159
|
+
try {
|
|
160
|
+
pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
161
|
+
} catch {
|
|
162
|
+
return {};
|
|
163
|
+
}
|
|
164
|
+
const depEntries = collectDirectDependencyEntries(pkg, options);
|
|
165
|
+
const result = {};
|
|
166
|
+
for (const [name, specifier] of depEntries) {
|
|
167
|
+
const installed = readPackageJson(appRoot, name);
|
|
168
|
+
result[name] = typeof installed?.version === "string" ? installed.version : specifier;
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
57
171
|
}
|
|
58
172
|
var RESOLVED_PACKAGE_INFO_KEY = "__RESOLVED_PACKAGE_INFO__";
|
|
59
173
|
/** Virtual module id; prepended to `src/main.ts` when extension side-effects are enabled. */
|
|
@@ -67,8 +181,6 @@ function prependExtensionSideEffectImport(code) {
|
|
|
67
181
|
if (code.includes("virtual:eclipse-docks-extension-imports")) return code;
|
|
68
182
|
return EXTENSION_IMPORT_STATEMENT + code;
|
|
69
183
|
}
|
|
70
|
-
/** Unscoped `extension-*` or scoped `@namespace/extension-*` (any npm scope). */
|
|
71
|
-
var DEFAULT_EXTENSION_PATTERN = /^(?:@[^/]+\/)?extension-/;
|
|
72
184
|
var DEFAULT_PRIORITY_FIRST = ["@eclipse-docks/extension-pwa", "extension-pwa"];
|
|
73
185
|
function normalizeExtensionSideEffects(opt) {
|
|
74
186
|
if (opt === false) return null;
|
|
@@ -119,6 +231,11 @@ function resolveExtensionSideEffectPackages(appRoot, dependencies, sideEffects)
|
|
|
119
231
|
const allNames = [.../* @__PURE__ */ new Set([...direct, ...transitive])];
|
|
120
232
|
return listExtensionSideEffectPackages(Object.fromEntries(allNames.map((name) => [name, "*"])), sideEffects);
|
|
121
233
|
}
|
|
234
|
+
function dependencyKeysFromInfo(info) {
|
|
235
|
+
if (!info) return [];
|
|
236
|
+
if (info.directDependencies.length > 0) return info.directDependencies;
|
|
237
|
+
return Object.keys(info.dependencies);
|
|
238
|
+
}
|
|
122
239
|
function resolveDepVersionsPlugin(options) {
|
|
123
240
|
let appRoot = process.cwd();
|
|
124
241
|
let extensionSideEffectsActive = false;
|
|
@@ -131,6 +248,8 @@ function resolveDepVersionsPlugin(options) {
|
|
|
131
248
|
version: "0.0.0",
|
|
132
249
|
description: void 0,
|
|
133
250
|
dependencies: {},
|
|
251
|
+
directDependencies: [],
|
|
252
|
+
nestedDependencies: {},
|
|
134
253
|
marketplaceCatalogUrls: void 0
|
|
135
254
|
};
|
|
136
255
|
return { define: { [RESOLVED_PACKAGE_INFO_KEY]: JSON.stringify(value) } };
|
|
@@ -143,8 +262,8 @@ function resolveDepVersionsPlugin(options) {
|
|
|
143
262
|
extensionImportPackages = [];
|
|
144
263
|
return;
|
|
145
264
|
}
|
|
146
|
-
const
|
|
147
|
-
extensionImportPackages = resolveExtensionSideEffectPackages(appRoot,
|
|
265
|
+
const depKeys = dependencyKeysFromInfo(resolvePackageInfo(appRoot, options));
|
|
266
|
+
extensionImportPackages = resolveExtensionSideEffectPackages(appRoot, Object.fromEntries(depKeys.map((name) => [name, "*"])), normalized);
|
|
148
267
|
},
|
|
149
268
|
resolveId(id) {
|
|
150
269
|
if (id === "virtual:eclipse-docks-extension-imports") return RESOLVED_VIRTUAL_EXTENSION_IMPORTS;
|
|
@@ -164,6 +283,6 @@ function resolveDepVersionsPlugin(options) {
|
|
|
164
283
|
};
|
|
165
284
|
}
|
|
166
285
|
//#endregion
|
|
167
|
-
export { VIRTUAL_EXTENSION_IMPORTS, collectTransitiveExtensionPackages, listExtensionSideEffectPackages, prependExtensionSideEffectImport, resolveDepVersions, resolveDepVersionsPlugin, resolveExtensionSideEffectPackages, resolvePackageInfo };
|
|
286
|
+
export { VIRTUAL_EXTENSION_IMPORTS, collectTransitiveExtensionPackages, listExtensionSideEffectPackages, prependExtensionSideEffectImport, resolveDepVersions, resolveDepVersionsPlugin, resolveDependencyInfo, resolveExtensionSideEffectPackages, resolvePackageInfo };
|
|
168
287
|
|
|
169
288
|
//# 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 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; prepended to `src/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/** App entry module transformed by {@link resolveDepVersionsPlugin}. */\nconst MAIN_TS_MODULE_RE = /[/\\\\]src[/\\\\]main\\.ts$/;\n\nconst EXTENSION_IMPORT_STATEMENT = `import ${JSON.stringify(VIRTUAL_EXTENSION_IMPORTS)};\\n`;\n\n/** Prepends the virtual extension side-effect import when not already present. */\nexport function prependExtensionSideEffectImport(code: string): string {\n if (code.includes(VIRTUAL_EXTENSION_IMPORTS)) {\n return code;\n }\n return EXTENSION_IMPORT_STATEMENT + code;\n}\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\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 prepends\n * `import 'virtual:eclipse-docks-extension-imports'` to `src/main.ts` so extension\n * registration completes before `registerApp({ autoStart: true })`.\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 transform(code, id) {\n if (!extensionSideEffectsActive || extensionImportPackages.length === 0) {\n return null;\n }\n if (!MAIN_TS_MODULE_RE.test(id)) {\n return null;\n }\n const next = prependExtensionSideEffectImport(code);\n if (next === code) {\n return null;\n }\n return next;\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';\nimport type { ResolvedDependencyInfo, ResolvedDependencyMap } from './core/resolved-package-info';\n\nexport type { ResolvedDependencyInfo, ResolvedDependencyMap };\n\nexport interface ResolvedPackageInfo {\n name: string;\n version: string;\n description?: string;\n dependencies: ResolvedDependencyMap;\n /** Direct app `package.json` dependencies, in declaration order. */\n directDependencies: string[];\n /** Third-party runtime packages nested under a direct @eclipse-docks/core or extension-* dependency. */\n nestedDependencies: Record<string, string[]>;\n marketplaceCatalogUrls?: string[];\n}\n\ntype LicenseField =\n | string\n | { type?: string; url?: string }\n | Array<string | { type?: string; url?: string }>;\n\ninterface PackageJson {\n name?: string;\n version?: string;\n description?: string;\n license?: LicenseField;\n homepage?: string;\n repository?: string | { type?: string; url?: string };\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\nexport type ResolvePackageInfoOptions = {\n includeDevDependencies?: boolean;\n /**\n * When true (default), list each direct `@eclipse-docks/core` and `extension-*`\n * dependency's own third-party `package.json` dependencies in the About tree.\n */\n includeExtensionRuntimeDependencies?: boolean;\n};\n\nconst RUNTIME_SKIP_PATTERN = /^@types\\//;\n\nconst RUNTIME_SKIP_PACKAGES = new Set([\n 'typescript',\n 'vite',\n 'vitest',\n 'jsdom',\n 'playwright',\n 'rolldown',\n 'fake-indexeddb',\n '@vitest/coverage-v8',\n 'vite-plugin-dts',\n 'vite-plugin-cross-origin-isolation',\n 'vite-plugin-mkcert',\n 'vite-plugin-pwa',\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 readWorkspacePackageJson(appRoot: string, depName: string): PackageJson | null {\n if (!depName.startsWith('@eclipse-docks/')) return null;\n\n const folder = depName === '@eclipse-docks/core' ? 'core' : depName.slice('@eclipse-docks/'.length);\n let dir = path.resolve(appRoot);\n const root = path.parse(dir).root;\n\n while (dir !== root) {\n const workspacePkgPath = path.join(dir, 'packages', folder, 'package.json');\n if (existsSync(workspacePkgPath)) {\n try {\n return JSON.parse(readFileSync(workspacePkgPath, 'utf8')) as PackageJson;\n } catch {\n return null;\n }\n }\n dir = path.dirname(dir);\n }\n\n return null;\n}\n\nfunction readPackageJson(appRoot: string, packageName: string): PackageJson | null {\n const pkgPath = packageJsonPath(appRoot, packageName);\n let pkg: PackageJson | null = null;\n if (pkgPath) {\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;\n } catch {\n pkg = null;\n }\n }\n\n const workspacePkg = readWorkspacePackageJson(appRoot, packageName);\n if (workspacePkg) {\n pkg = {\n ...workspacePkg,\n ...pkg,\n description: pkg?.description ?? workspacePkg.description,\n license: pkg?.license ?? workspacePkg.license,\n homepage: pkg?.homepage ?? workspacePkg.homepage,\n repository: pkg?.repository ?? workspacePkg.repository,\n };\n }\n\n return pkg;\n}\n\nfunction normalizeLicense(license: LicenseField | undefined): string | undefined {\n if (!license) return undefined;\n if (typeof license === 'string') return license;\n if (Array.isArray(license)) {\n const parts = license\n .map((entry) => (typeof entry === 'string' ? entry : entry.type ?? ''))\n .filter(Boolean);\n return parts.length > 0 ? parts.join(' AND ') : undefined;\n }\n return license.type;\n}\n\nfunction normalizeRepository(\n repository: PackageJson['repository'],\n): string | undefined {\n if (!repository) return undefined;\n const raw = typeof repository === 'string' ? repository : repository.url;\n if (!raw) return undefined;\n return raw\n .replace(/^git\\+/, '')\n .replace(/^git:\\/\\//, 'https://')\n .replace(/\\.git$/, '');\n}\n\nfunction shouldSkipRuntimePackage(name: string): boolean {\n if (RUNTIME_SKIP_PATTERN.test(name)) return true;\n if (RUNTIME_SKIP_PACKAGES.has(name)) return true;\n if (name.startsWith('vite-plugin-')) return true;\n return false;\n}\n\n/** Unscoped `extension-*` or scoped `@namespace/extension-*` (any npm scope). */\nconst DEFAULT_EXTENSION_PATTERN = /^(?:@[^/]+\\/)?extension-/;\n\nfunction isEclipseDocksPlatformPackage(name: string): boolean {\n return name === '@eclipse-docks/core' || DEFAULT_EXTENSION_PATTERN.test(name);\n}\n\nexport function resolveDependencyInfo(\n appRoot: string,\n depName: string,\n): ResolvedDependencyInfo {\n const pkg = readPackageJson(appRoot, depName);\n\n return {\n license: normalizeLicense(pkg?.license),\n homepage: typeof pkg?.homepage === 'string' ? pkg.homepage : undefined,\n repository: normalizeRepository(pkg?.repository),\n description: typeof pkg?.description === 'string' ? pkg.description : undefined,\n };\n}\n\nfunction collectDirectDependencyEntries(\n pkg: PackageJson,\n options?: ResolvePackageInfoOptions,\n): Array<[string, string]> {\n const deps = { ...pkg.dependencies };\n if (options?.includeDevDependencies && pkg.devDependencies) {\n Object.assign(deps, pkg.devDependencies);\n }\n return Object.entries(deps);\n}\n\n/** Direct third-party runtime dependencies declared in `seed`'s package.json. */\nfunction collectDirectThirdPartyDependencies(appRoot: string, seed: string): string[] {\n const pkg = readPackageJson(appRoot, seed);\n if (!pkg?.dependencies) return [];\n\n return Object.keys(pkg.dependencies)\n .filter((dep) => !shouldSkipRuntimePackage(dep))\n .filter((dep) => !isEclipseDocksPlatformPackage(dep))\n .sort((a, b) => a.localeCompare(b));\n}\n\nfunction resolveDependenciesFromPkg(\n appRoot: string,\n pkg: PackageJson,\n options?: ResolvePackageInfoOptions,\n): Pick<ResolvedPackageInfo, 'dependencies' | 'directDependencies' | 'nestedDependencies'> {\n const depEntries = collectDirectDependencyEntries(pkg, options);\n const directDependencies = depEntries.map(([name]) => name);\n const dependencies: ResolvedDependencyMap = {};\n\n for (const [name] of depEntries) {\n dependencies[name] = resolveDependencyInfo(appRoot, name);\n }\n\n const nestedDependencies: Record<string, string[]> = {};\n\n if (options?.includeExtensionRuntimeDependencies !== false) {\n for (const name of directDependencies) {\n if (!isEclipseDocksPlatformPackage(name)) continue;\n\n const thirdParty = collectDirectThirdPartyDependencies(appRoot, name);\n if (thirdParty.length === 0) continue;\n\n nestedDependencies[name] = thirdParty;\n for (const dep of thirdParty) {\n if (!dependencies[dep]) {\n dependencies[dep] = resolveDependencyInfo(appRoot, dep);\n }\n }\n }\n }\n\n return { dependencies, directDependencies, nestedDependencies };\n}\n\nexport function resolvePackageInfo(\n appRoot: string,\n options?: ResolvePackageInfoOptions,\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, directDependencies, nestedDependencies } = resolveDependenciesFromPkg(\n appRoot,\n pkg,\n options,\n );\n const marketplaceCatalogUrls = (pkg as { marketplace?: { catalogUrls?: string[] } }).marketplace\n ?.catalogUrls;\n\n return {\n name,\n version,\n description,\n dependencies,\n directDependencies,\n nestedDependencies,\n marketplaceCatalogUrls,\n };\n}\n\nexport function resolveDepVersions(\n appRoot: string,\n options?: ResolvePackageInfoOptions,\n): Record<string, string> {\n const pkgPath = path.join(appRoot, 'package.json');\n if (!existsSync(pkgPath)) return {};\n\n let pkg: PackageJson;\n try {\n pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;\n } catch {\n return {};\n }\n\n const depEntries = collectDirectDependencyEntries(pkg, options);\n const result: Record<string, string> = {};\n for (const [name, specifier] of depEntries) {\n const installed = readPackageJson(appRoot, name);\n result[name] =\n typeof installed?.version === 'string' ? installed.version : specifier;\n }\n return result;\n}\n\nconst RESOLVED_PACKAGE_INFO_KEY = '__RESOLVED_PACKAGE_INFO__';\n\n/** Virtual module id; prepended to `src/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/** App entry module transformed by {@link resolveDepVersionsPlugin}. */\nconst MAIN_TS_MODULE_RE = /[/\\\\]src[/\\\\]main\\.ts$/;\n\nconst EXTENSION_IMPORT_STATEMENT = `import ${JSON.stringify(VIRTUAL_EXTENSION_IMPORTS)};\\n`;\n\n/** Prepends the virtual extension side-effect import when not already present. */\nexport function prependExtensionSideEffectImport(code: string): string {\n if (code.includes(VIRTUAL_EXTENSION_IMPORTS)) {\n return code;\n }\n return EXTENSION_IMPORT_STATEMENT + code;\n}\n\nconst DEFAULT_PRIORITY_FIRST = ['@eclipse-docks/extension-pwa', 'extension-pwa'];\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 = ResolvePackageInfoOptions & {\n /**\n * By default, registers a virtual module that side-effect-imports every matching direct\n * `dependencies` entry (see `ExtensionSideEffectsOptions`), and prepends\n * `import 'virtual:eclipse-docks-extension-imports'` to `src/main.ts` so extension\n * registration completes before `registerApp({ autoStart: true })`.\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\nfunction dependencyKeysFromInfo(info: ResolvedPackageInfo | null | undefined): string[] {\n if (!info) return [];\n if (info.directDependencies.length > 0) {\n return info.directDependencies;\n }\n return Object.keys(info.dependencies);\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 directDependencies: [],\n nestedDependencies: {},\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 const depKeys = dependencyKeysFromInfo(info);\n extensionImportPackages = resolveExtensionSideEffectPackages(\n appRoot,\n Object.fromEntries(depKeys.map((name) => [name, '*'])),\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 transform(code, id) {\n if (!extensionSideEffectsActive || extensionImportPackages.length === 0) {\n return null;\n }\n if (!MAIN_TS_MODULE_RE.test(id)) {\n return null;\n }\n const next = prependExtensionSideEffectImport(code);\n if (next === code) {\n return null;\n }\n return next;\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/api/index.ts
CHANGED
|
@@ -27,5 +27,14 @@ export * from './constants';
|
|
|
27
27
|
export * from './types';
|
|
28
28
|
|
|
29
29
|
// Re-export AppDefinition for convenience
|
|
30
|
-
export type {
|
|
30
|
+
export type {
|
|
31
|
+
AppDefinition,
|
|
32
|
+
AppContributions,
|
|
33
|
+
LayoutDescriptor,
|
|
34
|
+
ReleaseEntry,
|
|
35
|
+
ReleaseHistory,
|
|
36
|
+
RenderDescriptor,
|
|
37
|
+
} from '../core/apploader';
|
|
38
|
+
export type { ResolvedDependencyInfo, ResolvedDependencyMap } from '../core/resolved-package-info';
|
|
39
|
+
export type { LicenseAttributionOptions } from '../core/license-attribution';
|
|
31
40
|
|
package/src/api/services.ts
CHANGED
|
@@ -91,4 +91,6 @@ export {
|
|
|
91
91
|
resolveStoredPanelVisibility,
|
|
92
92
|
} from '../core/layout-panels';
|
|
93
93
|
export { sanitizeHtml, parseMarkdownHtml } from '../core/markdown-html';
|
|
94
|
+
export { registerLicenseAttribution } from '../core/license-attribution';
|
|
95
|
+
export type { LicenseAttributionOptions } from '../core/license-attribution';
|
|
94
96
|
|
package/src/api/types.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
// Re-export framework types for app usage
|
|
2
|
-
export type {
|
|
2
|
+
export type {
|
|
3
|
+
AppDefinition,
|
|
4
|
+
AppContributions,
|
|
5
|
+
LayoutDescriptor,
|
|
6
|
+
ReleaseEntry,
|
|
7
|
+
ReleaseHistory,
|
|
8
|
+
RenderDescriptor,
|
|
9
|
+
} from '../core/apploader';
|
|
10
|
+
export type { ResolvedDependencyInfo, ResolvedDependencyMap } from '../core/resolved-package-info';
|
|
11
|
+
export type { LicenseAttributionOptions } from '../core/license-attribution';
|
|
3
12
|
export type {
|
|
4
13
|
Command,
|
|
5
14
|
Parameter,
|
package/src/commands/global.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import { html, css } from "lit";
|
|
1
|
+
import { html, css, nothing, type TemplateResult } from "lit";
|
|
2
2
|
import { customElement } from "lit/decorators.js";
|
|
3
3
|
import { DocksPart } from "../parts/part";
|
|
4
4
|
import { appLoaderService } from "../core/apploader";
|
|
5
|
+
import {
|
|
6
|
+
normalizeDependencyInfo,
|
|
7
|
+
type ResolvedDependencyInfo,
|
|
8
|
+
} from "../core/resolved-package-info";
|
|
9
|
+
|
|
10
|
+
function packageLink(info: ResolvedDependencyInfo): string | undefined {
|
|
11
|
+
return info.homepage ?? info.repository;
|
|
12
|
+
}
|
|
5
13
|
|
|
6
14
|
@customElement("docks-npm-packages")
|
|
7
15
|
export class DocksNpmPackages extends DocksPart {
|
|
@@ -14,18 +22,101 @@ export class DocksNpmPackages extends DocksPart {
|
|
|
14
22
|
box-sizing: border-box;
|
|
15
23
|
}
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
.pkg-name a {
|
|
26
|
+
color: inherit;
|
|
27
|
+
text-decoration: underline;
|
|
28
|
+
text-underline-offset: 0.12em;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.pkg-meta {
|
|
18
32
|
color: var(--wa-color-neutral-60);
|
|
19
33
|
font-size: 0.875em;
|
|
20
|
-
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.pkg-meta-label {
|
|
37
|
+
font-weight: 600;
|
|
38
|
+
color: var(--wa-color-neutral-50);
|
|
21
39
|
}
|
|
22
40
|
`,
|
|
23
41
|
];
|
|
24
42
|
|
|
43
|
+
private renderPackageName(name: string, info: ResolvedDependencyInfo) {
|
|
44
|
+
const link = packageLink(info);
|
|
45
|
+
return html`
|
|
46
|
+
<span class="pkg-name">
|
|
47
|
+
${link
|
|
48
|
+
? html`<a href=${link} target="_blank" rel="noopener noreferrer">${name}</a>`
|
|
49
|
+
: name}
|
|
50
|
+
</span>
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private renderMetaRows(info: ResolvedDependencyInfo) {
|
|
55
|
+
return html`
|
|
56
|
+
${info.license
|
|
57
|
+
? html`
|
|
58
|
+
<wa-tree-item>
|
|
59
|
+
<span class="pkg-meta">
|
|
60
|
+
<span class="pkg-meta-label">License:</span> ${info.license}
|
|
61
|
+
</span>
|
|
62
|
+
</wa-tree-item>
|
|
63
|
+
`
|
|
64
|
+
: nothing}
|
|
65
|
+
${info.description
|
|
66
|
+
? html`
|
|
67
|
+
<wa-tree-item>
|
|
68
|
+
<span class="pkg-meta">
|
|
69
|
+
<span class="pkg-meta-label">Description:</span> ${info.description}
|
|
70
|
+
</span>
|
|
71
|
+
</wa-tree-item>
|
|
72
|
+
`
|
|
73
|
+
: nothing}
|
|
74
|
+
`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private renderDependencyNode(
|
|
78
|
+
name: string,
|
|
79
|
+
info: ResolvedDependencyInfo | undefined,
|
|
80
|
+
nested: Record<string, string[]>,
|
|
81
|
+
allDependencies: Record<string, ResolvedDependencyInfo>,
|
|
82
|
+
): TemplateResult | typeof nothing {
|
|
83
|
+
if (!info) {
|
|
84
|
+
return nothing;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const children = nested[name] ?? [];
|
|
88
|
+
const hasChildren = children.length > 0 || info.license || info.description;
|
|
89
|
+
|
|
90
|
+
return html`
|
|
91
|
+
<wa-tree-item ?expanded=${hasChildren}>
|
|
92
|
+
${this.renderPackageName(name, info)}
|
|
93
|
+
${this.renderMetaRows(info)}
|
|
94
|
+
${children.map((childName) => {
|
|
95
|
+
const childInfo = normalizeDependencyInfo(allDependencies[childName]);
|
|
96
|
+
if (!childInfo) {
|
|
97
|
+
return nothing;
|
|
98
|
+
}
|
|
99
|
+
return this.renderDependencyNode(
|
|
100
|
+
childName,
|
|
101
|
+
childInfo,
|
|
102
|
+
nested,
|
|
103
|
+
allDependencies,
|
|
104
|
+
);
|
|
105
|
+
})}
|
|
106
|
+
</wa-tree-item>
|
|
107
|
+
`;
|
|
108
|
+
}
|
|
109
|
+
|
|
25
110
|
protected renderContent() {
|
|
26
111
|
const app = appLoaderService.getCurrentApp();
|
|
27
|
-
const
|
|
28
|
-
|
|
112
|
+
const dependencies = app?.dependencies ?? {};
|
|
113
|
+
const directDependencies =
|
|
114
|
+
app?.directDependencies && app.directDependencies.length > 0
|
|
115
|
+
? app.directDependencies
|
|
116
|
+
: Object.keys(dependencies);
|
|
117
|
+
const nestedDependencies = app?.nestedDependencies ?? {};
|
|
118
|
+
|
|
119
|
+
if (directDependencies.length === 0) {
|
|
29
120
|
return html`<div class="packages-panel">No package information available.</div>`;
|
|
30
121
|
}
|
|
31
122
|
|
|
@@ -34,12 +125,13 @@ export class DocksNpmPackages extends DocksPart {
|
|
|
34
125
|
<wa-tree style="--indent-guide-width: 1px;">
|
|
35
126
|
<wa-tree-item expanded>
|
|
36
127
|
<span>${app?.name ?? ""}</span>
|
|
37
|
-
${
|
|
38
|
-
(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
128
|
+
${directDependencies.map((name) =>
|
|
129
|
+
this.renderDependencyNode(
|
|
130
|
+
name,
|
|
131
|
+
normalizeDependencyInfo(dependencies[name]),
|
|
132
|
+
nestedDependencies,
|
|
133
|
+
dependencies,
|
|
134
|
+
),
|
|
43
135
|
)}
|
|
44
136
|
</wa-tree-item>
|
|
45
137
|
</wa-tree>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import { registerLicenseAttribution } from "../core/license-attribution";
|
|
3
|
+
import { ATTRIBUTION_ECLIPSE_DOCKS, ATTRIBUTION_FONT_AWESOME } from "../core/contribution-names";
|
|
4
|
+
|
|
5
|
+
registerLicenseAttribution({
|
|
6
|
+
name: ATTRIBUTION_ECLIPSE_DOCKS,
|
|
7
|
+
label: "Eclipse Docks",
|
|
8
|
+
ranking: 1000,
|
|
9
|
+
component: () => html`
|
|
10
|
+
<p>Copyright (c) 2026 The Eclipse Foundation and others.</p>
|
|
11
|
+
<p>
|
|
12
|
+
Eclipse Docks is made available under the
|
|
13
|
+
<a href="https://www.eclipse.org/legal/epl-2.0" target="_blank" rel="noopener noreferrer"
|
|
14
|
+
>Eclipse Public License 2.0</a
|
|
15
|
+
>.
|
|
16
|
+
</p>
|
|
17
|
+
`,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
registerLicenseAttribution({
|
|
21
|
+
name: ATTRIBUTION_FONT_AWESOME,
|
|
22
|
+
label: "Font Awesome",
|
|
23
|
+
ranking: 900,
|
|
24
|
+
component: () => html`
|
|
25
|
+
<p>
|
|
26
|
+
Icons by
|
|
27
|
+
<a href="https://fontawesome.com" target="_blank" rel="noopener noreferrer">Font Awesome</a>.
|
|
28
|
+
Font Awesome Free is licensed under
|
|
29
|
+
<a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="noopener noreferrer"
|
|
30
|
+
>CC BY 4.0</a
|
|
31
|
+
>.
|
|
32
|
+
</p>
|
|
33
|
+
`,
|
|
34
|
+
});
|