@intelligentgraphics/ig.gfx.packager 3.1.3 → 3.2.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 (61) hide show
  1. package/build/bin.js +7 -0
  2. package/build/bin.js.map +1 -0
  3. package/build/build-CMbCj7x-.js +945 -0
  4. package/build/build-CMbCj7x-.js.map +1 -0
  5. package/build/build-kkMVBBJL.js +408 -0
  6. package/build/build-kkMVBBJL.js.map +1 -0
  7. package/build/cli-Co1DhAmx.js +405 -0
  8. package/build/cli-Co1DhAmx.js.map +1 -0
  9. package/build/docs-BkGeoYY2.js +30 -0
  10. package/build/docs-BkGeoYY2.js.map +1 -0
  11. package/build/generateIndex-C_DxQ2R4.js +209 -0
  12. package/build/generateIndex-C_DxQ2R4.js.map +1 -0
  13. package/build/generateParameterType-CdCi5BWM.js +46 -0
  14. package/build/generateParameterType-CdCi5BWM.js.map +1 -0
  15. package/build/package-DHx2bvVO.js +1 -0
  16. package/build/postinstall-DHTlEmNr.js +35 -0
  17. package/build/postinstall-DHTlEmNr.js.map +1 -0
  18. package/build/prompter-DONgUlzS.js +20 -0
  19. package/build/prompter-DONgUlzS.js.map +1 -0
  20. package/build/publish-E5zcQAo0.js +348 -0
  21. package/build/publish-E5zcQAo0.js.map +1 -0
  22. package/build/publishNpm-CBT1819u.js +115 -0
  23. package/build/publishNpm-CBT1819u.js.map +1 -0
  24. package/build/publishedPackage-D-KiU0FG.js +1 -0
  25. package/build/rollup-Csyght27.js +179 -0
  26. package/build/rollup-Csyght27.js.map +1 -0
  27. package/build/scripts-CBblHIL1.js +29 -0
  28. package/build/scripts-CBblHIL1.js.map +1 -0
  29. package/build/versionFile-DViDwgCa.js +123 -0
  30. package/build/versionFile-DViDwgCa.js.map +1 -0
  31. package/build/workspace-D0XY2EMu.js +1 -0
  32. package/lib/lib.js +1595 -0
  33. package/package.json +30 -30
  34. package/readme.md +11 -0
  35. package/build/bin.mjs +0 -5
  36. package/build/bin.mjs.map +0 -1
  37. package/build/cli-CPzBOjl0.mjs +0 -768
  38. package/build/cli-CPzBOjl0.mjs.map +0 -1
  39. package/build/dependencies-CYuZmWpt.mjs +0 -129
  40. package/build/dependencies-CYuZmWpt.mjs.map +0 -1
  41. package/build/docs-BlCIta3Y.mjs +0 -37
  42. package/build/docs-BlCIta3Y.mjs.map +0 -1
  43. package/build/generateIndex-D5rR39-Z.mjs +0 -306
  44. package/build/generateIndex-D5rR39-Z.mjs.map +0 -1
  45. package/build/generateParameterType-BDyh-daC.mjs +0 -69
  46. package/build/generateParameterType-BDyh-daC.mjs.map +0 -1
  47. package/build/index-Dn5_iPca.mjs +0 -1370
  48. package/build/index-Dn5_iPca.mjs.map +0 -1
  49. package/build/index-Uwhzx9k9.mjs +0 -477
  50. package/build/index-Uwhzx9k9.mjs.map +0 -1
  51. package/build/postinstall-BkmY43I5.mjs +0 -61
  52. package/build/postinstall-BkmY43I5.mjs.map +0 -1
  53. package/build/publishNpm-S60dL_YV.mjs +0 -167
  54. package/build/publishNpm-S60dL_YV.mjs.map +0 -1
  55. package/build/rollup-BeQ0dM8U.mjs +0 -221
  56. package/build/rollup-BeQ0dM8U.mjs.map +0 -1
  57. package/build/scripts-B3noxiX3.mjs +0 -45
  58. package/build/scripts-B3noxiX3.mjs.map +0 -1
  59. package/build/versionFile-HrFQXwyU.mjs +0 -206
  60. package/build/versionFile-HrFQXwyU.mjs.map +0 -1
  61. package/lib/lib.mjs +0 -2676
