@intelligentgraphics/ig.gfx.packager 3.1.0-alpha.1 → 3.1.0-alpha.2

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 (37) hide show
  1. package/build/bin.mjs +1 -1
  2. package/build/{cli-fec9c069.mjs → cli-CuiqZ39_.mjs} +87 -82
  3. package/build/cli-CuiqZ39_.mjs.map +1 -0
  4. package/build/{dependencies-d870016d.mjs → dependencies-BiYItaVS.mjs} +2 -2
  5. package/build/{dependencies-d870016d.mjs.map → dependencies-BiYItaVS.mjs.map} +1 -1
  6. package/build/{generateIndex-dd0b4563.mjs → generateIndex-hg6jRXQv.mjs} +96 -83
  7. package/build/generateIndex-hg6jRXQv.mjs.map +1 -0
  8. package/build/{generateParameterType-9a671e36.mjs → generateParameterType-CDjqLM4J.mjs} +3 -4
  9. package/build/{generateParameterType-9a671e36.mjs.map → generateParameterType-CDjqLM4J.mjs.map} +1 -1
  10. package/build/{index-0caf1a6e.mjs → index-B2kXo6K7.mjs} +343 -119
  11. package/build/index-B2kXo6K7.mjs.map +1 -0
  12. package/build/{index-7fa42d48.mjs → index-BoGrZubW.mjs} +201 -188
  13. package/build/index-BoGrZubW.mjs.map +1 -0
  14. package/build/{postinstall-81b6f0b0.mjs → postinstall-CbMUz2zy.mjs} +3 -4
  15. package/build/{postinstall-81b6f0b0.mjs.map → postinstall-CbMUz2zy.mjs.map} +1 -1
  16. package/build/{publishNpm-c985bd6e.mjs → publishNpm-CrnuTwss.mjs} +14 -11
  17. package/build/publishNpm-CrnuTwss.mjs.map +1 -0
  18. package/build/rollup-UR3DADp8.mjs +198 -0
  19. package/build/rollup-UR3DADp8.mjs.map +1 -0
  20. package/build/scripts-Bfojy_uD.mjs +48 -0
  21. package/build/scripts-Bfojy_uD.mjs.map +1 -0
  22. package/build/versionFile-DSqOw-XB.mjs +208 -0
  23. package/build/versionFile-DSqOw-XB.mjs.map +1 -0
  24. package/lib/lib.mjs +2649 -18
  25. package/package.json +20 -15
  26. package/readme.md +126 -13
  27. package/build/cli-fec9c069.mjs.map +0 -1
  28. package/build/generateIndex-dd0b4563.mjs.map +0 -1
  29. package/build/index-0caf1a6e.mjs.map +0 -1
  30. package/build/index-7fa42d48.mjs.map +0 -1
  31. package/build/publishNpm-c985bd6e.mjs.map +0 -1
  32. package/build/scripts-7ed8dff6.mjs +0 -10
  33. package/build/scripts-7ed8dff6.mjs.map +0 -1
  34. package/build/swc-9ed0f3ce.mjs +0 -60
  35. package/build/swc-9ed0f3ce.mjs.map +0 -1
  36. package/build/versionFile-cbfd3f4a.mjs +0 -380
  37. package/build/versionFile-cbfd3f4a.mjs.map +0 -1
package/lib/lib.mjs CHANGED
@@ -1,21 +1,2652 @@
1
- export { b as buildFolders, a as buildFoldersWatch, c as generateIndex, r as releaseFolder } from './lib-5a3a2112.mjs';
2
- import 'path';
3
- import 'fs/promises';
4
- import 'terser';
5
- import 'fs';
6
- import 'resolve';
1
+ import * as path from 'path';
2
+ import * as fs$1 from 'fs/promises';
3
+ import * as terser from 'terser';
4
+ import { EOL } from 'os';
5
+ import ts from 'typescript';
6
+ import * as fs from 'fs';
7
+ import { createWriteStream, createReadStream } from 'fs';
8
+ import resolve from 'resolve';
7
9
  import 'write-pkg';
8
- import 'glob';
10
+ import glob from 'glob';
9
11
  import 'write-json-file';
