@ws-test-realm/admin-kit 0.1.8 → 0.1.10
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/bin/ws-modules.js +4 -3
- package/bin/ws-purge.js +113 -0
- package/lib/purge-jar.js +27 -7
- package/lib/purge-remotes.js +179 -68
- package/lib/webpack-factory.js +16 -0
- package/package.json +4 -2
- package/template/package.json +1 -1
package/bin/ws-modules.js
CHANGED
|
@@ -142,10 +142,11 @@ async function main() {
|
|
|
142
142
|
process.exit(1);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
// No positional but step flags present → implicit `all`. Lets npm scripts
|
|
146
|
+
// like `"wire": "ws-modules --build --pack --deploy"` run cleanly without
|
|
147
|
+
// requiring callers to remember `-- all`.
|
|
145
148
|
if (!argv.positional.length) {
|
|
146
|
-
|
|
147
|
-
console.error(USAGE);
|
|
148
|
-
process.exit(1);
|
|
149
|
+
argv.positional.push("all");
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
let restrictTo;
|
package/bin/ws-purge.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ws-purge — strip prior federation contributions across an admin-modules
|
|
3
|
+
// workspace's deploy targets (jars + ext dirs) + the host's .federation/<id>/
|
|
4
|
+
// types dirs. Mirrors `ws-modules --deploy`'s target-resolution exactly so the
|
|
5
|
+
// two stay in lockstep (same wsconfig override > package.json rules).
|
|
6
|
+
//
|
|
7
|
+
// Usage:
|
|
8
|
+
// ws-purge # all remotes, each by own resolved target
|
|
9
|
+
// ws-purge jar # only jar-targeted remotes
|
|
10
|
+
// ws-purge ext # only ext-targeted remotes
|
|
11
|
+
// ws-purge jar <pathtojar> # purge a specific jar by path (drops every
|
|
12
|
+
// META-INF/federation/<*>/, regardless of
|
|
13
|
+
// which project owned it)
|
|
14
|
+
// ws-purge <name>... # restrict to those modules (each by own
|
|
15
|
+
// target)
|
|
16
|
+
// ws-purge <name>... jar # restrict + require jar-targeted; errors
|
|
17
|
+
// on mismatch with hint to use
|
|
18
|
+
// `ws-purge jar <pathtojar>`
|
|
19
|
+
// ws-purge <name>... ext # restrict + require ext-targeted
|
|
20
|
+
//
|
|
21
|
+
// End-of-run report lists every target acted on (path + entries dropped or
|
|
22
|
+
// dir removed), every skipped target with reason, and every error.
|
|
23
|
+
|
|
24
|
+
const path = require("path");
|
|
25
|
+
const fs = require("fs");
|
|
26
|
+
const { purgeRemotes, purgeJarPath } = require("../lib/purge-remotes");
|
|
27
|
+
|
|
28
|
+
const USAGE = `ws-purge [<name>...] [jar | ext] [<pathtojar>]
|
|
29
|
+
|
|
30
|
+
Strip prior federation contributions across the workspace's deploy targets.
|
|
31
|
+
|
|
32
|
+
Modes:
|
|
33
|
+
(default) every remote, each by its own resolved target
|
|
34
|
+
jar only jar-targeted remotes
|
|
35
|
+
ext only ext-targeted remotes
|
|
36
|
+
jar <pathtojar> purge a specific jar by path (no module resolution)
|
|
37
|
+
|
|
38
|
+
Restrict to specific modules by listing names first:
|
|
39
|
+
ws-purge crm shop-common
|
|
40
|
+
ws-purge crm jar # errors if crm isn't jar-targeted
|
|
41
|
+
ws-purge crm ext # errors if crm isn't ext-targeted
|
|
42
|
+
|
|
43
|
+
The end-of-run report lists exactly what was purged.
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
function parseArgv(argv) {
|
|
47
|
+
const tokens = argv.slice(2);
|
|
48
|
+
let mode = null;
|
|
49
|
+
let jarPath = null;
|
|
50
|
+
const names = [];
|
|
51
|
+
|
|
52
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
53
|
+
const t = tokens[i];
|
|
54
|
+
if (t === "--help" || t === "-h") {
|
|
55
|
+
process.stdout.write(USAGE);
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
if (t === "jar" || t === "ext") {
|
|
59
|
+
if (mode) {
|
|
60
|
+
throw new Error(`mode specified twice: ${mode} then ${t}`);
|
|
61
|
+
}
|
|
62
|
+
mode = t;
|
|
63
|
+
// Look ahead: if jar and next looks like a path, consume it
|
|
64
|
+
const next = tokens[i + 1];
|
|
65
|
+
if (mode === "jar" && next && /[/.]/.test(next)) {
|
|
66
|
+
jarPath = next;
|
|
67
|
+
i++;
|
|
68
|
+
}
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
names.push(t);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (jarPath && names.length) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`\`jar <pathtojar>\` can't be combined with module names — the jar path purges that file regardless of which module owned it.`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return { mode, jarPath, names };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function main() {
|
|
84
|
+
let parsed;
|
|
85
|
+
try {
|
|
86
|
+
parsed = parseArgv(process.argv);
|
|
87
|
+
} catch (e) {
|
|
88
|
+
console.error(`ws-purge: ${e.message}`);
|
|
89
|
+
console.error(USAGE);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (parsed.jarPath) {
|
|
94
|
+
const abs = path.resolve(parsed.jarPath);
|
|
95
|
+
if (!fs.existsSync(abs)) {
|
|
96
|
+
console.error(`ws-purge: jar not found at ${abs}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
const { errors } = purgeJarPath(abs);
|
|
100
|
+
process.exit(errors.length ? 1 : 0);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const workspaceDir = process.cwd();
|
|
104
|
+
const { errors } = purgeRemotes({
|
|
105
|
+
workspaceDir,
|
|
106
|
+
restrictTo: parsed.names,
|
|
107
|
+
modeFilter: parsed.mode,
|
|
108
|
+
strict: parsed.mode !== null && parsed.names.length > 0,
|
|
109
|
+
});
|
|
110
|
+
process.exit(errors.length ? 1 : 0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
main();
|
package/lib/purge-jar.js
CHANGED
|
@@ -2,22 +2,32 @@ const fs = require("fs");
|
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const AdmZip = require("adm-zip");
|
|
4
4
|
|
|
5
|
-
// Strip
|
|
6
|
-
//
|
|
7
|
-
//
|
|
5
|
+
// Strip federated remote contributions from a jar by dropping entries under
|
|
6
|
+
// META-INF/federation/.
|
|
7
|
+
//
|
|
8
|
+
// purgeJar({ jarPath, id }) — drops only META-INF/federation/<id>/.
|
|
9
|
+
// purgeJar({ jarPath }) — drops every META-INF/federation/<*>/.
|
|
10
|
+
//
|
|
11
|
+
// Returns { jarPath, droppedEntries, droppedIds[], hadContribution }.
|
|
8
12
|
function purgeJar({ jarPath, id }) {
|
|
9
13
|
if (!fs.existsSync(jarPath)) {
|
|
10
14
|
throw new Error(`Jar not found: ${jarPath}`);
|
|
11
15
|
}
|
|
12
16
|
|
|
13
|
-
const
|
|
17
|
+
const federationRoot = `META-INF/federation/`;
|
|
18
|
+
const targetPrefix = id ? `${federationRoot}${id}/` : federationRoot;
|
|
19
|
+
|
|
14
20
|
const original = new AdmZip(jarPath);
|
|
15
21
|
const out = new AdmZip();
|
|
16
22
|
|
|
17
23
|
let dropped = 0;
|
|
24
|
+
const idsHit = new Set();
|
|
18
25
|
for (const entry of original.getEntries()) {
|
|
19
|
-
if (entry.entryName.startsWith(
|
|
26
|
+
if (entry.entryName.startsWith(targetPrefix)) {
|
|
20
27
|
dropped++;
|
|
28
|
+
const rest = entry.entryName.slice(federationRoot.length);
|
|
29
|
+
const slash = rest.indexOf("/");
|
|
30
|
+
if (slash > 0) idsHit.add(rest.slice(0, slash));
|
|
21
31
|
continue;
|
|
22
32
|
}
|
|
23
33
|
if (entry.isDirectory) {
|
|
@@ -33,7 +43,12 @@ function purgeJar({ jarPath, id }) {
|
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
if (dropped === 0) {
|
|
36
|
-
return {
|
|
46
|
+
return {
|
|
47
|
+
jarPath,
|
|
48
|
+
droppedEntries: 0,
|
|
49
|
+
droppedIds: [],
|
|
50
|
+
hadContribution: false,
|
|
51
|
+
};
|
|
37
52
|
}
|
|
38
53
|
|
|
39
54
|
const dir = path.dirname(jarPath);
|
|
@@ -44,7 +59,12 @@ function purgeJar({ jarPath, id }) {
|
|
|
44
59
|
out.writeZip(tmp);
|
|
45
60
|
fs.renameSync(tmp, jarPath);
|
|
46
61
|
|
|
47
|
-
return {
|
|
62
|
+
return {
|
|
63
|
+
jarPath,
|
|
64
|
+
droppedEntries: dropped,
|
|
65
|
+
droppedIds: [...idsHit].sort(),
|
|
66
|
+
hadContribution: true,
|
|
67
|
+
};
|
|
48
68
|
}
|
|
49
69
|
|
|
50
70
|
module.exports = { purgeJar };
|
package/lib/purge-remotes.js
CHANGED
|
@@ -4,117 +4,228 @@ const { purgeJar } = require("./purge-jar");
|
|
|
4
4
|
const { loadOrder, partitionByKind } = require("./build-modules");
|
|
5
5
|
const { loadDeployContext, resolveTarget } = require("./target-resolution");
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// - always: remove host's <adminDir>/.federation/<id>/ types dir
|
|
11
|
-
//
|
|
12
|
-
// Uses the exact same target resolution as deploy — wsconfig override >
|
|
13
|
-
// project package.json (target=ext | pom-derived artifactId). No part of the
|
|
14
|
-
// jar location is implied from the project id; same abuse-resistance as deploy.
|
|
15
|
-
function purgeOne({
|
|
16
|
-
workspaceDir,
|
|
17
|
-
id,
|
|
18
|
-
wpmRoot,
|
|
19
|
-
modulesFolder,
|
|
20
|
-
adminDir,
|
|
21
|
-
wsconfig,
|
|
22
|
-
}) {
|
|
23
|
-
const hostFederationDir = path.join(adminDir, ".federation", id);
|
|
7
|
+
// Per-remote purge action. Returns a structured action record.
|
|
8
|
+
function purgeOne({ workspaceDir, id, ctx }) {
|
|
9
|
+
const hostFederationDir = path.join(ctx.adminDir, ".federation", id);
|
|
24
10
|
|
|
25
11
|
const target = resolveTarget({
|
|
26
12
|
workspaceDir,
|
|
27
13
|
projectName: id,
|
|
28
|
-
wsconfig,
|
|
29
|
-
wpmRoot,
|
|
30
|
-
modulesFolder,
|
|
14
|
+
wsconfig: ctx.wsconfig,
|
|
15
|
+
wpmRoot: ctx.wpmRoot,
|
|
16
|
+
modulesFolder: ctx.modulesFolder,
|
|
31
17
|
});
|
|
32
18
|
|
|
33
|
-
let
|
|
19
|
+
let artifact;
|
|
34
20
|
if (target.kind === "jar") {
|
|
35
|
-
const
|
|
36
|
-
|
|
21
|
+
const r = purgeJar({ jarPath: target.jarPath, id });
|
|
22
|
+
artifact = {
|
|
37
23
|
kind: "jar",
|
|
38
24
|
jarPath: target.jarPath,
|
|
39
25
|
pomPath: target.pomPath,
|
|
40
26
|
artifactId: target.artifactId,
|
|
41
|
-
|
|
27
|
+
droppedEntries: r.droppedEntries,
|
|
28
|
+
hadContribution: r.hadContribution,
|
|
42
29
|
};
|
|
43
30
|
} else {
|
|
44
|
-
|
|
45
|
-
if (fs.
|
|
46
|
-
|
|
47
|
-
removed = true;
|
|
48
|
-
}
|
|
49
|
-
artifactReport = { kind: "ext", extDir: target.extDir, removedExtDir: removed };
|
|
31
|
+
const removed = fs.existsSync(target.extDir);
|
|
32
|
+
if (removed) fs.rmSync(target.extDir, { recursive: true, force: true });
|
|
33
|
+
artifact = { kind: "ext", extDir: target.extDir, removedExtDir: removed };
|
|
50
34
|
}
|
|
51
35
|
|
|
52
|
-
|
|
53
|
-
if (
|
|
36
|
+
const typesRemoved = fs.existsSync(hostFederationDir);
|
|
37
|
+
if (typesRemoved) {
|
|
54
38
|
fs.rmSync(hostFederationDir, { recursive: true, force: true });
|
|
55
|
-
typesRemoved = true;
|
|
56
39
|
}
|
|
57
40
|
|
|
58
|
-
return { ...
|
|
41
|
+
return { id, kind: target.kind, ...artifact, hostFederationDir, typesRemoved };
|
|
59
42
|
}
|
|
60
43
|
|
|
61
|
-
|
|
44
|
+
// Purge across an admin-modules workspace.
|
|
45
|
+
//
|
|
46
|
+
// modeFilter: null | "jar" | "ext"
|
|
47
|
+
// null → each remote is purged according to its own resolved target
|
|
48
|
+
// "jar" → only act on jar-targeted remotes (skip ext)
|
|
49
|
+
// "ext" → only act on ext-targeted remotes (skip jar)
|
|
50
|
+
//
|
|
51
|
+
// strict: when true and modeFilter is set with explicit restrictTo names,
|
|
52
|
+
// mismatches throw with an actionable error (suggests `ws-purge jar <path>`
|
|
53
|
+
// for jar-mismatch). When false (modeFilter without restrictTo), mismatches
|
|
54
|
+
// are silently filtered.
|
|
55
|
+
function purgeRemotes({
|
|
56
|
+
workspaceDir,
|
|
57
|
+
restrictTo = [],
|
|
58
|
+
withDeps = false,
|
|
59
|
+
modeFilter = null,
|
|
60
|
+
strict = false,
|
|
61
|
+
}) {
|
|
62
62
|
const ctx = loadDeployContext(workspaceDir);
|
|
63
|
-
|
|
64
63
|
const { order } = loadOrder({ workspaceDir, restrictTo, withDeps });
|
|
65
64
|
const { remotes, libraries } = partitionByKind(workspaceDir, order);
|
|
66
65
|
|
|
67
|
-
console.log(
|
|
68
|
-
|
|
66
|
+
console.log(`=== Purge ===`);
|
|
67
|
+
console.log(` mode: ${modeFilter || "auto (each by own target)"}`);
|
|
68
|
+
console.log(
|
|
69
|
+
` scope: ${restrictTo.length ? restrictTo.join(", ") : "all remotes"}`
|
|
70
|
+
);
|
|
69
71
|
if (libraries.length) {
|
|
70
72
|
console.log(
|
|
71
|
-
`
|
|
73
|
+
` skipped libraries: ${libraries.join(", ")} (wsmodules.kind=library)`
|
|
72
74
|
);
|
|
73
75
|
}
|
|
76
|
+
console.log("");
|
|
77
|
+
|
|
78
|
+
const actions = [];
|
|
79
|
+
const skipped = [];
|
|
80
|
+
const errors = [];
|
|
74
81
|
|
|
75
|
-
const results = [];
|
|
76
82
|
for (const id of remotes) {
|
|
77
|
-
|
|
83
|
+
let target;
|
|
78
84
|
try {
|
|
79
|
-
|
|
85
|
+
target = resolveTarget({
|
|
80
86
|
workspaceDir,
|
|
81
|
-
id,
|
|
87
|
+
projectName: id,
|
|
88
|
+
wsconfig: ctx.wsconfig,
|
|
82
89
|
wpmRoot: ctx.wpmRoot,
|
|
83
90
|
modulesFolder: ctx.modulesFolder,
|
|
84
|
-
adminDir: ctx.adminDir,
|
|
85
|
-
wsconfig: ctx.wsconfig,
|
|
86
91
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
} catch (e) {
|
|
93
|
+
errors.push({ id, stage: "resolve", message: e.message });
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (modeFilter && target.kind !== modeFilter) {
|
|
98
|
+
if (strict) {
|
|
99
|
+
const hint =
|
|
100
|
+
modeFilter === "jar"
|
|
101
|
+
? `Use \`ws-purge jar <pathtojar>\` to purge a specific jar by path.`
|
|
102
|
+
: `Use \`ws-purge\` (no mode) to purge by each module's own target.`;
|
|
103
|
+
errors.push({
|
|
104
|
+
id,
|
|
105
|
+
stage: "filter",
|
|
106
|
+
message: `${id} is ${target.kind}-targeted, not ${modeFilter}-targeted. ${hint}`,
|
|
107
|
+
});
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
skipped.push({ id, reason: `target is ${target.kind}, filter is ${modeFilter}` });
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const action = purgeOne({ workspaceDir, id, ctx });
|
|
116
|
+
actions.push(action);
|
|
117
|
+
} catch (e) {
|
|
118
|
+
errors.push({ id, stage: "purge", message: e.message });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
reportActions({ actions, skipped, errors });
|
|
123
|
+
return { actions, skipped, errors };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Escape hatch: purge a specific jar by path, dropping every
|
|
127
|
+
// META-INF/federation/<*>/ entry regardless of which workspace owns it.
|
|
128
|
+
function purgeJarPath(jarPath) {
|
|
129
|
+
console.log(`=== Purge ===`);
|
|
130
|
+
console.log(` mode: jar (specific path)`);
|
|
131
|
+
console.log(` jar: ${jarPath}`);
|
|
132
|
+
console.log("");
|
|
133
|
+
|
|
134
|
+
const actions = [];
|
|
135
|
+
const errors = [];
|
|
136
|
+
try {
|
|
137
|
+
const r = purgeJar({ jarPath });
|
|
138
|
+
actions.push({
|
|
139
|
+
id: null,
|
|
140
|
+
kind: "jar",
|
|
141
|
+
jarPath,
|
|
142
|
+
droppedEntries: r.droppedEntries,
|
|
143
|
+
droppedIds: r.droppedIds,
|
|
144
|
+
hadContribution: r.hadContribution,
|
|
145
|
+
hostFederationDir: null,
|
|
146
|
+
typesRemoved: false,
|
|
147
|
+
});
|
|
148
|
+
} catch (e) {
|
|
149
|
+
errors.push({ id: jarPath, stage: "purge", message: e.message });
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
reportActions({ actions, skipped: [], errors });
|
|
153
|
+
return { actions, skipped: [], errors };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function reportActions({ actions, skipped, errors }) {
|
|
157
|
+
console.log(`=== Actions ===`);
|
|
158
|
+
if (!actions.length) {
|
|
159
|
+
console.log(` (nothing purged)`);
|
|
160
|
+
}
|
|
161
|
+
for (const a of actions) {
|
|
162
|
+
const label = a.id ? a.id : "(by path)";
|
|
163
|
+
if (a.kind === "jar") {
|
|
164
|
+
if (a.hadContribution) {
|
|
165
|
+
const ids = a.droppedIds && a.droppedIds.length
|
|
166
|
+
? ` (ids: ${a.droppedIds.join(", ")})`
|
|
167
|
+
: "";
|
|
168
|
+
console.log(
|
|
169
|
+
` ${label} jar purged ${a.droppedEntries} entries from ${a.jarPath}${ids}`
|
|
170
|
+
);
|
|
97
171
|
} else {
|
|
98
|
-
console.log(
|
|
99
|
-
|
|
100
|
-
|
|
172
|
+
console.log(
|
|
173
|
+
` ${label} jar no contribution to purge in ${a.jarPath}`
|
|
174
|
+
);
|
|
101
175
|
}
|
|
176
|
+
} else {
|
|
177
|
+
console.log(
|
|
178
|
+
` ${label} ext ${a.removedExtDir ? "removed" : "(absent)"} ${a.extDir}`
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
if (a.hostFederationDir) {
|
|
102
182
|
console.log(
|
|
103
|
-
`
|
|
183
|
+
` host types ${a.typesRemoved ? "removed" : "(absent)"}: ${a.hostFederationDir}`
|
|
104
184
|
);
|
|
105
|
-
results.push({ id, ok: true, ...r });
|
|
106
|
-
} catch (err) {
|
|
107
|
-
console.error(` \x1b[31mfailed:\x1b[0m ${err.message}`);
|
|
108
|
-
results.push({ id, ok: false, error: err.message });
|
|
109
185
|
}
|
|
110
186
|
}
|
|
111
187
|
|
|
112
|
-
|
|
113
|
-
|
|
188
|
+
if (skipped.length) {
|
|
189
|
+
console.log(`\n=== Skipped ===`);
|
|
190
|
+
for (const s of skipped) console.log(` ${s.id}: ${s.reason}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (errors.length) {
|
|
194
|
+
console.log(`\n=== Errors ===`);
|
|
195
|
+
for (const e of errors)
|
|
196
|
+
console.log(` \x1b[31m${e.id}\x1b[0m [${e.stage}] ${e.message}`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const jars = actions.filter((a) => a.kind === "jar");
|
|
200
|
+
const exts = actions.filter((a) => a.kind === "ext");
|
|
201
|
+
const typesRemoved = actions.filter((a) => a.typesRemoved).length;
|
|
202
|
+
const noopJars = jars.filter((a) => !a.hadContribution).length;
|
|
203
|
+
const removedExt = exts.filter((a) => a.removedExtDir).length;
|
|
204
|
+
|
|
205
|
+
console.log(`\n=== Summary ===`);
|
|
114
206
|
console.log(
|
|
115
|
-
|
|
207
|
+
` acted on ${actions.length} target(s): ${jars.length} jar, ${exts.length} ext`
|
|
116
208
|
);
|
|
117
|
-
|
|
209
|
+
if (jars.length) {
|
|
210
|
+
const totalEntries = jars.reduce((s, a) => s + (a.droppedEntries || 0), 0);
|
|
211
|
+
console.log(
|
|
212
|
+
` jar: ${totalEntries} entries dropped` +
|
|
213
|
+
(noopJars ? `; ${noopJars} jar(s) had no contribution` : "")
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
if (exts.length) {
|
|
217
|
+
console.log(
|
|
218
|
+
` ext: ${removedExt} dir(s) removed` +
|
|
219
|
+
(exts.length - removedExt
|
|
220
|
+
? `; ${exts.length - removedExt} already absent`
|
|
221
|
+
: "")
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
if (typesRemoved) {
|
|
225
|
+
console.log(` host: ${typesRemoved} .federation/<id>/ dir(s) removed`);
|
|
226
|
+
}
|
|
227
|
+
if (skipped.length) console.log(` skipped: ${skipped.length}`);
|
|
228
|
+
if (errors.length) console.log(` \x1b[31merrors: ${errors.length}\x1b[0m`);
|
|
118
229
|
}
|
|
119
230
|
|
|
120
|
-
module.exports = { purgeRemotes, purgeOne };
|
|
231
|
+
module.exports = { purgeRemotes, purgeOne, purgeJarPath };
|
package/lib/webpack-factory.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
1
2
|
const path = require("path");
|
|
2
3
|
const Module = require("module");
|
|
4
|
+
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
|
|
3
5
|
|
|
4
6
|
// Build the in-memory webpack config used to produce a federated remote
|
|
5
7
|
// from a single synthetic entry that re-exports the lib's public API.
|
|
@@ -30,6 +32,19 @@ function buildWebpackConfig({
|
|
|
30
32
|
|
|
31
33
|
const remoteOutDir = path.join(outDir, id, "remote");
|
|
32
34
|
|
|
35
|
+
// tsconfig.federation.json is the SSOT for cross-workspace paths
|
|
36
|
+
// (`@ws-remote/*` → `<adminDir>/.federation/*`, sibling lib aliases,
|
|
37
|
+
// etc.). Without this plugin webpack ignores tsconfig `paths` and
|
|
38
|
+
// walks node_modules — which fails for cross-workspace federation
|
|
39
|
+
// siblings that only live in the host's federation dir.
|
|
40
|
+
const federationTsconfig = path.join(workspaceDir, "tsconfig.federation.json");
|
|
41
|
+
const resolvePlugins = [];
|
|
42
|
+
if (fs.existsSync(federationTsconfig)) {
|
|
43
|
+
resolvePlugins.push(
|
|
44
|
+
new TsconfigPathsPlugin({ configFile: federationTsconfig })
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
33
48
|
return {
|
|
34
49
|
mode: "production",
|
|
35
50
|
entry: syntheticEntry,
|
|
@@ -56,6 +71,7 @@ function buildWebpackConfig({
|
|
|
56
71
|
},
|
|
57
72
|
resolve: {
|
|
58
73
|
alias: aliasMap,
|
|
74
|
+
plugins: resolvePlugins,
|
|
59
75
|
extensions: [".ts", ".js", ".mjs", ".json"],
|
|
60
76
|
// ngcc rewrites Angular packages in-place but leaves the
|
|
61
77
|
// originals next to them, exposing both via package.json fields
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ws-test-realm/admin-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Workflow CLI + scaffolding for Wiresphere admin-modules workspaces. Ships `ws-init-workspace` (init/merge into a project, stamps @wiresphere/shared's `getOverrides()` into the workspace's npm overrides block), `ws-modules` (build/pack/deploy driver), `ws-generate-module`/`ws-drop-module`, `ws-wire-host`, `ws-wire-pom`, `ws-sync-paths`, and `ws-pack-remote`. Depends on @wiresphere/devkit (toolchain BOM, peerDeps); pairs with @wiresphere/shared (runtime BOM + MF share map + overrides manifest). Requires npm 9+ for overrides + peerDep resolution to coexist cleanly.",
|
|
5
5
|
"license": "Artistic-2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"ws-generate-module": "./bin/ws-generate-module.js",
|
|
15
15
|
"ws-drop-module": "./bin/ws-drop-module.js",
|
|
16
16
|
"ws-modules": "./bin/ws-modules.js",
|
|
17
|
+
"ws-purge": "./bin/ws-purge.js",
|
|
17
18
|
"ws-sync-paths": "./bin/ws-sync-paths.js"
|
|
18
19
|
},
|
|
19
20
|
"main": "lib/index.js",
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
"@ws-test-realm/devkit": "^0.3.0",
|
|
29
30
|
"@ws-test-realm/shared": "^0.3.0",
|
|
30
31
|
"adm-zip": "^0.5.10",
|
|
31
|
-
"fast-xml-parser": "^4.3.0"
|
|
32
|
+
"fast-xml-parser": "^4.3.0",
|
|
33
|
+
"tsconfig-paths-webpack-plugin": "^4.1.0"
|
|
32
34
|
}
|
|
33
35
|
}
|
package/template/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"build": "ws-modules --build",
|
|
13
13
|
"pack": "ws-modules --pack",
|
|
14
14
|
"deploy": "ws-modules --deploy",
|
|
15
|
-
"purge": "ws-
|
|
15
|
+
"purge": "ws-purge",
|
|
16
16
|
"wire": "ws-modules --build --pack --deploy"
|
|
17
17
|
},
|
|
18
18
|
"prettier": "@ws-test-realm/devkit/prettier.config.js",
|