@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
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
PANEL_BOTTOM,
|
|
6
6
|
SIDEBAR_MAIN,
|
|
7
7
|
SIDEBAR_MAIN_TOOLBAR,
|
|
8
|
-
SYSTEM_ATTRIBUTIONS,
|
|
9
8
|
TOOLBAR_BOTTOM_END,
|
|
10
9
|
TOOLBAR_MAIN_RIGHT
|
|
11
10
|
} from "../core/contribution-targets";
|
|
@@ -13,7 +12,6 @@ import {
|
|
|
13
12
|
ABOUT_TAB_ATTRIBUTIONS,
|
|
14
13
|
ABOUT_TAB_PACKAGES,
|
|
15
14
|
ABOUT_TAB_RELEASE,
|
|
16
|
-
ATTRIBUTION_ECLIPSE_DOCKS,
|
|
17
15
|
VIEW_FILEBROWSER,
|
|
18
16
|
VIEW_LOG_TERMINAL,
|
|
19
17
|
TOOLBAR_LAYOUT_SWITCHER,
|
|
@@ -67,17 +65,6 @@ contributionRegistry.registerContribution(ABOUT_TABS, {
|
|
|
67
65
|
component: (id: string) => html`<docks-npm-packages id="${id}" embedded></docks-npm-packages>`
|
|
68
66
|
});
|
|
69
67
|
|
|
70
|
-
contributionRegistry.registerContribution(SYSTEM_ATTRIBUTIONS, {
|
|
71
|
-
name: ATTRIBUTION_ECLIPSE_DOCKS,
|
|
72
|
-
label: "Eclipse Docks",
|
|
73
|
-
component: () => html`
|
|
74
|
-
<p>
|
|
75
|
-
Eclipse Docks is made available under the
|
|
76
|
-
<a href="https://www.eclipse.org/legal/epl-2.0" target="_blank" rel="noopener noreferrer">Eclipse Public License 2.0</a>.
|
|
77
|
-
</p>
|
|
78
|
-
`
|
|
79
|
-
} as HTMLContribution);
|
|
80
|
-
|
|
81
68
|
contributionRegistry.registerContribution(TOOLBAR_BOTTOM_END, {
|
|
82
69
|
name: TOOLBAR_INFO,
|
|
83
70
|
label: "Info",
|
|
@@ -107,6 +94,6 @@ contributionRegistry.registerContribution(TOOLBAR_MAIN_RIGHT, {
|
|
|
107
94
|
contributionRegistry.registerContribution(SIDEBAR_MAIN_TOOLBAR, {
|
|
108
95
|
name: SIDEBAR_TOOLBAR_EXTENSIONS,
|
|
109
96
|
command: "open_extensions",
|
|
110
|
-
icon: "
|
|
97
|
+
icon: "puzzle-piece",
|
|
111
98
|
label: "Extensions",
|
|
112
99
|
});
|
package/src/core/apploader.ts
CHANGED
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
* - App Loader: Bridge between framework and application
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { render
|
|
15
|
+
import { render } from "lit";
|
|
16
|
+
import { contributionTargetMappingRegistry, type ContributionNameRemap } from "./contribution-mapping";
|
|
17
|
+
import { SYSTEM_LAYOUTS } from "./contribution-targets";
|
|
18
|
+
import { Contribution, LayoutContribution, TOPIC_CONTRIBUTEIONS_CHANGED, contributionRegistry } from "./contributionregistry";
|
|
16
19
|
import { rootContext } from "./di";
|
|
20
|
+
import { publish } from "./events";
|
|
21
|
+
import { Extension, extensionRegistry } from "./extensionregistry";
|
|
17
22
|
import { createLogger } from "./logger";
|
|
18
|
-
import { extensionRegistry, Extension } from "./extensionregistry";
|
|
19
|
-
import { contributionRegistry, Contribution, LayoutContribution, TOPIC_CONTRIBUTEIONS_CHANGED } from "./contributionregistry";
|
|
20
|
-
import { SYSTEM_LAYOUTS } from "./contribution-targets";
|
|
21
|
-
import { appSettings } from "./settingsservice";
|
|
22
23
|
import { marketplaceRegistry } from "./marketplaceregistry";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
|
|
24
|
+
import type { ResolvedDependencyMap } from "./resolved-package-info";
|
|
25
|
+
import { appSettings } from "./settingsservice";
|
|
26
26
|
|
|
27
27
|
const logger = createLogger('AppLoader');
|
|
28
28
|
|
|
@@ -179,8 +179,14 @@ export interface AppDefinition {
|
|
|
179
179
|
*/
|
|
180
180
|
dispose?: () => void | Promise<void>;
|
|
181
181
|
|
|
182
|
-
/** Resolved dependency
|
|
183
|
-
dependencies?:
|
|
182
|
+
/** Resolved dependency metadata (from build plugin). Shown in About / NPM Packages. */
|
|
183
|
+
dependencies?: ResolvedDependencyMap;
|
|
184
|
+
|
|
185
|
+
/** Direct app package.json dependencies, in declaration order. */
|
|
186
|
+
directDependencies?: string[];
|
|
187
|
+
|
|
188
|
+
/** Third-party packages nested under a direct core/extension dependency in the About tree. */
|
|
189
|
+
nestedDependencies?: Record<string, string[]>;
|
|
184
190
|
|
|
185
191
|
/** Marketplace catalog URLs for this app. Registered when the app is registered. */
|
|
186
192
|
marketplaceCatalogUrls?: string[];
|
|
@@ -213,7 +219,8 @@ export interface RegisterAppOptions {
|
|
|
213
219
|
container?: HTMLElement;
|
|
214
220
|
|
|
215
221
|
/**
|
|
216
|
-
* When true, fill name, version, description, dependencies,
|
|
222
|
+
* When true, fill name, version, description, dependencies, directDependencies,
|
|
223
|
+
* nestedDependencies, and marketplaceCatalogUrls from __RESOLVED_PACKAGE_INFO__ only when not already set on the app.
|
|
217
224
|
*/
|
|
218
225
|
hostConfig?: boolean;
|
|
219
226
|
}
|
|
@@ -250,6 +257,8 @@ class AppLoaderService {
|
|
|
250
257
|
if (app.version === undefined) app.version = resolved.version;
|
|
251
258
|
if (app.description === undefined) app.description = resolved.description;
|
|
252
259
|
if (app.dependencies === undefined) app.dependencies = resolved.dependencies;
|
|
260
|
+
if (app.directDependencies === undefined) app.directDependencies = resolved.directDependencies;
|
|
261
|
+
if (app.nestedDependencies === undefined) app.nestedDependencies = resolved.nestedDependencies;
|
|
253
262
|
if (app.marketplaceCatalogUrls === undefined) app.marketplaceCatalogUrls = resolved.marketplaceCatalogUrls;
|
|
254
263
|
}
|
|
255
264
|
app.name = app.name ?? 'app';
|
|
@@ -26,6 +26,7 @@ export const ABOUT_TAB_PACKAGES = "about.tab.packages";
|
|
|
26
26
|
export const ABOUT_TAB_ATTRIBUTIONS = "about.tab.attributions";
|
|
27
27
|
|
|
28
28
|
export const ATTRIBUTION_ECLIPSE_DOCKS = "attribution.eclipse-docks";
|
|
29
|
+
export const ATTRIBUTION_FONT_AWESOME = "attribution.font-awesome";
|
|
29
30
|
|
|
30
31
|
export const CTXMENU_FILEBROWSER_RENAME = "contextmenu.filebrowser.rename";
|
|
31
32
|
export const CTXMENU_FILEBROWSER_DELETE = "contextmenu.filebrowser.delete";
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { html, nothing, type TemplateResult } from "lit";
|
|
2
|
+
import { contributionRegistry, type HTMLContribution } from "./contributionregistry";
|
|
3
|
+
import { SYSTEM_ATTRIBUTIONS } from "./contribution-targets";
|
|
4
|
+
|
|
5
|
+
export type LicenseAttributionOptions = {
|
|
6
|
+
name: string;
|
|
7
|
+
label: string;
|
|
8
|
+
ranking?: number;
|
|
9
|
+
component?: () => TemplateResult;
|
|
10
|
+
license?: string;
|
|
11
|
+
licenseUrl?: string;
|
|
12
|
+
projectUrl?: string;
|
|
13
|
+
projectLabel?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function registerLicenseAttribution(options: LicenseAttributionOptions): void {
|
|
17
|
+
const component =
|
|
18
|
+
options.component ??
|
|
19
|
+
(() => {
|
|
20
|
+
if (!options.license || !options.licenseUrl) {
|
|
21
|
+
return html`<p>${options.label}</p>`;
|
|
22
|
+
}
|
|
23
|
+
return html`
|
|
24
|
+
<p>
|
|
25
|
+
${options.label} is used under the
|
|
26
|
+
<a href=${options.licenseUrl} target="_blank" rel="noopener noreferrer">${options.license}</a>.
|
|
27
|
+
${options.projectUrl
|
|
28
|
+
? html`
|
|
29
|
+
See
|
|
30
|
+
<a href=${options.projectUrl} target="_blank" rel="noopener noreferrer"
|
|
31
|
+
>${options.projectLabel ?? options.projectUrl}</a
|
|
32
|
+
>.
|
|
33
|
+
`
|
|
34
|
+
: nothing}
|
|
35
|
+
</p>
|
|
36
|
+
`;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
contributionRegistry.registerContribution(SYSTEM_ATTRIBUTIONS, {
|
|
40
|
+
name: options.name,
|
|
41
|
+
label: options.label,
|
|
42
|
+
ranking: options.ranking ?? 0,
|
|
43
|
+
component,
|
|
44
|
+
} as HTMLContribution);
|
|
45
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Metadata for one npm package resolved at build time from its installed package.json. */
|
|
2
|
+
export interface ResolvedDependencyInfo {
|
|
3
|
+
license?: string;
|
|
4
|
+
homepage?: string;
|
|
5
|
+
repository?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type ResolvedDependencyMap = Record<string, ResolvedDependencyInfo>;
|
|
10
|
+
|
|
11
|
+
export function normalizeDependencyInfo(
|
|
12
|
+
value: ResolvedDependencyInfo | undefined,
|
|
13
|
+
): ResolvedDependencyInfo | undefined {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
package/src/vite-env.d.ts
CHANGED
|
@@ -14,7 +14,16 @@ declare const __RESOLVED_PACKAGE_INFO__: {
|
|
|
14
14
|
name: string;
|
|
15
15
|
version: string;
|
|
16
16
|
description?: string;
|
|
17
|
-
dependencies: Record<
|
|
17
|
+
dependencies: Record<
|
|
18
|
+
string,
|
|
19
|
+
{
|
|
20
|
+
license?: string;
|
|
21
|
+
homepage?: string;
|
|
22
|
+
repository?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
}
|
|
25
|
+
>;
|
|
26
|
+
directDependencies: string[];
|
|
27
|
+
nestedDependencies: Record<string, string[]>;
|
|
18
28
|
marketplaceCatalogUrls?: string[];
|
|
19
29
|
} | undefined;
|
|
20
|
-
|
|
@@ -1,23 +1,64 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import type { Plugin } from 'vite';
|
|
4
|
+
import type { ResolvedDependencyInfo, ResolvedDependencyMap } from './core/resolved-package-info';
|
|
5
|
+
|
|
6
|
+
export type { ResolvedDependencyInfo, ResolvedDependencyMap };
|
|
4
7
|
|
|
5
8
|
export interface ResolvedPackageInfo {
|
|
6
9
|
name: string;
|
|
7
10
|
version: string;
|
|
8
11
|
description?: string;
|
|
9
|
-
dependencies:
|
|
12
|
+
dependencies: ResolvedDependencyMap;
|
|
13
|
+
/** Direct app `package.json` dependencies, in declaration order. */
|
|
14
|
+
directDependencies: string[];
|
|
15
|
+
/** Third-party runtime packages nested under a direct @eclipse-docks/core or extension-* dependency. */
|
|
16
|
+
nestedDependencies: Record<string, string[]>;
|
|
10
17
|
marketplaceCatalogUrls?: string[];
|
|
11
18
|
}
|
|
12
19
|
|
|
20
|
+
type LicenseField =
|
|
21
|
+
| string
|
|
22
|
+
| { type?: string; url?: string }
|
|
23
|
+
| Array<string | { type?: string; url?: string }>;
|
|
24
|
+
|
|
13
25
|
interface PackageJson {
|
|
14
26
|
name?: string;
|
|
15
27
|
version?: string;
|
|
16
28
|
description?: string;
|
|
29
|
+
license?: LicenseField;
|
|
30
|
+
homepage?: string;
|
|
31
|
+
repository?: string | { type?: string; url?: string };
|
|
17
32
|
dependencies?: Record<string, string>;
|
|
18
33
|
devDependencies?: Record<string, string>;
|
|
19
34
|
}
|
|
20
35
|
|
|
36
|
+
export type ResolvePackageInfoOptions = {
|
|
37
|
+
includeDevDependencies?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* When true (default), list each direct `@eclipse-docks/core` and `extension-*`
|
|
40
|
+
* dependency's own third-party `package.json` dependencies in the About tree.
|
|
41
|
+
*/
|
|
42
|
+
includeExtensionRuntimeDependencies?: boolean;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const RUNTIME_SKIP_PATTERN = /^@types\//;
|
|
46
|
+
|
|
47
|
+
const RUNTIME_SKIP_PACKAGES = new Set([
|
|
48
|
+
'typescript',
|
|
49
|
+
'vite',
|
|
50
|
+
'vitest',
|
|
51
|
+
'jsdom',
|
|
52
|
+
'playwright',
|
|
53
|
+
'rolldown',
|
|
54
|
+
'fake-indexeddb',
|
|
55
|
+
'@vitest/coverage-v8',
|
|
56
|
+
'vite-plugin-dts',
|
|
57
|
+
'vite-plugin-cross-origin-isolation',
|
|
58
|
+
'vite-plugin-mkcert',
|
|
59
|
+
'vite-plugin-pwa',
|
|
60
|
+
]);
|
|
61
|
+
|
|
21
62
|
function packageJsonPath(appRoot: string, packageName: string): string | null {
|
|
22
63
|
const segments = packageName.startsWith('@')
|
|
23
64
|
? packageName.split('/')
|
|
@@ -37,42 +78,165 @@ function packageJsonPath(appRoot: string, packageName: string): string | null {
|
|
|
37
78
|
return null;
|
|
38
79
|
}
|
|
39
80
|
|
|
81
|
+
function readWorkspacePackageJson(appRoot: string, depName: string): PackageJson | null {
|
|
82
|
+
if (!depName.startsWith('@eclipse-docks/')) return null;
|
|
83
|
+
|
|
84
|
+
const folder = depName === '@eclipse-docks/core' ? 'core' : depName.slice('@eclipse-docks/'.length);
|
|
85
|
+
let dir = path.resolve(appRoot);
|
|
86
|
+
const root = path.parse(dir).root;
|
|
87
|
+
|
|
88
|
+
while (dir !== root) {
|
|
89
|
+
const workspacePkgPath = path.join(dir, 'packages', folder, 'package.json');
|
|
90
|
+
if (existsSync(workspacePkgPath)) {
|
|
91
|
+
try {
|
|
92
|
+
return JSON.parse(readFileSync(workspacePkgPath, 'utf8')) as PackageJson;
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
dir = path.dirname(dir);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
40
103
|
function readPackageJson(appRoot: string, packageName: string): PackageJson | null {
|
|
41
104
|
const pkgPath = packageJsonPath(appRoot, packageName);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
105
|
+
let pkg: PackageJson | null = null;
|
|
106
|
+
if (pkgPath) {
|
|
107
|
+
try {
|
|
108
|
+
pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;
|
|
109
|
+
} catch {
|
|
110
|
+
pkg = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const workspacePkg = readWorkspacePackageJson(appRoot, packageName);
|
|
115
|
+
if (workspacePkg) {
|
|
116
|
+
pkg = {
|
|
117
|
+
...workspacePkg,
|
|
118
|
+
...pkg,
|
|
119
|
+
description: pkg?.description ?? workspacePkg.description,
|
|
120
|
+
license: pkg?.license ?? workspacePkg.license,
|
|
121
|
+
homepage: pkg?.homepage ?? workspacePkg.homepage,
|
|
122
|
+
repository: pkg?.repository ?? workspacePkg.repository,
|
|
123
|
+
};
|
|
47
124
|
}
|
|
125
|
+
|
|
126
|
+
return pkg;
|
|
48
127
|
}
|
|
49
128
|
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
if (typeof
|
|
53
|
-
|
|
129
|
+
function normalizeLicense(license: LicenseField | undefined): string | undefined {
|
|
130
|
+
if (!license) return undefined;
|
|
131
|
+
if (typeof license === 'string') return license;
|
|
132
|
+
if (Array.isArray(license)) {
|
|
133
|
+
const parts = license
|
|
134
|
+
.map((entry) => (typeof entry === 'string' ? entry : entry.type ?? ''))
|
|
135
|
+
.filter(Boolean);
|
|
136
|
+
return parts.length > 0 ? parts.join(' AND ') : undefined;
|
|
137
|
+
}
|
|
138
|
+
return license.type;
|
|
54
139
|
}
|
|
55
140
|
|
|
56
|
-
function
|
|
141
|
+
function normalizeRepository(
|
|
142
|
+
repository: PackageJson['repository'],
|
|
143
|
+
): string | undefined {
|
|
144
|
+
if (!repository) return undefined;
|
|
145
|
+
const raw = typeof repository === 'string' ? repository : repository.url;
|
|
146
|
+
if (!raw) return undefined;
|
|
147
|
+
return raw
|
|
148
|
+
.replace(/^git\+/, '')
|
|
149
|
+
.replace(/^git:\/\//, 'https://')
|
|
150
|
+
.replace(/\.git$/, '');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function shouldSkipRuntimePackage(name: string): boolean {
|
|
154
|
+
if (RUNTIME_SKIP_PATTERN.test(name)) return true;
|
|
155
|
+
if (RUNTIME_SKIP_PACKAGES.has(name)) return true;
|
|
156
|
+
if (name.startsWith('vite-plugin-')) return true;
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Unscoped `extension-*` or scoped `@namespace/extension-*` (any npm scope). */
|
|
161
|
+
const DEFAULT_EXTENSION_PATTERN = /^(?:@[^/]+\/)?extension-/;
|
|
162
|
+
|
|
163
|
+
function isEclipseDocksPlatformPackage(name: string): boolean {
|
|
164
|
+
return name === '@eclipse-docks/core' || DEFAULT_EXTENSION_PATTERN.test(name);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function resolveDependencyInfo(
|
|
57
168
|
appRoot: string,
|
|
169
|
+
depName: string,
|
|
170
|
+
): ResolvedDependencyInfo {
|
|
171
|
+
const pkg = readPackageJson(appRoot, depName);
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
license: normalizeLicense(pkg?.license),
|
|
175
|
+
homepage: typeof pkg?.homepage === 'string' ? pkg.homepage : undefined,
|
|
176
|
+
repository: normalizeRepository(pkg?.repository),
|
|
177
|
+
description: typeof pkg?.description === 'string' ? pkg.description : undefined,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function collectDirectDependencyEntries(
|
|
58
182
|
pkg: PackageJson,
|
|
59
|
-
options?:
|
|
60
|
-
):
|
|
183
|
+
options?: ResolvePackageInfoOptions,
|
|
184
|
+
): Array<[string, string]> {
|
|
61
185
|
const deps = { ...pkg.dependencies };
|
|
62
186
|
if (options?.includeDevDependencies && pkg.devDependencies) {
|
|
63
187
|
Object.assign(deps, pkg.devDependencies);
|
|
64
188
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
189
|
+
return Object.entries(deps);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Direct third-party runtime dependencies declared in `seed`'s package.json. */
|
|
193
|
+
function collectDirectThirdPartyDependencies(appRoot: string, seed: string): string[] {
|
|
194
|
+
const pkg = readPackageJson(appRoot, seed);
|
|
195
|
+
if (!pkg?.dependencies) return [];
|
|
196
|
+
|
|
197
|
+
return Object.keys(pkg.dependencies)
|
|
198
|
+
.filter((dep) => !shouldSkipRuntimePackage(dep))
|
|
199
|
+
.filter((dep) => !isEclipseDocksPlatformPackage(dep))
|
|
200
|
+
.sort((a, b) => a.localeCompare(b));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function resolveDependenciesFromPkg(
|
|
204
|
+
appRoot: string,
|
|
205
|
+
pkg: PackageJson,
|
|
206
|
+
options?: ResolvePackageInfoOptions,
|
|
207
|
+
): Pick<ResolvedPackageInfo, 'dependencies' | 'directDependencies' | 'nestedDependencies'> {
|
|
208
|
+
const depEntries = collectDirectDependencyEntries(pkg, options);
|
|
209
|
+
const directDependencies = depEntries.map(([name]) => name);
|
|
210
|
+
const dependencies: ResolvedDependencyMap = {};
|
|
211
|
+
|
|
212
|
+
for (const [name] of depEntries) {
|
|
213
|
+
dependencies[name] = resolveDependencyInfo(appRoot, name);
|
|
69
214
|
}
|
|
70
|
-
|
|
215
|
+
|
|
216
|
+
const nestedDependencies: Record<string, string[]> = {};
|
|
217
|
+
|
|
218
|
+
if (options?.includeExtensionRuntimeDependencies !== false) {
|
|
219
|
+
for (const name of directDependencies) {
|
|
220
|
+
if (!isEclipseDocksPlatformPackage(name)) continue;
|
|
221
|
+
|
|
222
|
+
const thirdParty = collectDirectThirdPartyDependencies(appRoot, name);
|
|
223
|
+
if (thirdParty.length === 0) continue;
|
|
224
|
+
|
|
225
|
+
nestedDependencies[name] = thirdParty;
|
|
226
|
+
for (const dep of thirdParty) {
|
|
227
|
+
if (!dependencies[dep]) {
|
|
228
|
+
dependencies[dep] = resolveDependencyInfo(appRoot, dep);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return { dependencies, directDependencies, nestedDependencies };
|
|
71
235
|
}
|
|
72
236
|
|
|
73
237
|
export function resolvePackageInfo(
|
|
74
238
|
appRoot: string,
|
|
75
|
-
options?:
|
|
239
|
+
options?: ResolvePackageInfoOptions,
|
|
76
240
|
): ResolvedPackageInfo | null {
|
|
77
241
|
const pkgPath = path.join(appRoot, 'package.json');
|
|
78
242
|
if (!existsSync(pkgPath)) return null;
|
|
@@ -87,18 +251,47 @@ export function resolvePackageInfo(
|
|
|
87
251
|
const name = typeof pkg.name === 'string' ? pkg.name : '';
|
|
88
252
|
const version = typeof pkg.version === 'string' ? pkg.version : '0.0.0';
|
|
89
253
|
const description = typeof pkg.description === 'string' ? pkg.description : undefined;
|
|
90
|
-
const dependencies =
|
|
91
|
-
|
|
254
|
+
const { dependencies, directDependencies, nestedDependencies } = resolveDependenciesFromPkg(
|
|
255
|
+
appRoot,
|
|
256
|
+
pkg,
|
|
257
|
+
options,
|
|
258
|
+
);
|
|
259
|
+
const marketplaceCatalogUrls = (pkg as { marketplace?: { catalogUrls?: string[] } }).marketplace
|
|
260
|
+
?.catalogUrls;
|
|
92
261
|
|
|
93
|
-
return {
|
|
262
|
+
return {
|
|
263
|
+
name,
|
|
264
|
+
version,
|
|
265
|
+
description,
|
|
266
|
+
dependencies,
|
|
267
|
+
directDependencies,
|
|
268
|
+
nestedDependencies,
|
|
269
|
+
marketplaceCatalogUrls,
|
|
270
|
+
};
|
|
94
271
|
}
|
|
95
272
|
|
|
96
273
|
export function resolveDepVersions(
|
|
97
274
|
appRoot: string,
|
|
98
|
-
options?:
|
|
275
|
+
options?: ResolvePackageInfoOptions,
|
|
99
276
|
): Record<string, string> {
|
|
100
|
-
const
|
|
101
|
-
|
|
277
|
+
const pkgPath = path.join(appRoot, 'package.json');
|
|
278
|
+
if (!existsSync(pkgPath)) return {};
|
|
279
|
+
|
|
280
|
+
let pkg: PackageJson;
|
|
281
|
+
try {
|
|
282
|
+
pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;
|
|
283
|
+
} catch {
|
|
284
|
+
return {};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const depEntries = collectDirectDependencyEntries(pkg, options);
|
|
288
|
+
const result: Record<string, string> = {};
|
|
289
|
+
for (const [name, specifier] of depEntries) {
|
|
290
|
+
const installed = readPackageJson(appRoot, name);
|
|
291
|
+
result[name] =
|
|
292
|
+
typeof installed?.version === 'string' ? installed.version : specifier;
|
|
293
|
+
}
|
|
294
|
+
return result;
|
|
102
295
|
}
|
|
103
296
|
|
|
104
297
|
const RESOLVED_PACKAGE_INFO_KEY = '__RESOLVED_PACKAGE_INFO__';
|
|
@@ -121,9 +314,6 @@ export function prependExtensionSideEffectImport(code: string): string {
|
|
|
121
314
|
return EXTENSION_IMPORT_STATEMENT + code;
|
|
122
315
|
}
|
|
123
316
|
|
|
124
|
-
/** Unscoped `extension-*` or scoped `@namespace/extension-*` (any npm scope). */
|
|
125
|
-
const DEFAULT_EXTENSION_PATTERN = /^(?:@[^/]+\/)?extension-/;
|
|
126
|
-
|
|
127
317
|
const DEFAULT_PRIORITY_FIRST = ['@eclipse-docks/extension-pwa', 'extension-pwa'];
|
|
128
318
|
|
|
129
319
|
export interface ExtensionSideEffectsOptions {
|
|
@@ -145,8 +335,7 @@ export interface ExtensionSideEffectsOptions {
|
|
|
145
335
|
packageNamePattern?: RegExp;
|
|
146
336
|
}
|
|
147
337
|
|
|
148
|
-
export type ResolveDepVersionsPluginOptions = {
|
|
149
|
-
includeDevDependencies?: boolean;
|
|
338
|
+
export type ResolveDepVersionsPluginOptions = ResolvePackageInfoOptions & {
|
|
150
339
|
/**
|
|
151
340
|
* By default, registers a virtual module that side-effect-imports every matching direct
|
|
152
341
|
* `dependencies` entry (see `ExtensionSideEffectsOptions`), and prepends
|
|
@@ -241,6 +430,14 @@ export function resolveExtensionSideEffectPackages(
|
|
|
241
430
|
);
|
|
242
431
|
}
|
|
243
432
|
|
|
433
|
+
function dependencyKeysFromInfo(info: ResolvedPackageInfo | null | undefined): string[] {
|
|
434
|
+
if (!info) return [];
|
|
435
|
+
if (info.directDependencies.length > 0) {
|
|
436
|
+
return info.directDependencies;
|
|
437
|
+
}
|
|
438
|
+
return Object.keys(info.dependencies);
|
|
439
|
+
}
|
|
440
|
+
|
|
244
441
|
export function resolveDepVersionsPlugin(
|
|
245
442
|
options?: ResolveDepVersionsPluginOptions,
|
|
246
443
|
): Plugin {
|
|
@@ -259,6 +456,8 @@ export function resolveDepVersionsPlugin(
|
|
|
259
456
|
version: '0.0.0',
|
|
260
457
|
description: undefined,
|
|
261
458
|
dependencies: {},
|
|
459
|
+
directDependencies: [],
|
|
460
|
+
nestedDependencies: {},
|
|
262
461
|
marketplaceCatalogUrls: undefined,
|
|
263
462
|
};
|
|
264
463
|
return {
|
|
@@ -276,9 +475,10 @@ export function resolveDepVersionsPlugin(
|
|
|
276
475
|
return;
|
|
277
476
|
}
|
|
278
477
|
const info = resolvePackageInfo(appRoot, options);
|
|
478
|
+
const depKeys = dependencyKeysFromInfo(info);
|
|
279
479
|
extensionImportPackages = resolveExtensionSideEffectPackages(
|
|
280
480
|
appRoot,
|
|
281
|
-
|
|
481
|
+
Object.fromEntries(depKeys.map((name) => [name, '*'])),
|
|
282
482
|
normalized,
|
|
283
483
|
);
|
|
284
484
|
},
|