@guanjinke/artifact-client 1.5.1 → 1.6.1

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 (99) hide show
  1. package/README.md +32 -3
  2. package/dist/cli/setup.d.ts.map +1 -1
  3. package/dist/cli/setup.js +6 -5
  4. package/dist/cli/setup.js.map +1 -1
  5. package/dist/cli/stored-client.d.ts +24 -0
  6. package/dist/cli/stored-client.d.ts.map +1 -0
  7. package/dist/cli/stored-client.js +59 -0
  8. package/dist/cli/stored-client.js.map +1 -0
  9. package/dist/cli/web.d.ts +23 -0
  10. package/dist/cli/web.d.ts.map +1 -0
  11. package/dist/cli/web.js +99 -0
  12. package/dist/cli/web.js.map +1 -0
  13. package/dist/environment/builder.d.ts.map +1 -1
  14. package/dist/environment/builder.js +26 -13
  15. package/dist/environment/builder.js.map +1 -1
  16. package/dist/environment/catalog.d.ts.map +1 -1
  17. package/dist/environment/catalog.js +18 -0
  18. package/dist/environment/catalog.js.map +1 -1
  19. package/dist/environment/config.d.ts +1 -1
  20. package/dist/environment/config.d.ts.map +1 -1
  21. package/dist/environment/config.js +7 -5
  22. package/dist/environment/config.js.map +1 -1
  23. package/dist/environment/manager.d.ts +9 -0
  24. package/dist/environment/manager.d.ts.map +1 -1
  25. package/dist/environment/manager.js +34 -6
  26. package/dist/environment/manager.js.map +1 -1
  27. package/dist/environment/plan.d.ts +37 -1
  28. package/dist/environment/plan.d.ts.map +1 -1
  29. package/dist/environment/plan.js +71 -16
  30. package/dist/environment/plan.js.map +1 -1
  31. package/dist/environment/posix-process.d.ts +71 -0
  32. package/dist/environment/posix-process.d.ts.map +1 -0
  33. package/dist/environment/posix-process.js +393 -0
  34. package/dist/environment/posix-process.js.map +1 -0
  35. package/dist/environment/process.d.ts +3 -1
  36. package/dist/environment/process.d.ts.map +1 -1
  37. package/dist/environment/process.js +5 -2
  38. package/dist/environment/process.js.map +1 -1
  39. package/dist/environment/registry.d.ts.map +1 -1
  40. package/dist/environment/registry.js +2 -1
  41. package/dist/environment/registry.js.map +1 -1
  42. package/dist/environment/root.d.ts +24 -6
  43. package/dist/environment/root.d.ts.map +1 -1
  44. package/dist/environment/root.js +78 -24
  45. package/dist/environment/root.js.map +1 -1
  46. package/dist/environment/types.d.ts +7 -2
  47. package/dist/environment/types.d.ts.map +1 -1
  48. package/dist/environment/update.d.ts +3 -1
  49. package/dist/environment/update.d.ts.map +1 -1
  50. package/dist/environment/update.js +48 -36
  51. package/dist/environment/update.js.map +1 -1
  52. package/dist/environment/validate.d.ts.map +1 -1
  53. package/dist/environment/validate.js +5 -1
  54. package/dist/environment/validate.js.map +1 -1
  55. package/dist/index.d.ts +9 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +18 -1
  58. package/dist/index.js.map +1 -1
  59. package/dist/utils/atomic.d.ts +10 -0
  60. package/dist/utils/atomic.d.ts.map +1 -0
  61. package/dist/utils/atomic.js +65 -0
  62. package/dist/utils/atomic.js.map +1 -0
  63. package/dist/utils/local-path.d.ts +14 -0
  64. package/dist/utils/local-path.d.ts.map +1 -1
  65. package/dist/utils/local-path.js +25 -0
  66. package/dist/utils/local-path.js.map +1 -1
  67. package/dist/web/api.d.ts +28 -0
  68. package/dist/web/api.d.ts.map +1 -0
  69. package/dist/web/api.js +336 -0
  70. package/dist/web/api.js.map +1 -0
  71. package/dist/web/assets.d.ts +26 -0
  72. package/dist/web/assets.d.ts.map +1 -0
  73. package/dist/web/assets.js +87 -0
  74. package/dist/web/assets.js.map +1 -0
  75. package/dist/web/http.d.ts +41 -0
  76. package/dist/web/http.d.ts.map +1 -0
  77. package/dist/web/http.js +167 -0
  78. package/dist/web/http.js.map +1 -0
  79. package/dist/web/jobs.d.ts +69 -0
  80. package/dist/web/jobs.d.ts.map +1 -0
  81. package/dist/web/jobs.js +110 -0
  82. package/dist/web/jobs.js.map +1 -0
  83. package/dist/web/providers.d.ts +12 -0
  84. package/dist/web/providers.d.ts.map +1 -0
  85. package/dist/web/providers.js +108 -0
  86. package/dist/web/providers.js.map +1 -0
  87. package/dist/web/server.d.ts +43 -0
  88. package/dist/web/server.d.ts.map +1 -0
  89. package/dist/web/server.js +148 -0
  90. package/dist/web/server.js.map +1 -0
  91. package/dist/web/static/app.js +59 -0
  92. package/dist/web/static/favicon.svg +12 -0
  93. package/dist/web/static/index.html +15 -0
  94. package/dist/web/static/styles.css +1333 -0
  95. package/dist/web/types.d.ts +82 -0
  96. package/dist/web/types.d.ts.map +1 -0
  97. package/dist/web/types.js +3 -0
  98. package/dist/web/types.js.map +1 -0
  99. package/package.json +9 -2
