lucid-package 0.0.125 → 0.0.127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucid-package",
3
- "version": "0.0.125",
3
+ "version": "0.0.127",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -39,7 +39,7 @@ async function createEditorExtension(name, isInternal, skipSDKDependency, source
39
39
  manifest['extensions'].push({
40
40
  'name': name,
41
41
  'title': name,
42
- 'products': [supportedproduct_1.SupportedProduct.Chart, supportedproduct_1.SupportedProduct.Spark, supportedproduct_1.SupportedProduct.TeamSpaces],
42
+ 'products': [supportedproduct_1.SupportedProduct.Chart, supportedproduct_1.SupportedProduct.Spark],
43
43
  'codePath': codePath,
44
44
  'scopes': ['READ', 'WRITE', 'DOWNLOAD', 'SHOW_MODAL', 'CUSTOM_UI', 'NETWORK'],
45
45
  });
package/src/package.js CHANGED
@@ -12,6 +12,7 @@ const packagemanifest_1 = require("./packagemanifest");
12
12
  const shapelibrary_1 = require("./shapelibrary");
13
13
  const shellutil_1 = require("./shellutil");
14
14
  const theme_1 = require("./theme");
15
+ const ziputil_1 = require("./ziputil");
15
16
  async function createEmptyPackage(root) {
16
17
  console.log((0, theme_1.success)('Creating Lucid Suite package in ' + root));
17
18
  const source = path.join(__dirname, '..', 'templates', 'package');
@@ -61,8 +62,6 @@ exports.updateAllExtensionSDK = updateAllExtensionSDK;
61
62
  */
62
63
  async function writePackage(quiet = false, manifestOverrideEnv, skipSdkDependency = false) {
63
64
  const zip = new JSZip();
64
- // A fixed date for reproducible output
65
- const reproducibleTimestamp = new Date('2000-01-01T00:00:00Z');
66
65
  const quietableConsoleLog = (...data) => {
67
66
  if (!quiet) {
68
67
  console.log(data);
@@ -105,7 +104,7 @@ async function writePackage(quiet = false, manifestOverrideEnv, skipSdkDependenc
105
104
  quietableConsoleLog(cmd);
106
105
  quietableConsoleLog((0, shellutil_1.execSyncLoggingOutputOnError)(cmd, (quiet = quiet)).toString());
107
106
  }
108
- zip.file(extension['codePath'], await fs.readFile(extension['codePath']), { date: reproducibleTimestamp });
107
+ (0, ziputil_1.jsZipFileDeterministic)(zip, extension['codePath'], await fs.readFile(extension['codePath']));
109
108
  }
110
109
  //Do the same for each shape library
111
110
  for (const library of manifest['shapeLibraries'] || []) {
@@ -114,7 +113,7 @@ async function writePackage(quiet = false, manifestOverrideEnv, skipSdkDependenc
114
113
  quietableConsoleLog((0, theme_1.success)(`Building shape library ${parts[1]}`));
115
114
  await (0, shapelibrary_1.buildShapeLibrary)(parts[1].replace('.lcsz', ''), quiet);
116
115
  }
117
- zip.file(library['lcszPath'], await fs.readFile(library['lcszPath']), { date: reproducibleTimestamp });
116
+ (0, ziputil_1.jsZipFileDeterministic)(zip, library['lcszPath'], await fs.readFile(library['lcszPath']));
118
117
  }
119
118
  //Add any static resources
120
119
  const checkDirForResources = async (directory, zipDirectory) => {
@@ -131,7 +130,7 @@ async function writePackage(quiet = false, manifestOverrideEnv, skipSdkDependenc
131
130
  }
132
131
  const normalizedZipPath = (0, filesystemutil_1.getNormalizedZipPath)(zipPath);
133
132
  quietableConsoleLog('Adding resource file: ' + filePath + ' -> ' + normalizedZipPath);
134
- zip.file(normalizedZipPath, await fs.readFile(filePath), { date: reproducibleTimestamp });
133
+ (0, ziputil_1.jsZipFileDeterministic)(zip, normalizedZipPath, await fs.readFile(filePath));
135
134
  }
136
135
  else if (stat.isDirectory()) {
137
136
  await checkDirForResources(filePath, zipDirectory ? path.join(zipDirectory, fileName) : undefined);
@@ -146,7 +145,7 @@ async function writePackage(quiet = false, manifestOverrideEnv, skipSdkDependenc
146
145
  }
147
146
  }
148
147
  //Add the manifest itself
149
- zip.file('manifest.json', JSON.stringify(manifest, undefined, 2), { date: reproducibleTimestamp });
148
+ (0, ziputil_1.jsZipFileDeterministic)(zip, 'manifest.json', JSON.stringify(manifest, undefined, 2));
150
149
  //Write out the zip file
151
150
  const zipBytes = await zip.generateAsync({
152
151
  type: 'uint8array',
@@ -11,6 +11,7 @@ const filesystemutil_1 = require("./filesystemutil");
11
11
  const package_1 = require("./package");
12
12
  const packagemanifest_1 = require("./packagemanifest");
13
13
  const theme_1 = require("./theme");
14
+ const ziputil_1 = require("./ziputil");
14
15
  const hjson = require('hjson');
15
16
  const ws = require('ws');
16
17
  const chokidar = require('chokidar');
@@ -240,14 +241,15 @@ async function buildShapeLibrary(name, quiet) {
240
241
  }
241
242
  const stat = await fs.lstat(source);
242
243
  if (stat.isDirectory()) {
243
- const dir = await fs.readdir(source);
244
+ // readdir file order is not guaranteed. Sort for determinism.
245
+ const dir = (await fs.readdir(source)).sort();
244
246
  for (const file of dir) {
245
247
  await addToZip(path.join(source, file));
246
248
  }
247
249
  }
248
250
  else {
249
251
  const normalizedSource = (0, filesystemutil_1.getNormalizedZipPath)(source);
250
- zip.file(normalizedSource.replace(`shapelibraries/${name}/`, ''), await fs.readFile(source));
252
+ (0, ziputil_1.jsZipFileDeterministic)(zip, normalizedSource.replace(`shapelibraries/${name}/`, ''), await fs.readFile(source));
251
253
  }
252
254
  };
253
255
  await addToZip(`shapelibraries/${name}`);
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ import * as JSZip from 'jszip';
3
+ import { Buffer } from 'buffer';
4
+ type JSZipInputType = string | Buffer | Uint8Array | ArrayBuffer | Blob | number[];
5
+ /**
6
+ * Calls JSZip.file with deterministic timestamps.
7
+ * For files it uses the given timestamp, if one exists. If not it uses a fixed date.
8
+ *
9
+ * Automatically creates all parent directories with a fixed timestamps.
10
+ *
11
+ * Parent directories do not use the given date for parent directory creation to avoid
12
+ * order-sensitive determinism issues when different files have different time stamps.
13
+ *
14
+ * @param zip The JSZip instance to add the file to
15
+ * @param filePath The path of the file within the zip
16
+ * @param data The file contents
17
+ * @param options JSZip file options (date defaults to DETERMINISTIC_DATE if not specified)
18
+ * @returns The JSZip instance
19
+ */
20
+ export declare function jsZipFileDeterministic(zip: JSZip, filePath: string, data: JSZipInputType | Promise<JSZipInputType>, options?: JSZip.JSZipFileOptions): JSZip;
21
+ export {};
package/src/ziputil.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.jsZipFileDeterministic = void 0;
4
+ const filesystemutil_1 = require("./filesystemutil");
5
+ // Use a fixed date for deterministic files and directories inside the zip
6
+ const DETERMINISTIC_DATE = new Date('2000-01-01T00:00:00Z');
7
+ /**
8
+ * Calls JSZip.file with deterministic timestamps.
9
+ * For files it uses the given timestamp, if one exists. If not it uses a fixed date.
10
+ *
11
+ * Automatically creates all parent directories with a fixed timestamps.
12
+ *
13
+ * Parent directories do not use the given date for parent directory creation to avoid
14
+ * order-sensitive determinism issues when different files have different time stamps.
15
+ *
16
+ * @param zip The JSZip instance to add the file to
17
+ * @param filePath The path of the file within the zip
18
+ * @param data The file contents
19
+ * @param options JSZip file options (date defaults to DETERMINISTIC_DATE if not specified)
20
+ * @returns The JSZip instance
21
+ */
22
+ function jsZipFileDeterministic(zip, filePath, data, options) {
23
+ // Normalize the path to use '/' separators
24
+ const normalizedPath = (0, filesystemutil_1.getNormalizedZipPath)(filePath);
25
+ const fileDate = options?.date ?? DETERMINISTIC_DATE;
26
+ // Get the parent parts of the path, removing any empty parts
27
+ const parentPathParts = normalizedPath.split('/').filter((p) => p).slice(0, -1);
28
+ // Add all non-existent parent directories with deterministic timestamps
29
+ for (let i = 0; i < parentPathParts.length; i++) {
30
+ const dirPath = parentPathParts.slice(0, i + 1).join('/') + '/';
31
+ if (!zip.files[dirPath]) {
32
+ // Always use the deterministic date when creating the parent directories because
33
+ // if different files have different dates, then the date for the parent directories
34
+ // will depend on which file is added first.
35
+ zip.file(dirPath, null, { dir: true, date: DETERMINISTIC_DATE });
36
+ }
37
+ }
38
+ ;
39
+ return zip.file(normalizedPath, data, { ...options, date: fileDate });
40
+ }
41
+ exports.jsZipFileDeterministic = jsZipFileDeterministic;
@@ -5,7 +5,6 @@
5
5
  "packages": {
6
6
  "": {
7
7
  "dependencies": {
8
- "axios": "^0.27.2",
9
8
  "express": "^4.18.1"
10
9
  },
11
10
  "devDependencies": {
@@ -259,22 +258,6 @@
259
258
  "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
260
259
  "license": "MIT"
261
260
  },
262
- "node_modules/asynckit": {
263
- "version": "0.4.0",
264
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
265
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
266
- "license": "MIT"
267
- },
268
- "node_modules/axios": {
269
- "version": "0.27.2",
270
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
271
- "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
272
- "license": "MIT",
273
- "dependencies": {
274
- "follow-redirects": "^1.14.9",
275
- "form-data": "^4.0.0"
276
- }
277
- },
278
261
  "node_modules/balanced-match": {
279
262
  "version": "1.0.2",
280
263
  "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -406,18 +389,6 @@
406
389
  "fsevents": "~2.3.2"
407
390
  }
408
391
  },
409
- "node_modules/combined-stream": {
410
- "version": "1.0.8",
411
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
412
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
413
- "license": "MIT",
414
- "dependencies": {
415
- "delayed-stream": "~1.0.0"
416
- },
417
- "engines": {
418
- "node": ">= 0.8"
419
- }
420
- },
421
392
  "node_modules/concat-map": {
422
393
  "version": "0.0.1",
423
394
  "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -477,15 +448,6 @@
477
448
  "ms": "2.0.0"
478
449
  }
479
450
  },
480
- "node_modules/delayed-stream": {
481
- "version": "1.0.0",
482
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
483
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
484
- "license": "MIT",
485
- "engines": {
486
- "node": ">=0.4.0"
487
- }
488
- },
489
451
  "node_modules/depd": {
490
452
  "version": "2.0.0",
491
453
  "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -574,21 +536,6 @@
574
536
  "node": ">= 0.4"
575
537
  }
576
538
  },
577
- "node_modules/es-set-tostringtag": {
578
- "version": "2.1.0",
579
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
580
- "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
581
- "license": "MIT",
582
- "dependencies": {
583
- "es-errors": "^1.3.0",
584
- "get-intrinsic": "^1.2.6",
585
- "has-tostringtag": "^1.0.2",
586
- "hasown": "^2.0.2"
587
- },
588
- "engines": {
589
- "node": ">= 0.4"
590
- }
591
- },
592
539
  "node_modules/escape-html": {
593
540
  "version": "1.0.3",
594
541
  "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -681,42 +628,6 @@
681
628
  "node": ">= 0.8"
682
629
  }
683
630
  },
684
- "node_modules/follow-redirects": {
685
- "version": "1.15.11",
686
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
687
- "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
688
- "funding": [
689
- {
690
- "type": "individual",
691
- "url": "https://github.com/sponsors/RubenVerborgh"
692
- }
693
- ],
694
- "license": "MIT",
695
- "engines": {
696
- "node": ">=4.0"
697
- },
698
- "peerDependenciesMeta": {
699
- "debug": {
700
- "optional": true
701
- }
702
- }
703
- },
704
- "node_modules/form-data": {
705
- "version": "4.0.4",
706
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
707
- "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
708
- "license": "MIT",
709
- "dependencies": {
710
- "asynckit": "^0.4.0",
711
- "combined-stream": "^1.0.8",
712
- "es-set-tostringtag": "^2.1.0",
713
- "hasown": "^2.0.2",
714
- "mime-types": "^2.1.12"
715
- },
716
- "engines": {
717
- "node": ">= 6"
718
- }
719
- },
720
631
  "node_modules/forwarded": {
721
632
  "version": "0.2.0",
722
633
  "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -843,21 +754,6 @@
843
754
  "url": "https://github.com/sponsors/ljharb"
844
755
  }
845
756
  },
846
- "node_modules/has-tostringtag": {
847
- "version": "1.0.2",
848
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
849
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
850
- "license": "MIT",
851
- "dependencies": {
852
- "has-symbols": "^1.0.3"
853
- },
854
- "engines": {
855
- "node": ">= 0.4"
856
- },
857
- "funding": {
858
- "url": "https://github.com/sponsors/ljharb"
859
- }
860
- },
861
757
  "node_modules/hasown": {
862
758
  "version": "2.0.2",
863
759
  "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -7,7 +7,6 @@
7
7
  "typescript": "^5.1.6"
8
8
  },
9
9
  "dependencies": {
10
- "axios": "^0.27.2",
11
10
  "express": "^4.18.1"
12
11
  },
13
12
  "engines": {