@jsii/kernel 1.66.0 → 1.68.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ export declare function digestFile(path: string, ...comments: readonly string[]): Buffer;
3
+ //# sourceMappingURL=digest-file.d.ts.map
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.digestFile = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const fs_1 = require("fs");
6
+ const ALGORITHM = 'sha256';
7
+ function digestFile(path, ...comments) {
8
+ const hash = (0, crypto_1.createHash)(ALGORITHM);
9
+ const buffer = Buffer.alloc(16384);
10
+ const fd = (0, fs_1.openSync)(path, 'r');
11
+ try {
12
+ let bytesRead = 0;
13
+ while ((bytesRead = (0, fs_1.readSync)(fd, buffer)) > 0) {
14
+ hash.update(buffer.slice(0, bytesRead));
15
+ }
16
+ for (const comment of comments) {
17
+ hash.update('\0');
18
+ hash.update(comment);
19
+ }
20
+ return hash.digest();
21
+ }
22
+ finally {
23
+ (0, fs_1.closeSync)(fd);
24
+ }
25
+ }
26
+ exports.digestFile = digestFile;
27
+ //# sourceMappingURL=digest-file.js.map
@@ -0,0 +1,27 @@
1
+ /// <reference types="node" />
2
+ export declare class DiskCache {
3
+ #private;
4
+ private static readonly CACHE;
5
+ static inDirectory(path: string): DiskCache;
6
+ private constructor();
7
+ entry(...key: readonly string[]): Entry;
8
+ entryFor(path: string, ...comments: readonly string[]): Entry;
9
+ pruneExpiredEntries(): void;
10
+ private entries;
11
+ }
12
+ export declare class Entry {
13
+ readonly path: string;
14
+ constructor(path: string);
15
+ get atime(): Date;
16
+ get pathExists(): boolean;
17
+ private get lockFile();
18
+ private get markerFile();
19
+ lock<T>(cb: (entry: LockedEntry) => T): T;
20
+ read(file: string): Buffer | undefined;
21
+ }
22
+ export interface LockedEntry {
23
+ delete(): void;
24
+ write(name: string, data: Buffer): void;
25
+ touch(): void;
26
+ }
27
+ //# sourceMappingURL=disk-cache.d.ts.map
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _DiskCache_root;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.Entry = exports.DiskCache = void 0;
16
+ const fs_1 = require("fs");
17
+ const lockfile_1 = require("lockfile");
18
+ const path_1 = require("path");
19
+ const digest_file_1 = require("./digest-file");
20
+ const MARKER_FILE_NAME = '.jsii-runtime-package-cache';
21
+ const ONE_DAY_IN_MS = 86400000;
22
+ const PRUNE_AFTER_MILLISECONDS = process.env.JSII_RUNTIME_PACKAGE_CACHE_TTL
23
+ ? parseInt(process.env.JSII_RUNTIME_PACKAGE_CACHE_TTL, 10) * ONE_DAY_IN_MS
24
+ : 30 * ONE_DAY_IN_MS;
25
+ class DiskCache {
26
+ constructor(root) {
27
+ _DiskCache_root.set(this, void 0);
28
+ __classPrivateFieldSet(this, _DiskCache_root, root, "f");
29
+ process.once('beforeExit', () => this.pruneExpiredEntries());
30
+ }
31
+ static inDirectory(path) {
32
+ const didCreate = (0, fs_1.mkdirSync)(path, { recursive: true }) != null;
33
+ if (didCreate && process.platform === 'darwin') {
34
+ // Mark the directories for no iCloud sync, no Spotlight indexing, no TimeMachine backup
35
+ // @see https://michaelbach.de/2019/03/19/MacOS-nosync-noindex-nobackup.html
36
+ (0, fs_1.writeFileSync)((0, path_1.join)(path, '.nobackup'), '');
37
+ (0, fs_1.writeFileSync)((0, path_1.join)(path, '.noindex'), '');
38
+ (0, fs_1.writeFileSync)((0, path_1.join)(path, '.nosync'), '');
39
+ }
40
+ path = (0, fs_1.realpathSync)(path);
41
+ if (!this.CACHE.has(path)) {
42
+ this.CACHE.set(path, new DiskCache(path));
43
+ }
44
+ return this.CACHE.get(path);
45
+ }
46
+ entry(...key) {
47
+ if (key.length === 0) {
48
+ throw new Error(`Cache entry key must contain at least 1 element!`);
49
+ }
50
+ return new Entry((0, path_1.join)(__classPrivateFieldGet(this, _DiskCache_root, "f"), ...key.flatMap((s) => s
51
+ .replace(/[^@a-z0-9_.\\/-]+/g, '_')
52
+ .split(/[\\/]+/)
53
+ .map((ss) => {
54
+ if (ss === '..') {
55
+ throw new Error(`A cache entry key cannot contain a '..' path segment! (${s})`);
56
+ }
57
+ return ss;
58
+ }))));
59
+ }
60
+ entryFor(path, ...comments) {
61
+ const rawDigest = (0, digest_file_1.digestFile)(path, ...comments);
62
+ return this.entry(...comments, rawDigest.toString('hex'));
63
+ }
64
+ pruneExpiredEntries() {
65
+ const cutOff = new Date(Date.now() - PRUNE_AFTER_MILLISECONDS);
66
+ for (const entry of this.entries()) {
67
+ if (entry.atime < cutOff) {
68
+ entry.lock((lockedEntry) => {
69
+ // Check again in case it's been accessed which we waited for the lock...
70
+ if (entry.atime > cutOff) {
71
+ return;
72
+ }
73
+ lockedEntry.delete();
74
+ });
75
+ }
76
+ }
77
+ for (const dir of directoriesUnder(__classPrivateFieldGet(this, _DiskCache_root, "f"), true)) {
78
+ if (process.platform === 'darwin') {
79
+ try {
80
+ (0, fs_1.rmSync)((0, path_1.join)(dir, '.DS_Store'), { force: true });
81
+ }
82
+ catch {
83
+ // Ignore errors...
84
+ }
85
+ }
86
+ if ((0, fs_1.readdirSync)(dir).length === 0) {
87
+ try {
88
+ (0, fs_1.rmdirSync)(dir);
89
+ }
90
+ catch {
91
+ // Ignore errors, directory may no longer be empty...
92
+ }
93
+ }
94
+ }
95
+ }
96
+ *entries() {
97
+ yield* inDirectory(__classPrivateFieldGet(this, _DiskCache_root, "f"));
98
+ function* inDirectory(dir) {
99
+ if ((0, fs_1.existsSync)((0, path_1.join)(dir, MARKER_FILE_NAME))) {
100
+ return yield new Entry(dir);
101
+ }
102
+ for (const file of directoriesUnder(dir)) {
103
+ yield* inDirectory(file);
104
+ }
105
+ }
106
+ }
107
+ }
108
+ exports.DiskCache = DiskCache;
109
+ _DiskCache_root = new WeakMap();
110
+ DiskCache.CACHE = new Map();
111
+ class Entry {
112
+ constructor(path) {
113
+ this.path = path;
114
+ }
115
+ get atime() {
116
+ try {
117
+ const stat = (0, fs_1.statSync)(this.markerFile);
118
+ return stat.atime;
119
+ }
120
+ catch (err) {
121
+ if (err.code !== 'ENOENT') {
122
+ throw err;
123
+ }
124
+ return new Date(0);
125
+ }
126
+ }
127
+ get pathExists() {
128
+ return (0, fs_1.existsSync)(this.path);
129
+ }
130
+ get lockFile() {
131
+ return `${this.path}.lock`;
132
+ }
133
+ get markerFile() {
134
+ return (0, path_1.join)(this.path, MARKER_FILE_NAME);
135
+ }
136
+ lock(cb) {
137
+ (0, fs_1.mkdirSync)((0, path_1.dirname)(this.path), { recursive: true });
138
+ (0, lockfile_1.lockSync)(this.lockFile, { retries: 12, stale: 5000 });
139
+ let disposed = false;
140
+ try {
141
+ return cb({
142
+ delete: () => {
143
+ if (disposed) {
144
+ throw new Error(`Cannot delete ${this.path} once the lock block was returned!`);
145
+ }
146
+ (0, fs_1.rmSync)(this.path, { force: true, recursive: true });
147
+ },
148
+ write: (name, content) => {
149
+ if (disposed) {
150
+ throw new Error(`Cannot write ${(0, path_1.join)(this.path, name)} once the lock block was returned!`);
151
+ }
152
+ (0, fs_1.mkdirSync)((0, path_1.dirname)((0, path_1.join)(this.path, name)), { recursive: true });
153
+ (0, fs_1.writeFileSync)((0, path_1.join)(this.path, name), content);
154
+ },
155
+ touch: () => {
156
+ if (disposed) {
157
+ throw new Error(`Cannot touch ${this.path} once the lock block was returned!`);
158
+ }
159
+ if (this.pathExists) {
160
+ if ((0, fs_1.existsSync)(this.markerFile)) {
161
+ const now = new Date();
162
+ (0, fs_1.utimesSync)(this.markerFile, now, now);
163
+ }
164
+ else {
165
+ (0, fs_1.writeFileSync)(this.markerFile, '');
166
+ }
167
+ }
168
+ },
169
+ });
170
+ }
171
+ finally {
172
+ disposed = true;
173
+ (0, lockfile_1.unlockSync)(this.lockFile);
174
+ }
175
+ }
176
+ read(file) {
177
+ try {
178
+ return (0, fs_1.readFileSync)((0, path_1.join)(this.path, file));
179
+ }
180
+ catch (error) {
181
+ if (error.code === 'ENOENT') {
182
+ return undefined;
183
+ }
184
+ throw error;
185
+ }
186
+ }
187
+ }
188
+ exports.Entry = Entry;
189
+ function* directoriesUnder(root, recursive = false, ignoreErrors = true) {
190
+ for (const file of (0, fs_1.readdirSync)(root)) {
191
+ const path = (0, path_1.join)(root, file);
192
+ try {
193
+ const stat = (0, fs_1.statSync)(path);
194
+ if (stat.isDirectory()) {
195
+ if (recursive) {
196
+ yield* directoriesUnder(path, recursive, ignoreErrors);
197
+ }
198
+ yield path;
199
+ }
200
+ }
201
+ catch (error) {
202
+ if (!ignoreErrors) {
203
+ throw error;
204
+ }
205
+ }
206
+ }
207
+ }
208
+ //# sourceMappingURL=disk-cache.js.map
@@ -0,0 +1,2 @@
1
+ export * from './disk-cache';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./disk-cache"), exports);
18
+ //# sourceMappingURL=index.js.map
package/lib/kernel.d.ts CHANGED
@@ -1,10 +1,29 @@
1
1
  import * as api from './api';