@@ -1,15 +1,33 @@
1
+ /**
2
+ * Canonicalize a directory that may not exist yet: the deepest existing
3
+ * ancestor is resolved (`fs.realpath`), the missing tail is appended.
4
+ *
5
+ * This is what makes the tool work on macOS, where `$TMPDIR` lives under
6
+ * `/var/folders/...` and `/var` is itself a symlink to `/private/var`: the
7
+ * stored root is the real location, so the "no linked ancestor" rule below
8
+ * rejects only links the operator created, and deletion later removes exactly
9
+ * the recorded directory instead of traversing a link.
10
+ */
11
+ export declare function canonicalDirectory(directory: string): Promise<string>;
12
+ /**
13
+ * macOS ships `/var`, `/tmp` and `/etc` as symlinks into `/private`. Those are
14
+ * system links rather than operator ones, so the "no linked ancestor" rule has to
15
+ * let them through or `$TMPDIR` paths could never be used; the recorded root is
16
+ * still the canonical location, so nothing is ever operated through the link.
17
+ */
18
+ export declare function isSystemLinkTarget(resolved: string, platform?: NodeJS.Platform): boolean;
1
19
  /**
2
20
  * Verify that a directory is safe to use as an environment directory or as the
3
21
  * unified directory that contains managed environments.
4
22
  *
5
23
  * Rejected locations are filesystem roots, the user profile itself, the AFM
6
- * configuration directory, Windows/Program Files locations, ancestors of the
7
- * configuration directory, and any path with an existing linked (symlink or
8
- * junction) ancestor. The check is read-only; it never creates or removes
9
- * anything and returns whether the directory already exists as a regular
10
- * directory.
24
+ * configuration directory, system locations and their descendants, ancestors of
25
+ * the configuration directory, and any path with an existing linked (symlink or
26
+ * junction) ancestor other than a platform system link. The check is read-only;
27
+ * it never creates or removes anything and returns whether the directory already
28
+ * exists as a regular directory.
11
29
  */