10
- import 'axios';
11
- import 'typescript';
12
- import 'typedoc';
13
- import 'events';
14
- import 'source-map-js';
15
- import 'ajv';
16
- import 'stream/promises';
17
- import 'child_process';
18
- import 'util';
19
- import 'simple-git';
20
- import 'jszip';
12
+ import axios, { AxiosError } from 'axios';
13
+ import typedoc from 'typedoc';
14
+ import EventEmitter from 'events';
15
+ import { SourceMapGenerator, SourceMapConsumer } from 'source-map-js';
16
+ import Ajv from 'ajv';
17
+ import { pipeline } from 'stream/promises';
18
+ import { exec } from 'child_process';
19
+ import { promisify } from 'util';
20
+ import simpleGit from 'simple-git';
21
+ import JSZip from 'jszip';
22
+ import { buffer } from 'node:stream/consumers';
23
+ import { resolveNamespaces, resolveNamespaceFullName } from '@intelligentgraphics/declarationbundler';
24
+
25
+ const stripUtf8Bom = (text)=>{
26
+ // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string
27
+ // conversion translates it to FEFF (UTF-16 BOM).
28
+ if (text.charCodeAt(0) === 0xfeff) {
29
+ return text.slice(1);
30
+ }
31
+ return text;
32
+ };
33
+
34
+ const readNpmManifest = (directory)=>{
35
+ const packageJsonPath = path.join(directory, "package.json");
36
+ const packageJson = stripUtf8Bom(fs.readFileSync(packageJsonPath, {
37
+ encoding: "utf8"
38
+ }));
39
+ return JSON.parse(packageJson);
40
+ };
41
+
42
+ const getNodeErrorCode = (error)=>{
43
+ if (error !== null && typeof error === "object" && error.code !== undefined) {
44
+ return error.code;
45
+ }
46
+ };
47
+ /**
48
+ * Permission denied: An attempt was made to access a file in a way forbidden by its file access permissions.
49
+ *
50
+ * @param {unknown} error
51
+ */ const isErrorEACCES = (error)=>getNodeErrorCode(error) === "EACCES";
52
+ /**
53
+ * No such file or directory: Commonly raised by fs operations to indicate that a component of the specified pathname does not exist. No entity (file or directory) could be found by the given path.
54
+ *
55
+ * @param {unknown} error
56
+ */ const isErrorENOENT = (error)=>getNodeErrorCode(error) === "ENOENT";
57
+ const isErrorEPERM = (error)=>getNodeErrorCode(error) === "EPERM";
58
+
59
+ // Functionality related to working with a single package.
60
+ const PACKAGE_FILE = "_Package.json";
61
+ const INDEX_FILE = "_Index.json";
62
+ const ANIMATION_FILE_SUFFIX = ".animation.json";
63
+ function parseCreatorPackageName(manifest) {
64
+ const [domain, subdomain] = manifest.Package.split(".");
65
+ if (subdomain === undefined) {
66
+ throw new Error(`Expected "Package" field of the _Package.json file to contain a value in the form of Domain.SubDomain`);
67
+ }
68
+ return {
69
+ domain,
70
+ subdomain
71
+ };
72
+ }
73
+ const readPackageCreatorManifest = (location)=>{
74
+ const packageJsonPath = path.join(location.manifestDir, PACKAGE_FILE);
75
+ const packageJson = stripUtf8Bom(fs.readFileSync(packageJsonPath, {
76
+ encoding: "utf8"
77
+ }));
78
+ return JSON.parse(packageJson);
79
+ };
80
+ const writePackageCreatorManifest = (location, creatorPackage)=>{
81
+ const packageJsonPath = path.join(location.manifestDir, PACKAGE_FILE);
82
+ fs.writeFileSync(packageJsonPath, JSON.stringify(creatorPackage, null, "\t") + "\n");
83
+ };
84
+ const getPackageCreatorIndexPath = (location)=>path.join(location.manifestDir, INDEX_FILE);
85
+ const readPackageCreatorIndex = (location)=>{
86
+ try {
87
+ const indexPath = getPackageCreatorIndexPath(location);
88
+ const index = stripUtf8Bom(fs.readFileSync(indexPath, {
89
+ encoding: "utf8"
90
+ }));
91
+ return JSON.parse(index);
92
+ } catch (err) {
93
+ if (isErrorENOENT(err)) {
94
+ return undefined;
95
+ }
96
+ throw err;
97
+ }
98
+ };
99
+ const writePackageCreatorIndex = (location, index)=>{
100
+ const indexPath = getPackageCreatorIndexPath(location);
101
+ fs.writeFileSync(indexPath, JSON.stringify(index, null, "\t") + "\n");
102
+ };
103
+ const readPackageNpmManifest = (location)=>{
104
+ try {
105
+ return readNpmManifest(location.manifestDir);
106
+ } catch (err) {
107
+ if (isErrorENOENT(err)) {
108
+ return undefined;
109
+ }
110
+ throw err;
111
+ }
112
+ };
113
+ const readPackageAnimationList = (location)=>{
114
+ const directoryContent = fs.readdirSync(location.manifestDir);
115
+ const animationPathList = [];
116
+ for (const entry of directoryContent){
117
+ if (entry.endsWith(ANIMATION_FILE_SUFFIX)) {
118
+ const animationPath = path.join(location.manifestDir, entry);
119
+ animationPathList.push(animationPath);
120
+ }
121
+ }
122
+ return animationPathList;
123
+ };
124
+ const getPackageReleasesDirectory = (location)=>path.join(location.path, "Releases");
125
+
126
+ /**
127
+ * Detects a published package from a path.
128
+ *
129
+ * Can return undefined if the package is not installed.
130
+ *
131
+ * @param {string} resolveBasePath
132
+ * @param {string} name
133
+ * @return {*} {(PublishedPackageLocation | undefined)}
134
+ */ const detectPublishedPackageFromPath = (resolveBasePath, name)=>{
135
+ try {
136
+ const manifestPath = resolve.sync(name + "/package.json", {
137
+ basedir: resolveBasePath
138
+ });
139
+ const dir = path.dirname(manifestPath);
140
+ return {
141
+ _kind: "PublishedPackageLocation",
142
+ path: dir
143
+ };
144
+ } catch (err) {
145
+ return undefined;
146
+ }
147
+ };
148
+ const readPublishedPackageNpmManifest = (location)=>{
149
+ return readNpmManifest(location.path);
150
+ };
151
+ const readPublishedPackageCreatorManifest = (location)=>{
152
+ try {
153
+ const packageJsonPath = path.join(location.path, PACKAGE_FILE);
154
+ const packageJson = stripUtf8Bom(fs.readFileSync(packageJsonPath, {
155
+ encoding: "utf8"
156
+ }));
157
+ return JSON.parse(packageJson);
158
+ } catch (err) {
159
+ if (isErrorENOENT(err)) {
160
+ return undefined;
161
+ }
162
+ throw err;
163
+ }
164
+ };
165
+ const readPublishedPackageCreatorIndex = (location)=>{
166
+ try {
167
+ const packageJsonPath = path.join(location.path, INDEX_FILE);
168
+ const packageJson = stripUtf8Bom(fs.readFileSync(packageJsonPath, {
169
+ encoding: "utf8"
170
+ }));
171
+ const result = JSON.parse(packageJson);
172
+ return result;
173
+ } catch (err) {
174
+ if (isErrorENOENT(err)) {
175
+ return undefined;
176
+ }
177
+ throw err;
178
+ }
179
+ };
180
+
181
+ const readWorkspaceNpmManifest = (workspace)=>{
182
+ try {
183
+ return readNpmManifest(workspace.path);
184
+ } catch (err) {
185
+ if (isErrorENOENT(err)) {
186
+ throw new Error(`Expected a package.json file to exist in ${workspace.path}. See packager readme for instructions on how to create the package.json.`);
187
+ }
188
+ throw err;
189
+ }
190
+ };
191
+ const getWorkspaceOutputPath = (workspace)=>path.join(workspace.path, "bin");
192
+
193
+ // /**
194
+ // * Determines the implicit dependencies of a an actual data workspace package.
195
+ // *
196
+ // * An implicit dependency is a dependency that is installed for the workspace and has the same runtime environment (evaluator, interactor) as the package.
197
+ // *
198
+ // * @param {WorkspaceLocation} workspace
199
+ // * @param {CreatorPackage} creatorPackage
200
+ // * @returns {PublishedPackageLocation[]}
201
+ // */
202
+ // export const determinePackageImplicitDependencies = (
203
+ // workspace: WorkspaceLocation,
204
+ // creatorPackage: CreatorPackage,
205
+ // ): PublishedPackageLocation[] => {
206
+ // const libraries = determineWorkspaceIGLibraries(workspace);
207
+ // const results: PublishedPackageLocation[] = [];
208
+ // for (const librarylocation of libraries) {
209
+ // const libraryManifest =
210
+ // readPublishedPackageCreatorManifest(librarylocation);
211
+ // if (
212
+ // libraryManifest !== undefined &&
213
+ // (libraryManifest.Type === "Mixed" ||
214
+ // libraryManifest.RunTime === creatorPackage.RunTime)
215
+ // ) {
216
+ // results.push(librarylocation);
217
+ // }
218
+ // }
219
+ // return results;
220
+ // };
221
+ /**
222
+ * Recursively determines all installed ig libraries for a workspace.
223
+ *
224
+ * @param {WorkspaceLocation} workspace
225
+ * @returns {PublishedPackageLocation[]}
226
+ */ const determineWorkspaceIGLibraries = (workspace)=>{
227
+ const manifest = readWorkspaceNpmManifest(workspace);
228
+ const libraries = collectIGLibraries(workspace, manifest);
229
+ const results = new Map();
230
+ for (const location of libraries){
231
+ const manifest = readPublishedPackageNpmManifest(location);
232
+ if (!results.has(manifest.name)) {
233
+ results.set(manifest.name, location);
234
+ }
235
+ }
236
+ return Array.from(results.values());
237
+ };
238
+ const collectIGLibraries = (workspace, manifest)=>{
239
+ if (!manifest.dependencies) {
240
+ return [];
241
+ }
242
+ const runtimeDependencies = Object.getOwnPropertyNames(manifest.dependencies);
243
+ const result = [];
244
+ for (const runtimeDependency of runtimeDependencies){
245
+ var _runtimeManifest_ig;
246
+ const location = detectPublishedPackageFromPath(workspace.path, runtimeDependency);
247
+ if (location === undefined) {
248
+ continue;
249
+ }
250
+ const runtimeManifest = readPublishedPackageNpmManifest(location);
251
+ // packages need to explicitly be marked as ig scriptingLibraries
252
+ if ((_runtimeManifest_ig = runtimeManifest.ig) == null ? void 0 : _runtimeManifest_ig.scriptingLibrary) {
253
+ result.push(location);
254
+ result.push(...collectIGLibraries(workspace, runtimeManifest));
255
+ }
256
+ }
257
+ return result;
258
+ };
259
+
260
+ const readStringFromFile = (filePath)=>fs.readFileSync(filePath, {
261
+ encoding: "utf8"
262
+ });
263
+ const readStringFromFileOrUndefined = (filePath)=>{
264
+ try {
265
+ return readStringFromFile(filePath);
266
+ } catch (err) {
267
+ if (!isErrorENOENT(err)) {
268
+ throw err;
269
+ }
270
+ return undefined;
271
+ }
272
+ };
273
+
274
+ const consoleReporter = {
275
+ log (message) {
276
+ console.log(message);
277
+ },
278
+ error (message, _error) {
279
+ console.error(message);
280
+ }
281
+ };
282
+ const createPackageScopedReporter = (reporter, scope, index, total, maxNameLength = 15)=>{
283
+ const numLength = total === undefined ? undefined : total.toString().length;
284
+ const indexString = total === undefined || total < 2 ? "" : `${index.toString().padStart(numLength, "0")}/${total} `;
285
+ const identifierString = `${indexString}${scope.padEnd(maxNameLength)}`;
286
+ return {
287
+ log (message) {
288
+ reporter.log(`${identifierString} >> ${message}`);
289
+ },
290
+ error (message, error) {
291
+ reporter.error(`${identifierString} >> ${message}`, error);
292
+ }
293
+ };
294
+ };
295
+
296
+ const getPackageTypescriptFiles = (location)=>glob.sync("**/*.ts", {
297
+ absolute: true,
298
+ cwd: location.scriptsDir,
299
+ ignore: "node_modules/**/*"
300
+ });
301
+
302
+ const PLUGIN_ID = "0feba3a0-b6d1-11e6-9598-0800200c9a66";
303
+ /**
304
+ * Starts an IG.Asset.Server session and returns the sessionId
305
+ *
306
+ * @param {SessionStartParams} params
307
+ * @returns
308
+ */ const startSession = async ({ url, authentication, ...params })=>{
309
+ const payload = {
310
+ ...params,
311
+ user: undefined,
312
+ password: undefined,
313
+ license: undefined,
314
+ plugin: PLUGIN_ID
315
+ };
316
+ if (authentication.type === "credentials") {
317
+ payload.user = authentication.username;
318
+ payload.password = authentication.password;
319
+ } else if (authentication.type === "license") {
320
+ payload.license = authentication.license;
321
+ }
322
+ const { data: { session: sessionId, state, response } } = await axios.post(`Session/Start2`, JSON.stringify(payload), {
323
+ baseURL: url
324
+ });
325
+ if (state !== "SUCCESS") {
326
+ let message = `Could not start session. IG.Asset.Server responded with ${state}`;
327
+ if (response) {
328
+ message += `: ${response}`;
329
+ }
330
+ throw new Error(message);
331
+ }
332
+ return {
333
+ _kind: "AssetService",
334
+ url,
335
+ sessionId,
336
+ domain: params.domain,
337
+ subDomain: params.subDomain
338
+ };
339
+ };
340
+ const closeSession = async (session)=>{
341
+ await axios.get(`Session/Close/${session.sessionId}`, {
342
+ baseURL: session.url
343
+ });
344
+ };
345
+ const uploadPackageFromBuffer = async (session, { name, version }, buffer)=>{
346
+ try {
347
+ await uploadPackageToUrl(session.url, `UploadPackage/${session.sessionId}/${name}_${version}`, buffer);
348
+ } catch (err) {
349
+ if (err instanceof AxiosError) {
350
+ var _err_response;
351
+ if (((_err_response = err.response) == null ? void 0 : _err_response.status) === 404) {
352
+ await uploadPackageToUrl(session.url, `UploadPackage/${session.sessionId}/${name}_${version}/`, buffer);
353
+ return;
354
+ }
355
+ throw new Error(`Failed to upload package: ${err.message}`);
356
+ }
357
+ throw err;
358
+ }
359
+ };
360
+ const uploadPackageToUrl = async (url, path, buffer)=>{
361
+ const { data, status } = await axios.post(path, buffer, {
362
+ baseURL: url
363
+ });
364
+ let objectBody;
365
+ if (typeof data === "string") {
366
+ try {
367
+ objectBody = JSON.parse(data);
368
+ } catch (err) {}
369
+ } else if (typeof data === "object") {
370
+ objectBody = data;
371
+ }
372
+ if (objectBody !== undefined) {
373
+ if ("state" in objectBody && objectBody.state !== "SUCCESS") {
374
+ throw new Error(objectBody.response ?? objectBody.state);
375
+ }
376
+ }
377
+ if (status >= 400) {
378
+ if (objectBody !== undefined) {
379
+ let text_1 = "";
380
+ for(const key in objectBody){
381
+ text_1 += key + ": \n";
382
+ if (typeof objectBody[key] === "object") {
383
+ text_1 += JSON.stringify(objectBody[key], undefined, 2);
384
+ } else {
385
+ text_1 += objectBody[key];
386
+ }
387
+ text_1 += "\n\n";
388
+ }
389
+ throw new Error(text_1);
390
+ }
391
+ throw new Error(data);
392
+ }
393
+ return data;
394
+ };
395
+ const getExistingPackages = async (session)=>{
396
+ const { data } = await axios.get(`Script/GetInformation/${session.sessionId}`, {
397
+ baseURL: session.url,
398
+ validateStatus: (status)=>status === 404 || status === 200
399
+ }).catch((err)=>{
400
+ throw new Error(`Failed to get existing packages: ${err.message}`);
401
+ });
402
+ return data;
403
+ };
404
+
405
+ function resolveScriptPackageEntryModule(location, manifest) {
406
+ let candidates = [
407
+ "index.ts"
408
+ ];
409
+ if (manifest.Type === "Context") {
410
+ candidates.push("Context.ts");
411
+ }
412
+ for (const candidate of candidates){
413
+ const candidatePath = path.join(location.scriptsDir, candidate);
414
+ if (fs.existsSync(candidatePath)) {
415
+ return candidatePath;
416
+ }
417
+ }
418
+ }
419
+ function readScriptPackageTSConfig(location) {
420
+ const { config } = ts.readConfigFile(path.join(location.scriptsDir, "tsconfig.json"), (path)=>{
421
+ try {
422
+ return fs.readFileSync(path, "utf8");
423
+ } catch {
424
+ return undefined;
425
+ }
426
+ });
427
+ const parsedTsConfig = ts.parseJsonConfigFileContent(config, ts.sys, location.scriptsDir);
428
+ return parsedTsConfig;
429
+ }
430
+ function isScriptPackageModules(options) {
431
+ return options.module === ts.ModuleKind.ES2015;
432
+ }
433
+
434
+ const tryReadTsConfig = (location)=>{
435
+ const { config } = ts.readConfigFile(path.join(location.scriptsDir, "tsconfig.json"), (path)=>{
436
+ try {
437
+ return fs.readFileSync(path, "utf8");
438
+ } catch {
439
+ return undefined;
440
+ }
441
+ });
442
+ return config;
443
+ };
444
+ const createTSCBuildParticipant = (location, outputDir)=>(env)=>{
445
+ const files = getPackageTypescriptFiles(location);
446
+ try {
447
+ env.onBuildStart();
448
+ env.log("Compiling typescript files");
449
+ const compilerOptions = getCompilerOptions(location, outputDir);
450
+ const host = ts.createCompilerHost(compilerOptions);
451
+ host.getCurrentDirectory = ()=>location.scriptsDir;
452
+ let js;
453
+ let definitions;
454
+ let sourceMap;
455
+ host.writeFile = (fileName, data, writeByteOrderMark)=>{
456
+ if (fileName.endsWith(".js")) {
457
+ js = data;
458
+ } else if (fileName.endsWith(".d.ts")) {
459
+ definitions = data;
460
+ } else if (fileName.endsWith(".js.map")) {
461
+ sourceMap = data;
462
+ }
463
+ };
464
+ const programOptions = {
465
+ rootNames: files,
466
+ options: compilerOptions,
467
+ host
468
+ };
469
+ const program = ts.createProgram(programOptions);
470
+ const emitResult = program.emit();
471
+ const allDiagnostics = ts.getPreEmitDiagnostics(program);
472
+ if (!emitResult.emitSkipped) {
473
+ if (allDiagnostics.length > 0) {
474
+ console.log(ts.formatDiagnostics(allDiagnostics, host));
475
+ }
476
+ if (js === undefined || definitions === undefined) {
477
+ throw new Error(`Unexpected: no js or definitions were created`);
478
+ }
479
+ env.onBuildEnd({
480
+ type: "success",
481
+ artefacts: {
482
+ js: js.replace(`//# sourceMappingURL=out.js.map`, ""),
483
+ declarations: definitions,
484
+ sourceMap
485
+ }
486
+ });
487
+ } else {
488
+ const error = ts.formatDiagnostics(allDiagnostics, host);
489
+ throw new Error(error);
490
+ }
491
+ } catch (err) {
492
+ env.onBuildEnd({
493
+ type: "error",
494
+ error: err.message
495
+ });
496
+ }
497
+ return {
498
+ destroy: ()=>{}
499
+ };
500
+ };
501
+ const createTSCWatchBuildParticipant = (location, outputDir)=>{
502
+ return ({ onBuildStart, onBuildEnd })=>{
503
+ let state = {
504
+ diagnostics: [],
505
+ js: undefined,
506
+ definitions: undefined,
507
+ sourceMap: undefined
508
+ };
509
+ const customSys = {
510
+ ...ts.sys,
511
+ writeFile: (fileName, data, writeByteOrderMark)=>{
512
+ if (fileName.endsWith(".js")) {
513
+ state.js = data;
514
+ } else if (fileName.endsWith(".d.ts")) {
515
+ state.definitions = data;
516
+ } else if (fileName.endsWith(".js.map")) {
517
+ state.sourceMap = data;
518
+ }
519
+ }
520
+ };
521
+ const registerDiagnostic = (diagnostic)=>{
522
+ switch(diagnostic.code){
523
+ // file not found - https://github.com/microsoft/TypeScript/blob/93e6b9da0c4cb164ca90a5a1b07415e81e97f2b1/src/compiler/diagnosticMessages.json#L4640
524
+ // probably deleted -> ignore
525
+ case 6053:
526
+ return;
527
+ // no inputs were found - https://github.com/microsoft/TypeScript/blob/93e6b9da0c4cb164ca90a5a1b07415e81e97f2b1/src/compiler/diagnosticMessages.json#L6838
528
+ // we don't care about this error. a user might have temporarily deleted the last ts file and will readd one later.
529
+ case 18003:
530
+ return;
531
+ }
532
+ state.diagnostics.push(diagnostic);
533
+ };
534
+ const reportWatchStatusChanged = (diagnostic)=>{
535
+ switch(diagnostic.code){
536
+ // regular watch mode - https://github.com/microsoft/TypeScript/blob/93e6b9da0c4cb164ca90a5a1b07415e81e97f2b1/src/compiler/diagnosticMessages.json#L4567
537
+ case 6031:
538
+ // incremental watch mode - https://github.com/microsoft/TypeScript/blob/93e6b9da0c4cb164ca90a5a1b07415e81e97f2b1/src/compiler/diagnosticMessages.json#L4571
539
+ case 6032:
540
+ // build start
541
+ onBuildStart();
542
+ break;
543
+ // found one error - https://github.com/microsoft/TypeScript/blob/93e6b9da0c4cb164ca90a5a1b07415e81e97f2b1/src/compiler/diagnosticMessages.json#L5119
544
+ case 6193:
545
+ // found n or 0 errors - https://github.com/microsoft/TypeScript/blob/93e6b9da0c4cb164ca90a5a1b07415e81e97f2b1/src/compiler/diagnosticMessages.json#L5123
546
+ case 6194:
547
+ // build end
548
+ const emitState = state;
549
+ state = {
550
+ diagnostics: [],
551
+ js: undefined,
552
+ definitions: undefined,
553
+ sourceMap: undefined
554
+ };
555
+ if (emitState.diagnostics.length > 0) {
556
+ const message = ts.formatDiagnostics(emitState.diagnostics, formattingHost);
557
+ onBuildEnd({
558
+ type: "error",
559
+ error: message
560
+ });
561
+ return;
562
+ }
563
+ if (emitState.js === undefined || emitState.definitions === undefined) {
564
+ onBuildEnd({
565
+ type: "success",
566
+ artefacts: {
567
+ js: ""
568
+ }
569
+ });
570
+ return;
571
+ }
572
+ onBuildEnd({
573
+ type: "success",
574
+ artefacts: {
575
+ js: emitState.js.replace(`//# sourceMappingURL=out.js.map`, ""),
576
+ declarations: emitState.definitions,
577
+ sourceMap: emitState.sourceMap
578
+ }
579
+ });
580
+ break;
581
+ }
582
+ };
583
+ const host = ts.createWatchCompilerHost(path.join(location.scriptsDir, "tsconfig.json"), getCompilerOptions(location, outputDir), customSys, ts.createSemanticDiagnosticsBuilderProgram, registerDiagnostic, reportWatchStatusChanged);
584
+ const formattingHost = {
585
+ getCanonicalFileName: (path)=>path,
586
+ getCurrentDirectory: host.getCurrentDirectory,
587
+ getNewLine: ()=>ts.sys.newLine
588
+ };
589
+ const watchProgram = ts.createWatchProgram(host);
590
+ return {
591
+ destroy: ()=>{
592
+ watchProgram.close();
593
+ }
594
+ };
595
+ };
596
+ };
597
+ const getCompilerOptions = (location, outputDir)=>{
598
+ const config = tryReadTsConfig(location);
599
+ config.compilerOptions.lib = [
600
+ "es5",
601
+ "dom"
602
+ ];
603
+ const result = ts.convertCompilerOptionsFromJson(config.compilerOptions, location.scriptsDir);
604
+ const compilerOptions = {
605
+ ...result.options,
606
+ removeComments: false,
607
+ declaration: true,
608
+ sourceMap: true,
609
+ inlineSources: false,
610
+ // We don't use tsc to actually emit the files, but we still need to set the correct
611
+ // output directory so the compiler can rewrite the `reference path` directives.
612
+ outFile: path.join(outputDir, "out.js"),
613
+ target: ts.ScriptTarget.ES5,
614
+ noEmitOnError: true
615
+ };
616
+ return compilerOptions;
617
+ };
618
+
619
+ const generateDocs = async (location, declarationFile, outFolder, name)=>{
620
+ const app = new typedoc.Application();
621
+ const mediaDir = path.join(location.manifestDir, "Media");
622
+ app.bootstrap({
623
+ entryPoints: [
624
+ declarationFile
625
+ ],
626
+ media: mediaDir,
627
+ out: outFolder,
628
+ tsconfig: path.join(location.scriptsDir, "tsconfig.json"),
629
+ skipErrorChecking: true
630
+ });
631
+ app.options.setCompilerOptions([
632
+ declarationFile
633
+ ], {
634
+ target: ts.ScriptTarget.ES5
635
+ }, undefined);
636
+ app.options.setValue("name", name);
637
+ const [readmePath] = glob.sync("**/readme.md", {
638
+ absolute: true,
639
+ cwd: location.manifestDir
640
+ });
641
+ if (readmePath) {
642
+ app.options.setValue("readme", readmePath);
643
+ }
644
+ const project = app.convert();
645
+ if (project) {
646
+ await app.generateDocs(project, outFolder);
647
+ }
648
+ };
649
+
650
+ // Stolen from ig.tools.core
651
+ const toposort = (packages)=>{
652
+ const queue = Object.getOwnPropertyNames(packages);
653
+ const result = [];
654
+ let index = 0;
655
+ while(queue.length > 0){
656
+ if (index >= queue.length) {
657
+ throw new Error("Packages can not have cyclic dependencies");
658
+ }
659
+ const queueEntry = queue[index];
660
+ const dependencies = packages[queueEntry];
661
+ const dependencyQueued = dependencies.some((dependency)=>queue.includes(dependency));
662
+ if (dependencyQueued) {
663
+ index++;
664
+ continue;
665
+ }
666
+ queue.splice(index, 1);
667
+ index = 0;
668
+ result.push(queueEntry);
669
+ }
670
+ return result;
671
+ };
672
+
673
+ class BuildManager extends EventEmitter {
674
+ constructor(manifest, writer, reporter){
675
+ super(), this.manifest = manifest, this.writer = writer, this.reporter = reporter, this.participants = new Map(), this.states = new Map();
676
+ }
677
+ addParticipant(name, participant) {
678
+ this.participants.set(name, participant);
679
+ }
680
+ run() {
681
+ for (const [name] of this.participants){
682
+ this.states.set(name, {
683
+ type: "busy"
684
+ });
685
+ }
686
+ this.emit("start");
687
+ for (const [name, participant] of this.participants){
688
+ participant({
689
+ onBuildStart: ()=>{
690
+ let alreadyBusy = false;
691
+ for (const [name, state] of this.states){
692
+ if (state.type === "busy") {
693
+ alreadyBusy = true;
694
+ continue;
695
+ }
696
+ }
697
+ this.states.set(name, {
698
+ type: "busy"
699
+ });
700
+ if (!alreadyBusy) {
701
+ this.emit("start");
702
+ }
703
+ },
704
+ onBuildEnd: (result)=>{
705
+ this.states.set(name, result);
706
+ this.maybeEmit();
707
+ },
708
+ log: (message)=>this.reporter.log(message)
709
+ });
710
+ }
711
+ }
712
+ maybeEmit() {
713
+ const errors = [];
714
+ const results = [];
715
+ for (const [_, state] of this.states){
716
+ if (state.type === "busy") {
717
+ return;
718
+ }
719
+ if (state.type === "success") {
720
+ results.push(state);
721
+ } else if (state.type === "error") {
722
+ errors.push(state.error);
723
+ }
724
+ }
725
+ if (errors.length > 0) {
726
+ this.emit("error", errors.join("\n"));
727
+ return;
728
+ }
729
+ const completeResult = {
730
+ js: ""
731
+ };
732
+ const sourceMapGenerator = new SourceMapGenerator();
733
+ for (const result of results){
734
+ if (result.artefacts.js) {
735
+ if (completeResult.js) {
736
+ completeResult.js += "\n";
737
+ }
738
+ if (result.artefacts.sourceMap) {
739
+ const lines = completeResult.js.split("\n").length - 1;
740
+ const sourceMap = new SourceMapConsumer(JSON.parse(result.artefacts.sourceMap));
741
+ const sources = new Set();
742
+ sourceMap.eachMapping((mapping)=>{
743
+ sourceMapGenerator.addMapping({
744
+ generated: {
745
+ line: lines + mapping.generatedLine,
746
+ column: mapping.generatedColumn
747
+ },
748
+ original: mapping.originalLine !== null && mapping.originalColumn !== null ? {
749
+ line: mapping.originalLine,
750
+ column: mapping.originalColumn
751
+ } : undefined,
752
+ source: mapping.source,
753
+ name: mapping.name
754
+ });
755
+ if (mapping.source !== null) {
756
+ sources.add(mapping.source);
757
+ }
758
+ });
759
+ for (const source of sources){
760
+ const content = sourceMap.sourceContentFor(source);
761
+ if (content !== null) {
762
+ sourceMapGenerator.setSourceContent(source, content);
763
+ }
764
+ }
765
+ }
766
+ completeResult.js += result.artefacts.js;
767
+ }
768
+ if (result.artefacts.declarations) {
769
+ if (completeResult.declarations) {
770
+ completeResult.declarations += "\n";
771
+ } else {
772
+ completeResult.declarations = "";
773
+ }
774
+ completeResult.declarations += result.artefacts.declarations;
775
+ }
776
+ }
777
+ completeResult.sourceMap = sourceMapGenerator.toString();
778
+ this.writer(completeResult).then(()=>{
779
+ this.emit("build");
780
+ });
781
+ }
782
+ }
783
+
784
+ var animationSchema = {
785
+ $schema: "http://json-schema.org/draft-07/schema",
786
+ $id: "https://archive.intelligentgraphics.biz/schemas/gfx/animation.json",
787
+ $comment: "Version 2023-02-17, Source: ig.data.gfx/Specs/animation.json",
788
+ title: "Animation description format",
789
+ additionalProperties: false,
790
+ type: "object",
791
+ properties: {
792
+ $schema: {
793
+ type: "string"
794
+ },
795
+ Id: {
796
+ type: "string",
797
+ description: "Animation id, to be unique in the project scope. Needs to be a valid JavaScript identifier."
798
+ },
799
+ Animations: {
800
+ type: "array",
801
+ description: "Declaration of animation states for gfx objects",
802
+ items: {
803
+ type: "object",
804
+ additionalProperties: false,
805
+ properties: {
806
+ _: {
807
+ type: "string",
808
+ description: "Comment"
809
+ },
810
+ Path: {
811
+ $ref: "#/definitions/igxcPath"
812
+ },
813
+ States: {
814
+ type: "object",
815
+ additionalProperties: {
816
+ type: "object",
817
+ additionalProperties: false,
818
+ properties: {
819
+ Position: {
820
+ $ref: "#/definitions/vec3"
821
+ },
822
+ Rotation: {
823
+ $ref: "#/definitions/rotation"
824
+ },
825
+ Scaling: {
826
+ $ref: "#/definitions/vec3"
827
+ },
828
+ Visibility: {
829
+ type: "boolean"
830
+ },
831
+ Deformation: {
832
+ anyOf: [
833
+ {
834
+ type: "number"
835
+ },
836
+ {
837
+ type: "string"
838
+ }
839
+ ]
840
+ }
841
+ }
842
+ }
843
+ }
844
+ }
845
+ }
846
+ },
847
+ Kinematics: {
848
+ oneOf: [
849
+ {
850
+ $ref: "#/definitions/kinematicChain"
851
+ },
852
+ {
853
+ type: "array",
854
+ items: {
855
+ $ref: "#/definitions/kinematicChain"
856
+ }
857
+ }
858
+ ]
859
+ },
860
+ LinkedPoints: {
861
+ type: "object",
862
+ additionalProperties: {
863
+ type: "array",
864
+ items: {
865
+ type: "string"
866
+ }
867
+ }
868
+ },
869
+ _: {
870
+ type: "string",
871
+ description: "Comment"
872
+ }
873
+ },
874
+ definitions: {
875
+ vec3: {
876
+ type: "object",
877
+ additionalProperties: false,
878
+ properties: {
879
+ X: {
880
+ anyOf: [
881
+ {
882
+ type: "number"
883
+ },
884
+ {
885
+ type: "string"
886
+ }
887
+ ]
888
+ },
889
+ Y: {
890
+ anyOf: [
891
+ {
892
+ type: "number"
893
+ },
894
+ {
895
+ type: "string"
896
+ }
897
+ ]
898
+ },
899
+ Z: {
900
+ anyOf: [
901
+ {
902
+ type: "number"
903
+ },
904
+ {
905
+ type: "string"
906
+ }
907
+ ]
908
+ },
909
+ _: {
910
+ type: "string",
911
+ description: "Comment"
912
+ }
913
+ }
914
+ },
915
+ rotation: {
916
+ type: "object",
917
+ additionalProperties: false,
918
+ properties: {
919
+ Q: {
920
+ description: "If true, the rotation is considered to be a Quaternion. Otherwise, it's interpreted as Euler arcs and W will be ignored.",
921
+ type: "boolean"
922
+ },
923
+ X: {
924
+ anyOf: [
925
+ {
926
+ type: "number"
927
+ },
928
+ {
929
+ type: "string"
930
+ }
931
+ ]
932
+ },
933
+ Y: {
934
+ anyOf: [
935
+ {
936
+ type: "number"
937
+ },
938
+ {
939
+ type: "string"
940
+ }
941
+ ]
942
+ },
943
+ Z: {
944
+ anyOf: [
945
+ {
946
+ type: "number"
947
+ },
948
+ {
949
+ type: "string"
950
+ }
951
+ ]
952
+ },
953
+ W: {
954
+ anyOf: [
955
+ {
956
+ type: "number"
957
+ },
958
+ {
959
+ type: "string"
960
+ }
961
+ ]
962
+ },
963
+ _: {
964
+ type: "string",
965
+ description: "Comment"
966
+ }
967
+ }
968
+ },
969
+ igxcPath: {
970
+ type: "string",
971
+ description: "Relative path of the target object",
972
+ pattern: "^((o|e)\\d+(\\.(o|e)\\d+)*|\\.)$"
973
+ },
974
+ param: {
975
+ type: "string",
976
+ pattern: "^Param\\d+$"
977
+ },
978
+ kinematicChain: {
979
+ type: "object",
980
+ additionalProperties: false,
981
+ properties: {
982
+ GeometryBase: {
983
+ type: "string"
984
+ },
985
+ Joints: {
986
+ type: "array",
987
+ items: {
988
+ type: "object",
989
+ additionalProperties: false,
990
+ properties: {
991
+ Name: {
992
+ oneOf: [
993
+ {
994
+ $ref: "#/definitions/param"
995
+ },
996
+ {
997
+ type: "string"
998
+ }
999
+ ]
1000
+ },
1001
+ HeadX: {
1002
+ oneOf: [
1003
+ {
1004
+ $ref: "#/definitions/param"
1005
+ },
1006
+ {
1007
+ $ref: "#/definitions/igxcPath"
1008
+ }
1009
+ ]
1010
+ },
1011
+ HeadY: {
1012
+ oneOf: [
1013
+ {
1014
+ $ref: "#/definitions/param"
1015
+ },
1016
+ {
1017
+ $ref: "#/definitions/igxcPath"
1018
+ }
1019
+ ]
1020
+ },
1021
+ HeadZ: {
1022
+ oneOf: [
1023
+ {
1024
+ $ref: "#/definitions/param"
1025
+ },
1026
+ {
1027
+ $ref: "#/definitions/igxcPath"
1028
+ }
1029
+ ]
1030
+ },
1031
+ Tail: {
1032
+ oneOf: [
1033
+ {
1034
+ $ref: "#/definitions/param"
1035
+ },
1036
+ {
1037
+ $ref: "#/definitions/igxcPath"
1038
+ }
1039
+ ]
1040
+ },
1041
+ LimitLeft: {
1042
+ type: "number"
1043
+ },
1044
+ LimitRight: {
1045
+ type: "number"
1046
+ },
1047
+ LimitUp: {
1048
+ type: "number"
1049
+ },
1050
+ LimitDown: {
1051
+ type: "number"
1052
+ },
1053
+ FollowJointNode: {
1054
+ $ref: "#/definitions/igxcPath"
1055
+ },
1056
+ _TargetNodeForFollow: {
1057
+ type: "string"
1058
+ }
1059
+ }
1060
+ }
1061
+ },
1062
+ Target: {
1063
+ oneOf: [
1064
+ {
1065
+ $ref: "#/definitions/igxcPath"
1066
+ },
1067
+ {
1068
+ $ref: "#/definitions/param"
1069
+ },
1070
+ {
1071
+ type: "string",
1072
+ enum: [
1073
+ "subbase"
1074
+ ]
1075
+ }
1076
+ ]
1077
+ },
1078
+ Parent: {
1079
+ oneOf: [
1080
+ {
1081
+ $ref: "#/definitions/igxcPath"
1082
+ },
1083
+ {
1084
+ type: "string",
1085
+ enum: [
1086
+ "root"
1087
+ ]
1088
+ }
1089
+ ]
1090
+ },
1091
+ Tolerance: {
1092
+ type: "number"
1093
+ },
1094
+ MaxIterations: {
1095
+ type: "integer"
1096
+ },
1097
+ _: {
1098
+ type: "string",
1099
+ description: "Comment"
1100
+ },
1101
+ __: {
1102
+ type: "string",
1103
+ description: "Super Comment"
1104
+ }
1105
+ }
1106
+ }
1107
+ }
1108
+ };
1109
+
1110
+ const createAnimationBuildParticipant = (location, manifest)=>{
1111
+ return (env)=>{
1112
+ env.onBuildStart();
1113
+ bundleAnimations(location, manifest, env.log).then((result)=>{
1114
+ env.onBuildEnd({
1115
+ type: "success",
1116
+ artefacts: {
1117
+ js: (result == null ? void 0 : result.js) ?? ""
1118
+ }
1119
+ });
1120
+ }).catch((err)=>{
1121
+ env.onBuildEnd({
1122
+ type: "error",
1123
+ error: err.message
1124
+ });
1125
+ });
1126
+ return {
1127
+ destroy: ()=>{}
1128
+ };
1129
+ };
1130
+ };
1131
+ const createAnimationWatchBuildParticipant = (location, manifest)=>(env)=>{
1132
+ env.onBuildStart();
1133
+ bundleAnimations(location, manifest, env.log).then((result)=>{
1134
+ env.onBuildEnd({
1135
+ type: "success",
1136
+ artefacts: {
1137
+ js: (result == null ? void 0 : result.js) ?? ""
1138
+ }
1139
+ });
1140
+ }).catch((err)=>{
1141
+ env.onBuildEnd({
1142
+ type: "error",
1143
+ error: err.message
1144
+ });
1145
+ });
1146
+ (async ()=>{
1147
+ for await (const event of fs$1.watch(location.scriptsDir)){
1148
+ var _event_filename;
1149
+ if ((_event_filename = event.filename) == null ? void 0 : _event_filename.endsWith(".animation.json")) {
1150
+ env.onBuildStart();
1151
+ try {
1152
+ const result = await bundleAnimations(location, manifest, env.log);
1153
+ env.onBuildEnd({
1154
+ type: "success",
1155
+ artefacts: {
1156
+ js: (result == null ? void 0 : result.js) ?? ""
1157
+ }
1158
+ });
1159
+ } catch (err) {
1160
+ env.onBuildEnd({
1161
+ type: "error",
1162
+ error: err.message
1163
+ });
1164
+ }
1165
+ }
1166
+ }
1167
+ })();
1168
+ return {
1169
+ destroy: ()=>{}
1170
+ };
1171
+ };
1172
+ const bundleAnimations = async (location, manifest, logStep)=>{
1173
+ const animations = new Map();
1174
+ for (const scriptFilePath of readPackageAnimationList(location)){
1175
+ const content = await fs$1.readFile(scriptFilePath, {
1176
+ encoding: "utf8"
1177
+ });
1178
+ let data;
1179
+ try {
1180
+ data = JSON.parse(content);
1181
+ } catch (err) {
1182
+ const relativePath = path.relative(location.path, scriptFilePath);
1183
+ if (err instanceof SyntaxError) {
1184
+ throw new Error(`Encountered invalid syntax in file "${relativePath}": ${String(err)}`);
1185
+ }
1186
+ throw new Error(`Encountered an unexpected error while parsing animation json file at path "${relativePath}"`, {
1187
+ cause: err
1188
+ });
1189
+ }
1190
+ if (!data.Id) {
1191
+ const fileName = path.basename(scriptFilePath, ".animation.json");
1192
+ data.Id = fileName;
1193
+ }
1194
+ (await getAnimationJsonValidation())(data);
1195
+ delete data.$schema;
1196
+ animations.set(data.Id, JSON.stringify(data));
1197
+ }
1198
+ if (animations.size > 0) {
1199
+ const scope = manifest.Scope ?? manifest.Package;
1200
+ const scopeParts = scope.split(".");
1201
+ let js = createNamespace(scopeParts);
1202
+ for (const [name, content] of animations){
1203
+ js += `${scope}["${name}"] = ` + content + ";";
1204
+ logStep(`Adding animation ${scope}.${name}`);
1205
+ }
1206
+ return {
1207
+ js
1208
+ };
1209
+ }
1210
+ return undefined;
1211
+ };
1212
+ const createNamespace = (parts)=>{
1213
+ let code = `var ${parts[0]};`;
1214
+ for(let index = 0; index < parts.length; index++){
1215
+ const path = parts.slice(0, index + 1).join(".");
1216
+ code += `\n(${path} = ${path} || {});`;
1217
+ }
1218
+ return code;
1219
+ };
1220
+ let validateAnimationJson;
1221
+ const getAnimationJsonValidation = async ()=>{
1222
+ if (validateAnimationJson === undefined) {
1223
+ validateAnimationJson = new Ajv({
1224
+ coerceTypes: true,
1225
+ allErrors: true,
1226
+ removeAdditional: true,
1227
+ useDefaults: "empty",
1228
+ validateSchema: "log"
1229
+ }).compile(animationSchema);
1230
+ }
1231
+ return validateAnimationJson;
1232
+ };
1233
+
1234
+ // Stolen from ig.tools.core
1235
+ class PackageVersion {
1236
+ static #_ = // https://regex101.com/r/90PEY9/1
1237
+ this.fullTextMatcher = /(\d+)(\.(\d+)(\.(\d+)(\.(\d+))?(-([^\.]+)\.(\d+))?)?)?/;
1238
+ static #_2 = this.lineMatcher = /^(\d+)(\.(\d+)(\.(\d+)(\.(\d+))?(-([^\.]+)\.(\d+))?)?)?$/;
1239
+ static extractFromText(input, description) {
1240
+ if (input === undefined) {
1241
+ throw new Error(`Can not parse version from undefined`);
1242
+ }
1243
+ const match = input.match(PackageVersion.fullTextMatcher);
1244
+ if (!match) {
1245
+ throw new Error(`Could not extract a version from input: ${input}`);
1246
+ }
1247
+ return PackageVersion.fromMatch(match, description);
1248
+ }
1249
+ static extractFromLine(input, description) {
1250
+ if (input === undefined) {
1251
+ throw new Error(`Can not parse version from undefined`);
1252
+ }
1253
+ const match = input.match(PackageVersion.lineMatcher);
1254
+ if (!match) {
1255
+ throw new Error(`Could not parse version from input: ${input}`);
1256
+ }
1257
+ return PackageVersion.fromMatch(match, description);
1258
+ }
1259
+ static equals(a, b, checkPrerelease = false) {
1260
+ if (a.major !== b.major || a.minor !== b.minor || a.patch !== b.patch) {
1261
+ return false;
1262
+ }
1263
+ if (checkPrerelease === false) {
1264
+ return true;
1265
+ }
1266
+ if (a.preRelease === b.preRelease) {
1267
+ return true;
1268
+ }
1269
+ if (a.preRelease === undefined || b.preRelease === undefined) {
1270
+ return false;
1271
+ }
1272
+ return a.preRelease.type === b.preRelease.type && a.preRelease.version === b.preRelease.version;
1273
+ }
1274
+ static fromMatch([, major, , minor = "0", , patch = "0", , build, , preReleaseType, preReleaseNumber], description) {
1275
+ let preRelease = undefined;
1276
+ let buildNumber = 100;
1277
+ if (preReleaseType && preReleaseNumber) {
1278
+ preRelease = {
1279
+ type: preReleaseType,
1280
+ version: parseInt(preReleaseNumber)
1281
+ };
1282
+ }
1283
+ if (build) {
1284
+ buildNumber = Number(build);
1285
+ } else if (description) {
1286
+ const descriptionMatch = description.match(/(\d+)\)$/);
1287
+ if (descriptionMatch) {
1288
+ buildNumber = parseInt(descriptionMatch[1]);
1289
+ }
1290
+ }
1291
+ return new PackageVersion(parseInt(major), parseInt(minor), parseInt(patch), preRelease, buildNumber);
1292
+ }
1293
+ static sort(a, b, ascending = true) {
1294
+ const createSortResult = (a, b)=>ascending ? a - b : b - a;
1295
+ if (a.major !== b.major) {
1296
+ return createSortResult(a.major, b.major);
1297
+ }
1298
+ if (a.minor !== b.minor) {
1299
+ return createSortResult(a.minor, b.minor);
1300
+ }
1301
+ if (a.patch !== b.patch) {
1302
+ return createSortResult(a.patch, b.patch);
1303
+ }
1304
+ return createSortResult(a.preRelease ? a.preRelease.version : 0, b.preRelease ? b.preRelease.version : 0);
1305
+ }
1306
+ static toNumber(version) {
1307
+ return ((version.major * 1000 + version.minor) * 1000 + version.patch) * 1000 + version.buildNumber;
1308
+ }
1309
+ constructor(major, minor, patch, preRelease, buildNumber){
1310
+ this.major = major;
1311
+ this.minor = minor;
1312
+ this.patch = patch;
1313
+ this.preRelease = preRelease;
1314
+ this.buildNumber = buildNumber;
1315
+ }
1316
+ isPreRelease() {
1317
+ return this.preRelease !== undefined;
1318
+ }
1319
+ clone() {
1320
+ return new PackageVersion(this.major, this.minor, this.patch, this.preRelease ? {
1321
+ ...this.preRelease
1322
+ } : undefined, this.buildNumber);
1323
+ }
1324
+ incrementMajor() {
1325
+ this.preRelease = undefined;
1326
+ this.patch = 0;
1327
+ this.minor = 0;
1328
+ this.major++;
1329
+ }
1330
+ incrementMinor() {
1331
+ this.preRelease = undefined;
1332
+ this.patch = 0;
1333
+ this.minor++;
1334
+ }
1335
+ incrementPatch() {
1336
+ this.preRelease = undefined;
1337
+ this.patch++;
1338
+ }
1339
+ createPreRelease(type) {
1340
+ if (!this.preRelease) {
1341
+ this.buildNumber = 1;
1342
+ } else {
1343
+ this.buildNumber++;
1344
+ }
1345
+ if (this.preRelease && type === this.preRelease.type) {
1346
+ this.preRelease.version++;
1347
+ return;
1348
+ }
1349
+ this.preRelease = {
1350
+ version: 0,
1351
+ type
1352
+ };
1353
+ }
1354
+ createRelease() {
1355
+ this.preRelease = undefined;
1356
+ this.buildNumber = 100;
1357
+ }
1358
+ toVersionString({ buildNumber } = {}) {
1359
+ let version = [
1360
+ this.major,
1361
+ this.minor,
1362
+ this.patch
1363
+ ].join(".");
1364
+ if (buildNumber) {
1365
+ version += "." + this.buildNumber;
1366
+ }
1367
+ if (this.preRelease) {
1368
+ version += `-${this.preRelease.type}.${this.preRelease.version}`;
1369
+ }
1370
+ return version;
1371
+ }
1372
+ toDescriptionString(packageName) {
1373
+ const base = [
1374
+ this.major,
1375
+ this.minor,
1376
+ this.patch
1377
+ ].join(".");
1378
+ const parts = [
1379
+ packageName,
1380
+ base
1381
+ ];
1382
+ if (this.preRelease) {
1383
+ parts.push(upperCaseFirst(this.preRelease.type));
1384
+ parts.push(this.preRelease.version);
1385
+ }
1386
+ parts.push(`(${base}.${this.buildNumber})`);
1387
+ return parts.join(" ");
1388
+ }
1389
+ /**
1390
+ * Determines wether the version is lesser than the input version
1391
+ *
1392
+ * @param {PackageVersion} version
1393
+ * @returns
1394
+ */ isLesserThan(version) {
1395
+ return PackageVersion.toNumber(this) < PackageVersion.toNumber(version);
1396
+ }
1397
+ /**
1398
+ * Determines wether the version is greater than the input version
1399
+ *
1400
+ * @param {PackageVersion} version
1401
+ * @returns
1402
+ */ isGreaterThan(version) {
1403
+ return PackageVersion.toNumber(this) > PackageVersion.toNumber(version);
1404
+ }
1405
+ }
1406
+ const upperCaseFirst = (input)=>{
1407
+ return input.slice(0, 1).toUpperCase() + input.slice(1);
1408
+ };
1409
+
1410
+ async function buildFolders(options) {
1411
+ if (options.outDir !== undefined && options.clean) {
1412
+ await fs$1.rm(options.outDir, {
1413
+ recursive: true
1414
+ });
1415
+ }
1416
+ const baseReporter = options.reporter ?? consoleReporter;
1417
+ const workspace = options.workspace;
1418
+ const folders = options.packages;
1419
+ let sortedPackages = sortPackagesByBuildOrder(folders);
1420
+ let index = 1;
1421
+ const manifests = new Map(sortedPackages.map((location)=>[
1422
+ location,
1423
+ readPackageCreatorManifest(location)
1424
+ ]));
1425
+ const maxNameLength = Array.from(manifests.values(), (manifest)=>manifest.Package.length).reduce((acc, length)=>Math.max(acc, length), 0);
1426
+ for (const location of sortedPackages){
1427
+ const tsConfig = await ensureTsConfig(location);
1428
+ const data = manifests.get(location);
1429
+ const reporter = options.preparedReporter ?? createPackageScopedReporter(baseReporter, data.Package, index, folders.length, maxNameLength);
1430
+ const outputDirectory = options.outDir || location.scriptsDir;
1431
+ await fs$1.mkdir(outputDirectory, {
1432
+ recursive: true
1433
+ });
1434
+ const manager = new BuildManager(data, (result)=>writeBuildResult(result, data, location, workspace, outputDirectory, options.minimize, reporter), reporter);
1435
+ if (options.banner) {
1436
+ manager.addParticipant("banner", createBannerCommentBuildParticipant(options.banner));
1437
+ }
1438
+ const typescriptFiles = getPackageTypescriptFiles(location);
1439
+ if (!typescriptFiles.some((file)=>path.basename(file).toLowerCase() === "version.ts")) {
1440
+ manager.addParticipant("version", createVersionLogBuildParticipant(data));
1441
+ }
1442
+ if (typescriptFiles.length > 0) {
1443
+ if (isScriptPackageModules(tsConfig.options)) {
1444
+ const { createRollupBuildParticipant } = await import('./rollup-BITLKeAN.mjs');
1445
+ manager.addParticipant("rollup", createRollupBuildParticipant(location, data, outputDirectory));
1446
+ } else {
1447
+ manager.addParticipant("tsc", createTSCBuildParticipant(location, outputDirectory));
1448
+ }
1449
+ }
1450
+ manager.addParticipant("animation", createAnimationBuildParticipant(location, data));
1451
+ await new Promise((resolve, reject)=>{
1452
+ manager.addListener("start", ()=>{
1453
+ reporter.log(`Build started`);
1454
+ });
1455
+ manager.addListener("error", (error)=>{
1456
+ reject(new Error(error));
1457
+ });
1458
+ manager.addListener("build", ()=>{
1459
+ reporter.log(`Build complete`);
1460
+ resolve();
1461
+ });
1462
+ manager.run();
1463
+ });
1464
+ if (options.docs) {
1465
+ reporter.log("Generating typedoc documentation");
1466
+ await generateDocs(location, path.join(outputDirectory, `${data.Package}.d.ts`), path.join(workspace.path, "docs", data.Package), data.Package);
1467
+ }
1468
+ index++;
1469
+ }
1470
+ }
1471
+ async function buildFoldersWatch(options) {
1472
+ if (options.outDir !== undefined && options.clean) {
1473
+ await fs$1.rm(options.outDir, {
1474
+ recursive: true
1475
+ });
1476
+ }
1477
+ const workspace = options.workspace;
1478
+ const folders = options.packages;
1479
+ let sortedPackages = sortPackagesByBuildOrder(folders);
1480
+ let index = 1;
1481
+ const manifests = new Map(sortedPackages.map((location)=>[
1482
+ location,
1483
+ readPackageCreatorManifest(location)
1484
+ ]));
1485
+ const maxNameLength = Array.from(manifests.values(), (manifest)=>manifest.Package.length).reduce((acc, length)=>Math.max(acc, length), 0);
1486
+ for (const location of sortedPackages){
1487
+ const tsConfig = await ensureTsConfig(location);
1488
+ const baseReporter = options.reporter ?? consoleReporter;
1489
+ const data = manifests.get(location);
1490
+ const reporter = createPackageScopedReporter(baseReporter, data.Package, index, folders.length, maxNameLength);
1491
+ const outputDirectory = options.outDir || location.scriptsDir;
1492
+ await fs$1.mkdir(outputDirectory, {
1493
+ recursive: true
1494
+ });
1495
+ const manager = new BuildManager(data, (result)=>writeBuildResult(result, data, location, workspace, outputDirectory, options.minimize, reporter), reporter);
1496
+ if (options.banner) {
1497
+ manager.addParticipant("banner", createBannerCommentBuildParticipant(options.banner));
1498
+ }
1499
+ const typescriptFiles = getPackageTypescriptFiles(location);
1500
+ if (!typescriptFiles.some((file)=>path.basename(file).toLowerCase() === "version.ts")) {
1501
+ manager.addParticipant("version", createVersionLogBuildParticipant(data));
1502
+ }
1503
+ if (typescriptFiles.length > 0) {
1504
+ if (isScriptPackageModules(tsConfig.options)) {
1505
+ const { createRollupWatchBuildParticipant } = await import('./rollup-BITLKeAN.mjs');
1506
+ manager.addParticipant("rollup", createRollupWatchBuildParticipant(location, data, outputDirectory));
1507
+ } else {
1508
+ manager.addParticipant("tsc", createTSCWatchBuildParticipant(location, outputDirectory));
1509
+ }
1510
+ }
1511
+ manager.addParticipant("animation", createAnimationWatchBuildParticipant(location, data));
1512
+ await new Promise((resolve, reject)=>{
1513
+ manager.addListener("start", ()=>{
1514
+ reporter.log(`Build started`);
1515
+ });
1516
+ manager.addListener("error", (error)=>{
1517
+ reporter.log(`Build failed: ${EOL}${error}`);
1518
+ resolve();
1519
+ });
1520
+ manager.addListener("build", ()=>{
1521
+ reporter.log(`Build complete`);
1522
+ resolve();
1523
+ });
1524
+ manager.run();
1525
+ });
1526
+ index++;
1527
+ }
1528
+ await new Promise(()=>{});
1529
+ }
1530
+ async function writeBuildResult(buildResult, manifest, location, workspace, outputDirectory, minimize, reporter) {
1531
+ let js = buildResult.js;
1532
+ if (buildResult.sourceMap) {
1533
+ js += `\n//# sourceMappingURL=${manifest.Package}.js.map`;
1534
+ }
1535
+ await fs$1.writeFile(path.join(outputDirectory, `${manifest.Package}.js`), js, {
1536
+ encoding: "utf8"
1537
+ });
1538
+ if (buildResult.declarations !== undefined) {
1539
+ await fs$1.writeFile(path.join(outputDirectory, `${manifest.Package}.d.ts`), buildResult.declarations, {
1540
+ encoding: "utf8"
1541
+ });
1542
+ }
1543
+ if (buildResult.sourceMap !== undefined) {
1544
+ await fs$1.writeFile(path.join(outputDirectory, `${manifest.Package}.js.map`), buildResult.sourceMap, {
1545
+ encoding: "utf8"
1546
+ });
1547
+ }
1548
+ if (minimize) {
1549
+ reporter.log("Minifying the output");
1550
+ const minifyResult = await terser.minify(js, {
1551
+ ecma: 5,
1552
+ sourceMap: {
1553
+ content: buildResult.sourceMap,
1554
+ includeSources: false
1555
+ }
1556
+ });
1557
+ const minifiedPath = path.join(outputDirectory, `${manifest.Package}.min.js`);
1558
+ await fs$1.writeFile(minifiedPath, minifyResult.code, {
1559
+ encoding: "utf8"
1560
+ });
1561
+ if (minifyResult.map !== undefined) {
1562
+ await fs$1.writeFile(minifiedPath + ".map", typeof minifyResult.map === "string" ? minifyResult.map : JSON.stringify(minifyResult.map), {
1563
+ encoding: "utf8"
1564
+ });
1565
+ }
1566
+ }
1567
+ if (location.path.includes("Basics") && buildResult.declarations !== undefined) {
1568
+ await fs$1.mkdir(path.join(workspace.path, "lib"), {
1569
+ recursive: true
1570
+ });
1571
+ reporter.log("Copying basics definition file to the lib folder");
1572
+ await fs$1.writeFile(path.join(workspace.path, "lib", `${manifest.Package}.d.ts`), buildResult.declarations, {
1573
+ encoding: "utf8"
1574
+ });
1575
+ }
1576
+ }
1577
+ function createVersionLogBuildParticipant(manifest) {
1578
+ return (env)=>{
1579
+ env.onBuildStart();
1580
+ const parsedVersion = manifest.Version !== undefined ? PackageVersion.extractFromLine(manifest.Version) : undefined;
1581
+ let logText;
1582
+ if (parsedVersion !== undefined) {
1583
+ logText = parsedVersion.toDescriptionString(manifest.Package);
1584
+ } else {
1585
+ logText = manifest.Package;
1586
+ }
1587
+ logText += ".";
1588
+ if (manifest.Copyright !== undefined) {
1589
+ logText += " " + manifest.Copyright;
1590
+ }
1591
+ env.onBuildEnd({
1592
+ type: "success",
1593
+ artefacts: {
1594
+ js: `console.log(${JSON.stringify(logText)})`
1595
+ }
1596
+ });
1597
+ return {
1598
+ destroy: ()=>{}
1599
+ };
1600
+ };
1601
+ }
1602
+ function createBannerCommentBuildParticipant(options) {
1603
+ return (env)=>{
1604
+ env.onBuildStart();
1605
+ const banner = createBannerComment(options);
1606
+ env.onBuildEnd({
1607
+ type: "success",
1608
+ artefacts: {
1609
+ js: banner ?? "",
1610
+ declarations: banner ?? ""
1611
+ }
1612
+ });
1613
+ return {
1614
+ destroy: ()=>{}
1615
+ };
1616
+ };
1617
+ }
1618
+ async function ensureTsConfig(location) {
1619
+ const tsconfigPath = path.join(location.scriptsDir, "tsconfig.json");
1620
+ try {
1621
+ const content = JSON.parse(await fs$1.readFile(tsconfigPath, "utf8"));
1622
+ applyTsConfigOptions(content);
1623
+ await fs$1.writeFile(tsconfigPath, JSON.stringify(content, undefined, "\t"), "utf8");
1624
+ return ts.parseJsonConfigFileContent(content, ts.sys, location.scriptsDir);
1625
+ } catch (err) {
1626
+ if (!isErrorENOENT(err)) {
1627
+ throw err;
1628
+ }
1629
+ const content = {};
1630
+ applyTsConfigOptions(content);
1631
+ await fs$1.writeFile(tsconfigPath, JSON.stringify(content, undefined, "\t"), "utf8");
1632
+ return ts.parseJsonConfigFileContent(content, ts.sys, location.scriptsDir);
1633
+ }
1634
+ }
1635
+ function applyTsConfigOptions(data) {
1636
+ var _data_compilerOptions_module, _data_compilerOptions;
1637
+ if ((_data_compilerOptions = data.compilerOptions) == null ? void 0 : (_data_compilerOptions_module = _data_compilerOptions.module) == null ? void 0 : _data_compilerOptions_module.toLowerCase().startsWith("es")) {
1638
+ data.compilerOptions = data.compilerOptions ?? {};
1639
+ data.compilerOptions.target = "esnext";
1640
+ data.compilerOptions.lib = [
1641
+ "esnext",
1642
+ "dom"
1643
+ ];
1644
+ data.compilerOptions.module = "es2015";
1645
+ data.compilerOptions.moduleResolution = "node";
1646
+ } else {
1647
+ data.compilerOptions = data.compilerOptions ?? {};
1648
+ data.compilerOptions.target = "es5";
1649
+ data.compilerOptions.lib = [
1650
+ "es5",
1651
+ "dom"
1652
+ ];
1653
+ }
1654
+ }
1655
+ function sortPackagesByBuildOrder(folders) {
1656
+ const packages = Array.from(folders).reduce((acc, location)=>{
1657
+ const data = readPackageNpmManifest(location);
1658
+ if (data !== undefined) {
1659
+ acc[data.name] = {
1660
+ data,
1661
+ location
1662
+ };
1663
+ } else {
1664
+ acc[location.path] = {
1665
+ data: undefined,
1666
+ location
1667
+ };
1668
+ }
1669
+ return acc;
1670
+ }, {});
1671
+ const packageDependencies = Object.getOwnPropertyNames(packages).reduce((acc, packageName)=>{
1672
+ const packageData = packages[packageName];
1673
+ if (packageData.data === undefined) {
1674
+ acc[packageName] = [];
1675
+ } else {
1676
+ acc[packageName] = Object.getOwnPropertyNames({
1677
+ ...packageData.data.devDependencies,
1678
+ ...packageData.data.dependencies,
1679
+ ...packageData.data.peerDependencies
1680
+ }).filter((packageName)=>packages[packageName] !== undefined);
1681
+ }
1682
+ return acc;
1683
+ }, {});
1684
+ const sortedPackages = toposort(packageDependencies);
1685
+ const result = [];
1686
+ for (const packageName of sortedPackages){
1687
+ const location = packages[packageName].location;
1688
+ if (readPackageCreatorManifest(location).Package.endsWith(".Basics")) {
1689
+ result.unshift(location);
1690
+ } else {
1691
+ result.push(location);
1692
+ }
1693
+ }
1694
+ return result;
1695
+ }
1696
+ function createBannerComment(banner) {
1697
+ const bannerParts = [];
1698
+ if (banner.text) {
1699
+ bannerParts.push(" * " + banner.text);
1700
+ }
1701
+ {
1702
+ const details = [];
1703
+ if (banner.version) {
1704
+ details.push(`Version: ${banner.version}`);
1705
+ }
1706
+ if (banner.commit) {
1707
+ if (banner.commitDirty) {
1708
+ details.push(`Commit: ${banner.commit} (dirty)`);
1709
+ } else {
1710
+ details.push(`Commit: ${banner.commit}`);
1711
+ }
1712
+ }
1713
+ if (banner.date) {
1714
+ details.push(`Date: ${banner.date.toISOString()}`);
1715
+ }
1716
+ const detailsText = details.map((line)=>` * ${line}`).join("\n");
1717
+ if (detailsText) {
1718
+ bannerParts.push(detailsText);
1719
+ }
1720
+ }
1721
+ const bannerText = bannerParts.join("\n\n");
1722
+ if (bannerText) {
1723
+ return `/*
1724
+ ${bannerText}
1725
+ *
1726
+ * @preserve
1727
+ */`;
1728
+ }
1729
+ return undefined;
1730
+ }
1731
+
1732
+ const getVersionInformationFromGit = async (workspaceLocation, packageLocation)=>{
1733
+ try {
1734
+ var _log_latest, _log_latest1;
1735
+ const git = simpleGit({
1736
+ baseDir: workspaceLocation.path
1737
+ });
1738
+ // check wether the files for a folder are changed
1739
+ // if so, mark as dirty
1740
+ const diff = await git.diffSummary();
1741
+ const dirty = diff.files.some((file)=>{
1742
+ if (file.file.toLowerCase().includes("releases") || file.file.toLowerCase().endsWith("version.ts") || file.file.toLowerCase().endsWith("package.json")) {
1743
+ return false;
1744
+ }
1745
+ const fullPath = path.resolve(workspaceLocation.path, file.file);
1746
+ const relativePath = path.relative(packageLocation.path, fullPath);
1747
+ return !relativePath.startsWith("..");
1748
+ });
1749
+ const log = await git.log({
1750
+ maxCount: 1
1751
+ });
1752
+ const commit = !((_log_latest = log.latest) == null ? void 0 : _log_latest.hash) ? undefined : log.latest.hash.substring(0, 7);
1753
+ return {
1754
+ commit,
1755
+ dirty,
1756
+ commitDate: (_log_latest1 = log.latest) == null ? void 0 : _log_latest1.date
1757
+ };
1758
+ } catch (err) {
1759
+ return {};
1760
+ }
1761
+ };
1762
+
1763
+ const getWorkspaceBannerText = (manifest)=>{
1764
+ var _manifest_packager;
1765
+ let bannerText = manifest == null ? void 0 : (_manifest_packager = manifest.packager) == null ? void 0 : _manifest_packager.banner;
1766
+ if (bannerText) {
1767
+ const match = bannerText.match(/Copyright \(C\) (\d+)( ?- ?(\d+))?/);
1768
+ if (match !== null) {
1769
+ const startYear = parseInt(match[1]);
1770
+ const endYear = new Date().getFullYear();
1771
+ if (startYear !== endYear) {
1772
+ bannerText = bannerText.replace(match[0], `Copyright (C) ${startYear} - ${endYear}`);
1773
+ } else {
1774
+ bannerText = bannerText.replace(match[0], `Copyright (C) ${startYear}`);
1775
+ }
1776
+ }
1777
+ }
1778
+ return bannerText;
1779
+ };
1780
+
1781
+ const parseVersionFromString = (input)=>{
1782
+ if (input === undefined) {
1783
+ throw new Error(`Can not parse version from undefined`);
1784
+ }
1785
+ let match;
1786
+ let major;
1787
+ let minor;
1788
+ let patch;
1789
+ let build;
1790
+ let preReleaseType;
1791
+ let preReleaseNumber;
1792
+ if (// first try to find a full match with build number
1793
+ (match = input.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)(-([^\.]+)\.(\d+))?/)) !== null) {
1794
+ [, major, minor, patch, build, preReleaseType, preReleaseNumber] = match;
1795
+ } else if ((match = input.match(/(\d+)\.(\d+)\.(\d+)(-([^\.]+)\.(\d+))?/)) !== null) {
1796
+ [, major, minor, patch, , preReleaseType, preReleaseNumber] = match;
1797
+ }
1798
+ if (match === null) {
1799
+ throw new Error(`Could not parse version from input: ${input}`);
1800
+ }
1801
+ let preRelease = undefined;
1802
+ let buildNumber = 100;
1803
+ if (preReleaseType && preReleaseNumber) {
1804
+ preRelease = {
1805
+ type: preReleaseType,
1806
+ version: parseInt(preReleaseNumber)
1807
+ };
1808
+ }
1809
+ if (build) {
1810
+ buildNumber = Number(build);
1811
+ } else if (input) {
1812
+ const descriptionMatch = input.match(/(\d+)\)$/);
1813
+ if (descriptionMatch) {
1814
+ buildNumber = parseInt(descriptionMatch[1]);
1815
+ }
1816
+ }
1817
+ return new PackageVersion(parseInt(major), parseInt(minor), parseInt(patch), preRelease, buildNumber);
1818
+ };
1819
+ // 1000001001 -> 1.0.1.1
1820
+ // 1002017001 -> 1.2.17.1
1821
+ const parseVersionFromNumericVersion = (version)=>{
1822
+ const major = Math.floor(version / 1000000000);
1823
+ const minor = Math.floor(version % 1000000000 / 1000000);
1824
+ const patch = Math.floor(version % 1000000 / 1000);
1825
+ const buildNumber = version % 1000;
1826
+ return new PackageVersion(major, minor, patch, undefined, buildNumber);
1827
+ };
1828
+
1829
+ // https://regex101.com/r/LtGAu5/1
1830
+ const logRegex = /console\.log\(\s*"([\w\s\.\(\)]+)\ *Copyright[\w\s\(\)\.]+(\d{4}|\d{4} - \d{4})([\w\s\(\)\.]+)?",?\s*\)/i;
1831
+ const currentYear = new Date(Date.now()).getFullYear();
1832
+ function getVersionFileHandler(location) {
1833
+ const filePath = path.join(location.scriptsDir, "Version.ts");
1834
+ function invalidVersionFile(versionFile, exists) {
1835
+ return {
1836
+ exists,
1837
+ write: (name, newVersion)=>{
1838
+ const scriptsContent = fs.readdirSync(location.scriptsDir);
1839
+ const tsFiles = scriptsContent.filter((file)=>file.endsWith(".ts"));
1840
+ if (tsFiles.length > 0) {
1841
+ return createVersionFileWriter([
1842
+ currentYear
1843
+ ], "")(name, newVersion);
1844
+ }
1845
+ },
1846
+ reset: ()=>{
1847
+ if (versionFile !== undefined) {
1848
+ fs.writeFileSync(filePath, versionFile, {
1849
+ encoding: "utf8"
1850
+ });
1851
+ } else {
1852
+ try {
1853
+ fs.rmSync(filePath);
1854
+ } catch (err) {
1855
+ if (!isErrorENOENT(err)) {
1856
+ throw err;
1857
+ }
1858
+ }
1859
+ }
1860
+ }
1861
+ };
1862
+ }
1863
+ function createVersionFileWriter(copyright = [
1864
+ currentYear
1865
+ ], copyrightStuff = "") {
1866
+ return (name, newVersion)=>{
1867
+ const descriptionText = newVersion.toDescriptionString(name);
1868
+ const copyrightText = createYearString(copyright);
1869
+ const result = `console.log("${descriptionText}. Copyright (C) ${copyrightText}${copyrightStuff}");`;
1870
+ fs.writeFileSync(filePath, result, {
1871
+ encoding: "utf-8"
1872
+ });
1873
+ };
1874
+ }
1875
+ let rawVersionFile = readStringFromFileOrUndefined(filePath);
1876
+ if (rawVersionFile === undefined) {
1877
+ return invalidVersionFile(rawVersionFile, false);
1878
+ }
1879
+ const versionFile = rawVersionFile.replace(/\n/g, "");
1880
+ const match = versionFile.match(logRegex);
1881
+ if (!match) {
1882
+ return invalidVersionFile(versionFile, true);
1883
+ }
1884
+ const [_full, _description, copyright, copyrightStuff] = match;
1885
+ const copyrightYears = copyright.match(/^(\d+)( ?- ?(\d+))?$/);
1886
+ let years;
1887
+ if (copyrightYears === null) {
1888
+ years = [
1889
+ currentYear
1890
+ ];
1891
+ } else {
1892
+ years = [
1893
+ Number(copyrightYears[1]),
1894
+ currentYear
1895
+ ];
1896
+ }
1897
+ return {
1898
+ exists: true,
1899
+ write: createVersionFileWriter(years, copyrightStuff),
1900
+ reset: ()=>{
1901
+ fs.writeFileSync(filePath, versionFile, {
1902
+ encoding: "utf8"
1903
+ });
1904
+ }
1905
+ };
1906
+ }
1907
+ const createYearString = (years)=>{
1908
+ if (years[1] === undefined || years[0] === years[1]) {
1909
+ return years[0].toString();
1910
+ }
1911
+ return `${years[0]} - ${years[1]}`;
1912
+ };
1913
+
1914
+ const buildArchiveFromPublishedPackage = (location, manifest, creatorPackage)=>{
1915
+ const archive = new JSZip();
1916
+ archive.file(PACKAGE_FILE, JSON.stringify(creatorPackage, null, 2));
1917
+ const index = readPublishedPackageCreatorIndex(location);
1918
+ if (index !== undefined) {
1919
+ archive.file(INDEX_FILE, JSON.stringify(index, null, 2));
1920
+ }
1921
+ archive.file(manifest.main, fs.createReadStream(path.join(location.path, manifest.main)));
1922
+ if (creatorPackage.Package === "IG.GFX.Standard") {
1923
+ const source = path.join(location.path, "Images");
1924
+ if (fs.existsSync(source)) {
1925
+ const images = fs.readdirSync(source);
1926
+ for (const file of images){
1927
+ const { ext } = path.parse(file);
1928
+ switch(ext){
1929
+ case ".png":
1930
+ case ".jpeg":
1931
+ case ".jpg":
1932
+ break;
1933
+ default:
1934
+ continue;
1935
+ }
1936
+ archive.file(file, fs.createReadStream(path.join(source, file)));
1937
+ }
1938
+ }
1939
+ }
1940
+ return archive;
1941
+ };
1942
+ const runtimeScripts = [
1943
+ "Interactor",
1944
+ "Core",
1945
+ "Mixed"
1946
+ ];
1947
+ const notRuntimeScripts = [
1948
+ "Context",
1949
+ "Evaluator"
1950
+ ];
1951
+ const buildArchiveFromPackage = async (reporter, packageLocation, data, binDir, minified = true)=>{
1952
+ const { domain } = parseCreatorPackageName(data);
1953
+ const scriptDirectories = [
1954
+ packageLocation.path,
1955
+ packageLocation.scriptsDir
1956
+ ];
1957
+ if (data.Package === "IG.GFX.Standard") {
1958
+ reporter.log(`Including Images folder`);
1959
+ scriptDirectories.push(path.join(packageLocation.path, "Images"));
1960
+ }
1961
+ const manifest = readPackageCreatorManifest(packageLocation);
1962
+ if (manifest !== undefined) {
1963
+ if (manifest.RunTime && notRuntimeScripts.includes(manifest.Type)) {
1964
+ reporter.log("Setting script RunTime to false because of script type");
1965
+ writePackageCreatorManifest(packageLocation, {
1966
+ ...manifest,
1967
+ RunTime: false
1968
+ });
1969
+ } else if (!manifest.RunTime && runtimeScripts.includes(manifest.Type)) {
1970
+ reporter.log("Setting script RunTime to true because of script type");
1971
+ writePackageCreatorManifest(packageLocation, {
1972
+ ...manifest,
1973
+ RunTime: true
1974
+ });
1975
+ }
1976
+ }
1977
+ let libFile;
1978
+ try {
1979
+ const libFilePath = minified ? path.join(binDir, `${data.Package}.min.js`) : path.join(binDir, `${data.Package}.js`);
1980
+ libFile = fs.readFileSync(libFilePath, {
1981
+ encoding: "utf8"
1982
+ });
1983
+ } catch (err) {
1984
+ if (!isErrorENOENT(err)) {
1985
+ throw err;
1986
+ }
1987
+ }
1988
+ const archive = new JSZip();
1989
+ let library = "";
1990
+ if (libFile) {
1991
+ library = libFile;
1992
+ }
1993
+ if (!library) {
1994
+ const date = new Date(Date.now());
1995
+ library = `/* This file is part of the ${domain} Data Packages.
1996
+ * Copyright (C) ${date.getFullYear()} intelligentgraphics. All Rights Reserved. */`;
1997
+ }
1998
+ archive.file(`${data.Package}.js`, library);
1999
+ archive.file(PACKAGE_FILE, JSON.stringify(data, null, 2));
2000
+ const creatorIndex = readPackageCreatorIndex(packageLocation);
2001
+ if (creatorIndex !== undefined) {
2002
+ archive.file(INDEX_FILE, JSON.stringify(creatorIndex, null, 2));
2003
+ }
2004
+ for (const directory of scriptDirectories){
2005
+ try {
2006
+ for (const file of fs.readdirSync(directory)){
2007
+ const { ext } = path.parse(file);
2008
+ switch(ext){
2009
+ case ".png":
2010
+ case ".jpeg":
2011
+ case ".jpg":
2012
+ break;
2013
+ default:
2014
+ continue;
2015
+ }
2016
+ archive.file(file, fs.createReadStream(path.join(directory, file)));
2017
+ }
2018
+ } catch (err) {
2019
+ reporter.error(`Script directory "${directory}" does not exist`);
2020
+ }
2021
+ }
2022
+ return archive;
2023
+ };
2024
+
2025
+ const createAssetServiceSessionManager = async (params)=>{
2026
+ const targetSession = await startSession(params);
2027
+ let basicsSession;
2028
+ return {
2029
+ getBasicsSession: async ()=>{
2030
+ if (targetSession.subDomain === "Basics") {
2031
+ return targetSession;
2032
+ }
2033
+ if (basicsSession === undefined) {
2034
+ basicsSession = await startSession({
2035
+ ...params,
2036
+ subDomain: "Basics"
2037
+ });
2038
+ }
2039
+ return basicsSession;
2040
+ },
2041
+ getTargetSession: ()=>targetSession,
2042
+ destroy: async ()=>{
2043
+ await closeSession(targetSession);
2044
+ if (basicsSession !== undefined) {
2045
+ await closeSession(basicsSession);
2046
+ }
2047
+ }
2048
+ };
2049
+ };
2050
+
2051
+ const synchronizeDependencies = async (workspaceLocation, creatorPackage, sessionManager, prompter, reporter, logUpToDate = false)=>{
2052
+ const libraries = determineWorkspaceIGLibraries(workspaceLocation);
2053
+ // If there are no libraries, we don't need to check for required versions
2054
+ if (libraries.length === 0) {
2055
+ return true;
2056
+ }
2057
+ const targetSession = sessionManager.getTargetSession();
2058
+ const rawUploadedPackages = await getExistingPackages(targetSession);
2059
+ const uploadedPackages = rawUploadedPackages.map((entry)=>{
2060
+ let version;
2061
+ try {
2062
+ version = parseVersionFromNumericVersion(entry.numericVersion);
2063
+ } catch (err) {
2064
+ throw new Error(`Encountered invalid format for version ${entry.numericVersion}`);
2065
+ }
2066
+ if (version.buildNumber < 100) {
2067
+ version.preRelease = {
2068
+ type: "beta",
2069
+ version: version.buildNumber
2070
+ };
2071
+ } else if (version.buildNumber > 100) {
2072
+ version.preRelease = {
2073
+ type: "patch",
2074
+ version: version.buildNumber - 100
2075
+ };
2076
+ }
2077
+ return {
2078
+ ...entry,
2079
+ version
2080
+ };
2081
+ });
2082
+ for (const libraryLocation of libraries){
2083
+ const libraryManifest = readPublishedPackageNpmManifest(libraryLocation);
2084
+ const libraryCreatorPackage = readPublishedPackageCreatorManifest(libraryLocation);
2085
+ if (libraryCreatorPackage === undefined || libraryManifest.main === undefined || libraryCreatorPackage.Package === (creatorPackage == null ? void 0 : creatorPackage.Package)) {
2086
+ continue;
2087
+ }
2088
+ const libraryVersion = PackageVersion.extractFromLine(libraryManifest.version);
2089
+ if (libraryVersion.preRelease) {
2090
+ libraryVersion.buildNumber = libraryVersion.preRelease.version;
2091
+ libraryVersion.preRelease = undefined;
2092
+ } else {
2093
+ libraryVersion.buildNumber = 100;
2094
+ }
2095
+ let uploadedPackageInBasics;
2096
+ let uploadedPackageInTarget;
2097
+ for (const uploadedPackage of uploadedPackages){
2098
+ if (uploadedPackage.scope === libraryCreatorPackage.Package) {
2099
+ if (uploadedPackage.support) {
2100
+ uploadedPackageInBasics = uploadedPackage;
2101
+ } else {
2102
+ uploadedPackageInTarget = uploadedPackage;
2103
+ }
2104
+ }
2105
+ }
2106
+ const validInBasics = uploadedPackageInBasics !== undefined && !uploadedPackageInBasics.version.isLesserThan(libraryVersion);
2107
+ const validInTarget = uploadedPackageInTarget !== undefined && !uploadedPackageInTarget.version.isLesserThan(libraryVersion);
2108
+ if (validInBasics || validInTarget) {
2109
+ if (targetSession.subDomain !== "Basics" && uploadedPackageInBasics !== undefined && uploadedPackageInTarget !== undefined) {
2110
+ reporter.log(`Package ${libraryCreatorPackage.Package} is uploaded both for Basics and ${targetSession.subDomain}. The package within ${targetSession.subDomain} will be used.`);
2111
+ }
2112
+ if (logUpToDate) {
2113
+ reporter.log(`Package ${libraryCreatorPackage.Package} is already uploaded with the required version ${libraryVersion.toVersionString({})}`);
2114
+ }
2115
+ continue;
2116
+ }
2117
+ const possibleTargets = [];
2118
+ if (uploadedPackageInBasics) {
2119
+ const version = uploadedPackageInBasics.version.toVersionString({
2120
+ buildNumber: true
2121
+ });
2122
+ possibleTargets.push({
2123
+ value: "Basics",
2124
+ name: `Basics (Current: ${version})`
2125
+ });
2126
+ } else {
2127
+ possibleTargets.push({
2128
+ value: "Basics",
2129
+ name: "Basics (Current: None)"
2130
+ });
2131
+ }
2132
+ if (targetSession.subDomain !== "Basics") {
2133
+ if (uploadedPackageInTarget) {
2134
+ const version = uploadedPackageInTarget.version.toVersionString({
2135
+ buildNumber: true
2136
+ });
2137
+ possibleTargets.push({
2138
+ value: targetSession.subDomain,
2139
+ name: `${targetSession.subDomain} (Current: ${version})`
2140
+ });
2141
+ } else {
2142
+ possibleTargets.push({
2143
+ value: targetSession.subDomain,
2144
+ name: `${targetSession.subDomain} (Current: None)`
2145
+ });
2146
+ }
2147
+ }
2148
+ const libraryVersionString = libraryVersion.toVersionString({
2149
+ buildNumber: true
2150
+ });
2151
+ const uploadTargetScope = await prompter.ask({
2152
+ message: `Version ${libraryVersionString} of dependency ${libraryCreatorPackage.Package} is required but not available. Please select a subdomain to upload the correct dependency version to`,
2153
+ options: [
2154
+ ...possibleTargets,
2155
+ {
2156
+ name: "Skip upload",
2157
+ value: "Skip"
2158
+ }
2159
+ ],
2160
+ default: possibleTargets[0].value
2161
+ });
2162
+ if (uploadTargetScope === "Skip") {
2163
+ continue;
2164
+ }
2165
+ const archive = buildArchiveFromPublishedPackage(libraryLocation, libraryManifest, libraryCreatorPackage);
2166
+ const newVersionString = libraryVersion.toVersionString({
2167
+ buildNumber: true
2168
+ });
2169
+ const session = uploadTargetScope === "Basics" ? await sessionManager.getBasicsSession() : targetSession;
2170
+ reporter.log(`Uploading package ${libraryCreatorPackage.Package} with version ${newVersionString} to ${session.domain}.${session.subDomain}`);
2171
+ await uploadPackageFromBuffer(session, {
2172
+ name: libraryCreatorPackage.Package,
2173
+ version: newVersionString
2174
+ }, await archive.generateAsync({
2175
+ type: "nodebuffer"
2176
+ }));
2177
+ }
2178
+ };
2179
+
2180
+ const execAsync = promisify(exec);
2181
+ const releaseFolder = async (options)=>{
2182
+ const workspace = options.workspace;
2183
+ const location = options.directory;
2184
+ const versionFile = getVersionFileHandler(location);
2185
+ const packageDescription = readPackageCreatorManifest(location);
2186
+ const fullPackageName = packageDescription.Package;
2187
+ const reporter = options.reporter ?? createPackageScopedReporter(consoleReporter, packageDescription.Package);
2188
+ const { domain, subdomain } = parseCreatorPackageName(packageDescription);
2189
+ const publishDomain = options.domain ?? domain;
2190
+ const publishSubdomain = options.subdomain ?? subdomain;
2191
+ const sharedPackageJson = readWorkspaceNpmManifest(workspace);
2192
+ let newVersion;
2193
+ try {
2194
+ newVersion = parseVersionFromString(options.newVersion);
2195
+ } catch (err) {
2196
+ throw new Error(`Please enter a version in this format 1.0.0.100`);
2197
+ }
2198
+ packageDescription.Version = newVersion.toVersionString({
2199
+ buildNumber: true
2200
+ });
2201
+ writePackageCreatorManifest(location, packageDescription);
2202
+ if (newVersion.buildNumber < 100) {
2203
+ newVersion.preRelease = {
2204
+ type: "beta",
2205
+ version: newVersion.buildNumber
2206
+ };
2207
+ } else if (newVersion.buildNumber > 100) {
2208
+ newVersion.preRelease = {
2209
+ type: "patch",
2210
+ version: newVersion.buildNumber - 100
2211
+ };
2212
+ }
2213
+ // if (sharedPackageJson !== undefined) {
2214
+ // reporter.log(
2215
+ // `Running npm install to make sure all dependencies are up to date`,
2216
+ // );
2217
+ // await execAsync(`npm install`, {
2218
+ // encoding: "utf-8",
2219
+ // cwd: workspace.path,
2220
+ // });
2221
+ // }
2222
+ const binDir = options.outDir ?? getWorkspaceOutputPath(workspace);
2223
+ await fs$1.mkdir(binDir, {
2224
+ recursive: true
2225
+ });
2226
+ let assetServerPackageDetails;
2227
+ let packageNameWithVersion;
2228
+ {
2229
+ const versionWithoutPrelease = newVersion.clone();
2230
+ versionWithoutPrelease.preRelease = undefined;
2231
+ const newVersionString = versionWithoutPrelease.toVersionString({
2232
+ buildNumber: true
2233
+ });
2234
+ packageNameWithVersion = `${packageDescription.Package}_${newVersionString}`;
2235
+ assetServerPackageDetails = {
2236
+ name: packageDescription.Package,
2237
+ version: newVersionString
2238
+ };
2239
+ }
2240
+ let zipFilePath = path.join(binDir, packageNameWithVersion + ".zip");
2241
+ let uploadable = {
2242
+ getStream: ()=>createReadStream(zipFilePath)
2243
+ };
2244
+ try {
2245
+ if (options.pushOnly) {
2246
+ const zipFileExists = await fs$1.stat(zipFilePath).catch((err)=>{
2247
+ if (isErrorENOENT(err)) {
2248
+ return false;
2249
+ }
2250
+ return Promise.reject(err);
2251
+ });
2252
+ if (zipFileExists) {
2253
+ throw new Error(`Expected a zip file to exist at path ${zipFilePath} since pushOnly is specified`);
2254
+ }
2255
+ } else {
2256
+ const gitVersionInformation = await getVersionInformationFromGit(workspace, location);
2257
+ if (versionFile.exists) {
2258
+ versionFile.write(fullPackageName, newVersion);
2259
+ }
2260
+ const bannerText = sharedPackageJson !== undefined ? getWorkspaceBannerText(sharedPackageJson) : undefined;
2261
+ await buildFolders({
2262
+ ...options,
2263
+ packages: [
2264
+ location
2265
+ ],
2266
+ banner: options.banner ? {
2267
+ text: bannerText,
2268
+ commit: gitVersionInformation.commit,
2269
+ commitDirty: gitVersionInformation.dirty,
2270
+ version: newVersion.toVersionString({
2271
+ buildNumber: true
2272
+ }),
2273
+ date: new Date(Date.now())
2274
+ } : undefined,
2275
+ preparedReporter: reporter
2276
+ });
2277
+ newVersion.preRelease = undefined;
2278
+ try {
2279
+ await fs$1.rm(zipFilePath);
2280
+ } catch (err) {
2281
+ if (!isErrorENOENT(err)) {
2282
+ throw err;
2283
+ }
2284
+ }
2285
+ if (readPackageAnimationList(location).length > 0) {
2286
+ var _workspaceManifest_dependencies;
2287
+ const workspaceManifest = readWorkspaceNpmManifest(workspace);
2288
+ if (!((_workspaceManifest_dependencies = workspaceManifest.dependencies) == null ? void 0 : _workspaceManifest_dependencies["@intelligentgraphics/3d.ig.gfx.standard"])) {
2289
+ const install = 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?`);
2290
+ if (install) {
2291
+ await execAsync(`npm install @intelligentgraphics/3d.ig.gfx.standard`, {
2292
+ encoding: "utf-8",
2293
+ cwd: workspace.path
2294
+ });
2295
+ await execAsync(`npm run postinstall`, {
2296
+ cwd: workspace.path
2297
+ });
2298
+ }
2299
+ }
2300
+ }
2301
+ reporter.log(`Creating zip file`);
2302
+ const archive = await buildArchiveFromPackage(reporter, location, packageDescription, binDir, options.minimize);
2303
+ try {
2304
+ const zipOutputStream = createWriteStream(zipFilePath);
2305
+ await pipeline(archive.generateNodeStream(), zipOutputStream);
2306
+ } catch (err) {
2307
+ if (isErrorEACCES(err) || isErrorEPERM(err)) {
2308
+ reporter.log(`Could not create zip file in the bin directory because of a permissions error. Only using it in-memory`);
2309
+ uploadable = {
2310
+ getStream: ()=>archive.generateNodeStream()
2311
+ };
2312
+ } else {
2313
+ throw err;
2314
+ }
2315
+ }
2316
+ }
2317
+ if (!options.noUpload) {
2318
+ if (!options.authentication) {
2319
+ throw new Error(`Expected authentication to be available`);
2320
+ }
2321
+ reporter.log(`Opening connection to IG.Asset.Server`);
2322
+ const sessionManager = await createAssetServiceSessionManager({
2323
+ url: options.service,
2324
+ address: options.address,
2325
+ domain: publishDomain,
2326
+ subDomain: publishSubdomain,
2327
+ authentication: options.authentication
2328
+ });
2329
+ try {
2330
+ if (!options.skipDependencies) {
2331
+ try {
2332
+ await synchronizeDependencies(workspace, packageDescription, sessionManager, options.prompter, reporter);
2333
+ } catch (err) {
2334
+ reporter.error(`Failed to synchronize dependencies for ${packageDescription.Package}`, err);
2335
+ }
2336
+ }
2337
+ reporter.log(`Uploading package to ${publishDomain}.${publishSubdomain}`);
2338
+ await uploadPackageFromBuffer(sessionManager.getTargetSession(), assetServerPackageDetails, await buffer(uploadable.getStream()));
2339
+ } finally{
2340
+ await sessionManager.destroy().catch((err)=>{
2341
+ reporter.error(`Failed to close IG.Asset.Server session(s)`, err);
2342
+ });
2343
+ }
2344
+ }
2345
+ } catch (err) {
2346
+ versionFile.reset();
2347
+ throw err;
2348
+ }
2349
+ if (newVersion.buildNumber >= 100 && !options.pushOnly) {
2350
+ reporter.error("Copying zip to releases folder");
2351
+ const zipFileName = `${packageNameWithVersion}.zip`;
2352
+ const releasesPath = getPackageReleasesDirectory(location);
2353
+ await fs$1.mkdir(releasesPath, {
2354
+ recursive: true
2355
+ });
2356
+ await pipeline(uploadable.getStream(), createWriteStream(path.join(releasesPath, zipFileName)));
2357
+ }
2358
+ };
2359
+
2360
+ /**
2361
+ * Extracts and returns script array for _Index.json from a src folder
2362
+ *
2363
+ * @param folderPath path to a src folder
2364
+ */ function generateIndex({ location, ignore = [], strictOptional = false }) {
2365
+ const arr = [];
2366
+ const existingIndex = readPackageCreatorIndex(location) ?? [];
2367
+ const manifest = readPackageCreatorManifest(location);
2368
+ const compilerOptions = readScriptPackageTSConfig(location).options;
2369
+ const isModule = compilerOptions.module === ts.ModuleKind.ES2015 || compilerOptions.module === ts.ModuleKind.ESNext;
2370
+ const files = getPackageTypescriptFiles(location).filter((path)=>!ignore.some((suffix)=>path.endsWith(suffix)));
2371
+ let program;
2372
+ let namespaces;
2373
+ if (isModule) {
2374
+ const entryFilePath = resolveScriptPackageEntryModule(location, manifest);
2375
+ if (entryFilePath === undefined) {
2376
+ throw new Error(`Could not resolve entry module`);
2377
+ }
2378
+ const host = ts.createCompilerHost({}, true);
2379
+ program = ts.createProgram([
2380
+ entryFilePath
2381
+ ], {
2382
+ allowJs: true,
2383
+ ...compilerOptions
2384
+ }, host);
2385
+ const entryFile = program.getSourceFile(entryFilePath);
2386
+ if (entryFile === undefined) {
2387
+ throw new Error(`Failed to find entry module`);
2388
+ }
2389
+ namespaces = resolveNamespaces(entryFile, program, host, manifest.Scope ?? manifest.Package);
2390
+ } else {
2391
+ program = ts.createProgram(files, {
2392
+ allowJs: true
2393
+ });
2394
+ namespaces = [];
2395
+ }
2396
+ const typeChecker = program.getTypeChecker();
2397
+ files.forEach((file)=>{
2398
+ // Create a Program to represent the project, then pull out the
2399
+ // source file to parse its AST.
2400
+ const sourceFile = program.getSourceFile(file);
2401
+ const namespace = namespaces.find((namespace)=>namespace.files.includes(sourceFile));
2402
+ // Loop through the root AST nodes of the file
2403
+ for (const scriptingClass of findScriptingClasses(sourceFile)){
2404
+ if (scriptingClass.node.name === undefined) {
2405
+ throw new Error(`Expected ${scriptingClass.type} class to have a name`);
2406
+ }
2407
+ let name;
2408
+ if (isModule && namespace !== undefined) {
2409
+ const moduleNamespace = resolveNamespaceFullName(namespace);
2410
+ name = `${moduleNamespace}.${scriptingClass.node.name.text}`;
2411
+ } else {
2412
+ name = typeChecker.getFullyQualifiedName(typeChecker.getSymbolAtLocation(scriptingClass.node.name));
2413
+ }
2414
+ if (name.length > 45) {
2415
+ throw new Error(`Package name length >45 '${name}'`);
2416
+ }
2417
+ const parameterDeclaration = getScriptingClassParameterdeclaration(scriptingClass);
2418
+ const parametersType = parameterDeclaration === undefined ? undefined : typeChecker.getTypeAtLocation(parameterDeclaration);
2419
+ if (parametersType === undefined) {
2420
+ console.log(`Failed to find parameters type declaration for ${scriptingClass.type} ${name}. Skipping parameter list generation`);
2421
+ }
2422
+ const existingIndexEntry = existingIndex.find((entry)=>entry.Name === name);
2423
+ const obj = {
2424
+ Name: name,
2425
+ Description: (existingIndexEntry == null ? void 0 : existingIndexEntry.Description) ?? name,
2426
+ Type: scriptingClass.type === "evaluator" ? "Evaluator" : "Interactor",
2427
+ Parameters: []
2428
+ };
2429
+ const rawDocTags = ts.getJSDocTags(scriptingClass.node);
2430
+ const dict = getTagDict(rawDocTags);
2431
+ if (dict.summary) {
2432
+ obj.Description = dict.summary;
2433
+ } else {
2434
+ const comment = typeChecker.getTypeAtLocation(scriptingClass.node).symbol.getDocumentationComment(typeChecker).map((comment)=>comment.text).join(" ");
2435
+ if (comment) {
2436
+ obj.Description = comment;
2437
+ }
2438
+ }
2439
+ if (parametersType !== undefined) {
2440
+ obj.Parameters = parseParametersList(typeChecker.getPropertiesOfType(parametersType), strictOptional);
2441
+ if (obj.Parameters.length === 0 && parametersType.getStringIndexType() !== undefined) {
2442
+ obj.Parameters = (existingIndexEntry == null ? void 0 : existingIndexEntry.Parameters) ?? [];
2443
+ }
2444
+ } else if (existingIndexEntry !== undefined) {
2445
+ obj.Parameters = existingIndexEntry.Parameters;
2446
+ }
2447
+ arr.push(obj);
2448
+ }
2449
+ });
2450
+ arr.sort((a, b)=>a.Name.localeCompare(b.Name));
2451
+ writePackageCreatorIndex(location, arr);
2452
+ }
2453
+ function capitalizeFirstLetter(string) {
2454
+ return (string == null ? void 0 : string.charAt(0).toUpperCase()) + (string == null ? void 0 : string.slice(1));
2455
+ }
2456
+ const parseDefault = (value, type)=>{
2457
+ const uType = capitalizeFirstLetter(type);
2458
+ if (value === "null") return null;
2459
+ switch(uType){
2460
+ case "LengthM":
2461
+ case "ArcDEG":
2462
+ case "Float":
2463
+ return parseFloat(value);
2464
+ case "Integer":
2465
+ case "Int":
2466
+ return parseInt(value);
2467
+ case "Boolean":
2468
+ case "Bool":
2469
+ return value === "true";
2470
+ case "Material":
2471
+ case "String":
2472
+ case "Geometry":
2473
+ default:
2474
+ return value.replace(/^"/, "").replace(/"$/, "");
2475
+ }
2476
+ };
2477
+ const parseTypeFromName = (name)=>{
2478
+ const parts = name.split(".");
2479
+ const identifier = parts[parts.length - 1];
2480
+ switch(identifier){
2481
+ case "LengthM":
2482
+ case "ArcDEG":
2483
+ case "Float":
2484
+ case "Integer":
2485
+ return identifier;
2486
+ case "GeometryReference":
2487
+ return "Geometry";
2488
+ case "MaterialReference":
2489
+ return "Material";
2490
+ case "AnimationReference":
2491
+ return "Animation";
2492
+ case "InteractorReference":
2493
+ return "Interactor";
2494
+ case "EvaluatorReference":
2495
+ return "Evaluator";
2496
+ case "String":
2497
+ case "string":
2498
+ return "String";
2499
+ case "number":
2500
+ case "Number":
2501
+ return "Float";
2502
+ case "boolean":
2503
+ case "Boolean":
2504
+ return "Boolean";
2505
+ }
2506
+ };
2507
+ const parseParametersList = (properties, strictOptional)=>{
2508
+ return properties.map((symbol, i)=>{
2509
+ var _symbol_getDeclarations;
2510
+ const parameter = {
2511
+ Name: symbol.name,
2512
+ Description: undefined,
2513
+ Type: "String",
2514
+ Default: undefined,
2515
+ DisplayIndex: i + 1
2516
+ };
2517
+ if (parameter.Name.length > 45) {
2518
+ throw new Error(`Parameter name length >45 '${parameter.Name}'`);
2519
+ }
2520
+ let declaration = (_symbol_getDeclarations = symbol.getDeclarations()) == null ? void 0 : _symbol_getDeclarations[0];
2521
+ let documentationComment = symbol.getDocumentationComment(undefined);
2522
+ let checkLinksSymbol = symbol;
2523
+ while(checkLinksSymbol !== undefined && declaration === undefined){
2524
+ const links = checkLinksSymbol.links;
2525
+ if (links == null ? void 0 : links.syntheticOrigin) {
2526
+ var _links_syntheticOrigin_getDeclarations;
2527
+ declaration = (_links_syntheticOrigin_getDeclarations = links.syntheticOrigin.getDeclarations()) == null ? void 0 : _links_syntheticOrigin_getDeclarations[0];
2528
+ if (documentationComment.length === 0) {
2529
+ documentationComment = links.syntheticOrigin.getDocumentationComment(undefined);
2530
+ }
2531
+ checkLinksSymbol = links.syntheticOrigin;
2532
+ }
2533
+ }
2534
+ if (declaration !== undefined) {
2535
+ const rawDocTags = ts.getJSDocTags(declaration);
2536
+ const dict = getTagDict(rawDocTags);
2537
+ if (dict.summary) {
2538
+ parameter.Description = dict.summary;
2539
+ } else {
2540
+ const comment = documentationComment.map((comment)=>comment.text).join(" ");
2541
+ if (comment) {
2542
+ parameter.Description = comment;
2543
+ }
2544
+ }
2545
+ if (dict.creatorType) {
2546
+ parameter.Type = dict.creatorType;
2547
+ } else {
2548
+ const propertySignature = declaration;
2549
+ if (propertySignature.type !== undefined) {
2550
+ const parsedType = parseTypeFromName(propertySignature.type.getText());
2551
+ if (parsedType !== undefined) {
2552
+ parameter.Type = parsedType;
2553
+ }
2554
+ }
2555
+ }
2556
+ if (dict.default) {
2557
+ parameter.Default = parseDefault(dict.default, parameter.Type);
2558
+ }
2559
+ if (strictOptional && declaration.kind === ts.SyntaxKind.PropertySignature) {
2560
+ const propertySignature = declaration;
2561
+ if (propertySignature.questionToken === undefined) {
2562
+ parameter.Required = true;
2563
+ }
2564
+ }
2565
+ }
2566
+ return parameter;
2567
+ });
2568
+ };
2569
+ function getTagDict(tags) {
2570
+ const dict = {};
2571
+ for (const tag of tags){
2572
+ dict[tag.tagName.text] = tag.comment;
2573
+ }
2574
+ return dict;
2575
+ }
2576
+ const getScriptingClassParameterdeclaration = (scriptingClass)=>{
2577
+ for (const member of scriptingClass.node.members){
2578
+ if (ts.isMethodDeclaration(member)) {
2579
+ for(let index = 0; index < member.parameters.length; index++){
2580
+ const parameter = member.parameters[index];
2581
+ if (isScriptingClassParameterDeclaration(scriptingClass, member, index)) {
2582
+ return parameter;
2583
+ }
2584
+ }
2585
+ }
2586
+ if (ts.isConstructorDeclaration(member)) {
2587
+ for(let index = 0; index < member.parameters.length; index++){
2588
+ const parameter = member.parameters[index];
2589
+ if (isScriptingClassParameterDeclaration(scriptingClass, member, index)) {
2590
+ return parameter;
2591
+ }
2592
+ }
2593
+ }
2594
+ }
2595
+ };
2596
+ const isScriptingClassParameterDeclaration = (scriptingClass, memberNode, parameterIndex)=>{
2597
+ if (scriptingClass.type === "evaluator") {
2598
+ var _memberNode_name;
2599
+ return (memberNode == null ? void 0 : (_memberNode_name = memberNode.name) == null ? void 0 : _memberNode_name.getText()) == "Create" && parameterIndex === 2;
2600
+ }
2601
+ if (scriptingClass.type === "interactor") {
2602
+ return memberNode.kind === ts.SyntaxKind.Constructor && parameterIndex === 0;
2603
+ }
2604
+ return false;
2605
+ };
2606
+ /**
2607
+ * Finds interactors and evaluators within a script file
2608
+ *
2609
+ * @param {ts.Node} node
2610
+ * @return {*}
2611
+ */ function* findScriptingClasses(node) {
2612
+ for (const child of node.getChildren()){
2613
+ if (!ts.isClassDeclaration(child)) {
2614
+ yield* findScriptingClasses(child);
2615
+ continue;
2616
+ }
2617
+ const scriptingClass = detectScriptingClass(child);
2618
+ if (scriptingClass !== undefined) {
2619
+ yield scriptingClass;
2620
+ }
2621
+ }
2622
+ }
2623
+ const detectScriptingClass = (node)=>{
2624
+ var _node_heritageClauses, _node_heritageClauses1;
2625
+ const isEvaluator = (_node_heritageClauses = node.heritageClauses) == null ? void 0 : _node_heritageClauses.some((clause)=>{
2626
+ if (clause.token !== ts.SyntaxKind.ExtendsKeyword && clause.token !== ts.SyntaxKind.ImplementsKeyword) {
2627
+ return false;
2628
+ }
2629
+ return clause.types.some((type)=>type.getText().includes("Evaluator"));
2630
+ });
2631
+ if (isEvaluator) {
2632
+ return {
2633
+ node,
2634
+ type: "evaluator"
2635
+ };
2636
+ }
2637
+ const isInteractor = (_node_heritageClauses1 = node.heritageClauses) == null ? void 0 : _node_heritageClauses1.some((clause)=>{
2638
+ if (clause.token !== ts.SyntaxKind.ExtendsKeyword) {
2639
+ return false;
2640
+ }
2641
+ return clause.types.some((type)=>type.getText().includes("Interactor"));
2642
+ });
2643
+ if (isInteractor) {
2644
+ return {
2645
+ node,
2646
+ type: "interactor"
2647
+ };
2648
+ }
2649
+ };
2650
+
2651
+ export { buildFolders, buildFoldersWatch, createAssetServiceSessionManager, generateIndex, isScriptPackageModules, readScriptPackageTSConfig, releaseFolder, resolveScriptPackageEntryModule, synchronizeDependencies };
21
2652
  //# sourceMappingURL=lib.mjs.map