2
+ export declare const enum JsiiErrorType {
3
+ JSII_FAULT = "@jsii/kernel.Fault",
4
+ RUNTIME_ERROR = "@jsii/kernel.RuntimeError"
5
+ }
6
+ export interface JsiiError extends Error {
7
+ readonly name: JsiiErrorType;
8
+ }
9
+ export declare class JsiiFault extends Error implements JsiiError {
10
+ readonly name = JsiiErrorType.JSII_FAULT;
11
+ constructor(message: string);
12
+ }
13
+ export declare class RuntimeError extends Error implements JsiiError {
14
+ readonly name = JsiiErrorType.RUNTIME_ERROR;
15
+ constructor(message: string);
16
+ }
2
17
  export declare class Kernel {
3
18
  callbackHandler: (callback: api.Callback) => any;
4
19
  /**
5
20
  * Set to true for verbose debugging.
6
21
  */
7
22
  traceEnabled: boolean;
23
+ /**
24
+ * Set to true for timing data to be emitted.
25
+ */
26
+ debugTimingEnabled: boolean;
8
27
  private readonly assemblies;
9
28
  private readonly objects;
10
29
  private readonly cbs;
@@ -24,6 +43,7 @@ export declare class Kernel {
24
43
  */
25
44
  constructor(callbackHandler: (callback: api.Callback) => any);
26
45
  load(req: api.LoadRequest): api.LoadResponse;
46
+ private _load;
27
47
  invokeBinScript(req: api.InvokeScriptRequest): api.InvokeScriptResponse;
28
48
  create(req: api.CreateRequest): api.CreateResponse;
29
49
  del(req: api.DelRequest): api.DelResponse;
@@ -67,6 +87,7 @@ export declare class Kernel {
67
87
  private _fromSandboxValues;
68
88
  private _boxUnboxParameters;
69
89
  private _debug;
90
+ private _debugTime;
70
91
  /**
71
92
  * Ensures that `fn` is called and defends against beginning to invoke
72
93
  * async methods until fn finishes (successfully or not).
package/lib/kernel.js CHANGED
@@ -1,19 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Kernel = void 0;
3
+ exports.Kernel = exports.RuntimeError = exports.JsiiFault = void 0;
4
4
  const spec = require("@jsii/spec");
5
5
  const spec_1 = require("@jsii/spec");
6
6
  const cp = require("child_process");
7
+ const fs_1 = require("fs");
7
8
  const fs = require("fs-extra");
8
9
  const module_1 = require("module");
9
10
  const os = require("os");
10
11
  const path = require("path");
11
- const tar = require("tar");
12
12
  const api = require("./api");
13
13
  const api_1 = require("./api");
14
+ const link_1 = require("./link");
14
15
  const objects_1 = require("./objects");
15
16
  const onExit = require("./on-exit");
16
17
  const wire = require("./serialization");
18
+ const tar = require("./tar-cache");
19
+ class JsiiFault extends Error {
20
+ constructor(message) {
21
+ super(message);
22
+ this.name = "@jsii/kernel.Fault" /* JsiiErrorType.JSII_FAULT */;
23
+ }
24
+ }
25
+ exports.JsiiFault = JsiiFault;
26
+ class RuntimeError extends Error {
27
+ constructor(message) {
28
+ super(message);
29
+ this.name = "@jsii/kernel.RuntimeError" /* JsiiErrorType.RUNTIME_ERROR */;
30
+ }
31
+ }
32
+ exports.RuntimeError = RuntimeError;
17
33
  class Kernel {
18
34
  /**
19
35
  * Creates a jsii kernel object.
@@ -28,6 +44,10 @@ class Kernel {
28
44
  * Set to true for verbose debugging.
29
45
  */
30
46
  this.traceEnabled = false;
47
+ /**
48
+ * Set to true for timing data to be emitted.
49
+ */
50
+ this.debugTimingEnabled = false;
31
51
  this.assemblies = new Map();
32
52
  this.objects = new objects_1.ObjectTable(this._typeInfoForFqn.bind(this));
33
53
  this.cbs = new Map();
@@ -36,10 +56,13 @@ class Kernel {
36
56
  this.nextid = 20000; // incrementing counter for objid, cbid, promiseid
37
57
  }
38
58
  load(req) {
39
- var _a, _b;
59
+ return this._debugTime(() => this._load(req), `load(${JSON.stringify(req, null, 2)})`);
60
+ }
61
+ _load(req) {
62
+ var _a, _b, _c;
40
63
  this._debug('load', req);
41
64
  if ('assembly' in req) {
42
- throw new Error('`assembly` field is deprecated for "load", use `name`, `version` and `tarball` instead');
65
+ throw new JsiiFault('`assembly` field is deprecated for "load", use `name`, `version` and `tarball` instead');
43
66
  }
44
67
  const pkgname = req.name;
45
68
  const pkgver = req.version;
@@ -49,7 +72,7 @@ class Kernel {
49
72
  // module exists, verify version
50
73
  const epkg = fs.readJsonSync(path.join(packageDir, 'package.json'));
51
74
  if (epkg.version !== pkgver) {
52
- throw new Error(`Multiple versions ${pkgver} and ${epkg.version} of the ` +
75
+ throw new JsiiFault(`Multiple versions ${pkgver} and ${epkg.version} of the ` +
53
76
  `package '${pkgname}' cannot be loaded together since this is unsupported by ` +
54
77
  'some runtime environments');
55
78
  }
@@ -61,20 +84,26 @@ class Kernel {
61
84
  types: Object.keys((_a = assm.metadata.types) !== null && _a !== void 0 ? _a : {}).length,
62
85
  };
63
86
  }
64
- // Create the install directory (there may be several path components for @scoped/packages)
65
- fs.mkdirpSync(packageDir);
66
87
  // Force umask to have npm-install-like permissions
67
88
  const originalUmask = process.umask(0o022);
68
89
  try {
69
90
  // untar the archive to its final location
70
- tar.extract({
71
- cwd: packageDir,
72
- file: req.tarball,
91
+ const { path: extractedTo, cache } = this._debugTime(() => tar.extract(req.tarball, {
73
92
  strict: true,
74
93
  strip: 1,
75
- sync: true,
76
94
  unlink: true,
77
- });
95
+ }, req.name, req.version), `tar.extract(${req.tarball}) => ${packageDir}`);
96
+ // Create the install directory (there may be several path components for @scoped/packages)
97
+ fs.mkdirSync(path.dirname(packageDir), { recursive: true });
98
+ if (cache != null) {
99
+ this._debug(`Package cache enabled, extraction resulted in a cache ${cache}`);
100
+ // Link the package into place.
101
+ this._debugTime(() => (0, link_1.link)(extractedTo, packageDir), `link(${extractedTo}, ${packageDir})`);
102
+ }
103
+ else {
104
+ // This is not from cache, so we move it around instead of copying.
105
+ (0, fs_1.renameSync)(extractedTo, packageDir);
106
+ }
78
107
  }
79
108
  finally {
80
109
  // Reset umask to the initial value
@@ -83,18 +112,18 @@ class Kernel {
83
112
  // read .jsii metadata from the root of the package
84
113
  let assmSpec;
85
114
  try {
86
- assmSpec = (0, spec_1.loadAssemblyFromPath)(packageDir);
115
+ assmSpec = this._debugTime(() => (0, spec_1.loadAssemblyFromPath)(packageDir), `loadAssemblyFromPath(${packageDir})`);
87
116
  }
88
117
  catch (e) {
89
- throw new Error(`Error for package tarball ${req.tarball}: ${e.message}`);
118
+ throw new JsiiFault(`Error for package tarball ${req.tarball}: ${e.message}`);
90
119
  }
91
120
  // load the module and capture its closure
92
- const closure = this.require(packageDir);
121
+ const closure = this._debugTime(() => this.require(packageDir), `require(${packageDir})`);
93
122
  const assm = new Assembly(assmSpec, closure);
94
- this._addAssembly(assm);
123
+ this._debugTime(() => this._addAssembly(assm), `registerAssembly({ name: ${assm.metadata.name}, types: ${Object.keys((_b = assm.metadata.types) !== null && _b !== void 0 ? _b : {}).length} })`);
95
124
  return {
96
125
  assembly: assmSpec.name,
97
- types: Object.keys((_b = assmSpec.types) !== null && _b !== void 0 ? _b : {}).length,
126
+ types: Object.keys((_c = assmSpec.types) !== null && _c !== void 0 ? _c : {}).length,
98
127
  };
99
128
  }
100
129
  invokeBinScript(req) {
@@ -104,11 +133,11 @@ class Kernel {
104
133
  // module exists, verify version
105
134
  const epkg = fs.readJsonSync(path.join(packageDir, 'package.json'));
106
135
  if (!epkg.bin) {
107
- throw new Error('There is no bin scripts defined for this package.');
136
+ throw new JsiiFault('There is no bin scripts defined for this package.');
108
137
  }
109
138
  const scriptPath = epkg.bin[req.script];
110
139
  if (!epkg.bin) {
111
- throw new Error(`Script with name ${req.script} was not defined.`);
140
+ throw new JsiiFault(`Script with name ${req.script} was not defined.`);
112
141
  }
113
142
  const result = cp.spawnSync(path.join(packageDir, scriptPath), (_a = req.args) !== null && _a !== void 0 ? _a : [], {
114
143
  encoding: 'utf-8',
@@ -128,7 +157,7 @@ class Kernel {
128
157
  signal: result.signal,
129
158
  };
130
159
  }
131
- throw new Error(`Package with name ${req.assembly} was not loaded.`);
160
+ throw new JsiiFault(`Package with name ${req.assembly} was not loaded.`);
132
161
  }
133
162
  create(req) {
134
163
  return this._create(req);
@@ -145,7 +174,7 @@ class Kernel {
145
174
  this._debug('sget', symbol);
146
175
  const ti = this._typeInfoForProperty(property, fqn);
147
176
  if (!ti.static) {
148
- throw new Error(`property ${symbol} is not static`);
177
+ throw new JsiiFault(`property ${symbol} is not static`);
149
178
  }
150
179
  const prototype = this._findSymbol(fqn);
151
180
  const value = this._ensureSync(`property ${property}`, () => prototype[property]);
@@ -160,10 +189,10 @@ class Kernel {
160
189
  this._debug('sset', symbol);
161
190
  const ti = this._typeInfoForProperty(property, fqn);
162
191
  if (!ti.static) {
163
- throw new Error(`property ${symbol} is not static`);
192
+ throw new JsiiFault(`property ${symbol} is not static`);
164
193
  }
165
194
  if (ti.immutable) {
166
- throw new Error(`static property ${symbol} is readonly`);
195
+ throw new JsiiFault(`static property ${symbol} is readonly`);
167
196
  }
168
197
  const prototype = this._findSymbol(fqn);
169
198
  this._ensureSync(`property ${property}`, () => (prototype[property] = this._toSandbox(value, ti, `assigned to static property ${symbol}`)));
@@ -194,7 +223,7 @@ class Kernel {
194
223
  const { instance, fqn, interfaces } = this.objects.findObject(objref);
195
224
  const propInfo = this._typeInfoForProperty(req.property, fqn, interfaces);
196
225
  if (propInfo.immutable) {
197
- throw new Error(`Cannot set value of immutable property ${req.property} to ${req.value}`);
226
+ throw new JsiiFault(`Cannot set value of immutable property ${req.property} to ${req.value}`);
198
227
  }
199
228
  const propertyToSet = this._findPropertyTarget(instance, property);
200
229
  this._ensureSync(`property '${objref[api_1.TOKEN_REF]}.${propertyToSet}'`, () => (instance[propertyToSet] = this._toSandbox(value, propInfo, `assigned to property ${fqn}.${property}`)));
@@ -208,7 +237,7 @@ class Kernel {
208
237
  const { ti, obj, fn } = this._findInvokeTarget(objref, method, args);
209
238
  // verify this is not an async method
210
239
  if (ti.async) {
211
- throw new Error(`${method} is an async method, use "begin" instead`);
240
+ throw new JsiiFault(`${method} is an async method, use "begin" instead`);
212
241
  }
213
242
  const fqn = (0, objects_1.jsiiTypeFqn)(obj);
214
243
  const ret = this._ensureSync(`method '${objref[api_1.TOKEN_REF]}.${method}'`, () => {
@@ -225,11 +254,11 @@ class Kernel {
225
254
  this._debug('sinvoke', fqn, method, args);
226
255
  const ti = this._typeInfoForMethod(method, fqn);
227
256
  if (!ti.static) {
228
- throw new Error(`${fqn}.${method} is not a static method`);
257
+ throw new JsiiFault(`${fqn}.${method} is not a static method`);
229
258
  }
230
259
  // verify this is not an async method
231
260
  if (ti.async) {
232
- throw new Error(`${method} is an async method, use "begin" instead`);
261
+ throw new JsiiFault(`${method} is an async method, use "begin" instead`);
233
262
  }
234
263
  const prototype = this._findSymbol(fqn);
235
264
  const fn = prototype[method];
@@ -247,12 +276,12 @@ class Kernel {
247
276
  const args = (_a = req.args) !== null && _a !== void 0 ? _a : [];
248
277
  this._debug('begin', objref, method, args);
249
278
  if (this.syncInProgress) {
250
- throw new Error(`Cannot invoke async method '${req.objref[api_1.TOKEN_REF]}.${req.method}' while sync ${this.syncInProgress} is being processed`);
279
+ throw new JsiiFault(`Cannot invoke async method '${req.objref[api_1.TOKEN_REF]}.${req.method}' while sync ${this.syncInProgress} is being processed`);
251
280
  }
252
281
  const { ti, obj, fn } = this._findInvokeTarget(objref, method, args);
253
282
  // verify this is indeed an async method
254
283
  if (!ti.async) {
255
- throw new Error(`Method ${method} is expected to be an async method`);
284
+ throw new JsiiFault(`Method ${method} is expected to be an async method`);
256
285
  }
257
286
  const fqn = (0, objects_1.jsiiTypeFqn)(obj);
258
287
  const promise = fn.apply(obj, this._toSandboxValues(args, `async method ${fqn ? `${fqn}#` : ''}${method}`, ti.parameters));
@@ -273,7 +302,7 @@ class Kernel {
273
302
  this._debug('end', promiseid);
274
303
  const storedPromise = this.promises.get(promiseid);
275
304
  if (storedPromise == null) {
276
- throw new Error(`Cannot find promise with ID: ${promiseid}`);
305
+ throw new JsiiFault(`Cannot find promise with ID: ${promiseid}`);
277
306
  }
278
307
  const { promise, method } = storedPromise;
279
308
  let result;
@@ -283,7 +312,7 @@ class Kernel {
283
312
  }
284
313
  catch (e) {
285
314
  this._debug('promise error:', e);
286
- throw e;
315
+ throw new JsiiFault(e.message);
287
316
  }
288
317
  return {
289
318
  result: this._fromSandbox(result, (_a = method.returns) !== null && _a !== void 0 ? _a : 'void', `returned by async method ${method.name}`),
@@ -313,7 +342,7 @@ class Kernel {
313
342
  this._debug('complete', cbid, err, result);
314
343
  const cb = this.waiting.get(cbid);
315
344
  if (!cb) {
316
- throw new Error(`Callback ${cbid} not found`);
345
+ throw new JsiiFault(`Callback ${cbid} not found`);
317
346
  }
318
347
  if (err) {
319
348
  this._debug('completed with error:', err);
@@ -337,7 +366,7 @@ class Kernel {
337
366
  const assembly = this._assemblyFor(assemblyName);
338
367
  const targets = assembly.metadata.targets;
339
368
  if (!targets) {
340
- throw new Error(`Unexpected - "targets" for ${assemblyName} is missing!`);
369
+ throw new JsiiFault(`Unexpected - "targets" for ${assemblyName} is missing!`);
341
370
  }
342
371
  return { naming: targets };
343
372
  }
@@ -378,9 +407,9 @@ class Kernel {
378
407
  parameters: classType.initializer && classType.initializer.parameters,
379
408
  };
380
409
  case spec.TypeKind.Interface:
381
- throw new Error(`Cannot create an object with an FQN of an interface: ${fqn}`);
410
+ throw new JsiiFault(`Cannot create an object with an FQN of an interface: ${fqn}`);
382
411
  default:
383
- throw new Error(`Unexpected FQN kind: ${fqn}`);
412
+ throw new JsiiFault(`Unexpected FQN kind: ${fqn}`);
384
413
  }
385
414
  }
386
415
  _getPackageDir(pkgname) {
@@ -414,26 +443,26 @@ class Kernel {
414
443
  for (const override of overrides) {
415
444
  if (api.isMethodOverride(override)) {
416
445
  if (api.isPropertyOverride(override)) {
417
- throw new Error(overrideTypeErrorMessage);
446
+ throw new JsiiFault(overrideTypeErrorMessage);
418
447
  }
419
448
  if (methods.has(override.method)) {
420
- throw new Error(`Duplicate override for method '${override.method}'`);
449
+ throw new JsiiFault(`Duplicate override for method '${override.method}'`);
421
450
  }
422
451
  methods.add(override.method);
423
452
  this._applyMethodOverride(obj, objref, fqn, interfaces, override);
424
453
  }
425
454
  else if (api.isPropertyOverride(override)) {
426
455
  if (api.isMethodOverride(override)) {
427
- throw new Error(overrideTypeErrorMessage);
456
+ throw new JsiiFault(overrideTypeErrorMessage);
428
457
  }
429
458
  if (properties.has(override.property)) {
430
- throw Error(`Duplicate override for property '${override.property}'`);
459
+ throw new JsiiFault(`Duplicate override for property '${override.property}'`);
431
460
  }
432
461
  properties.add(override.property);
433
462
  this._applyPropertyOverride(obj, objref, fqn, interfaces, override);
434
463
  }
435
464
  else {
436
- throw new Error(overrideTypeErrorMessage);
465
+ throw new JsiiFault(overrideTypeErrorMessage);
437
466
  }
438
467
  }
439
468
  }
@@ -445,7 +474,7 @@ class Kernel {
445
474
  _applyPropertyOverride(obj, objref, typeFqn, interfaces, override) {
446
475
  // error if we can find a method with this name
447
476
  if (this._tryTypeInfoForMethod(override.property, typeFqn, interfaces)) {
448
- throw new Error(`Trying to override method '${override.property}' as a property`);
477
+ throw new JsiiFault(`Trying to override method '${override.property}' as a property`);
449
478
  }
450
479
  let propInfo = this._tryTypeInfoForProperty(override.property, typeFqn, interfaces);
451
480
  // if this is a private property (i.e. doesn't have `propInfo` the object has a key)
@@ -531,7 +560,7 @@ class Kernel {
531
560
  _applyMethodOverride(obj, objref, typeFqn, interfaces, override) {
532
561
  // error if we can find a property with this name
533
562
  if (this._tryTypeInfoForProperty(override.method, typeFqn, interfaces)) {
534
- throw new Error(`Trying to override property '${override.method}' as a method`);
563
+ throw new JsiiFault(`Trying to override property '${override.method}' as a method`);
535
564
  }
536
565
  let methodInfo = this._tryTypeInfoForMethod(override.method, typeFqn, interfaces);
537
566
  // If this is a private method (doesn't have methodInfo, key resolves on the object), we
@@ -630,7 +659,7 @@ class Kernel {
630
659
  if (!fn) {
631
660
  fn = instance[methodName];
632
661
  if (!fn) {
633
- throw new Error(`Cannot find ${methodName} on object`);
662
+ throw new JsiiFault(`Cannot find ${methodName} on object`);
634
663
  }
635
664
  }
636
665
  return { ti, obj: instance, fn };
@@ -640,7 +669,7 @@ class Kernel {
640
669
  const params = (_a = method === null || method === void 0 ? void 0 : method.parameters) !== null && _a !== void 0 ? _a : [];
641
670
  // error if args > params
642
671
  if (args.length > params.length && !(method && method.variadic)) {
643
- throw new Error(`Too many arguments (method accepts ${params.length} parameters, got ${args.length} arguments)`);
672
+ throw new JsiiFault(`Too many arguments (method accepts ${params.length} parameters, got ${args.length} arguments)`);
644
673
  }
645
674
  for (let i = 0; i < params.length; ++i) {
646
675
  const param = params[i];
@@ -651,19 +680,19 @@ class Kernel {
651
680
  } // No vararg was provided
652
681
  for (let j = i; j < params.length; j++) {
653
682
  if (!param.optional && params[j] === undefined) {
654
- throw new Error(`Unexpected 'undefined' value at index ${j - i} of variadic argument '${param.name}' of type '${spec.describeTypeReference(param.type)}'`);
683
+ throw new JsiiFault(`Unexpected 'undefined' value at index ${j - i} of variadic argument '${param.name}' of type '${spec.describeTypeReference(param.type)}'`);
655
684
  }
656
685
  }
657
686
  }
658
687
  else if (!param.optional && arg === undefined) {
659
- throw new Error(`Not enough arguments. Missing argument for the required parameter '${param.name}' of type '${spec.describeTypeReference(param.type)}'`);
688
+ throw new JsiiFault(`Not enough arguments. Missing argument for the required parameter '${param.name}' of type '${spec.describeTypeReference(param.type)}'`);
660
689
  }
661
690
  }
662
691
  }
663
692
  _assemblyFor(assemblyName) {
664
693
  const assembly = this.assemblies.get(assemblyName);
665
694
  if (!assembly) {
666
- throw new Error(`Could not find assembly: ${assemblyName}`);
695
+ throw new JsiiFault(`Could not find assembly: ${assemblyName}`);
667
696
  }
668
697
  return assembly;
669
698
  }
@@ -679,7 +708,7 @@ class Kernel {
679
708
  curr = curr[name];
680
709
  }
681
710
  if (!curr) {
682
- throw new Error(`Could not find symbol ${fqn}`);
711
+ throw new JsiiFault(`Could not find symbol ${fqn}`);
683
712
  }
684
713
  return curr;
685
714
  }
@@ -689,12 +718,12 @@ class Kernel {
689
718
  const moduleName = components[0];
690
719
  const assembly = this.assemblies.get(moduleName);
691
720
  if (!assembly) {
692
- throw new Error(`Module '${moduleName}' not found`);
721
+ throw new JsiiFault(`Module '${moduleName}' not found`);
693
722
  }
694
723
  const types = (_a = assembly.metadata.types) !== null && _a !== void 0 ? _a : {};
695
724
  const fqnInfo = types[fqn];
696
725
  if (!fqnInfo) {
697
- throw new Error(`Type '${fqn}' not found`);
726
+ throw new JsiiFault(`Type '${fqn}' not found`);
698
727
  }
699
728
  return fqnInfo;
700
729
  }
@@ -704,7 +733,7 @@ class Kernel {
704
733
  const addendum = interfaces && interfaces.length > 0
705
734
  ? ` or interface(s) ${interfaces.join(', ')}`
706
735
  : '';
707
- throw new Error(`Class ${fqn}${addendum} doesn't have a method '${methodName}'`);
736
+ throw new JsiiFault(`Class ${fqn}${addendum} doesn't have a method '${methodName}'`);
708
737
  }
709
738
  return ti;
710
739
  }
@@ -758,7 +787,7 @@ class Kernel {
758
787
  bases = (_a = interfaceTypeInfo.interfaces) !== null && _a !== void 0 ? _a : [];
759
788
  }
760
789
  else {
761
- throw new Error(`Type of kind ${typeInfo.kind} does not have properties`);
790
+ throw new JsiiFault(`Type of kind ${typeInfo.kind} does not have properties`);
762
791
  }
763
792
  for (const p of properties !== null && properties !== void 0 ? properties : []) {
764
793
  if (p.name === property) {
@@ -781,7 +810,7 @@ class Kernel {
781
810
  const addendum = interfaces && interfaces.length > 0
782
811
  ? ` or interface(s) ${interfaces.join(', ')}`
783
812
  : '';
784
- throw new Error(`Type ${fqn}${addendum} doesn't have a property '${property}'`);
813
+ throw new JsiiFault(`Type ${fqn}${addendum} doesn't have a property '${property}'`);
785
814
  }
786
815
  return typeInfo;
787
816
  }
@@ -816,7 +845,7 @@ class Kernel {
816
845
  parametersCopy.push(parametersCopy[parametersCopy.length - 1]);
817
846
  }
818
847
  if (xs.length > parametersCopy.length) {
819
- throw new Error(`Argument list (${JSON.stringify(xs)}) not same size as expected argument list (length ${parametersCopy.length})`);
848
+ throw new JsiiFault(`Argument list (${JSON.stringify(xs)}) not same size as expected argument list (length ${parametersCopy.length})`);
820
849
  }
821
850
  return xs.map((x, i) => boxUnbox(x, parametersCopy[i], `passed to parameter ${parametersCopy[i].name} of ${methodContext}`));
822
851
  }
@@ -825,6 +854,20 @@ class Kernel {
825
854
  console.error('[@jsii/kernel]', ...args);
826
855
  }
827
856
  }
857
+ _debugTime(cb, label) {
858
+ const fullLabel = `[@jsii/kernel:timing] ${label}`;
859
+ if (this.debugTimingEnabled) {
860
+ console.time(fullLabel);
861
+ }
862
+ try {
863
+ return cb();
864
+ }
865
+ finally {
866
+ if (this.debugTimingEnabled) {
867
+ console.timeEnd(fullLabel);
868
+ }
869
+ }
870
+ }
828
871
  /**
829
872
  * Ensures that `fn` is called and defends against beginning to invoke
830
873
  * async methods until fn finishes (successfully or not).
@@ -834,6 +877,15 @@ class Kernel {
834
877
  try {
835
878
  return fn();
836
879
  }
880
+ catch (e) {
881
+ if (e.name === "@jsii/kernel.Fault" /* JsiiErrorType.JSII_FAULT */) {
882
+ throw new JsiiFault(e);
883
+ }
884
+ // This error can be thrown by the kernel directly, or it can be
885
+ // thrown from user code. If the error comes from the kernel, then its name field will be populated;
886
+ // if the error comes from user code, the name field will not be populated.
887
+ throw new RuntimeError(e);
888
+ }
837
889
  finally {
838
890
  delete this.syncInProgress;
839
891
  }
package/lib/link.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Creates directories containing hard links if possible, and falls back on
3
+ * copy otherwise.
4
+ *
5
+ * @param existing is the original file or directory to link.
6
+ * @param destination is the nbew file or directory to create.
7
+ */
8
+ export declare function link(existing: string, destination: string): void;
9
+ //# sourceMappingURL=link.d.ts.map
package/lib/link.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.link = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ /**
7
+ * Creates directories containing hard links if possible, and falls back on
8
+ * copy otherwise.
9
+ *
10
+ * @param existing is the original file or directory to link.
11
+ * @param destination is the nbew file or directory to create.
12
+ */
13
+ function link(existing, destination) {
14
+ const stat = (0, fs_1.statSync)(existing);
15
+ if (!stat.isDirectory()) {
16
+ try {
17
+ (0, fs_1.linkSync)(existing, destination);
18
+ }
19
+ catch {
20
+ (0, fs_1.copyFileSync)(existing, destination);
21
+ }
22
+ return;
23
+ }
24
+ (0, fs_1.mkdirSync)(destination, { recursive: true });
25
+ for (const file of (0, fs_1.readdirSync)(existing)) {
26
+ link((0, path_1.join)(existing, file), (0, path_1.join)(destination, file));
27
+ }
28
+ }
29
+ exports.link = link;
30
+ //# sourceMappingURL=link.js.map
package/lib/objects.js CHANGED
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObjectTable = exports.tagJsiiConstructor = exports.objectReference = exports.jsiiTypeFqn = void 0;
4
4
  const spec = require("@jsii/spec");
5
+ const assert = require("assert");
5
6
  const api = require("./api");
7
+ const kernel_1 = require("./kernel");
6
8
  const serialization_1 = require("./serialization");
7
9
  /**
8
10
  * Symbol under which we store the { type -> objid } map on object instances
@@ -13,9 +15,9 @@ const OBJID_SYMBOL = Symbol.for('$__jsii__objid__$');
13
15
  */
14
16
  const IFACES_SYMBOL = Symbol.for('$__jsii__interfaces__$');
15
17
  /**
16
- * Symbol we use to tag the constructor of a JSII class
18
+ * Symbol we use to tag constructors that are exported from a JSII module.
17
19
  */
18
- const JSII_SYMBOL = Symbol.for('__jsii__');
20
+ const JSII_TYPE_FQN_SYMBOL = Symbol('$__jsii__fqn__$');
19
21
  /**
20
22
  * Get the JSII fqn for an object (if available)
21
23
  *
@@ -24,8 +26,7 @@ const JSII_SYMBOL = Symbol.for('__jsii__');
24
26
  * information.
25
27
  */
26
28
  function jsiiTypeFqn(obj) {
27
- var _a;
28
- return (_a = obj.constructor[JSII_SYMBOL]) === null || _a === void 0 ? void 0 : _a.fqn;
29
+ return obj.constructor[JSII_TYPE_FQN_SYMBOL];
29
30
  }
30
31
  exports.jsiiTypeFqn = jsiiTypeFqn;
31
32
  /**
@@ -73,11 +74,16 @@ function tagObject(obj, objid, interfaces) {
73
74
  * Set the JSII FQN for classes produced by a given constructor
74
75
  */
75
76
  function tagJsiiConstructor(constructor, fqn) {
76
- Object.defineProperty(constructor, JSII_SYMBOL, {
77
+ if (Object.prototype.hasOwnProperty.call(constructor, JSII_TYPE_FQN_SYMBOL)) {
78
+ return assert(constructor[JSII_TYPE_FQN_SYMBOL] === fqn, `Unable to register ${constructor.name} as ${fqn}: it is already registerd with FQN ${constructor[JSII_TYPE_FQN_SYMBOL]}`);
79
+ }
80
+ // Mark this constructor as exported from a jsii module, so we know we
81
+ // should be considering it's FQN as a valid exported type.
82
+ Object.defineProperty(constructor, JSII_TYPE_FQN_SYMBOL, {
77
83
  configurable: false,
78
84
  enumerable: false,
79
85
  writable: false,
80
- value: { fqn },
86
+ value: fqn,
81
87
  });
82
88
  }
83
89
  exports.tagJsiiConstructor = tagJsiiConstructor;
@@ -101,7 +107,7 @@ class ObjectTable {
101
107
  registerObject(obj, fqn, interfaces) {
102
108
  var _a;
103
109
  if (fqn === undefined) {
104
- throw new Error('FQN cannot be undefined');
110
+ throw new kernel_1.JsiiFault('FQN cannot be undefined');
105
111
  }
106
112
  const existingRef = objectReference(obj);
107
113
  if (existingRef) {
@@ -135,12 +141,12 @@ class ObjectTable {
135
141
  findObject(objref) {
136
142
  var _a;
137
143
  if (typeof objref !== 'object' || !(api.TOKEN_REF in objref)) {
138
- throw new Error(`Malformed object reference: ${JSON.stringify(objref)}`);
144
+ throw new kernel_1.JsiiFault(`Malformed object reference: ${JSON.stringify(objref)}`);
139
145
  }
140
146
  const objid = objref[api.TOKEN_REF];
141
147
  const obj = this.objects.get(objid);
142
148
  if (!obj) {
143
- throw new Error(`Object ${objid} not found`);
149
+ throw new kernel_1.JsiiFault(`Object ${objid} not found`);
144
150
  }
145
151
  // If there are "additional" interfaces declared on the objref, merge them
146
152
  // into the returned object. This is used to support client-side forced
@@ -167,7 +173,7 @@ class ObjectTable {
167
173
  */
168
174
  deleteObject({ [api.TOKEN_REF]: objid }) {
169
175
  if (!this.objects.delete(objid)) {
170
- throw new Error(`Object ${objid} not found`);
176
+ throw new kernel_1.JsiiFault(`Object ${objid} not found`);
171
177
  }
172
178
  }
173
179
  get count() {
@@ -201,7 +207,7 @@ class InterfaceCollection {
201
207
  addFromClass(fqn) {
202
208
  const ti = this.resolveType(fqn);
203
209
  if (!spec.isClassType(ti)) {
204
- throw new Error(`Expected a class, but received ${spec.describeTypeReference(ti)}`);
210
+ throw new kernel_1.JsiiFault(`Expected a class, but received ${spec.describeTypeReference(ti)}`);
205
211
  }
206
212
  if (ti.base) {
207
213
  this.addFromClass(ti.base);
@@ -219,7 +225,7 @@ class InterfaceCollection {
219
225
  addFromInterface(fqn) {
220
226
  const ti = this.resolveType(fqn);
221
227
  if (!spec.isInterfaceType(ti)) {
222
- throw new Error(`Expected an interface, but received ${spec.describeTypeReference(ti)}`);
228
+ throw new kernel_1.JsiiFault(`Expected an interface, but received ${spec.describeTypeReference(ti)}`);
223
229
  }
224
230
  if (!ti.interfaces) {
225
231
  return;
package/lib/recording.js CHANGED
@@ -47,7 +47,7 @@ function recordInteraction(kernel, inputOutputLogPath) {
47
47
  ok(value);
48
48
  })
49
49
  .catch((err) => {
50
- logOutput({ error: err.message });
50
+ logOutput({ error: err.message, name: err.name });
51
51
  fail(err);
52
52
  });
53
53
  });
@@ -56,8 +56,11 @@ function recordInteraction(kernel, inputOutputLogPath) {
56
56
  return ret;
57
57
  }
58
58
  catch (e) {
59
- logOutput({ error: e.message });
60
- throw e;
59
+ logOutput({ error: e.message, name: e.name });
60
+ if (e.type === "@jsii/kernel.RuntimeError" /* JsiiErrorType.RUNTIME_ERROR */) {
61
+ throw new kernel_1.RuntimeError(e.message);
62
+ }
63
+ throw new kernel_1.JsiiFault(e.message);
61
64
  }
62
65
  },
63
66
  });
@@ -0,0 +1,2 @@
1
+ export declare function defaultCacheRoot(): string;
2
+ //# sourceMappingURL=default-cache-root.d.ts.map
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultCacheRoot = void 0;
4
+ const os_1 = require("os");
5
+ const path_1 = require("path");
6
+ function defaultCacheRoot() {
7
+ switch (process.platform) {
8
+ case 'darwin':
9
+ if (process.env.HOME)
10
+ return (0, path_1.join)(process.env.HOME, 'Library', 'Caches', 'com.amazonaws.jsii', 'package-cache');
11
+ break;
12
+ case 'linux':
13
+ if (process.env.HOME)
14
+ return (0, path_1.join)(process.env.HOME, '.cache', 'aws', 'jsii', 'package-cache');
15
+ break;
16
+ case 'win32':
17
+ if (process.env.LOCALAPPDATA)
18
+ return (0, path_1.join)(process.env.LOCALAPPDATA, 'AWS', 'jsii', 'package-cache');
19
+ break;
20
+ default:
21
+ // Fall back on putting in tmpdir()
22
+ }
23
+ return (0, path_1.join)((0, os_1.tmpdir)(), 'aws-jsii-package-cache');
24
+ }
25
+ exports.defaultCacheRoot = defaultCacheRoot;
26
+ //# sourceMappingURL=default-cache-root.js.map
@@ -0,0 +1,33 @@
1
+ import * as tar from 'tar';
2
+ export declare type ExtractOptions = Omit<tar.ExtractOptions & tar.FileOptions, 'file' | 'cwd'>;
3
+ export interface ExtractResult {
4
+ /**
5
+ * The path in which the extracted files are located
6
+ */
7
+ readonly path: string;
8
+ /**
9
+ * When `'hit'`, the data was already present in cache and was returned from
10
+ * cache.
11
+ *
12
+ * When `'miss'`, the data was extracted into the caache and returned from
13
+ * cache.
14
+ *
15
+ * When `undefined`, the cache is not enabled.
16
+ */
17
+ readonly cache?: 'hit' | 'miss';
18
+ }
19
+ /**
20
+ * Extracts the content of a tarball, possibly caching it on disk.
21
+ *
22
+ * @param file is the path to the tarball to be extracted.
23
+ * @param options are options to pass to `tar.extract`
24
+ * @param comments are included in the cache key, when caching is enabled.
25
+ *
26
+ * @returns the result of the extraction.
27
+ */
28
+ export declare function extract(file: string, options: ExtractOptions, ...comments: readonly string[]): ExtractResult;
29
+ /** @internal */
30
+ export declare function getPackageCacheEnabled(): boolean;
31
+ /** @internal */
32
+ export declare function setPackageCacheEnabled(value: boolean): void;
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.setPackageCacheEnabled = exports.getPackageCacheEnabled = exports.extract = void 0;
5
+ const fs_1 = require("fs");
6
+ const os_1 = require("os");
7
+ const path_1 = require("path");
8
+ const tar = require("tar");
9
+ const disk_cache_1 = require("../disk-cache");
10
+ const default_cache_root_1 = require("./default-cache-root");
11
+ let packageCacheEnabled = ((_a = process.env.JSII_RUNTIME_PACKAGE_CACHE) === null || _a === void 0 ? void 0 : _a.toLocaleUpperCase()) === 'enabled';
12
+ /**
13
+ * Extracts the content of a tarball, possibly caching it on disk.
14
+ *
15
+ * @param file is the path to the tarball to be extracted.
16
+ * @param options are options to pass to `tar.extract`
17
+ * @param comments are included in the cache key, when caching is enabled.
18
+ *
19
+ * @returns the result of the extraction.
20
+ */
21
+ function extract(file, options, ...comments) {
22
+ return (packageCacheEnabled ? extractToCache : extractToTemporary)(file, options, ...comments);
23
+ }
24
+ exports.extract = extract;
25
+ function extractToCache(file, options = {}, ...comments) {
26
+ var _a;
27
+ const cacheRoot = (_a = process.env.JSII_RUNTIME_PACKAGE_CACHE_ROOT) !== null && _a !== void 0 ? _a : (0, default_cache_root_1.defaultCacheRoot)();
28
+ const cache = disk_cache_1.DiskCache.inDirectory(cacheRoot);
29
+ const entry = cache.entryFor(file, ...comments);
30
+ return entry.lock((lock) => {
31
+ let cache = 'hit';
32
+ if (!entry.pathExists) {
33
+ const tmpPath = `${entry.path}.tmp`;
34
+ (0, fs_1.mkdirSync)(tmpPath, { recursive: true });
35
+ try {
36
+ untarInto({
37
+ ...options,
38
+ cwd: tmpPath,
39
+ file,
40
+ });
41
+ (0, fs_1.renameSync)(tmpPath, entry.path);
42
+ }
43
+ catch (error) {
44
+ (0, fs_1.rmSync)(entry.path, { force: true, recursive: true });
45
+ throw error;
46
+ }
47
+ cache = 'miss';
48
+ }
49
+ lock.touch();
50
+ return { path: entry.path, cache };
51
+ });
52
+ }
53
+ function extractToTemporary(file, options = {}) {
54
+ const path = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'jsii-runtime-untar-'));
55
+ untarInto({ ...options, cwd: path, file });
56
+ return { path };
57
+ }
58
+ function untarInto(options) {
59
+ try {
60
+ tar.extract({ ...options, sync: true });
61
+ }
62
+ catch (error) {
63
+ (0, fs_1.rmSync)(options.cwd, { force: true, recursive: true });
64
+ throw error;
65
+ }
66
+ }
67
+ /** @internal */
68
+ function getPackageCacheEnabled() {
69
+ return packageCacheEnabled;
70
+ }
71
+ exports.getPackageCacheEnabled = getPackageCacheEnabled;
72
+ /** @internal */
73
+ function setPackageCacheEnabled(value) {
74
+ packageCacheEnabled = value;
75
+ }
76
+ exports.setPackageCacheEnabled = setPackageCacheEnabled;
77
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsii/kernel",
3
- "version": "1.66.0",
3
+ "version": "1.68.0",
4
4
  "description": "kernel for jsii execution environment",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -31,17 +31,19 @@
31
31
  "package": "package-js"
32
32
  },
33
33
  "dependencies": {
34
- "@jsii/spec": "^1.66.0",
34
+ "@jsii/spec": "^1.68.0",
35
35
  "fs-extra": "^10.1.0",
36
+ "lockfile": "^1.0.4",
36
37
  "tar": "^6.1.11"
37
38
  },
38
39
  "devDependencies": {
39
- "@scope/jsii-calc-base": "^1.66.0",
40
- "@scope/jsii-calc-lib": "^1.66.0",
40
+ "@scope/jsii-calc-base": "^1.68.0",
41
+ "@scope/jsii-calc-lib": "^1.68.0",
41
42
  "@types/fs-extra": "^9.0.13",
43
+ "@types/lockfile": "^1.0.2",
42
44
  "@types/tar": "^6.1.2",
43
- "jest-expect-message": "^1.0.2",
44
- "jsii-build-tools": "^1.66.0",
45
+ "jest-expect-message": "^1.1.2",
46
+ "jsii-build-tools": "^1.68.0",
45
47
  "jsii-calc": "^3.20.120"
46
48
  }
47
49
  }