12
- export declare function inspectEnvironmentDirectory(directory: string, configDirectory: string): Promise<boolean>;
30
+ export declare function inspectEnvironmentDirectory(directory: string, configDirectory: string, platform?: NodeJS.Platform): Promise<boolean>;
13
31
  export interface EnvironmentContainer {
14
32
  directory: string;
15
33
  created: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/environment/root.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAwB9G;AAED,MAAM,WAAW,oBAAoB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;CAAE;AAE9E;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAS3J;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMxF"}
1
+ {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/environment/root.ts"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAc3E;AAUD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,OAAO,CAE1G;AAqBD;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,OAAO,CAAC,OAAO,CAAC,CAY5J;AAED,MAAM,WAAW,oBAAoB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;CAAE;AAE9E;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAS3J;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMxF"}
@@ -33,6 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.canonicalDirectory = canonicalDirectory;
37
+ exports.isSystemLinkTarget = isSystemLinkTarget;
36
38
  exports.inspectEnvironmentDirectory = inspectEnvironmentDirectory;
37
39
  exports.resolveEnvironmentContainer = resolveEnvironmentContainer;
38
40
  exports.resolveNamedEnvironmentDirectory = resolveNamedEnvironmentDirectory;
@@ -41,40 +43,67 @@ const os = __importStar(require("os"));
41
43
  const path = __importStar(require("path"));
42
44
  const registry_1 = require("./registry");
43
45
  /**
44
- * Verify that a directory is safe to use as an environment directory or as the
45
- * unified directory that contains managed environments.
46
+ * Canonicalize a directory that may not exist yet: the deepest existing
47
+ * ancestor is resolved (`fs.realpath`), the missing tail is appended.
46
48
  *
47
- * Rejected locations are filesystem roots, the user profile itself, the AFM
48
- * configuration directory, Windows/Program Files locations, ancestors of the
49
- * configuration directory, and any path with an existing linked (symlink or
50
- * junction) ancestor. The check is read-only; it never creates or removes
51
- * anything and returns whether the directory already exists as a regular
52
- * directory.
49
+ * This is what makes the tool work on macOS, where `$TMPDIR` lives under
50
+ * `/var/folders/...` and `/var` is itself a symlink to `/private/var`: the
51
+ * stored root is the real location, so the "no linked ancestor" rule below
52
+ * rejects only links the operator created, and deletion later removes exactly
53
+ * the recorded directory instead of traversing a link.
53
54
  */
54
- async function inspectEnvironmentDirectory(directory, configDirectory) {
55
- const root = path.resolve(directory);
56
- if (root === path.parse(root).root)
57
- throw new Error(`Protected environment root: ${root} is a filesystem root.`);
58
- const key = root.toLowerCase();
59
- const home = path.resolve(os.homedir()).toLowerCase();
60
- const config = path.resolve(configDirectory).toLowerCase();
61
- const protectedRoots = [home, config, process.env.ProgramFiles, process.env['ProgramFiles(x86)'], process.env.SystemRoot, process.env.WINDIR]
62
- .filter((value) => typeof value === 'string' && value.trim() !== '')
63
- .map(value => path.resolve(value).toLowerCase());
64
- if (protectedRoots.some(value => key === value || (value !== home && key.startsWith(value + path.sep))) || config.startsWith(key + path.sep)) {
65
- throw new Error(`Protected environment root: ${root} is a system, user profile or configuration location.`);
55
+ async function canonicalDirectory(directory) {
56
+ const absolute = path.resolve(directory);
57
+ const tail = [];
58
+ for (let current = absolute;; current = path.dirname(current)) {
59
+ try {
60
+ const resolved = await fs.realpath(current);
61
+ return tail.length ? path.join(resolved, ...tail.reverse()) : resolved;
62
+ }
63
+ catch (error) {
64
+ if (error.code !== 'ENOENT')
65
+ throw error;
66
+ }
67
+ const parent = path.dirname(current);
68
+ if (parent === current)
69
+ return absolute;
70
+ tail.push(path.basename(current));
66
71
  }
72
+ }
73
+ /** System locations that must never receive an environment, per platform. */
74
+ function systemRoots(platform = process.platform) {
75
+ const variables = platform === 'win32'
76
+ ? [process.env.ProgramFiles, process.env['ProgramFiles(x86)'], process.env.SystemRoot, process.env.WINDIR]
77
+ : ['/usr', '/etc', '/bin', '/sbin', '/lib', '/lib64', '/boot', '/dev', '/proc', '/sys', '/opt', '/System', '/Library', '/Applications'];
78
+ return variables.filter((value) => typeof value === 'string' && value.trim() !== '').map(value => path.resolve(value).toLowerCase());
79
+ }
80
+ /**
81
+ * macOS ships `/var`, `/tmp` and `/etc` as symlinks into `/private`. Those are
82
+ * system links rather than operator ones, so the "no linked ancestor" rule has to
83
+ * let them through or `$TMPDIR` paths could never be used; the recorded root is
84
+ * still the canonical location, so nothing is ever operated through the link.
85
+ */
86
+ function isSystemLinkTarget(resolved, platform = process.platform) {
87
+ return platform === 'darwin' && ['/private/var', '/private/tmp', '/private/etc', '/private/var/run'].includes(resolved);
88
+ }
89
+ /** Reject a linked or non-directory ancestor, allowing only a platform system link. */
90
+ async function assertRegularAncestors(requested, platform) {
67
91
  let exists = true;
68
- for (let current = root;; current = path.dirname(current)) {
92
+ for (let current = requested;; current = path.dirname(current)) {
69
93
  try {
70
94
  const stat = await fs.lstat(current);
71
- if (!stat.isDirectory() || stat.isSymbolicLink())
95
+ if (stat.isSymbolicLink()) {
96
+ const resolved = await fs.realpath(current).catch(() => '');
97
+ if (!isSystemLinkTarget(resolved, platform))
98
+ throw new Error(`Environment root or ancestor is linked or not a directory: ${current}`);
99
+ }
100
+ else if (!stat.isDirectory())
72
101
  throw new Error(`Environment root or ancestor is linked or not a directory: ${current}`);
73
102
  }
74
103
  catch (error) {
75
104
  if (error.code !== 'ENOENT')
76
105
  throw error;
77
- if (current === root)
106
+ if (current === requested)
78
107
  exists = false;
79
108
  }
80
109
  if (current === path.dirname(current))
@@ -82,6 +111,31 @@ async function inspectEnvironmentDirectory(directory, configDirectory) {
82
111
  }
83
112
  return exists;
84
113
  }
114
+ /**
115
+ * Verify that a directory is safe to use as an environment directory or as the
116
+ * unified directory that contains managed environments.
117
+ *
118
+ * Rejected locations are filesystem roots, the user profile itself, the AFM
119
+ * configuration directory, system locations and their descendants, ancestors of
120
+ * the configuration directory, and any path with an existing linked (symlink or
121
+ * junction) ancestor other than a platform system link. The check is read-only;
122
+ * it never creates or removes anything and returns whether the directory already
123
+ * exists as a regular directory.
124
+ */
125
+ async function inspectEnvironmentDirectory(directory, configDirectory, platform = process.platform) {
126
+ const requested = path.resolve(directory);
127
+ const root = await canonicalDirectory(requested);
128
+ if (root === path.parse(root).root)
129
+ throw new Error(`Protected environment root: ${root} is a filesystem root.`);
130
+ const key = root.toLowerCase();
131
+ const home = (await canonicalDirectory(os.homedir())).toLowerCase();
132
+ const config = (await canonicalDirectory(configDirectory)).toLowerCase();
133
+ const protectedRoots = [home, config, ...systemRoots(platform)];
134
+ if (protectedRoots.some(value => key === value || (value !== home && key.startsWith(value + path.sep))) || config.startsWith(key + path.sep)) {
135
+ throw new Error(`Protected environment root: ${root} is a system, user profile or configuration location.`);
136
+ }
137
+ return assertRegularAncestors(requested, platform);
138
+ }
85
139
  /**
86
140
  * Validate the unified directory that holds managed environments.
87
141
  *
@@ -93,7 +147,7 @@ async function inspectEnvironmentDirectory(directory, configDirectory) {
93
147
  async function resolveEnvironmentContainer(input, configDirectory, options = {}) {
94
148
  if (typeof input !== 'string' || input.trim() === '')
95
149
  throw new Error('Environment root must be a non-empty directory path.');
96
- const directory = path.resolve(input);
150
+ const directory = await canonicalDirectory(input);
97
151
  if (await inspectEnvironmentDirectory(directory, configDirectory))
98
152
  return { directory, created: false };
99
153
  if (!options.create)
@@ -1 +1 @@
1
- {"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/environment/root.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/environment/root.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { ArtifactClient } from '../artifact-client';
2
- export type EnvironmentModule = 'dashboard' | 'reporting' | 'analysis' | 'sheets' | 'documents';
2
+ export type EnvironmentModule = 'dashboard' | 'reporting' | 'analysis' | 'sheets' | 'documents' | 'collaboration';
3
3
  export interface EnvironmentOptions {
4
4
  root: string;
5
5
  major: string;
@@ -13,8 +13,13 @@ export type EnvironmentClient = Pick<ArtifactClient, 'getLatestVersion' | 'listA
13
13
  export interface LayoutMapping {
14
14
  source: string;
15
15
  destination: string;
16
+ /**
17
+ * .NET assemblies this mapping must contain. Empty for a `service` mapping:
18
+ * an out-of-process native service that ships no managed assembly and is
19
+ * loaded by the Server from its `<Services>` declaration alone.
20
+ */
16
21
  assemblies: string[];
17
- role: 'plugin' | 'worker' | 'server' | 'monitor';
22
+ role: 'plugin' | 'worker' | 'server' | 'monitor' | 'service';
18
23
  service?: string;
19
24
  }
20
25
  export interface EnvironmentArtifact {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/environment/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;AAChG,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,EAAE,kBAAkB,GAAG,eAAe,GAAG,kBAAkB,CAAC,CAAC;AAChH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AACD,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,CAAC;AAC/C,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtC,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,iBAAiB,EAAE,CAAC;IACrC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AACD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AACD,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAE5D,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,gEAAgE;IAChE,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/environment/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,eAAe,CAAC;AAClH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,EAAE,kBAAkB,GAAG,eAAe,GAAG,kBAAkB,CAAC,CAAC;AAChH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AACD,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,CAAC;AAC/C,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtC,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,iBAAiB,EAAE,CAAC;IACrC,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AACD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AACD,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAE5D,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,gEAAgE;IAChE,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC"}
@@ -1,6 +1,8 @@
1
1
  import { EnvironmentRegistry } from './registry';
2
2
  import { ProcessBackend } from './process';
3
3
  import { EnvironmentClient, EnvironmentProgress } from './types';
4
+ /** Modules `update-env` may replace; exported so the web interface lists the same set. */
5
+ export declare const updatableModules: string[];
4
6
  export interface ModuleUpdateSpec {
5
7
  module: string;
6
8
  version?: string;
@@ -81,7 +83,7 @@ export declare function parseModuleSpecs(values: string[]): ModuleUpdateSpec[];
81
83
  * `Disabled`; a configuration without that node is updated through
82
84
  * `<PluginWorkers>` alone.
83
85
  */
84
- export declare function patchEnvironmentConfiguration(xml: string, entries: PluginEntry[]): string;
86
+ export declare function patchEnvironmentConfiguration(xml: string, entries: PluginEntry[], platform?: NodeJS.Platform): string;
85
87
  /**
86
88
  * Update selected modules of a registered environment.
87
89
  *
@@ -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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"}
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.EnvironmentUpdater = void 0;
36
+ exports.EnvironmentUpdater = exports.updatableModules = void 0;
37
37
  exports.parseModuleSpecs = parseModuleSpecs;
38
38
  exports.patchEnvironmentConfiguration = patchEnvironmentConfiguration;
39
39
  const fs = __importStar(require("fs/promises"));
@@ -45,22 +45,28 @@ const builder_1 = require("./builder");
45
45
  const registry_1 = require("./registry");
46
46
  const validate_1 = require("./validate");
47
47
  const process_1 = require("./process");
48
+ const posix_process_1 = require("./posix-process");
49
+ const atomic_1 = require("../utils/atomic");
50
+ const local_path_1 = require("../utils/local-path");
48
51
  /** Same parser options as the creation path, so a rewrite round-trips identically. */
49
52
  const parserOptions = { ignoreAttributes: false, parseTagValue: false, processEntities: false };
50
53
  const builderOptions = { ignoreAttributes: false, format: true, suppressEmptyNode: false };
51
- const windowsPath = (value) => value.replace(/\//g, '\\');
52
- const updatableModules = ['dashboard', 'reporting', 'sheets', 'analysis', 'common'];
54
+ const windowsPath = (value, platform) => (0, local_path_1.nativeSeparators)(value, platform);
55
+ /** The separator the recorded entries use on the target platform. */
56
+ const separatorOf = (platform) => (platform === 'win32' ? '\\' : '/');
57
+ /** Modules `update-env` may replace; exported so the web interface lists the same set. */
58
+ exports.updatableModules = ['dashboard', 'reporting', 'sheets', 'documents', 'analysis', 'common'];
53
59
  const installationDirectory = (root, destination) => path.join(root, ...destination.split('/'));
54
60
  function validateUpdatableModule(module) {
55
- if (updatableModules.includes(module))
61
+ if (exports.updatableModules.includes(module))
56
62
  return;
57
63
  if (module === 'server')
58
64
  throw new Error('Module server cannot be updated: it defines the environment runtime and configuration schema. Recreate the environment with create-env instead.');
59
65
  if (module === 'monitoring')
60
66
  throw new Error('Module monitoring cannot be updated: it defines the configuration schema and monitor runtime. Recreate the environment with create-env instead.');
61
- if (module === 'documents')
62
- throw new Error('Module documents cannot be updated: embedded Documents execution is not supported.');
63
- throw new Error(`Unsupported module "${module}": updateable modules are dashboard, reporting, sheets, analysis and common.`);
67
+ if (module === 'collaboration')
68
+ throw new Error('Module collaboration is deployed together with documents by create-env and the Server loads it from its own configuration entry; it is not updated on its own. Update `documents`, or recreate the environment.');
69
+ throw new Error(`Unsupported module "${module}": updateable modules are dashboard, reporting, sheets, documents, analysis and common.`);
64
70
  }
65
71
  /** `all` is the only allowed pseudo-module: every configured module from remote. */
66
72
  const allModules = 'all';
@@ -208,24 +214,24 @@ function stringList(raw) {
208
214
  return list;
209
215
  }
210
216
  /** Replace or append one `<sys:string>` path list, matching by destination or assembly name. */
211
- function rewritePathList(values, entries) {
217
+ function rewritePathList(values, entries, platform) {
212
218
  const strings = values.map(value => value.trim());
213
219
  const used = new Set();
214
220
  const appended = [];
215
221
  for (const entry of entries) {
216
- const prefix = windowsPath(entry.destination).toLowerCase() + '\\';
222
+ const prefix = windowsPath(entry.destination, platform).toLowerCase() + separatorOf(platform);
217
223
  const assemblies = new Set(entry.assemblies.map(name => name.toLowerCase()));
218
224
  const index = strings.findIndex((value, candidate) => {
219
225
  if (used.has(candidate))
220
226
  return false;
221
- const folded = windowsPath(value).toLowerCase();
222
- return folded.startsWith(prefix) || assemblies.has(path.win32.basename(folded));
227
+ const folded = windowsPath(value, platform).toLowerCase();
228
+ return folded.startsWith(prefix) || assemblies.has((0, local_path_1.baseNameOf)(folded));
223
229
  });
224
230
  if (index < 0)
225
- appended.push(windowsPath(entry.path));
231
+ appended.push(windowsPath(entry.path, platform));
226
232
  else {
227
233
  used.add(index);
228
- strings[index] = windowsPath(entry.path);
234
+ strings[index] = windowsPath(entry.path, platform);
229
235
  }
230
236
  }
231
237
  return [...strings, ...appended];
@@ -242,7 +248,7 @@ function rewritePathList(values, entries) {
242
248
  * `Disabled`; a configuration without that node is updated through
243
249
  * `<PluginWorkers>` alone.
244
250
  */
245
- function patchEnvironmentConfiguration(xml, entries) {
251
+ function patchEnvironmentConfiguration(xml, entries, platform = process.platform) {
246
252
  if (typeof xml !== 'string' || /<!DOCTYPE|<!ENTITY/i.test(xml) || fast_xml_parser_1.XMLValidator.validate(xml) !== true)
247
253
  throw new Error('Invalid environment configuration.');
248
254
  const document = new fast_xml_parser_1.XMLParser(parserOptions).parse(xml);
@@ -254,11 +260,11 @@ function patchEnvironmentConfiguration(xml, entries) {
254
260
  const plugins = server.Plugins === undefined || server.Plugins === '' ? {} : server.Plugins;
255
261
  if (typeof plugins !== 'object' || Array.isArray(plugins))
256
262
  throw new Error('Invalid environment configuration.');
257
- const combined = rewritePathList(stringList(plugins['sys:string']), pluginEntries);
263
+ const combined = rewritePathList(stringList(plugins['sys:string']), pluginEntries, platform);
258
264
  // Keep Dashboard first even when it is a local build path rather than a deployed one.
259
265
  const dashboard = combined.findIndex(value => {
260
- const folded = windowsPath(value).toLowerCase();
261
- return folded.startsWith('plugins\\dashboard\\') || path.win32.basename(folded) === 'wyn.dashboards.plugin.dll';
266
+ const folded = windowsPath(value, platform).toLowerCase();
267
+ return folded.startsWith(separatorOf(platform) === '\\' ? 'plugins\\dashboard\\' : 'plugins/dashboard/') || (0, local_path_1.baseNameOf)(folded) === 'wyn.dashboards.plugin.dll';
262
268
  });
263
269
  if (dashboard > 0)
264
270
  combined.unshift(combined.splice(dashboard, 1)[0]);
@@ -270,7 +276,7 @@ function patchEnvironmentConfiguration(xml, entries) {
270
276
  const pluginWorkers = server.PluginWorkers === undefined || server.PluginWorkers === '' ? {} : server.PluginWorkers;
271
277
  if (typeof pluginWorkers !== 'object' || Array.isArray(pluginWorkers))
272
278
  throw new Error('Invalid environment configuration.');
273
- pluginWorkers['sys:string'] = rewritePathList(stringList(pluginWorkers['sys:string']), workers);
279
+ pluginWorkers['sys:string'] = rewritePathList(stringList(pluginWorkers['sys:string']), workers, platform);
274
280
  server.PluginWorkers = pluginWorkers;
275
281
  const services = document?.SystemConfig?.Services;
276
282
  for (const entry of workers) {
@@ -282,8 +288,8 @@ function patchEnvironmentConfiguration(xml, entries) {
282
288
  const node = service;
283
289
  // The worker is loaded from the path list above and uses its own directory
284
290
  // as its base directory: keep the service in step without touching Disabled.
285
- node.WorkingDirectory = windowsPath(path.win32.dirname(entry.path));
286
- node.Assembly = path.win32.basename(entry.path);
291
+ node.WorkingDirectory = windowsPath((0, local_path_1.directoryOf)(entry.path, platform), platform);
292
+ node.Assembly = (0, local_path_1.baseNameOf)(entry.path);
287
293
  }
288
294
  }
289
295
  const output = new fast_xml_parser_1.XMLBuilder(builderOptions).build(document);
@@ -361,7 +367,7 @@ function manifestSource(module, targets, previous) {
361
367
  async function writeAtomic(file, content) {
362
368
  const temporary = `${file}.afm-tmp`;
363
369
  await fs.writeFile(temporary, content, 'utf8');
364
- await fs.rename(temporary, file);
370
+ await (0, atomic_1.renameAtomic)(temporary, file);
365
371
  }
366
372
  const writeJsonAtomic = (file, value) => writeAtomic(file, JSON.stringify(value, null, 2) + '\n');
367
373
  /**
@@ -469,7 +475,7 @@ async function resolveLocalSource(entry, module, assembly, input) {
469
475
  if (path.extname(source).toLowerCase() !== '.dll')
470
476
  throw new Error(`Local source must be a .dll file: ${source}.`);
471
477
  if (assembly === undefined) {
472
- const name = path.win32.basename(source).toLowerCase();
478
+ const name = (0, local_path_1.baseNameOf)(source).toLowerCase();
473
479
  const matches = mappings.filter(mapping => mapping.assemblies.some(known => known.toLowerCase() === name));
474
480
  if (matches.length !== 1)
475
481
  throw new Error(`Local source ${source} matches ${matches.length} targets of module ${module}. Expected one of ${expectedAssemblies(module).join(', ')}; select one explicitly with ${module}#<assembly>=<path>.`);
@@ -480,7 +486,7 @@ async function resolveLocalSource(entry, module, assembly, input) {
480
486
  const named = mappingForAssembly(module, assembly);
481
487
  // The explicit form exists for a build whose file name matches no assembly;
482
488
  // a file that is another target's assembly is still a mistake.
483
- const basename = path.win32.basename(source);
489
+ const basename = (0, local_path_1.baseNameOf)(source);
484
490
  const conflicts = mappings.filter(mapping => mapping !== named.mapping && mapping.assemblies.some(known => known.toLowerCase() === basename.toLowerCase()));
485
491
  if (conflicts.length)
486
492
  throw new Error(`Local source ${source} is an assembly of ${conflicts.map(mapping => mapping.destination).join(', ')}, not of ${named.mapping.destination}: ${module}#${assembly}= selects ${named.mapping.destination}.`);
@@ -544,15 +550,13 @@ class EnvironmentUpdater {
544
550
  constructor(dependencies = {}) {
545
551
  this.dependencies = dependencies;
546
552
  this.registry = dependencies.registry ?? new registry_1.EnvironmentRegistry();
547
- this.processes = dependencies.processes ?? new process_1.WindowsProcessBackend();
553
+ this.processes = dependencies.processes ?? (process.platform === 'win32' ? new process_1.WindowsProcessBackend() : new posix_process_1.PosixProcessBackend());
548
554
  this.platform = dependencies.platform ?? process.platform;
549
555
  this.onProgress = dependencies.onProgress;
550
556
  }
551
557
  async update(name, specs, clientFactory, options = {}) {
552
558
  const dryRun = options.dryRun === true;
553
559
  const onProgress = options.onProgress ?? this.onProgress;
554
- if (!dryRun && this.platform !== 'win32')
555
- throw new Error('Environment execution is Windows-only. Use dry-run on other platforms.');
556
560
  onProgress?.('Validating module specs');
557
561
  let parsed = normalizeModuleSpecs(specs);
558
562
  if (!parsed.length)
@@ -564,12 +568,13 @@ class EnvironmentUpdater {
564
568
  await (0, validate_1.validateEnvironmentTree)(entry.root);
565
569
  const manifest = await readManifest(entry.root);
566
570
  const artifacts = [...(manifest.artifacts ?? [])];
571
+ const installed = new Set(artifacts.map(artifact => artifact.module));
567
572
  const skipped = [];
568
573
  if (parsed.some(spec => spec.module === 'all')) {
569
574
  // `all` means every configured module from remote; modules that already
570
575
  // point at a local developer build are left exactly as they are.
571
576
  const localModules = new Set([...Object.keys(manifest.moduleSources ?? {}), ...(entry.localModules ?? [])]);
572
- const configured = [...new Set(artifacts.map(artifact => artifact.module))].filter(module => updatableModules.includes(module)).sort();
577
+ const configured = [...new Set(artifacts.map(artifact => artifact.module))].filter(module => exports.updatableModules.includes(module)).sort();
573
578
  for (const module of configured)
574
579
  if (localModules.has(module))
575
580
  skipped.push({ module, reason: 'local' });
@@ -582,8 +587,8 @@ class EnvironmentUpdater {
582
587
  const localOverrides = new Map();
583
588
  const selectedTargets = new Set();
584
589
  for (const spec of parsed) {
585
- if (spec.module === 'sheets' && entry.edition !== 'en')
586
- throw new Error(`Module sheets requires an EN edition environment; ${entry.name} is ${entry.edition}.`);
590
+ if (['sheets', 'documents'].includes(spec.module) && entry.edition !== 'en')
591
+ throw new Error(`Module ${spec.module} requires an EN edition environment; ${entry.name} is ${entry.edition}.`);
587
592
  if (spec.localPath === undefined)
588
593
  continue;
589
594
  const resolution = await resolveLocalSource(entry, spec.module, spec.assembly, spec.localPath);
@@ -599,6 +604,14 @@ class EnvironmentUpdater {
599
604
  localOverrides.set(spec.module, targets);
600
605
  }
601
606
  const remote = parsed.filter(spec => spec.localPath === undefined);
607
+ // Smart documents cannot run without the collaboration service, which
608
+ // create-env deploys and declares in the Server configuration alongside
609
+ // documents. Installing documents into an environment with no collaboration
610
+ // deployment would produce a broken environment, so refuse — after the
611
+ // edition gate above, so a CN environment still reports the EN requirement.
612
+ if (parsed.some(spec => spec.module === 'documents') && !installed.has('collaboration')) {
613
+ throw new Error(`Module documents requires the collaboration service, which ${entry.name} has not deployed. Recreate the environment with create-env: selecting documents deploys collaboration automatically.`);
614
+ }
602
615
  const state = await (0, validate_1.observeRuntimeState)(entry, this.processes);
603
616
  if (remote.length && state !== 'ready' && state !== 'stopped')
604
617
  throw new Error(`Cannot update modules from a remote source while ${entry.name} is ${state}: deployed files may be in use. Run \`afm env stop ${entry.name}\` first.`);
@@ -607,7 +620,6 @@ class EnvironmentUpdater {
607
620
  const downloads = [...(manifest.downloads ?? [])];
608
621
  const selectedModules = manifest.selectedModules === undefined ? undefined : [...manifest.selectedModules];
609
622
  const moduleSources = { ...(manifest.moduleSources ?? {}) };
610
- const installed = new Set(artifacts.map(artifact => artifact.module));
611
623
  const workspace = remote.length && !dryRun ? await fs.mkdtemp(path.join(path.dirname(entry.root), '.afm-env-')) : undefined;
612
624
  const warnings = [];
613
625
  try {
@@ -671,7 +683,7 @@ class EnvironmentUpdater {
671
683
  if (stagedArtifact)
672
684
  copies.push({ source: path.join(stagedArtifact.expanded, mapping.source), destination });
673
685
  copiedDirectories.push(mapping.destination);
674
- const assembly = stagedArtifact?.assemblies.get(mapping.destination) ?? knownAssembly(configured, mapping);
686
+ const assembly = stagedArtifact?.assemblies.get(mapping.destination) ?? knownAssembly(configured, mapping, this.platform);
675
687
  // Plugins stay relative to the environment root; a worker entry does too,
676
688
  // and its service keeps using the deployed destination as working directory.
677
689
  if (mapping.role === 'plugin' || mapping.role === 'worker') {
@@ -702,7 +714,7 @@ class EnvironmentUpdater {
702
714
  });
703
715
  }
704
716
  const changes = plans.map(plan => ({ module: plan.module, previous: plan.previous, next: plan.next, copiedDirectories: plan.copiedDirectories, removedDirectories: plan.removedDirectories }));
705
- const configuration = patchEnvironmentConfiguration(configured, plans.flatMap(plan => plan.entries));
717
+ const configuration = patchEnvironmentConfiguration(configured, plans.flatMap(plan => plan.entries), this.platform);
706
718
  const nextArtifacts = [...artifacts];
707
719
  const nextDownloads = [...downloads];
708
720
  for (const plan of plans) {
@@ -785,20 +797,20 @@ class EnvironmentUpdater {
785
797
  }
786
798
  exports.EnvironmentUpdater = EnvironmentUpdater;
787
799
  /** Best-effort preview assembly for dry-run, where nothing can be extracted. */
788
- function knownAssembly(xml, mapping) {
800
+ function knownAssembly(xml, mapping, platform) {
789
801
  try {
790
802
  const document = new fast_xml_parser_1.XMLParser(parserOptions).parse(xml);
791
803
  const server = document?.SystemConfig?.Services?.Server;
792
804
  const raw = mapping.role === 'worker' ? server?.PluginWorkers?.['sys:string'] : server?.Plugins?.['sys:string'];
793
805
  const list = raw === undefined ? [] : Array.isArray(raw) ? raw : [raw];
794
- const prefix = windowsPath(mapping.destination).toLowerCase() + '\\';
806
+ const prefix = windowsPath(mapping.destination, platform).toLowerCase() + separatorOf(platform);
795
807
  for (const value of list) {
796
808
  if (typeof value !== 'string')
797
809
  continue;
798
- const folded = windowsPath(value).toLowerCase();
810
+ const folded = windowsPath(value, platform).toLowerCase();
799
811
  if (!folded.startsWith(prefix))
800
812
  continue;
801
- const name = path.win32.basename(folded);
813
+ const name = (0, local_path_1.baseNameOf)(folded);
802
814
  const match = mapping.assemblies.find(assembly => assembly.toLowerCase() === name);
803
815
  if (match)
804
816
  return match;