@guanjinke/artifact-client 1.11.0 → 1.12.0

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.
Files changed (35) hide show
  1. package/README.md +217 -217
  2. package/dist/cli/setup.js +2 -2
  3. package/dist/cli/setup.js.map +1 -1
  4. package/dist/cli.js +0 -0
  5. package/dist/environment/builder.d.ts.map +1 -1
  6. package/dist/environment/builder.js +78 -2
  7. package/dist/environment/builder.js.map +1 -1
  8. package/dist/environment/catalog.d.ts +24 -0
  9. package/dist/environment/catalog.d.ts.map +1 -1
  10. package/dist/environment/catalog.js +23 -1
  11. package/dist/environment/catalog.js.map +1 -1
  12. package/dist/environment/deferred.d.ts +38 -0
  13. package/dist/environment/deferred.d.ts.map +1 -0
  14. package/dist/environment/deferred.js +133 -0
  15. package/dist/environment/deferred.js.map +1 -0
  16. package/dist/environment/package-resource.d.ts +95 -0
  17. package/dist/environment/package-resource.d.ts.map +1 -0
  18. package/dist/environment/package-resource.js +323 -0
  19. package/dist/environment/package-resource.js.map +1 -0
  20. package/dist/environment/plan.d.ts +7 -1
  21. package/dist/environment/plan.d.ts.map +1 -1
  22. package/dist/environment/plan.js +25 -5
  23. package/dist/environment/plan.js.map +1 -1
  24. package/dist/environment/resource.d.ts +36 -0
  25. package/dist/environment/resource.d.ts.map +1 -0
  26. package/dist/environment/resource.js +101 -0
  27. package/dist/environment/resource.js.map +1 -0
  28. package/dist/environment/types.d.ts +36 -8
  29. package/dist/environment/types.d.ts.map +1 -1
  30. package/dist/environment/types.js +5 -0
  31. package/dist/environment/types.js.map +1 -1
  32. package/dist/environment/update.d.ts.map +1 -1
  33. package/dist/environment/update.js +210 -15
  34. package/dist/environment/update.js.map +1 -1
  35. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { ArtifactClient } from '../artifact-client';