package/lib/lib.js ADDED
@@ -0,0 +1,1595 @@
1
+ import { C as writePackageCreatorIndex, D as isErrorEPERM, E as isErrorENOENT, S as readPackageNpmManifest, T as isErrorEACCES, _ as getPackageReleasesDirectory, a as getPackageTypescriptFiles, b as readPackageCreatorIndex, c as readStringFromFileOrUndefined, d as readWorkspaceNpmManifest, f as readPublishedPackageCreatorIndex, g as PACKAGE_FILE, h as INDEX_FILE, i as assetService_exports, l as determineWorkspaceIGLibraries, m as readPublishedPackageNpmManifest, n as readScriptPackageTSConfig, o as consoleReporter, p as readPublishedPackageCreatorManifest, r as resolveScriptPackageEntryModule, s as createPackageScopedReporter, t as isScriptPackageModules, u as getWorkspaceOutputPath, v as parseCreatorPackageName, w as writePackageCreatorManifest, x as readPackageCreatorManifest, y as readPackageAnimationList } from "./scripts-B1CadgeN.js";
2
+ import * as path from "node:path";
3
+ import * as fs from "fs/promises";
4
+ import * as terser from "terser";
5
+ import { EOL } from "node:os";
6
+ import ts from "typescript";
7
+ import * as fs$1 from "node:fs";
8
+ import { createReadStream, createWriteStream } from "node:fs";
9
+ import EventEmitter from "events";
10
+ import { SourceMapConsumer, SourceMapGenerator } from "source-map-js";
11
+ import Ajv from "ajv";
12
+ import { pipeline } from "node:stream/promises";
13
+ import { exec } from "node:child_process";
14
+ import { promisify } from "node:util";
15
+ import simpleGit from "simple-git";
16
+ import JSZip from "jszip";
17
+ import "@inquirer/prompts";
18
+ import { buffer } from "node:stream/consumers";
19
+ import { findNamespaceByMemberSourceFile, resolveNamespaceFullName, resolveNamespaces } from "@intelligentgraphics/declarationbundler";
20
+ //#region src/commands/build/tsc.ts
21
+ const tryReadTsConfig = (location) => {
22
+ const { config } = ts.readConfigFile(path.join(location.scriptsDir, "tsconfig.json"), (path) => {
23
+ try {
24
+ return fs$1.readFileSync(path, "utf8");
25
+ } catch {
26
+ return;
27
+ }
28
+ });
29
+ return config;
30
+ };
31
+ const createTSCBuildParticipant = (location, outputDir, skipDeclarations) => (env) => {
32
+ const files = getPackageTypescriptFiles(location);
33
+ try {
34
+ env.onBuildStart();
35
+ env.log("Compiling typescript files");
36
+ const compilerOptions = getCompilerOptions(location, outputDir, skipDeclarations);
37
+ const host = ts.createCompilerHost(compilerOptions);
38
+ host.getCurrentDirectory = () => location.scriptsDir;
39
+ let js;
40
+ let definitions;
41
+ let sourceMap;
42
+ host.writeFile = (fileName, data, writeByteOrderMark) => {
43
+ if (fileName.endsWith(".js")) js = data;
44
+ else if (fileName.endsWith(".d.ts")) definitions = data;
45
+ else if (fileName.endsWith(".js.map")) sourceMap = data;
46
+ };
47
+ const programOptions = {
48
+ rootNames: files,
49
+ options: compilerOptions,
50
+ host
51
+ };
52
+ const program = ts.createProgram(programOptions);
53
+ const emitResult = program.emit();
54
+ const allDiagnostics = ts.getPreEmitDiagnostics(program);
55
+ if (!emitResult.emitSkipped) {
56
+ if (allDiagnostics.length > 0) console.log(ts.formatDiagnostics(allDiagnostics, host));
57
+ if (js === void 0 || definitions === void 0) throw new Error(`Unexpected: no js or definitions were created`);
58
+ env.onBuildEnd({
59
+ type: "success",
60
+ artefacts: {
61
+ js: js.replace(`//# sourceMappingURL=out.js.map`, ""),
62
+ declarations: getDeclarationFileReferences(location, program, outputDir) + definitions,
63
+ sourceMap
64
+ }
65
+ });
66
+ } else {
67
+ const error = ts.formatDiagnostics(allDiagnostics, host);
68
+ throw new Error(error);
69
+ }
70
+ } catch (err) {
71
+ env.onBuildEnd({
72
+ type: "error",
73
+ error: err instanceof Error ? err : new Error(String(err))
74
+ });
75
+ }
76
+ return { destroy: () => {} };
77
+ };
78
+ const createTSCWatchBuildParticipant = (location, outputDir, skipDeclarations) => {
79
+ return ({ onBuildStart, onBuildEnd }) => {
80
+ let state = {
81
+ diagnostics: [],
82
+ js: void 0,
83
+ definitions: void 0,
84
+ sourceMap: void 0
85
+ };
86
+ const customSys = {
87
+ ...ts.sys,
88
+ writeFile: (fileName, data, writeByteOrderMark) => {
89
+ if (fileName.endsWith(".js")) state.js = data;
90
+ else if (fileName.endsWith(".d.ts")) state.definitions = data;
91
+ else if (fileName.endsWith(".js.map")) state.sourceMap = data;
92
+ }
93
+ };
94
+ const registerDiagnostic = (diagnostic) => {
95
+ switch (diagnostic.code) {
96
+ case 6053: return;
97
+ case 18003: return;
98
+ }
99
+ state.diagnostics.push(diagnostic);
100
+ };
101
+ let currentProgram;
102
+ const reportWatchStatusChanged = (diagnostic) => {
103
+ switch (diagnostic.code) {
104
+ case 6031:
105
+ case 6032:
106
+ onBuildStart();
107
+ break;
108
+ case 6193:
109
+ case 6194:
110
+ const emitState = state;
111
+ state = {
112
+ diagnostics: [],
113
+ js: void 0,
114
+ definitions: void 0,
115
+ sourceMap: void 0
116
+ };
117
+ if (emitState.diagnostics.length > 0) {
118
+ const message = ts.formatDiagnostics(emitState.diagnostics, formattingHost);
119
+ onBuildEnd({
120
+ type: "error",
121
+ error: new Error(message)
122
+ });
123
+ return;
124
+ }
125
+ if (emitState.js === void 0) {
126
+ onBuildEnd({
127
+ type: "success",
128
+ artefacts: { js: "" }
129
+ });
130
+ return;
131
+ }
132
+ if (!currentProgram) throw new Error(`Expected a program to exist`);
133
+ onBuildEnd({
134
+ type: "success",
135
+ artefacts: {
136
+ js: emitState.js.replace(`//# sourceMappingURL=out.js.map`, ""),
137
+ declarations: emitState.definitions ? getDeclarationFileReferences(location, currentProgram, outputDir) + emitState.definitions : void 0,
138
+ sourceMap: emitState.sourceMap
139
+ }
140
+ });
141
+ break;
142
+ }
143
+ };
144
+ const host = ts.createWatchCompilerHost(path.join(location.scriptsDir, "tsconfig.json"), getCompilerOptions(location, outputDir, skipDeclarations), customSys, ts.createSemanticDiagnosticsBuilderProgram, registerDiagnostic, reportWatchStatusChanged);
145
+ const originalAfterProgramCreate = host.afterProgramCreate;
146
+ host.afterProgramCreate = (program) => {
147
+ currentProgram = program;
148
+ originalAfterProgramCreate?.(program);
149
+ };
150
+ const formattingHost = {
151
+ getCanonicalFileName: (path) => path,
152
+ getCurrentDirectory: host.getCurrentDirectory,
153
+ getNewLine: () => ts.sys.newLine
154
+ };
155
+ const watchProgram = ts.createWatchProgram(host);
156
+ return { destroy: () => {
157
+ watchProgram.close();
158
+ } };
159
+ };
160
+ };
161
+ const getCompilerOptions = (location, outputDir, skipDeclarations) => {
162
+ const config = tryReadTsConfig(location);
163
+ config.compilerOptions.lib = ["es2018", "dom"];
164
+ return {
165
+ ...ts.convertCompilerOptionsFromJson(config.compilerOptions, location.scriptsDir).options,
166
+ removeComments: false,
167
+ declaration: !skipDeclarations,
168
+ sourceMap: true,
169
+ inlineSources: false,
170
+ outFile: path.join(outputDir, "out.js"),
171
+ target: ts.ScriptTarget.ES5,
172
+ noEmitOnError: true
173
+ };
174
+ };
175
+ function getDeclarationFileReferences(location, program, outputDir) {
176
+ const references = /* @__PURE__ */ new Set();
177
+ for (const file of program.getSourceFiles()) for (const reference of file.referencedFiles) {
178
+ if (reference.preserve) continue;
179
+ const dir = path.dirname(file.fileName);
180
+ const absolute = path.resolve(dir, reference.fileName);
181
+ if (!absolute.startsWith(location.scriptsDir)) references.add(absolute);
182
+ }
183
+ let referenceString = Array.from(references, (reference) => {
184
+ return `/// <reference path="${path.relative(outputDir, reference).replaceAll(path.sep, "/")}" />`;
185
+ }).join(EOL);
186
+ if (referenceString) referenceString += EOL;
187
+ return referenceString;
188
+ }
189
+ //#endregion
190
+ //#region src/lib/toposort.ts
191
+ const toposort = (packages) => {
192
+ const queue = Object.getOwnPropertyNames(packages);
193
+ const result = [];
194
+ let index = 0;
195
+ while (queue.length > 0) {
196
+ if (index >= queue.length) throw new Error("Packages can not have cyclic dependencies");
197
+ const queueEntry = queue[index];
198
+ if (packages[queueEntry].some((dependency) => queue.includes(dependency))) {
199
+ index++;
200
+ continue;
201
+ }
202
+ queue.splice(index, 1);
203
+ index = 0;
204
+ result.push(queueEntry);
205
+ }
206
+ return result;
207
+ };
208
+ //#endregion
209
+ //#region src/commands/build/manager.ts
210
+ var BuildManager = class extends EventEmitter {
211
+ participants = /* @__PURE__ */ new Map();
212
+ states = /* @__PURE__ */ new Map();
213
+ participantInstances = [];
214
+ constructor(manifest, writer, reporter) {
215
+ super();
216
+ this.manifest = manifest;
217
+ this.writer = writer;
218
+ this.reporter = reporter;
219
+ }
220
+ addParticipant(name, participant) {
221
+ this.participants.set(name, participant);
222
+ }
223
+ run() {
224
+ for (const [name] of this.participants) this.states.set(name, { type: "busy" });
225
+ this.emit("start");
226
+ for (const [name, participant] of this.participants) {
227
+ const instance = participant({
228
+ onBuildStart: () => {
229
+ let alreadyBusy = false;
230
+ for (const [name, state] of this.states) if (state.type === "busy") {
231
+ alreadyBusy = true;
232
+ continue;
233
+ }
234
+ this.states.set(name, { type: "busy" });
235
+ if (!alreadyBusy) this.emit("start");
236
+ },
237
+ onBuildEnd: (result) => {
238
+ this.states.set(name, result);
239
+ this.maybeEmit();
240
+ },
241
+ log: (message) => this.reporter.log(message)
242
+ });
243
+ this.participantInstances.push(instance);
244
+ }
245
+ }
246
+ destroy() {
247
+ for (const instance of this.participantInstances) instance.destroy();
248
+ }
249
+ maybeEmit() {
250
+ const errors = [];
251
+ const results = [];
252
+ for (const [_, state] of this.states) {
253
+ if (state.type === "busy") return;
254
+ if (state.type === "success") results.push(state);
255
+ else if (state.type === "error") errors.push(state.error);
256
+ }
257
+ if (errors.length > 0) {
258
+ this.emit("error", errors.length === 1 ? errors[0] : new AggregateError(errors));
259
+ return;
260
+ }
261
+ const completeResult = { js: "" };
262
+ const sourceMapGenerator = new SourceMapGenerator();
263
+ for (const result of results) {
264
+ if (result.artefacts.js) {
265
+ if (completeResult.js) completeResult.js += "\n";
266
+ if (result.artefacts.sourceMap) {
267
+ const lines = completeResult.js.split("\n").length - 1;
268
+ const sourceMap = new SourceMapConsumer(JSON.parse(result.artefacts.sourceMap));
269
+ const sources = /* @__PURE__ */ new Set();
270
+ sourceMap.eachMapping((mapping) => {
271
+ sourceMapGenerator.addMapping({
272
+ generated: {
273
+ line: lines + mapping.generatedLine,
274
+ column: mapping.generatedColumn
275
+ },
276
+ original: mapping.originalLine !== null && mapping.originalColumn !== null ? {
277
+ line: mapping.originalLine,
278
+ column: mapping.originalColumn
279
+ } : void 0,
280
+ source: mapping.source,
281
+ name: mapping.name
282
+ });
283
+ if (mapping.source !== null) sources.add(mapping.source);
284
+ });
285
+ for (const source of sources) {
286
+ const content = sourceMap.sourceContentFor(source);
287
+ if (content !== null) sourceMapGenerator.setSourceContent(source, content);
288
+ }
289
+ }
290
+ completeResult.js += result.artefacts.js;
291
+ }
292
+ if (result.artefacts.declarations) {
293
+ if (completeResult.declarations) completeResult.declarations += "\n";
294
+ else completeResult.declarations = "";
295
+ completeResult.declarations += result.artefacts.declarations;
296
+ }
297
+ }
298
+ completeResult.sourceMap = sourceMapGenerator.toString();
299
+ this.writer(completeResult).then(() => {
300
+ this.emit("build");
301
+ });
302
+ }
303
+ };
304
+ //#endregion
305
+ //#region src/commands/build/animation.schema.ts
306
+ var animation_schema_default = {
307
+ $schema: "http://json-schema.org/draft-07/schema",
308
+ $id: "https://archive.intelligentgraphics.biz/schemas/gfx/animation.json",
309
+ $comment: "Version 2023-02-17, Source: ig.data.gfx/Specs/animation.json",
310
+ title: "Animation description format",
311
+ additionalProperties: false,
312
+ type: "object",
313
+ properties: {
314
+ $schema: { type: "string" },
315
+ Id: {
316
+ type: "string",
317
+ description: "Animation id, to be unique in the project scope. Needs to be a valid JavaScript identifier."
318
+ },
319
+ Animations: {
320
+ type: "array",
321
+ description: "Declaration of animation states for gfx objects",
322
+ items: {
323
+ type: "object",
324
+ additionalProperties: false,
325
+ properties: {
326
+ _: {
327
+ type: "string",
328
+ description: "Comment"
329
+ },
330
+ Path: { $ref: "#/definitions/igxcPath" },
331
+ States: {
332
+ type: "object",
333
+ additionalProperties: {
334
+ type: "object",
335
+ additionalProperties: false,
336
+ properties: {
337
+ Position: { $ref: "#/definitions/vec3" },
338
+ Rotation: { $ref: "#/definitions/rotation" },
339
+ Scaling: { $ref: "#/definitions/vec3" },
340
+ Visibility: { type: "boolean" },
341
+ Deformation: { anyOf: [{ type: "number" }, { type: "string" }] }
342
+ }
343
+ }
344
+ }
345
+ }
346
+ }
347
+ },
348
+ Kinematics: { oneOf: [{ $ref: "#/definitions/kinematicChain" }, {
349
+ type: "array",
350
+ items: { $ref: "#/definitions/kinematicChain" }
351
+ }] },
352
+ LinkedPoints: {
353
+ type: "object",
354
+ additionalProperties: {
355
+ type: "array",
356
+ items: { type: "string" }
357
+ }
358
+ },
359
+ _: {
360
+ type: "string",
361
+ description: "Comment"
362
+ }
363
+ },
364
+ definitions: {
365
+ vec3: {
366
+ type: "object",
367
+ additionalProperties: false,
368
+ properties: {
369
+ X: { anyOf: [{ type: "number" }, { type: "string" }] },
370
+ Y: { anyOf: [{ type: "number" }, { type: "string" }] },
371
+ Z: { anyOf: [{ type: "number" }, { type: "string" }] },
372
+ _: {
373
+ type: "string",
374
+ description: "Comment"
375
+ }
376
+ }
377
+ },
378
+ rotation: {
379
+ type: "object",
380
+ additionalProperties: false,
381
+ properties: {
382
+ Q: {
383
+ description: "If true, the rotation is considered to be a Quaternion. Otherwise, it's interpreted as Euler arcs and W will be ignored.",
384
+ type: "boolean"
385
+ },
386
+ X: { anyOf: [{ type: "number" }, { type: "string" }] },
387
+ Y: { anyOf: [{ type: "number" }, { type: "string" }] },
388
+ Z: { anyOf: [{ type: "number" }, { type: "string" }] },
389
+ W: { anyOf: [{ type: "number" }, { type: "string" }] },
390
+ _: {
391
+ type: "string",
392
+ description: "Comment"
393
+ }
394
+ }
395
+ },
396
+ igxcPath: {
397
+ type: "string",
398
+ description: "Relative path of the target object",
399
+ pattern: "^((o|e)\\d+(\\.(o|e)\\d+)*|\\.)$"
400
+ },
401
+ param: {
402
+ type: "string",
403
+ pattern: "^Param\\d+$"
404
+ },
405
+ kinematicChain: {
406
+ type: "object",
407
+ additionalProperties: false,
408
+ properties: {
409
+ GeometryBase: { type: "string" },
410
+ Joints: {
411
+ type: "array",
412
+ items: {
413
+ type: "object",
414
+ additionalProperties: false,
415
+ properties: {
416
+ Name: { oneOf: [{ $ref: "#/definitions/param" }, { type: "string" }] },
417
+ HeadX: { oneOf: [{ $ref: "#/definitions/param" }, { $ref: "#/definitions/igxcPath" }] },
418
+ HeadY: { oneOf: [{ $ref: "#/definitions/param" }, { $ref: "#/definitions/igxcPath" }] },
419
+ HeadZ: { oneOf: [{ $ref: "#/definitions/param" }, { $ref: "#/definitions/igxcPath" }] },
420
+ Tail: { oneOf: [{ $ref: "#/definitions/param" }, { $ref: "#/definitions/igxcPath" }] },
421
+ LimitLeft: { type: "number" },
422
+ LimitRight: { type: "number" },
423
+ LimitUp: { type: "number" },
424
+ LimitDown: { type: "number" },
425
+ FollowJointNode: { $ref: "#/definitions/igxcPath" },
426
+ _TargetNodeForFollow: { type: "string" }
427
+ }
428
+ }
429
+ },
430
+ Target: { oneOf: [
431
+ { $ref: "#/definitions/igxcPath" },
432
+ { $ref: "#/definitions/param" },
433
+ {
434
+ type: "string",
435
+ enum: ["subbase"]
436
+ }
437
+ ] },
438
+ Parent: { oneOf: [{ $ref: "#/definitions/igxcPath" }, {
439
+ type: "string",
440
+ enum: ["root"]
441
+ }] },
442
+ Tolerance: { type: "number" },
443
+ MaxIterations: { type: "integer" },
444
+ _: {
445
+ type: "string",
446
+ description: "Comment"
447
+ },
448
+ __: {
449
+ type: "string",
450
+ description: "Super Comment"
451
+ }
452
+ }
453
+ }
454
+ }
455
+ };
456
+ //#endregion
457
+ //#region src/commands/build/animations.ts
458
+ const createAnimationBuildParticipant = (location, manifest) => {
459
+ return (env) => {
460
+ env.onBuildStart();
461
+ bundleAnimations(location, manifest, env.log).then((result) => {
462
+ env.onBuildEnd({
463
+ type: "success",
464
+ artefacts: { js: result?.js ?? "" }
465
+ });
466
+ }).catch((err) => {
467
+ env.onBuildEnd({
468
+ type: "error",
469
+ error: err.message
470
+ });
471
+ });
472
+ return { destroy: () => {} };
473
+ };
474
+ };
475
+ const createAnimationWatchBuildParticipant = (location, manifest) => (env) => {
476
+ env.onBuildStart();
477
+ bundleAnimations(location, manifest, env.log).then((result) => {
478
+ env.onBuildEnd({
479
+ type: "success",
480
+ artefacts: { js: result?.js ?? "" }
481
+ });
482
+ }).catch((err) => {
483
+ env.onBuildEnd({
484
+ type: "error",
485
+ error: err.message
486
+ });
487
+ });
488
+ (async () => {
489
+ for await (const event of fs.watch(location.scriptsDir)) if (event.filename?.endsWith(".animation.json")) {
490
+ env.onBuildStart();
491
+ try {
492
+ const result = await bundleAnimations(location, manifest, env.log);
493
+ env.onBuildEnd({
494
+ type: "success",
495
+ artefacts: { js: result?.js ?? "" }
496
+ });
497
+ } catch (err) {
498
+ env.onBuildEnd({
499
+ type: "error",
500
+ error: err instanceof Error ? err : new Error(String(err))
501
+ });
502
+ }
503
+ }
504
+ })();
505
+ return { destroy: () => {} };
506
+ };
507
+ const bundleAnimations = async (location, manifest, logStep) => {
508
+ const animations = /* @__PURE__ */ new Map();
509
+ for (const scriptFilePath of readPackageAnimationList(location)) {
510
+ const content = await fs.readFile(scriptFilePath, { encoding: "utf8" });
511
+ let data;
512
+ try {
513
+ data = JSON.parse(content);
514
+ } catch (err) {
515
+ const relativePath = path.relative(location.path, scriptFilePath);
516
+ if (err instanceof SyntaxError) throw new Error(`Encountered invalid syntax in file "${relativePath}": ${String(err)}`);
517
+ throw new Error(`Encountered an unexpected error while parsing animation json file at path "${relativePath}"`, { cause: err });
518
+ }
519
+ if (!data.Id) {
520
+ const fileName = path.basename(scriptFilePath, ".animation.json");
521
+ data.Id = fileName;
522
+ }
523
+ (await getAnimationJsonValidation())(data);
524
+ delete data.$schema;
525
+ animations.set(data.Id, JSON.stringify(data));
526
+ }
527
+ if (animations.size > 0) {
528
+ const scope = manifest.Scope ?? manifest.Package;
529
+ let js = createNamespace(scope.split("."));
530
+ for (const [name, content] of animations) {
531
+ js += `${scope}["${name}"] = ` + content + ";";
532
+ logStep(`Adding animation ${scope}.${name}`);
533
+ }
534
+ return { js };
535
+ }
536
+ };
537
+ const createNamespace = (parts) => {
538
+ let code = `var ${parts[0]};`;
539
+ for (let index = 0; index < parts.length; index++) {
540
+ const path = parts.slice(0, index + 1).join(".");
541
+ code += `\n(${path} = ${path} || {});`;
542
+ }
543
+ return code;
544
+ };
545
+ let validateAnimationJson;
546
+ const getAnimationJsonValidation = async () => {
547
+ if (validateAnimationJson === void 0) validateAnimationJson = new Ajv({
548
+ coerceTypes: true,
549
+ allErrors: true,
550
+ removeAdditional: true,
551
+ useDefaults: "empty",
552
+ validateSchema: "log"
553
+ }).compile(animation_schema_default);
554
+ return validateAnimationJson;
555
+ };
556
+ //#endregion
557
+ //#region src/lib/packageVersion.ts
558
+ var PackageVersion = class PackageVersion {
559
+ static fullTextMatcher = /(\d+)(\.(\d+)(\.(\d+)(\.(\d+))?(-([^\.]+)\.(\d+))?)?)?/;
560
+ static lineMatcher = /^(\d+)(\.(\d+)(\.(\d+)(\.(\d+))?(-([^\.]+)\.(\d+))?)?)?$/;
561
+ static extractFromText(input, description) {
562
+ if (input === void 0) throw new Error(`Can not parse version from undefined`);
563
+ const match = input.match(PackageVersion.fullTextMatcher);
564
+ if (!match) throw new Error(`Could not extract a version from input: ${input}`);
565
+ return PackageVersion.fromMatch(match, description);
566
+ }
567
+ static extractFromLine(input, description) {
568
+ if (input === void 0) throw new Error(`Can not parse version from undefined`);
569
+ const match = input.match(PackageVersion.lineMatcher);
570
+ if (!match) throw new Error(`Could not parse version from input: ${input}`);
571
+ return PackageVersion.fromMatch(match, description);
572
+ }
573
+ static equals(a, b, checkPrerelease = false) {
574
+ if (a.major !== b.major || a.minor !== b.minor || a.patch !== b.patch) return false;
575
+ if (checkPrerelease === false) return true;
576
+ if (a.preRelease === b.preRelease) return true;
577
+ if (a.preRelease === void 0 || b.preRelease === void 0) return false;
578
+ return a.preRelease.type === b.preRelease.type && a.preRelease.version === b.preRelease.version;
579
+ }
580
+ static fromMatch([, major, , minor = "0", , patch = "0", , build, , preReleaseType, preReleaseNumber], description) {
581
+ let preRelease = void 0;
582
+ let buildNumber = 100;
583
+ if (preReleaseType && preReleaseNumber) preRelease = {
584
+ type: preReleaseType,
585
+ version: parseInt(preReleaseNumber)
586
+ };
587
+ if (build) buildNumber = Number(build);
588
+ else if (description) {
589
+ const descriptionMatch = description.match(/(\d+)\)$/);
590
+ if (descriptionMatch) buildNumber = parseInt(descriptionMatch[1]);
591
+ }
592
+ return new PackageVersion(parseInt(major), parseInt(minor), parseInt(patch), preRelease, buildNumber);
593
+ }
594
+ static sort(a, b, ascending = true) {
595
+ const createSortResult = (a, b) => ascending ? a - b : b - a;
596
+ if (a.major !== b.major) return createSortResult(a.major, b.major);
597
+ if (a.minor !== b.minor) return createSortResult(a.minor, b.minor);
598
+ if (a.patch !== b.patch) return createSortResult(a.patch, b.patch);
599
+ return createSortResult(a.preRelease ? a.preRelease.version : 0, b.preRelease ? b.preRelease.version : 0);
600
+ }
601
+ static toNumber(version) {
602
+ return ((version.major * 1e3 + version.minor) * 1e3 + version.patch) * 1e3 + version.buildNumber;
603
+ }
604
+ constructor(major, minor, patch, preRelease, buildNumber) {
605
+ this.major = major;
606
+ this.minor = minor;
607
+ this.patch = patch;
608
+ this.preRelease = preRelease;
609
+ this.buildNumber = buildNumber;
610
+ }
611
+ isPreRelease() {
612
+ return this.preRelease !== void 0;
613
+ }
614
+ clone() {
615
+ return new PackageVersion(this.major, this.minor, this.patch, this.preRelease ? { ...this.preRelease } : void 0, this.buildNumber);
616
+ }
617
+ incrementMajor() {
618
+ this.preRelease = void 0;
619
+ this.patch = 0;
620
+ this.minor = 0;
621
+ this.major++;
622
+ }
623
+ incrementMinor() {
624
+ this.preRelease = void 0;
625
+ this.patch = 0;
626
+ this.minor++;
627
+ }
628
+ incrementPatch() {
629
+ this.preRelease = void 0;
630
+ this.patch++;
631
+ }
632
+ createPreRelease(type) {
633
+ if (!this.preRelease) this.buildNumber = 1;
634
+ else this.buildNumber++;
635
+ if (this.preRelease && type === this.preRelease.type) {
636
+ this.preRelease.version++;
637
+ return;
638
+ }
639
+ this.preRelease = {
640
+ version: 0,
641
+ type
642
+ };
643
+ }
644
+ createRelease() {
645
+ this.preRelease = void 0;
646
+ this.buildNumber = 100;
647
+ }
648
+ toVersionString({ buildNumber } = {}) {
649
+ let version = [
650
+ this.major,
651
+ this.minor,
652
+ this.patch
653
+ ].join(".");
654
+ if (buildNumber) version += "." + this.buildNumber;
655
+ if (this.preRelease) version += `-${this.preRelease.type}.${this.preRelease.version}`;
656
+ return version;
657
+ }
658
+ toDescriptionString(packageName) {
659
+ const base = [
660
+ this.major,
661
+ this.minor,
662
+ this.patch
663
+ ].join(".");
664
+ const parts = [packageName, base];
665
+ if (this.preRelease) {
666
+ parts.push(upperCaseFirst(this.preRelease.type));
667
+ parts.push(this.preRelease.version);
668
+ }
669
+ parts.push(`(${base}.${this.buildNumber})`);
670
+ return parts.join(" ");
671
+ }
672
+ /**
673
+ * Determines wether the version is lesser than the input version
674
+ *
675
+ * @param {PackageVersion} version
676
+ * @returns
677
+ */
678
+ isLesserThan(version) {
679
+ return PackageVersion.toNumber(this) < PackageVersion.toNumber(version);
680
+ }
681
+ /**
682
+ * Determines wether the version is greater than the input version
683
+ *
684
+ * @param {PackageVersion} version
685
+ * @returns
686
+ */
687
+ isGreaterThan(version) {
688
+ return PackageVersion.toNumber(this) > PackageVersion.toNumber(version);
689
+ }
690
+ };
691
+ const upperCaseFirst = (input) => {
692
+ return input.slice(0, 1).toUpperCase() + input.slice(1);
693
+ };
694
+ //#endregion
695
+ //#region src/commands/build/index.ts
696
+ async function buildFolders(options) {
697
+ if (options.outDir !== void 0 && options.clean) await fs.rm(options.outDir, { recursive: true });
698
+ const baseReporter = options.reporter ?? consoleReporter;
699
+ const workspace = options.workspace;
700
+ const folders = options.packages;
701
+ let sortedPackages = sortPackagesByBuildOrder(folders);
702
+ let index = 1;
703
+ const manifests = new Map(sortedPackages.map((location) => [location, readPackageCreatorManifest(location)]));
704
+ const maxNameLength = Array.from(manifests.values(), (manifest) => manifest.Package.length).reduce((acc, length) => Math.max(acc, length), 0);
705
+ const managers = [];
706
+ for (const location of sortedPackages) {
707
+ const tsConfig = await ensureTsConfig(location);
708
+ const data = manifests.get(location);
709
+ const reporter = options.preparedReporter ?? createPackageScopedReporter(baseReporter, data.Package, index, folders.length, maxNameLength);
710
+ const outputDirectory = options.outDir || location.scriptsDir;
711
+ await fs.mkdir(outputDirectory, { recursive: true });
712
+ const manager = new BuildManager(data, (result) => writeBuildResult(result, data, location, workspace, outputDirectory, options.minimize, reporter), reporter);
713
+ if (options.banner) manager.addParticipant("banner", createBannerCommentBuildParticipant(options.banner));
714
+ const typescriptFiles = getPackageTypescriptFiles(location);
715
+ if (!typescriptFiles.some((file) => path.basename(file).toLowerCase() === "version.ts")) manager.addParticipant("version", createVersionLogBuildParticipant(data));
716
+ if (typescriptFiles.length > 0) if (isScriptPackageModules(tsConfig.options)) {
717
+ const { createRollupBuildParticipant } = await import("./rollup-DZ2wdbmd.js");
718
+ manager.addParticipant("rollup", createRollupBuildParticipant(location, data, outputDirectory, !tsConfig.options.declaration));
719
+ } else manager.addParticipant("tsc", createTSCBuildParticipant(location, outputDirectory, tsConfig.options.declaration === false));
720
+ manager.addParticipant("animation", createAnimationBuildParticipant(location, data));
721
+ await new Promise((resolve, reject) => {
722
+ manager.addListener("start", () => {
723
+ reporter.log(`Build started`);
724
+ });
725
+ manager.addListener("error", (error) => {
726
+ reject(error);
727
+ });
728
+ manager.addListener("build", () => {
729
+ reporter.log(`Build complete`);
730
+ resolve();
731
+ });
732
+ manager.run();
733
+ });
734
+ managers.push(manager);
735
+ if (options.docs) {
736
+ if (!options.docsHandler) throw new Error("Handler for typescript docs not available");
737
+ reporter.log("Generating typedoc documentation");
738
+ await options.docsHandler(location, path.join(outputDirectory, `${data.Package}.d.ts`), path.join(workspace.path, "docs", data.Package), data.Package);
739
+ }
740
+ index++;
741
+ }
742
+ }
743
+ async function buildFoldersWatch(options) {
744
+ if (options.outDir !== void 0 && options.clean) await fs.rm(options.outDir, { recursive: true });
745
+ const workspace = options.workspace;
746
+ const folders = options.packages;
747
+ options.reporter;
748
+ let sortedPackages = sortPackagesByBuildOrder(folders);
749
+ let index = 1;
750
+ const manifests = new Map(sortedPackages.map((location) => [location, readPackageCreatorManifest(location)]));
751
+ const maxNameLength = Array.from(manifests.values(), (manifest) => manifest.Package.length).reduce((acc, length) => Math.max(acc, length), 0);
752
+ const managers = [];
753
+ for (const location of sortedPackages) {
754
+ const tsConfig = await ensureTsConfig(location);
755
+ const baseReporter = options.reporter ?? consoleReporter;
756
+ const data = manifests.get(location);
757
+ const reporter = options.preparedReporter ?? createPackageScopedReporter(baseReporter, data.Package, index, folders.length, maxNameLength);
758
+ const outputDirectory = options.outDir || location.scriptsDir;
759
+ await fs.mkdir(outputDirectory, { recursive: true });
760
+ const manager = new BuildManager(data, (result) => writeBuildResult(result, data, location, workspace, outputDirectory, options.minimize, reporter), reporter);
761
+ if (options.banner) manager.addParticipant("banner", createBannerCommentBuildParticipant(options.banner));
762
+ const typescriptFiles = getPackageTypescriptFiles(location);
763
+ if (!typescriptFiles.some((file) => path.basename(file).toLowerCase() === "version.ts")) manager.addParticipant("version", createVersionLogBuildParticipant(data));
764
+ if (typescriptFiles.length > 0) if (isScriptPackageModules(tsConfig.options)) {
765
+ const { createRollupWatchBuildParticipant } = await import("./rollup-DZ2wdbmd.js");
766
+ manager.addParticipant("rollup", createRollupWatchBuildParticipant(location, data, outputDirectory, !tsConfig.options.declaration));
767
+ } else manager.addParticipant("tsc", createTSCWatchBuildParticipant(location, outputDirectory, tsConfig.options.declaration === false));
768
+ manager.addParticipant("animation", createAnimationWatchBuildParticipant(location, data));
769
+ await new Promise((resolve, reject) => {
770
+ manager.addListener("start", () => {
771
+ reporter.log(`Build started`);
772
+ });
773
+ manager.addListener("error", (error) => {
774
+ reporter.log(`Build failed: ${EOL}${error}`);
775
+ resolve();
776
+ });
777
+ manager.addListener("build", () => {
778
+ reporter.log(`Build complete`);
779
+ resolve();
780
+ });
781
+ manager.run();
782
+ });
783
+ managers.push(manager);
784
+ index++;
785
+ }
786
+ return { destroy: () => {
787
+ for (const manager of managers) manager.destroy();
788
+ } };
789
+ }
790
+ async function writeBuildResult(buildResult, manifest, location, workspace, outputDirectory, minimize, reporter) {
791
+ let js = buildResult.js;
792
+ if (buildResult.sourceMap) js += `\n//# sourceMappingURL=${manifest.Package}.js.map`;
793
+ await fs.writeFile(path.join(outputDirectory, `${manifest.Package}.js`), js, { encoding: "utf8" });
794
+ if (buildResult.declarations !== void 0) await fs.writeFile(path.join(outputDirectory, `${manifest.Package}.d.ts`), buildResult.declarations, { encoding: "utf8" });
795
+ if (buildResult.sourceMap !== void 0) await fs.writeFile(path.join(outputDirectory, `${manifest.Package}.js.map`), buildResult.sourceMap, { encoding: "utf8" });
796
+ if (minimize) {
797
+ reporter.log("Minifying the output");
798
+ const minifyResult = await terser.minify(js, {
799
+ ecma: 5,
800
+ sourceMap: {
801
+ content: buildResult.sourceMap,
802
+ includeSources: false
803
+ }
804
+ });
805
+ const minifiedPath = path.join(outputDirectory, `${manifest.Package}.min.js`);
806
+ let code = minifyResult.code;
807
+ if (minifyResult.map) code += `\n//# sourceMappingURL=${manifest.Package}.min.js.map`;
808
+ await fs.writeFile(minifiedPath, code, { encoding: "utf8" });
809
+ if (minifyResult.map !== void 0) await fs.writeFile(minifiedPath + ".map", typeof minifyResult.map === "string" ? minifyResult.map : JSON.stringify(minifyResult.map), { encoding: "utf8" });
810
+ }
811
+ if (location.path.includes("Basics") && buildResult.declarations !== void 0) {
812
+ await fs.mkdir(path.join(workspace.path, "lib"), { recursive: true });
813
+ reporter.log("Copying basics definition file to the lib folder");
814
+ await fs.writeFile(path.join(workspace.path, "lib", `${manifest.Package}.d.ts`), buildResult.declarations, { encoding: "utf8" });
815
+ }
816
+ }
817
+ function createVersionLogBuildParticipant(manifest) {
818
+ return (env) => {
819
+ env.onBuildStart();
820
+ const parsedVersion = manifest.Version !== void 0 ? PackageVersion.extractFromLine(manifest.Version) : void 0;
821
+ let logText;
822
+ if (parsedVersion !== void 0) logText = parsedVersion.toDescriptionString(manifest.Package);
823
+ else logText = manifest.Package;
824
+ logText += ".";
825
+ if (manifest.Copyright !== void 0) logText += " " + manifest.Copyright;
826
+ env.onBuildEnd({
827
+ type: "success",
828
+ artefacts: { js: `console.log(${JSON.stringify(logText)})` }
829
+ });
830
+ return { destroy: () => {} };
831
+ };
832
+ }
833
+ function createBannerCommentBuildParticipant(options) {
834
+ return (env) => {
835
+ env.onBuildStart();
836
+ const banner = createBannerComment(options);
837
+ env.onBuildEnd({
838
+ type: "success",
839
+ artefacts: {
840
+ js: banner ?? "",
841
+ declarations: banner ?? ""
842
+ }
843
+ });
844
+ return { destroy: () => {} };
845
+ };
846
+ }
847
+ async function ensureTsConfig(location) {
848
+ const tsconfigPath = path.join(location.scriptsDir, "tsconfig.json");
849
+ try {
850
+ const content = JSON.parse(await fs.readFile(tsconfigPath, "utf8"));
851
+ if (applyTsConfigOptions(content)) await fs.writeFile(tsconfigPath, JSON.stringify(content, void 0, " "), "utf8");
852
+ return ts.parseJsonConfigFileContent(content, ts.sys, location.scriptsDir);
853
+ } catch (err) {
854
+ if (!isErrorENOENT(err)) throw err;
855
+ const content = {};
856
+ applyTsConfigOptions(content);
857
+ await fs.writeFile(tsconfigPath, JSON.stringify(content, void 0, " "), "utf8");
858
+ return ts.parseJsonConfigFileContent(content, ts.sys, location.scriptsDir);
859
+ }
860
+ }
861
+ function applyTsConfigOptions(data) {
862
+ let expectedValues;
863
+ if (data.compilerOptions?.module?.toLowerCase().startsWith("es")) expectedValues = {
864
+ target: "esnext",
865
+ lib: ["es2024", "dom"],
866
+ module: "es2015",
867
+ moduleResolution: "node"
868
+ };
869
+ else expectedValues = {
870
+ target: "es5",
871
+ lib: ["es2018", "dom"]
872
+ };
873
+ data.compilerOptions = data.compilerOptions ?? {};
874
+ data.compilerOptions.strict ??= false;
875
+ const writeToOptions = data.compilerOptions;
876
+ let changed = false;
877
+ for (const [key, value] of Object.entries(expectedValues)) {
878
+ const currentValue = writeToOptions[key];
879
+ switch (typeof value) {
880
+ case "string":
881
+ case "number":
882
+ case "boolean":
883
+ if (value !== currentValue) {
884
+ changed = true;
885
+ writeToOptions[key] = value;
886
+ }
887
+ break;
888
+ case "object":
889
+ if (Array.isArray(value) && (!Array.isArray(currentValue) || value.length !== currentValue.length || value.some((item, index) => item !== currentValue[index]))) {
890
+ changed = true;
891
+ writeToOptions[key] = value;
892
+ }
893
+ break;
894
+ }
895
+ }
896
+ return changed;
897
+ }
898
+ function sortPackagesByBuildOrder(folders) {
899
+ const packages = Array.from(folders).reduce((acc, location) => {
900
+ const data = readPackageNpmManifest(location);
901
+ if (data !== void 0) acc[data.name] = {
902
+ data,
903
+ location
904
+ };
905
+ else acc[location.path] = {
906
+ data: void 0,
907
+ location
908
+ };
909
+ return acc;
910
+ }, {});
911
+ const sortedPackages = toposort(Object.getOwnPropertyNames(packages).reduce((acc, packageName) => {
912
+ const packageData = packages[packageName];
913
+ if (packageData.data === void 0) acc[packageName] = [];
914
+ else acc[packageName] = Object.getOwnPropertyNames({
915
+ ...packageData.data.devDependencies,
916
+ ...packageData.data.dependencies,
917
+ ...packageData.data.peerDependencies
918
+ }).filter((packageName) => packages[packageName] !== void 0);
919
+ return acc;
920
+ }, {}));
921
+ const result = [];
922
+ for (const packageName of sortedPackages) {
923
+ const location = packages[packageName].location;
924
+ if (readPackageCreatorManifest(location).Package.endsWith(".Basics")) result.unshift(location);
925
+ else result.push(location);
926
+ }
927
+ return result;
928
+ }
929
+ function createBannerComment(banner) {
930
+ const bannerParts = [];
931
+ if (banner.text) bannerParts.push(" * " + banner.text);
932
+ {
933
+ const details = [];
934
+ if (banner.version) details.push(`Version: ${banner.version}`);
935
+ if (banner.commit) if (banner.commitDirty) details.push(`Commit: ${banner.commit} (dirty)`);
936
+ else details.push(`Commit: ${banner.commit}`);
937
+ if (banner.date) details.push(`Date: ${banner.date.toISOString()}`);
938
+ const detailsText = details.map((line) => ` * ${line}`).join("\n");
939
+ if (detailsText) bannerParts.push(detailsText);
940
+ }
941
+ const bannerText = bannerParts.join("\n\n");
942
+ if (bannerText) return `/*
943
+ ${bannerText}
944
+ *
945
+ * @preserve
946
+ */`;
947
+ }
948
+ //#endregion
949
+ //#region src/lib/git.ts
950
+ const getVersionInformationFromGit = async (workspaceLocation, packageLocation) => {
951
+ try {
952
+ const git = simpleGit({ baseDir: workspaceLocation.path });
953
+ const dirty = (await git.diffSummary()).files.some((file) => {
954
+ if (file.file.toLowerCase().includes("releases") || file.file.toLowerCase().endsWith("version.ts") || file.file.toLowerCase().endsWith("package.json")) return false;
955
+ const fullPath = path.resolve(workspaceLocation.path, file.file);
956
+ return !path.relative(packageLocation.path, fullPath).startsWith("..");
957
+ });
958
+ const log = await git.log({ maxCount: 1 });
959
+ return {
960
+ commit: !log.latest?.hash ? void 0 : log.latest.hash.substring(0, 7),
961
+ dirty,
962
+ commitDate: log.latest?.date
963
+ };
964
+ } catch (err) {
965
+ return {};
966
+ }
967
+ };
968
+ //#endregion
969
+ //#region src/lib/banner.ts
970
+ const getWorkspaceBannerText = (manifest) => {
971
+ let bannerText = manifest?.packager?.banner;
972
+ if (bannerText) {
973
+ const match = bannerText.match(/Copyright \(C\) (\d+)( ?- ?(\d+))?/);
974
+ if (match !== null) {
975
+ const startYear = parseInt(match[1]);
976
+ const endYear = (/* @__PURE__ */ new Date()).getFullYear();
977
+ if (startYear !== endYear) bannerText = bannerText.replace(match[0], `Copyright (C) ${startYear} - ${endYear}`);
978
+ else bannerText = bannerText.replace(match[0], `Copyright (C) ${startYear}`);
979
+ }
980
+ }
981
+ return bannerText;
982
+ };
983
+ //#endregion
984
+ //#region src/lib/parseVersion.ts
985
+ const parseVersionFromString = (input) => {
986
+ if (input === void 0) throw new Error(`Can not parse version from undefined`);
987
+ let match;
988
+ let major;
989
+ let minor;
990
+ let patch;
991
+ let build;
992
+ let preReleaseType;
993
+ let preReleaseNumber;
994
+ if ((match = input.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)(-([^\.]+)\.(\d+))?/)) !== null) [, major, minor, patch, build, preReleaseType, preReleaseNumber] = match;
995
+ else if ((match = input.match(/(\d+)\.(\d+)\.(\d+)(-([^\.]+)\.(\d+))?/)) !== null) [, major, minor, patch, , preReleaseType, preReleaseNumber] = match;
996
+ if (match === null) throw new Error(`Could not parse version from input: ${input}`);
997
+ let preRelease = void 0;
998
+ let buildNumber = 100;
999
+ if (preReleaseType && preReleaseNumber) preRelease = {
1000
+ type: preReleaseType,
1001
+ version: parseInt(preReleaseNumber)
1002
+ };
1003
+ if (build) buildNumber = Number(build);
1004
+ else if (input) {
1005
+ const descriptionMatch = input.match(/(\d+)\)$/);
1006
+ if (descriptionMatch) buildNumber = parseInt(descriptionMatch[1]);
1007
+ }
1008
+ return new PackageVersion(parseInt(major), parseInt(minor), parseInt(patch), preRelease, buildNumber);
1009
+ };
1010
+ const parseVersionFromNumericVersion = (version) => {
1011
+ return new PackageVersion(Math.floor(version / 1e9), Math.floor(version % 1e9 / 1e6), Math.floor(version % 1e6 / 1e3), void 0, version % 1e3);
1012
+ };
1013
+ //#endregion
1014
+ //#region src/lib/versionFile.ts
1015
+ const logRegex = /console\.log\(\s*"([\w\s\.\(\)]+)\ *Copyright[\w\s\(\)\.]+(\d{4}|\d{4} - \d{4})([\w\s\(\)\.]+)?",?\s*\)/i;
1016
+ const currentYear = new Date(Date.now()).getFullYear();
1017
+ function getVersionFileHandler(location) {
1018
+ const filePath = path.join(location.scriptsDir, "Version.ts");
1019
+ function invalidVersionFile(versionFile, exists) {
1020
+ return {
1021
+ exists,
1022
+ write: (name, newVersion) => {
1023
+ if (fs$1.readdirSync(location.scriptsDir).filter((file) => file.endsWith(".ts")).length > 0) return createVersionFileWriter([currentYear], "")(name, newVersion);
1024
+ },
1025
+ reset: () => {
1026
+ if (versionFile !== void 0) fs$1.writeFileSync(filePath, versionFile, { encoding: "utf8" });
1027
+ else try {
1028
+ fs$1.rmSync(filePath);
1029
+ } catch (err) {
1030
+ if (!isErrorENOENT(err)) throw err;
1031
+ }
1032
+ }
1033
+ };
1034
+ }
1035
+ function createVersionFileWriter(copyright = [currentYear], copyrightStuff = "") {
1036
+ return (name, newVersion) => {
1037
+ const result = `console.log("${newVersion.toDescriptionString(name)}. Copyright (C) ${createYearString(copyright)}${copyrightStuff}");`;
1038
+ fs$1.writeFileSync(filePath, result, { encoding: "utf-8" });
1039
+ };
1040
+ }
1041
+ let rawVersionFile = readStringFromFileOrUndefined(filePath);
1042
+ if (rawVersionFile === void 0) return invalidVersionFile(rawVersionFile, false);
1043
+ const versionFile = rawVersionFile.replace(/\n/g, "");
1044
+ const match = versionFile.match(logRegex);
1045
+ if (!match) return invalidVersionFile(versionFile, true);
1046
+ const [_full, _description, copyright, copyrightStuff] = match;
1047
+ const copyrightYears = copyright.match(/^(\d+)( ?- ?(\d+))?$/);
1048
+ let years;
1049
+ if (copyrightYears === null) years = [currentYear];
1050
+ else years = [Number(copyrightYears[1]), currentYear];
1051
+ return {
1052
+ exists: true,
1053
+ write: createVersionFileWriter(years, copyrightStuff),
1054
+ reset: () => {
1055
+ fs$1.writeFileSync(filePath, versionFile, { encoding: "utf8" });
1056
+ }
1057
+ };
1058
+ }
1059
+ const createYearString = (years) => {
1060
+ if (years[1] === void 0 || years[0] === years[1]) return years[0].toString();
1061
+ return `${years[0]} - ${years[1]}`;
1062
+ };
1063
+ //#endregion
1064
+ //#region src/commands/publish/zip.ts
1065
+ const buildArchiveFromPublishedPackage = (location, manifest, creatorPackage) => {
1066
+ const archive = new JSZip();
1067
+ archive.file(PACKAGE_FILE, JSON.stringify(creatorPackage, null, 2));
1068
+ const index = readPublishedPackageCreatorIndex(location);
1069
+ if (index !== void 0) archive.file(INDEX_FILE, JSON.stringify(index, null, 2));
1070
+ archive.file(manifest.main, fs$1.createReadStream(path.join(location.path, manifest.main)));
1071
+ if (creatorPackage.Package === "IG.GFX.Standard") {
1072
+ const source = path.join(location.path, "Images");
1073
+ if (fs$1.existsSync(source)) {
1074
+ const images = fs$1.readdirSync(source);
1075
+ for (const file of images) {
1076
+ const { ext } = path.parse(file);
1077
+ switch (ext) {
1078
+ case ".png":
1079
+ case ".jpeg":
1080
+ case ".jpg": break;
1081
+ default: continue;
1082
+ }
1083
+ archive.file(file, fs$1.createReadStream(path.join(source, file)));
1084
+ }
1085
+ }
1086
+ }
1087
+ return archive;
1088
+ };
1089
+ const runtimeScripts = [
1090
+ "Interactor",
1091
+ "Core",
1092
+ "Mixed"
1093
+ ];
1094
+ const notRuntimeScripts = ["Context", "Evaluator"];
1095
+ const buildArchiveFromPackage = async (reporter, packageLocation, data, binDir, minified = true) => {
1096
+ const { domain } = parseCreatorPackageName(data);
1097
+ const scriptDirectories = [packageLocation.path, packageLocation.scriptsDir];
1098
+ if (data.Package === "IG.GFX.Standard") {
1099
+ reporter.log(`Including Images folder`);
1100
+ scriptDirectories.push(path.join(packageLocation.path, "Images"));
1101
+ }
1102
+ const manifest = readPackageCreatorManifest(packageLocation);
1103
+ if (manifest !== void 0) {
1104
+ if (manifest.RunTime && notRuntimeScripts.includes(manifest.Type)) {
1105
+ reporter.log("Setting script RunTime to false because of script type");
1106
+ writePackageCreatorManifest(packageLocation, {
1107
+ ...manifest,
1108
+ RunTime: false
1109
+ });
1110
+ } else if (!manifest.RunTime && runtimeScripts.includes(manifest.Type)) {
1111
+ reporter.log("Setting script RunTime to true because of script type");
1112
+ writePackageCreatorManifest(packageLocation, {
1113
+ ...manifest,
1114
+ RunTime: true
1115
+ });
1116
+ }
1117
+ }
1118
+ let libFile;
1119
+ try {
1120
+ const libFilePath = minified ? path.join(binDir, `${data.Package}.min.js`) : path.join(binDir, `${data.Package}.js`);
1121
+ libFile = fs$1.readFileSync(libFilePath, { encoding: "utf8" });
1122
+ } catch (err) {
1123
+ if (!isErrorENOENT(err)) throw err;
1124
+ }
1125
+ const archive = new JSZip();
1126
+ let library = "";
1127
+ if (libFile) library = libFile;
1128
+ if (!library) library = `/* This file is part of the ${domain} Data Packages.
1129
+ * Copyright (C) ${new Date(Date.now()).getFullYear()} intelligentgraphics. All Rights Reserved. */`;
1130
+ archive.file(`${data.Package}.js`, library);
1131
+ archive.file(PACKAGE_FILE, JSON.stringify(data, null, 2));
1132
+ const creatorIndex = readPackageCreatorIndex(packageLocation);
1133
+ if (creatorIndex !== void 0) archive.file(INDEX_FILE, JSON.stringify(creatorIndex, null, 2));
1134
+ for (const directory of scriptDirectories) try {
1135
+ for (const file of fs$1.readdirSync(directory)) {
1136
+ const { ext } = path.parse(file);
1137
+ switch (ext) {
1138
+ case ".png":
1139
+ case ".jpeg":
1140
+ case ".jpg": break;
1141
+ default: continue;
1142
+ }
1143
+ archive.file(file, fs$1.createReadStream(path.join(directory, file)));
1144
+ }
1145
+ } catch (err) {
1146
+ reporter.error(`Script directory "${directory}" does not exist`);
1147
+ }
1148
+ return archive;
1149
+ };
1150
+ //#endregion
1151
+ //#region src/lib/assetServiceSessionManager.ts
1152
+ const createAssetServiceSessionManager = async (params) => {
1153
+ const targetSession = await assetService_exports.startSession(params);
1154
+ let basicsSession;
1155
+ return {
1156
+ getBasicsSession: async () => {
1157
+ if (targetSession.subDomain === "Basics") return targetSession;
1158
+ if (basicsSession === void 0) basicsSession = await assetService_exports.startSession({
1159
+ ...params,
1160
+ subDomain: "Basics"
1161
+ });
1162
+ return basicsSession;
1163
+ },
1164
+ getTargetSession: () => targetSession,
1165
+ destroy: async () => {
1166
+ await assetService_exports.closeSession(targetSession);
1167
+ if (basicsSession !== void 0) await assetService_exports.closeSession(basicsSession);
1168
+ }
1169
+ };
1170
+ };
1171
+ //#endregion
1172
+ //#region src/lib/dependencySync.ts
1173
+ const synchronizeDependencies = async (workspaceLocation, creatorPackage, sessionManager, prompter, reporter, logUpToDate = false) => {
1174
+ const libraries = determineWorkspaceIGLibraries(workspaceLocation);
1175
+ if (libraries.length === 0) return true;
1176
+ const targetSession = sessionManager.getTargetSession();
1177
+ const uploadedPackages = (await assetService_exports.getExistingPackages(targetSession)).map((entry) => {
1178
+ let version;
1179
+ try {
1180
+ version = parseVersionFromNumericVersion(entry.numericVersion);
1181
+ } catch (err) {
1182
+ throw new Error(`Encountered invalid format for version ${entry.numericVersion}`);
1183
+ }
1184
+ if (version.buildNumber < 100) version.preRelease = {
1185
+ type: "beta",
1186
+ version: version.buildNumber
1187
+ };
1188
+ else if (version.buildNumber > 100) version.preRelease = {
1189
+ type: "patch",
1190
+ version: version.buildNumber - 100
1191
+ };
1192
+ return {
1193
+ ...entry,
1194
+ version
1195
+ };
1196
+ });
1197
+ for (const libraryLocation of libraries) {
1198
+ const libraryManifest = readPublishedPackageNpmManifest(libraryLocation);
1199
+ const libraryCreatorPackage = readPublishedPackageCreatorManifest(libraryLocation);
1200
+ if (libraryCreatorPackage === void 0 || libraryManifest.main === void 0 || libraryCreatorPackage.Package === creatorPackage?.Package) continue;
1201
+ const libraryVersion = PackageVersion.extractFromLine(libraryManifest.version);
1202
+ if (libraryVersion.preRelease) {
1203
+ libraryVersion.buildNumber = libraryVersion.preRelease.version;
1204
+ libraryVersion.preRelease = void 0;
1205
+ } else libraryVersion.buildNumber = 100;
1206
+ let uploadedPackageInBasics;
1207
+ let uploadedPackageInTarget;
1208
+ for (const uploadedPackage of uploadedPackages) if (uploadedPackage.scope === libraryCreatorPackage.Package) if (uploadedPackage.support) uploadedPackageInBasics = uploadedPackage;
1209
+ else uploadedPackageInTarget = uploadedPackage;
1210
+ const validInBasics = uploadedPackageInBasics !== void 0 && !uploadedPackageInBasics.version.isLesserThan(libraryVersion);
1211
+ const validInTarget = uploadedPackageInTarget !== void 0 && !uploadedPackageInTarget.version.isLesserThan(libraryVersion);
1212
+ if (validInBasics || validInTarget) {
1213
+ if (targetSession.subDomain !== "Basics" && uploadedPackageInBasics !== void 0 && uploadedPackageInTarget !== void 0) reporter.log(`Package ${libraryCreatorPackage.Package} is uploaded both for Basics and ${targetSession.subDomain}. The package within ${targetSession.subDomain} will be used.`);
1214
+ if (logUpToDate) reporter.log(`Package ${libraryCreatorPackage.Package} is already uploaded with the required version ${libraryVersion.toVersionString({})}`);
1215
+ continue;
1216
+ }
1217
+ const possibleTargets = [];
1218
+ if (uploadedPackageInBasics) {
1219
+ const version = uploadedPackageInBasics.version.toVersionString({ buildNumber: true });
1220
+ possibleTargets.push({
1221
+ value: "Basics",
1222
+ name: `Basics (Current: ${version})`
1223
+ });
1224
+ } else possibleTargets.push({
1225
+ value: "Basics",
1226
+ name: "Basics (Current: None)"
1227
+ });
1228
+ if (targetSession.subDomain !== "Basics") if (uploadedPackageInTarget) {
1229
+ const version = uploadedPackageInTarget.version.toVersionString({ buildNumber: true });
1230
+ possibleTargets.push({
1231
+ value: targetSession.subDomain,
1232
+ name: `${targetSession.subDomain} (Current: ${version})`
1233
+ });
1234
+ } else possibleTargets.push({
1235
+ value: targetSession.subDomain,
1236
+ name: `${targetSession.subDomain} (Current: None)`
1237
+ });
1238
+ const libraryVersionString = libraryVersion.toVersionString({ buildNumber: true });
1239
+ const uploadTargetScope = await prompter.ask({
1240
+ message: `Version ${libraryVersionString} of dependency ${libraryCreatorPackage.Package} is required but not available. Please select a subdomain to upload the required dependency version to`,
1241
+ options: [...possibleTargets, {
1242
+ name: "Skip upload",
1243
+ value: "Skip"
1244
+ }],
1245
+ default: possibleTargets[0].value
1246
+ });
1247
+ if (uploadTargetScope === "Skip") continue;
1248
+ const archive = buildArchiveFromPublishedPackage(libraryLocation, libraryManifest, libraryCreatorPackage);
1249
+ const newVersionString = libraryVersion.toVersionString({ buildNumber: true });
1250
+ const session = uploadTargetScope === "Basics" ? await sessionManager.getBasicsSession() : targetSession;
1251
+ reporter.log(`Uploading package ${libraryCreatorPackage.Package} with version ${newVersionString} to ${session.domain}.${session.subDomain}`);
1252
+ await assetService_exports.uploadPackageFromBuffer(session, {
1253
+ name: libraryCreatorPackage.Package,
1254
+ version: newVersionString
1255
+ }, await archive.generateAsync({ type: "nodebuffer" }));
1256
+ }
1257
+ };
1258
+ //#endregion
1259
+ //#region src/commands/publish/index.ts
1260
+ const execAsync = promisify(exec);
1261
+ const releaseFolder = async (options) => {
1262
+ const workspace = options.workspace;
1263
+ const location = options.directory;
1264
+ const versionFile = getVersionFileHandler(location);
1265
+ const packageDescription = readPackageCreatorManifest(location);
1266
+ const fullPackageName = packageDescription.Package;
1267
+ const reporter = options.reporter ?? createPackageScopedReporter(consoleReporter, packageDescription.Package);
1268
+ const { domain, subdomain } = parseCreatorPackageName(packageDescription);
1269
+ const publishDomain = options.domain ?? domain;
1270
+ const publishSubdomain = options.subdomain ?? subdomain;
1271
+ const sharedPackageJson = readWorkspaceNpmManifest(workspace);
1272
+ let newVersion;
1273
+ try {
1274
+ newVersion = parseVersionFromString(options.newVersion);
1275
+ } catch (err) {
1276
+ throw new Error(`Please enter a version in this format 1.0.0.100`);
1277
+ }
1278
+ packageDescription.Version = newVersion.toVersionString({ buildNumber: true });
1279
+ writePackageCreatorManifest(location, packageDescription);
1280
+ if (newVersion.buildNumber < 100) newVersion.preRelease = {
1281
+ type: "beta",
1282
+ version: newVersion.buildNumber
1283
+ };
1284
+ else if (newVersion.buildNumber > 100) newVersion.preRelease = {
1285
+ type: "patch",
1286
+ version: newVersion.buildNumber - 100
1287
+ };
1288
+ const binDir = options.outDir ?? getWorkspaceOutputPath(workspace);
1289
+ await fs.mkdir(binDir, { recursive: true });
1290
+ let assetServerPackageDetails;
1291
+ let packageNameWithVersion;
1292
+ {
1293
+ const versionWithoutPrelease = newVersion.clone();
1294
+ versionWithoutPrelease.preRelease = void 0;
1295
+ const newVersionString = versionWithoutPrelease.toVersionString({ buildNumber: true });
1296
+ packageNameWithVersion = `${packageDescription.Package}_${newVersionString}`;
1297
+ assetServerPackageDetails = {
1298
+ name: packageDescription.Package,
1299
+ version: newVersionString
1300
+ };
1301
+ }
1302
+ let zipFilePath = path.join(binDir, packageNameWithVersion + ".zip");
1303
+ let uploadable = { getStream: () => createReadStream(zipFilePath) };
1304
+ try {
1305
+ if (options.pushOnly) {
1306
+ if (await fs.stat(zipFilePath).catch((err) => {
1307
+ if (isErrorENOENT(err)) return false;
1308
+ return Promise.reject(err);
1309
+ })) throw new Error(`Expected a zip file to exist at path ${zipFilePath} since pushOnly is specified`);
1310
+ } else {
1311
+ const gitVersionInformation = await getVersionInformationFromGit(workspace, location);
1312
+ if (versionFile.exists) versionFile.write(fullPackageName, newVersion);
1313
+ const bannerText = sharedPackageJson !== void 0 ? getWorkspaceBannerText(sharedPackageJson) : void 0;
1314
+ await buildFolders({
1315
+ ...options,
1316
+ packages: [location],
1317
+ banner: options.banner ? {
1318
+ text: bannerText,
1319
+ commit: gitVersionInformation.commit,
1320
+ commitDirty: gitVersionInformation.dirty,
1321
+ version: newVersion.toVersionString({ buildNumber: true }),
1322
+ date: new Date(Date.now())
1323
+ } : void 0,
1324
+ preparedReporter: reporter
1325
+ });
1326
+ newVersion.preRelease = void 0;
1327
+ try {
1328
+ await fs.rm(zipFilePath);
1329
+ } catch (err) {
1330
+ if (!isErrorENOENT(err)) throw err;
1331
+ }
1332
+ if (readPackageAnimationList(location).length > 0) {
1333
+ if (!readWorkspaceNpmManifest(workspace).dependencies?.["@intelligentgraphics/3d.ig.gfx.standard"]) {
1334
+ if (await options.prompter.confirm(`The IG.GFX.Standard package should be added as a dependency to provide the 'AnimationInteractor' used to display animations. Do you wish to add it now?`)) {
1335
+ await execAsync(`npm install @intelligentgraphics/3d.ig.gfx.standard`, {
1336
+ encoding: "utf-8",
1337
+ cwd: workspace.path
1338
+ });
1339
+ await execAsync(`npm run postinstall`, { cwd: workspace.path });
1340
+ }
1341
+ }
1342
+ }
1343
+ reporter.log(`Creating zip file`);
1344
+ const archive = await buildArchiveFromPackage(reporter, location, packageDescription, binDir, options.minimize);
1345
+ try {
1346
+ const zipOutputStream = createWriteStream(zipFilePath);
1347
+ await pipeline(archive.generateNodeStream(), zipOutputStream);
1348
+ } catch (err) {
1349
+ if (isErrorEACCES(err) || isErrorEPERM(err)) {
1350
+ reporter.log(`Could not create zip file in the bin directory because of a permissions error. Only using it in-memory`);
1351
+ uploadable = { getStream: () => archive.generateNodeStream() };
1352
+ } else throw err;
1353
+ }
1354
+ }
1355
+ if (!options.noUpload) {
1356
+ if (!options.authentication) throw new Error(`Expected authentication to be available`);
1357
+ reporter.log(`Opening connection to IG.Asset.Server`);
1358
+ const sessionManager = await createAssetServiceSessionManager({
1359
+ url: options.service,
1360
+ address: options.address,
1361
+ domain: publishDomain,
1362
+ subDomain: publishSubdomain,
1363
+ authentication: options.authentication
1364
+ });
1365
+ try {
1366
+ if (!options.skipDependencies) try {
1367
+ await synchronizeDependencies(workspace, packageDescription, sessionManager, options.prompter, reporter);
1368
+ } catch (err) {
1369
+ reporter.error(`Failed to synchronize dependencies for ${packageDescription.Package}`, err instanceof Error ? err : new Error(String(err)));
1370
+ }
1371
+ reporter.log(`Uploading package to ${publishDomain}.${publishSubdomain}`);
1372
+ await assetService_exports.uploadPackageFromBuffer(sessionManager.getTargetSession(), assetServerPackageDetails, await buffer(uploadable.getStream()));
1373
+ } finally {
1374
+ await sessionManager.destroy().catch((err) => {
1375
+ reporter.error(`Failed to close IG.Asset.Server session(s)`, err);
1376
+ });
1377
+ }
1378
+ }
1379
+ } catch (err) {
1380
+ versionFile.reset();
1381
+ throw err;
1382
+ }
1383
+ if (newVersion.buildNumber >= 100 && !options.pushOnly) {
1384
+ reporter.error("Copying zip to releases folder");
1385
+ const zipFileName = `${packageNameWithVersion}.zip`;
1386
+ const releasesPath = getPackageReleasesDirectory(location);
1387
+ await fs.mkdir(releasesPath, { recursive: true });
1388
+ await pipeline(uploadable.getStream(), createWriteStream(path.join(releasesPath, zipFileName)));
1389
+ }
1390
+ };
1391
+ //#endregion
1392
+ //#region src/commands/generateIndex.ts
1393
+ /**
1394
+ * Extracts and returns script array for _Index.json from a src folder
1395
+ *
1396
+ * @param folderPath path to a src folder
1397
+ */
1398
+ function generateIndex({ location, ignore = [], strictOptional }) {
1399
+ const arr = [];
1400
+ const existingIndex = readPackageCreatorIndex(location) ?? [];
1401
+ const manifest = readPackageCreatorManifest(location);
1402
+ const compilerOptions = readScriptPackageTSConfig(location).options;
1403
+ const isModule = compilerOptions.module === ts.ModuleKind.ES2015 || compilerOptions.module === ts.ModuleKind.ESNext;
1404
+ if (strictOptional === void 0) strictOptional = compilerOptions.strict === true || compilerOptions.strictNullChecks === true;
1405
+ const files = getPackageTypescriptFiles(location).filter((path) => !ignore.some((suffix) => path.endsWith(suffix)));
1406
+ let program;
1407
+ let rootNamespace;
1408
+ if (isModule) {
1409
+ const entryFilePath = resolveScriptPackageEntryModule(location, manifest);
1410
+ if (entryFilePath === void 0) throw new Error(`Could not resolve entry module`);
1411
+ const host = ts.createCompilerHost({}, true);
1412
+ program = ts.createProgram([entryFilePath], {
1413
+ allowJs: true,
1414
+ ...compilerOptions
1415
+ }, host);
1416
+ const entryFile = program.getSourceFile(entryFilePath);
1417
+ if (entryFile === void 0) throw new Error(`Failed to find entry module`);
1418
+ rootNamespace = resolveNamespaces(entryFile, program, host, program.getTypeChecker(), manifest.Scope ?? manifest.Package);
1419
+ } else program = ts.createProgram(files, { allowJs: true });
1420
+ const typeChecker = program.getTypeChecker();
1421
+ files.forEach((file) => {
1422
+ const sourceFile = program.getSourceFile(file);
1423
+ if (sourceFile === void 0) return;
1424
+ const namespace = rootNamespace === void 0 ? void 0 : findNamespaceByMemberSourceFile(rootNamespace, sourceFile);
1425
+ for (const scriptingClass of findScriptingClasses(sourceFile)) {
1426
+ if (scriptingClass.node.name === void 0) throw new Error(`Expected ${scriptingClass.type} class to have a name`);
1427
+ let name;
1428
+ if (isModule && namespace !== void 0) name = `${resolveNamespaceFullName(namespace)}.${scriptingClass.node.name.text}`;
1429
+ else name = typeChecker.getFullyQualifiedName(typeChecker.getSymbolAtLocation(scriptingClass.node.name));
1430
+ const parameterDeclaration = getScriptingClassParameterdeclaration(scriptingClass);
1431
+ const parametersType = parameterDeclaration === void 0 ? void 0 : typeChecker.getTypeAtLocation(parameterDeclaration);
1432
+ if (parametersType === void 0) console.log(`Failed to find parameters type declaration for ${scriptingClass.type} ${name}. Skipping parameter list generation`);
1433
+ const existingIndexEntry = existingIndex.find((entry) => entry.Name === name);
1434
+ const obj = {
1435
+ Name: name,
1436
+ Description: existingIndexEntry?.Description ?? name,
1437
+ Type: scriptingClass.type === "evaluator" ? "Evaluator" : "Interactor",
1438
+ Parameters: []
1439
+ };
1440
+ const dict = getTagDict(ts.getJSDocTags(scriptingClass.node));
1441
+ if (dict.summary) obj.Description = dict.summary;
1442
+ else {
1443
+ const comment = typeChecker.getTypeAtLocation(scriptingClass.node).symbol.getDocumentationComment(typeChecker).map((comment) => comment.text).join(" ");
1444
+ if (comment) obj.Description = comment;
1445
+ }
1446
+ if (parametersType !== void 0) {
1447
+ obj.Parameters = parseParametersList(typeChecker.getPropertiesOfType(parametersType), strictOptional);
1448
+ if (obj.Parameters.length === 0 && parametersType.getStringIndexType() !== void 0) obj.Parameters = existingIndexEntry?.Parameters ?? [];
1449
+ } else if (existingIndexEntry !== void 0) obj.Parameters = existingIndexEntry.Parameters;
1450
+ arr.push(obj);
1451
+ }
1452
+ });
1453
+ arr.sort((a, b) => a.Name.localeCompare(b.Name));
1454
+ writePackageCreatorIndex(location, arr);
1455
+ }
1456
+ function capitalizeFirstLetter(string) {
1457
+ return string?.charAt(0).toUpperCase() + string?.slice(1);
1458
+ }
1459
+ const parseDefault = (value, type) => {
1460
+ const uType = capitalizeFirstLetter(type);
1461
+ if (value === "null") return null;
1462
+ switch (uType) {
1463
+ case "LengthM":
1464
+ case "ArcDEG":
1465
+ case "Float": return parseFloat(value);
1466
+ case "Integer":
1467
+ case "Int": return parseInt(value);
1468
+ case "Boolean":
1469
+ case "Bool": return value === "true";
1470
+ default: return value.replace(/^"/, "").replace(/"$/, "");
1471
+ }
1472
+ };
1473
+ const parseTypeFromName = (name) => {
1474
+ const parts = name.split(".");
1475
+ const identifier = parts[parts.length - 1];
1476
+ switch (identifier) {
1477
+ case "LengthM":
1478
+ case "ArcDEG":
1479
+ case "Float":
1480
+ case "Integer": return identifier;
1481
+ case "GeometryReference": return "Geometry";
1482
+ case "MaterialReference": return "Material";
1483
+ case "AnimationReference": return "Animation";
1484
+ case "InteractorReference": return "Interactor";
1485
+ case "EvaluatorReference": return "Evaluator";
1486
+ case "String":
1487
+ case "string": return "String";
1488
+ case "number":
1489
+ case "Number": return "Float";
1490
+ case "boolean":
1491
+ case "Boolean": return "Boolean";
1492
+ }
1493
+ };
1494
+ const parseParametersList = (properties, strictOptional) => {
1495
+ return properties.map((symbol, i) => {
1496
+ const parameter = {
1497
+ Name: symbol.name,
1498
+ Description: void 0,
1499
+ Type: "String",
1500
+ Default: void 0,
1501
+ DisplayIndex: i + 1
1502
+ };
1503
+ if (parameter.Name.length > 45) throw new Error(`Parameter name length >45 '${parameter.Name}'`);
1504
+ let declaration = symbol.getDeclarations()?.[0];
1505
+ let documentationComment = symbol.getDocumentationComment(void 0);
1506
+ let checkLinksSymbol = symbol;
1507
+ while (checkLinksSymbol !== void 0 && declaration === void 0) {
1508
+ const links = checkLinksSymbol.links;
1509
+ if (links?.syntheticOrigin) {
1510
+ declaration = links.syntheticOrigin.getDeclarations()?.[0];
1511
+ if (documentationComment.length === 0) documentationComment = links.syntheticOrigin.getDocumentationComment(void 0);
1512
+ checkLinksSymbol = links.syntheticOrigin;
1513
+ }
1514
+ }
1515
+ if (declaration !== void 0) {
1516
+ const dict = getTagDict(ts.getJSDocTags(declaration));
1517
+ if (dict.summary) parameter.Description = dict.summary;
1518
+ else {
1519
+ const comment = documentationComment.map((comment) => comment.text).join(" ");
1520
+ if (comment) parameter.Description = comment;
1521
+ }
1522
+ if (dict.creatorType) parameter.Type = dict.creatorType;
1523
+ else {
1524
+ const propertySignature = declaration;
1525
+ if (propertySignature.type !== void 0) {
1526
+ const parsedType = parseTypeFromName(propertySignature.type.getText());
1527
+ if (parsedType !== void 0) parameter.Type = parsedType;
1528
+ }
1529
+ }
1530
+ if (dict.default) parameter.Default = parseDefault(dict.default, parameter.Type);
1531
+ if (strictOptional && declaration.kind === ts.SyntaxKind.PropertySignature) {
1532
+ if (declaration.questionToken === void 0) parameter.Required = true;
1533
+ }
1534
+ }
1535
+ return parameter;
1536
+ });
1537
+ };
1538
+ function getTagDict(tags) {
1539
+ const dict = {};
1540
+ for (const tag of tags) dict[tag.tagName.text] = tag.comment;
1541
+ return dict;
1542
+ }
1543
+ const getScriptingClassParameterdeclaration = (scriptingClass) => {
1544
+ for (const member of scriptingClass.node.members) {
1545
+ if (ts.isMethodDeclaration(member)) for (let index = 0; index < member.parameters.length; index++) {
1546
+ const parameter = member.parameters[index];
1547
+ if (isScriptingClassParameterDeclaration(scriptingClass, member, index)) return parameter;
1548
+ }
1549
+ if (ts.isConstructorDeclaration(member)) for (let index = 0; index < member.parameters.length; index++) {
1550
+ const parameter = member.parameters[index];
1551
+ if (isScriptingClassParameterDeclaration(scriptingClass, member, index)) return parameter;
1552
+ }
1553
+ }
1554
+ };
1555
+ const isScriptingClassParameterDeclaration = (scriptingClass, memberNode, parameterIndex) => {
1556
+ if (scriptingClass.type === "evaluator") return memberNode?.name?.getText() == "Create" && parameterIndex === 2;
1557
+ if (scriptingClass.type === "interactor") return memberNode.kind === ts.SyntaxKind.Constructor && parameterIndex === 0;
1558
+ return false;
1559
+ };
1560
+ /**
1561
+ * Finds interactors and evaluators within a script file
1562
+ *
1563
+ * @param {ts.Node} node
1564
+ * @return {*}
1565
+ */
1566
+ function* findScriptingClasses(node) {
1567
+ for (const child of node.getChildren()) {
1568
+ if (!ts.isClassDeclaration(child)) {
1569
+ yield* findScriptingClasses(child);
1570
+ continue;
1571
+ }
1572
+ const scriptingClass = detectScriptingClass(child);
1573
+ if (scriptingClass !== void 0) yield scriptingClass;
1574
+ }
1575
+ }
1576
+ const detectScriptingClass = (node) => {
1577
+ if (node.heritageClauses?.some((clause) => {
1578
+ if (clause.token !== ts.SyntaxKind.ExtendsKeyword && clause.token !== ts.SyntaxKind.ImplementsKeyword) return false;
1579
+ return clause.types.some((type) => type.getText().includes("Evaluator"));
1580
+ })) return {
1581
+ node,
1582
+ type: "evaluator"
1583
+ };
1584
+ if (node.heritageClauses?.some((clause) => {
1585
+ if (clause.token !== ts.SyntaxKind.ExtendsKeyword) return false;
1586
+ return clause.types.some((type) => type.getText().includes("Interactor"));
1587
+ })) return {
1588
+ node,
1589
+ type: "interactor"
1590
+ };
1591
+ };
1592
+ //#endregion
1593
+ export { buildFolders, buildFoldersWatch, createAssetServiceSessionManager, generateIndex, isScriptPackageModules, readScriptPackageTSConfig, releaseFolder, resolveScriptPackageEntryModule, synchronizeDependencies };
1594
+
1595
+ //# sourceMappingURL=lib.js.map