2
- export type EnvironmentModule = 'dashboard' | 'reporting' | 'data-monitoring' | 'analysis' | 'sheets' | 'documents' | 'collaboration';
2
+ export type EnvironmentModule = 'dashboard' | 'reporting' | 'data-monitoring' | 'analysis' | 'sheets' | 'documents' | 'collaboration' | 'patch';
3
3
  export interface EnvironmentOptions {
4
4
  root: string;
5
5
  major: string;
@@ -24,9 +24,10 @@ export interface LayoutMapping {
24
24
  * `resource` is a static tree deployed into the environment's web root for the
25
25
  * Server to serve (the built-in `dashboard-resource` module's 3D scene and map
26
26
  * assets). It carries no assembly, needs no `.runtimeconfig.json`, and adds
27
- * nothing to `conf/Wyn.conf`.
27
+ * nothing to `conf/Wyn.conf`. `replace` overwrites one existing regular file
28
+ * instead of deploying a directory; the selectable `patch` module uses it.
28
29
  */
29
- role: 'plugin' | 'worker' | 'server' | 'monitor' | 'service' | 'resource';
30
+ role: 'plugin' | 'worker' | 'server' | 'monitor' | 'service' | 'resource' | 'replace';
30
31
  service?: string;
31
32
  /**
32
33
  * Edition this mapping belongs to. A mapping without one is deployed for every
@@ -40,21 +41,22 @@ export interface LayoutMapping {
40
41
  interface EnvironmentArtifactBase {
41
42
  module: string;
42
43
  plugin: string;
43
- version: string;
44
44
  /**
45
45
  * Remote object name of the artifact inside the version directory, or — for a
46
46
  * directory-of-files module — the remote directory holding its payload files.
47
- * Never a credential-bearing URL.
47
+ * Never a credential-bearing URL. A resolved deferred replacement records no
48
+ * path: the provider's path would expose a name the module hides.
48
49
  */
49
- path: string;
50
+ path?: string;
50
51
  mappings: LayoutMapping[];
51
52
  }
52
53
  /**
53
54
  * A module that publishes exactly one archive, downloaded and then extracted
54
55
  * before its mappings are laid out. This is the shape every module but
55
- * `builtin-samples` has.
56
+ * `builtin-samples` and `patch` has.
56
57
  */
57
58
  export interface EnvironmentArtifact extends EnvironmentArtifactBase {
59
+ version: string;
58
60
  /** File name of the single archive, relative to the version directory. */
59
61
  name: string;
60
62
  names?: undefined;
@@ -69,10 +71,36 @@ export interface EnvironmentArtifact extends EnvironmentArtifactBase {
69
71
  * artifact can never describe this module and vice versa.
70
72
  */
71
73
  export interface EnvironmentPayloadArtifact extends EnvironmentArtifactBase {
74
+ version: string;
72
75
  names: string[];
73
76
  name?: undefined;
74
77
  }
75
- export type PlannedArtifact = EnvironmentArtifact | EnvironmentPayloadArtifact;
78
+ /**
79
+ * A selectable module whose version is only known while an environment is
80
+ * assembled.
81
+ *
82
+ * `patch` replaces one file inside the Server package, and the version of that
83
+ * replacement is the version of the component the Server package itself depends
84
+ * on. Neither value exists at plan time: the plan carries this descriptor after
85
+ * all core modules, and the builder resolves it from the Server tree it has just
86
+ * laid out. The descriptor deliberately carries no mapping: the mapping names
87
+ * the file the module replaces, and the module's real identity must stay out of
88
+ * every public document.
89
+ */
90
+ export interface EnvironmentDeferredArtifact {
91
+ module: string;
92
+ /** The module's public label, never the publishing plugin. */
93
+ plugin: string;
94
+ deferred: true;
95
+ path?: undefined;
96
+ version?: undefined;
97
+ name?: undefined;
98
+ names?: undefined;
99
+ mappings?: undefined;
100
+ }
101
+ export type PlannedArtifact = EnvironmentArtifact | EnvironmentPayloadArtifact | EnvironmentDeferredArtifact;
102
+ /** True for the plan descriptor whose version and payload resolve while assembling. */
103
+ export declare function isDeferredArtifact(artifact: PlannedArtifact): artifact is EnvironmentDeferredArtifact;
76
104
  export type EnvironmentSchema = 'V91' | 'V100';
77
105
  export interface EnvironmentPlan {
78
106
  managed?: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/environment/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/environment/types.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDeferredArtifact = isDeferredArtifact;
4
+ /** True for the plan descriptor whose version and payload resolve while assembling. */
5
+ function isDeferredArtifact(artifact) {
6
+ return artifact.deferred === true;
7
+ }
3
8
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/environment/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/environment/types.ts"],"names":[],"mappings":";;AAwGA,gDAEC;AAHD,uFAAuF;AACvF,SAAgB,kBAAkB,CAAC,QAAyB;IAC1D,OAAQ,QAAmC,CAAC,QAAQ,KAAK,IAAI,CAAC;AAChE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/environment/update.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/environment/update.ts"],"names":[],"mappings":"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"}
@@ -40,6 +40,7 @@ const fs = __importStar(require("fs/promises"));
40
40
  const path = __importStar(require("path"));
41
41
  const fast_xml_parser_1 = require("fast-xml-parser");
42
42
  const catalog_1 = require("./catalog");
43
+ const deferred_1 = require("./deferred");
43
44
  const archive_1 = require("./archive");
44
45
  const builder_1 = require("./builder");
45
46
  const config_1 = require("./config");
@@ -93,7 +94,49 @@ const requiredPackageFiles = {
93
94
  */
94
95
  const excludedCopyNames = (mapping) => mapping.role === 'server' ? [...serverOwnedFiles] : mapping.role === 'monitor' ? ['conf'] : [];
95
96
  /**
96
- * The modules a selection may name, from the same table `create-env` and the web
97
+ * Download the payload of a deferred module.
98
+ *
99
+ * It is published as files, not as an archive: the provider keeps the relative
100
+ * sub-path and the file is deployed exactly as downloaded, so nothing is
101
+ * extracted. Exactly one object is downloaded for `patch`. The public label is
102
+ * the only name in progress output or in errors.
103
+ */
104
+ async function stageReplacement(client, module, version, payloads, workspace, onProgress) {
105
+ const entry = catalog_1.catalog[module];
106
+ const label = (0, catalog_1.moduleLabel)(entry);
107
+ const download = path.join(workspace, 'download', label);
108
+ try {
109
+ await fs.mkdir(download, { recursive: true });
110
+ onProgress?.(`[${label}] ${label}/${version}: Downloading replacement`);
111
+ const files = [];
112
+ for (const payload of payloads) {
113
+ await client.downloadArtifact(entry.plugin, version, payload.name, download);
114
+ const source = path.join(download, ...payload.name.split('/'));
115
+ await (0, builder_1.regularFile)(source);
116
+ files.push({ name: payload.name, source, sha256: await (0, builder_1.hashFile)(source) });
117
+ }
118
+ onProgress?.(`[${label}] ${label}/${version}: Download complete; replacement ready`);
119
+ return { version, files };
120
+ }
121
+ catch (error) {
122
+ if (error instanceof Error && error.message.startsWith(`Module ${label} could not be applied:`))
123
+ throw error;
124
+ throw new Error(`Module update failed for ${label}/${version} (download or layout).`);
125
+ }
126
+ }
127
+ /** One environment-relative Server path inside a staged Server package. */
128
+ function stagedServerPath(staged, relative) {
129
+ const server = catalog_1.catalog.server.mappings.find(mapping => mapping.role === 'server');
130
+ const prefix = server ? `${server.destination}/` : '';
131
+ const inner = prefix && relative.startsWith(prefix) ? relative.slice(prefix.length) : relative;
132
+ return path.join(staged.expanded, ...(server?.source ? server.source.split('/') : []), ...inner.split('/'));
133
+ }
134
+ /** The version file inside a staged Server package, before it is laid out. */
135
+ function stagedServerFile(staged, module) {
136
+ const descriptor = catalog_1.catalog[module].deferred;
137
+ return stagedServerPath(staged, descriptor.versionFile);
138
+ }
139
+ /** The modules a selection may name, from the same table `create-env` and the web
97
140
  * interface read.
98
141
  *
99
142
  * Reading it through the call keeps this module loadable on its own: the policy
@@ -185,6 +228,11 @@ function pushSpec(specs, seen, spec) {
185
228
  }
186
229
  else {
187
230
  validateUpdatableModule(spec.module);
231
+ // A deferred module's version is always the one recorded by the deployed (or
232
+ // newly staged) Server package. Pinning a different one would either be
233
+ // ignored or produce a mismatched environment, so it is refused.
234
+ if (catalog_1.catalog[spec.module].deferred && spec.version !== undefined)
235
+ throw new Error(`Module ${spec.module} takes its version from the deployed Server package: a pinned version is not supported.`);
188
236
  if (seen.has(allModules))
189
237
  throw new Error('Module spec all cannot be combined with individual modules.');
190
238
  const previous = seen.get(spec.module);
@@ -560,14 +608,17 @@ function environmentSchema(manifest, configuration) {
560
608
  * that policy. Returns the warning text, or undefined when the package is
561
609
  * complete.
562
610
  */
563
- async function verifyStagedPackage(module, staged, schema) {
611
+ async function verifyStagedPackage(module, staged, schema, required = requiredPackageFiles[module] ?? []) {
564
612
  const label = `${staged.plugin}/${staged.version}/${staged.name}`;
565
- for (const name of requiredPackageFiles[module] ?? []) {
613
+ for (const name of required) {
566
614
  try {
567
615
  await (0, builder_1.regularFile)(path.join(staged.expanded, name));
568
616
  }
617
+ // The Server's required file is the one the selectable patch replaces, so the
618
+ // message stays generic: its name must not be user-visible. Every other
619
+ // module's required file name is public and useful.
569
620
  catch {
570
- throw new Error(`Module update failed for ${label}: the package is missing ${name}.`);
621
+ throw new Error(`Module update failed for ${label}: the package is missing ${module === 'server' ? 'a required runtime file' : name}.`);
571
622
  }
572
623
  }
573
624
  const relative = `xsd/${schema}/Wyn.conf.xsd`;
@@ -643,11 +694,17 @@ function mappingForAssembly(module, assembly) {
643
694
  * explicitly, for a build whose file name matches no assembly at all.
644
695
  */
645
696
  async function resolveLocalSource(entry, module, assembly, input) {
646
- // Any built-in trailing module is never a developer-build target: it ships a
647
- // static asset tree no local DLL could stand in for. Both are refused as
648
- // explicit specs before this point (one internal, one create-only); this guard
649
- // is the safety net for a trailing module a user could select, whose remote
650
- // specs would keep working.
697
+ // A deferred module is a published replacement for one file the Server package
698
+ // owns; a developer build has no mapping the configuration could point at, so
699
+ // a local source is refused on its own terms before any path is looked at.
700
+ // The message names the module only.
701
+ if (catalog_1.catalog[module].deferred)
702
+ throw new Error(`Module ${module} is refreshed from its published artifact only and has no local source.`);
703
+ // Any built-in trailing module is never a developer-build target either: it
704
+ // ships a static asset tree no local DLL could stand in for. Both are refused
705
+ // as explicit specs before this point (one internal, one create-only); this
706
+ // guard is the safety net for a trailing module a user could select, whose
707
+ // remote specs would keep working.
651
708
  if (plan_1.trailingModules.includes(module))
652
709
  throw new Error(`Module ${module} is built in and has no local source: it ships the 3D scene and map assets and is always deployed from its published artifact. Refresh it from the cloud (\`${module}\`, \`${module}:<version>\` or \`all\`).`);
653
710
  const mappings = localMappings(module);
@@ -817,6 +874,21 @@ class EnvironmentUpdater {
817
874
  onProgress?.(`${module} is refreshed with the Server package: its trees deploy inside the Server directory`);
818
875
  }
819
876
  }
877
+ // A Server refresh restores the unpatched file the Server package ships, so
878
+ // an installed deferred module is re-applied in the same call. Its version is
879
+ // resolved from the *new* package below, never from the old tree. Without a
880
+ // Server refresh it is only applied when the caller names it explicitly.
881
+ const autoReplaced = [];
882
+ if (remote.some(spec => spec.module === 'server')) {
883
+ for (const module of Object.keys(catalog_1.catalog)) {
884
+ if (!catalog_1.catalog[module].deferred || !installed.has(module) || parsed.some(spec => spec.module === module))
885
+ continue;
886
+ parsed.push({ module });
887
+ remote.push({ module });
888
+ autoReplaced.push(module);
889
+ onProgress?.(`${module} is re-applied with the Server package: the new package replaces the file it patches`);
890
+ }
891
+ }
820
892
  // Smart documents cannot run without the collaboration service, which
821
893
  // create-env deploys and declares in the Server configuration alongside
822
894
  // documents. Installing documents into an environment with no collaboration
@@ -847,15 +919,57 @@ class EnvironmentUpdater {
847
919
  try {
848
920
  const resolved = new Map();
849
921
  const staged = new Map();
922
+ const replacements = new Map();
850
923
  if (remote.length) {
851
924
  const client = clientFactory();
852
- for (const spec of remote) {
925
+ const direct = remote.filter(spec => !catalog_1.catalog[spec.module].deferred);
926
+ for (const spec of direct) {
853
927
  onProgress?.(`Resolving ${catalog_1.catalog[spec.module].plugin}`);
854
928
  resolved.set(spec.module, await resolveRemoteArtifact(client, entry, spec));
855
929
  }
856
930
  if (!dryRun)
857
- for (const spec of remote)
931
+ for (const spec of direct)
858
932
  staged.set(spec.module, await stageRemoteArtifact(client, resolved.get(spec.module), editionOf(entry), workspace, onProgress));
933
+ // A deferred module resolves after the direct artifacts are staged, so a
934
+ // Server refresh contributes the *new* package's version. Without a
935
+ // Server refresh the already deployed tree is the authority. A dry-run
936
+ // that refreshes the Server cannot know that version without downloading
937
+ // the package, so it reports the deferred resolution and stops there.
938
+ for (const spec of remote.filter(candidate => catalog_1.catalog[candidate.module].deferred)) {
939
+ const module = spec.module;
940
+ const source = catalog_1.catalog[module];
941
+ const label = (0, catalog_1.moduleLabel)(source);
942
+ const server = staged.get('server');
943
+ let version;
944
+ if (server) {
945
+ version = await (0, deferred_1.deferredVersionAt)(source, stagedServerFile(server, module));
946
+ // The replacement must overwrite an existing regular file in the new
947
+ // package; checking the staged tree catches a package that no longer
948
+ // ships it before anything has been written.
949
+ for (const mapping of (0, deferred_1.replacementMappings)(source)) {
950
+ const file = stagedServerPath(server, mapping.destination);
951
+ const stat = await lstatOrUndefined(file);
952
+ if (!stat)
953
+ throw new Error(`Module ${label} could not be applied: the Server package holds no file to replace.`);
954
+ if (!stat.isFile() || stat.isSymbolicLink())
955
+ throw new Error(`Module ${label} could not be applied: the Server package holds no regular file to replace.`);
956
+ }
957
+ }
958
+ else if (remote.some(candidate => candidate.module === 'server')) {
959
+ onProgress?.(`${label}: version resolves from the refreshed Server package at execution time`);
960
+ replacements.set(module, { version: '' });
961
+ continue;
962
+ }
963
+ else
964
+ version = await (0, deferred_1.deferredVersion)(source, entry.root);
965
+ const payloads = await (0, deferred_1.deferredPayload)(source, version, client);
966
+ if (dryRun) {
967
+ onProgress?.(`${label}/${version}: resolved from the deployed Server package; nothing downloaded`);
968
+ replacements.set(module, { version });
969
+ continue;
970
+ }
971
+ replacements.set(module, await stageReplacement(client, module, version, payloads, workspace, onProgress));
972
+ }
859
973
  }
860
974
  const configured = await fs.readFile(path.join(entry.root, 'conf', 'Wyn.conf'), 'utf8');
861
975
  // A Server or Monitor package is only usable when it still serves the
@@ -867,11 +981,16 @@ class EnvironmentUpdater {
867
981
  if (remote.some(spec => spec.module === 'server' || spec.module === 'monitoring') && !schema) {
868
982
  throw new Error(`Module update for ${remote.filter(spec => spec.module === 'server' || spec.module === 'monitoring').map(spec => spec.module).join(' and ')} needs the configuration schema of ${entry.name}, which neither its manifest nor its conf/Wyn.conf records. Recreate the environment with create-env.`);
869
983
  }
984
+ // A planned deferred module validates the exact Server file it replaces,
985
+ // with a message that names only the module; the Server's own required-file
986
+ // check would otherwise report the same missing file by its internal name.
987
+ const deferredPlanned = remote.some(spec => catalog_1.catalog[spec.module].deferred);
870
988
  for (const spec of remote) {
871
989
  const stagedArtifact = staged.get(spec.module);
872
990
  if (!stagedArtifact || !schema || !(spec.module in requiredPackageFiles))
873
991
  continue;
874
- const warning = await verifyStagedPackage(spec.module, stagedArtifact, schema);
992
+ const required = spec.module === 'server' && deferredPlanned ? [] : requiredPackageFiles[spec.module];
993
+ const warning = await verifyStagedPackage(spec.module, stagedArtifact, schema, required);
875
994
  if (warning)
876
995
  warnings.push(warning);
877
996
  }
@@ -879,9 +998,11 @@ class EnvironmentUpdater {
879
998
  // A module may carry several local specs: plan it once, for all its targets.
880
999
  // The built-in trailing modules are planned last, in the same order
881
1000
  // `create-env` assembles: their trees live inside other modules'
882
- // directories, so a Server replacement must not wipe them again.
883
- const planOrder = [...new Set(parsed.map(spec => spec.module))]
884
- .sort((left, right) => Number(plan_1.trailingModules.includes(left)) - Number(plan_1.trailingModules.includes(right)));
1001
+ // directories, so a Server replacement must not wipe them again. A deferred
1002
+ // module runs after `server` even when the caller wrote it first: the Server
1003
+ // directory must hold the new package before it is patched.
1004
+ const rank = (module) => plan_1.trailingModules.includes(module) ? 2 : catalog_1.catalog[module].deferred ? 1 : 0;
1005
+ const planOrder = [...new Set(parsed.map(spec => spec.module))].sort((left, right) => rank(left) - rank(right));
885
1006
  for (const module of planOrder) {
886
1007
  const artifact = artifacts.find(candidate => candidate.module === module);
887
1008
  const previous = moduleSources[module] ? { local: moduleSources[module].path } : { version: artifact?.version };
@@ -911,6 +1032,37 @@ class EnvironmentUpdater {
911
1032
  });
912
1033
  continue;
913
1034
  }
1035
+ // A deferred module replaces one existing regular file and contributes
1036
+ // no directory, plugin, worker, service or runtime requirement. Its
1037
+ // version and payload were resolved above; nothing about the provider is
1038
+ // recorded, and the target is checked before any write.
1039
+ if (catalog_1.catalog[module].deferred) {
1040
+ const replacement = replacements.get(module);
1041
+ const label = (0, catalog_1.moduleLabel)(catalog_1.catalog[module]);
1042
+ const version = replacement?.version || undefined;
1043
+ const files = [];
1044
+ if (replacement?.files?.length) {
1045
+ const mappings = (0, deferred_1.replacementMappings)(catalog_1.catalog[module]);
1046
+ for (const file of replacement.files) {
1047
+ const matches = mappings.filter(mapping => mapping.source === file.name);
1048
+ if (matches.length !== 1)
1049
+ throw new Error(`Module ${label} could not be applied: the replacement target is not configured.`);
1050
+ const destination = installationDirectory(entry.root, matches[0].destination);
1051
+ const stat = await lstatOrUndefined(destination);
1052
+ if (!stat)
1053
+ throw new Error(`Module ${label} could not be applied: the Server tree holds no file to replace.`);
1054
+ if (!stat.isFile() || stat.isSymbolicLink())
1055
+ throw new Error(`Module ${label} could not be applied: the Server tree holds no regular file to replace.`);
1056
+ files.push({ source: file.source, destination, sha256: file.sha256 });
1057
+ }
1058
+ }
1059
+ plans.push({
1060
+ module, previous, next: version ? { version } : {},
1061
+ ...(files.length ? { replacement: { version: version, files } } : {}),
1062
+ entries: [], copies: [], removals: [], preserved: [], copiedDirectories: [], removedDirectories: [],
1063
+ });
1064
+ continue;
1065
+ }
914
1066
  const remoteArtifact = resolved.get(module);
915
1067
  const stagedArtifact = staged.get(module);
916
1068
  const copies = [];
@@ -1029,6 +1181,28 @@ class EnvironmentUpdater {
1029
1181
  }
1030
1182
  delete moduleSources[plan.module];
1031
1183
  }
1184
+ if (plan.replacement) {
1185
+ // The record keeps the public label, the resolved version and the
1186
+ // payload's SHA256. No remote path and no mapping are written: both
1187
+ // would expose a name the module hides.
1188
+ const label = (0, catalog_1.moduleLabel)(catalog_1.catalog[plan.module]);
1189
+ const replacement = { module: plan.module, plugin: label, version: plan.replacement.version, name: label };
1190
+ const index = nextArtifacts.findIndex(candidate => candidate.module === plan.module);
1191
+ if (index < 0)
1192
+ nextArtifacts.push(replacement);
1193
+ else
1194
+ nextArtifacts[index] = { ...nextArtifacts[index], ...replacement };
1195
+ for (const file of plan.replacement.files) {
1196
+ const download = { plugin: label, version: plan.replacement.version, name: label, sha256: file.sha256 };
1197
+ const downloadIndex = nextDownloads.findIndex(candidate => candidate.plugin === label);
1198
+ if (downloadIndex < 0)
1199
+ nextDownloads.push(download);
1200
+ else
1201
+ nextDownloads[downloadIndex] = download;
1202
+ }
1203
+ requirements = requirements.filter(line => !line.endsWith(` (${plan.module})`));
1204
+ delete moduleSources[plan.module];
1205
+ }
1032
1206
  if (plan.local)
1033
1207
  moduleSources[plan.module] = manifestSource(plan.module, plan.local, moduleSources[plan.module]);
1034
1208
  // First installing a module records it the way `create-env` would: a
@@ -1108,6 +1282,8 @@ class EnvironmentUpdater {
1108
1282
  }
1109
1283
  if (autoRefreshed.length)
1110
1284
  warnings.push(`${autoRefreshed.join(', ')} was refreshed with the Server package: its trees live inside the Server directory and would otherwise be lost.`);
1285
+ if (autoReplaced.length)
1286
+ warnings.push(`${autoReplaced.join(', ')} was re-applied with the Server package: the new package ships the file it replaces, so it was applied again.`);
1111
1287
  if (removedCreateOnly.length)
1112
1288
  warnings.push(`${removedCreateOnly.join(', ')} was removed with the Server package: it is deployed only when an environment is created.`);
1113
1289
  if (!dryRun) {
@@ -1132,6 +1308,25 @@ class EnvironmentUpdater {
1132
1308
  await (0, builder_1.copyTree)(copy.source, copy.destination, copy.exclude);
1133
1309
  for (const file of plan.preserved)
1134
1310
  await fs.copyFile(file.source, path.join(file.directory, file.name));
1311
+ // The replacement is applied after the directory it lives in has been
1312
+ // copied, so a Server refresh cannot overwrite it again. The target is
1313
+ // re-checked here and every error names the module only.
1314
+ if (plan.replacement) {
1315
+ const label = (0, catalog_1.moduleLabel)(catalog_1.catalog[plan.module]);
1316
+ try {
1317
+ for (const file of plan.replacement.files) {
1318
+ const stat = await fs.lstat(file.destination).catch(() => undefined);
1319
+ if (!stat)
1320
+ throw new Error('missing');
1321
+ if (!stat.isFile() || stat.isSymbolicLink())
1322
+ throw new Error('not a regular file');
1323
+ await fs.copyFile(file.source, file.destination);
1324
+ }
1325
+ }
1326
+ catch {
1327
+ throw new Error(`Module ${label} could not be applied: the Server tree holds no regular file to replace.`);
1328
+ }
1329
+ }
1135
1330
  if (plan.configurationAssets) {
1136
1331
  onProgress?.(`Refreshing Monitor configuration assets in ${path.relative(entry.root, plan.configurationAssets.destination)}`);
1137
1332
  await mergeConfigurationAssets(plan.configurationAssets.source, plan.configurationAssets.destination);