@jsii/kernel 1.67.0 → 1.69.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.
package/lib/kernel.d.ts CHANGED
@@ -1,4 +1,19 @@
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
  /**
package/lib/kernel.js CHANGED
@@ -1,21 +1,33 @@
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");
8
7
  const fs = require("fs-extra");
9
8
  const module_1 = require("module");
10
9
  const os = require("os");
11
10
  const path = require("path");
12
11
  const api = require("./api");
13
12
  const api_1 = require("./api");
14
- const link_1 = require("./link");
15
13
  const objects_1 = require("./objects");
16
14
  const onExit = require("./on-exit");
17
15
  const wire = require("./serialization");
18
16
  const tar = require("./tar-cache");
17
+ class JsiiFault extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "@jsii/kernel.Fault" /* JsiiErrorType.JSII_FAULT */;
21
+ }
22
+ }
23
+ exports.JsiiFault = JsiiFault;
24
+ class RuntimeError extends Error {
25
+ constructor(message) {
26
+ super(message);
27
+ this.name = "@jsii/kernel.RuntimeError" /* JsiiErrorType.RUNTIME_ERROR */;
28
+ }
29
+ }
30
+ exports.RuntimeError = RuntimeError;
19
31
  class Kernel {
20
32
  /**
21
33
  * Creates a jsii kernel object.
@@ -48,7 +60,7 @@ class Kernel {
48
60
  var _a, _b, _c;
49
61
  this._debug('load', req);
50
62
  if ('assembly' in req) {
51
- throw new Error('`assembly` field is deprecated for "load", use `name`, `version` and `tarball` instead');
63
+ throw new JsiiFault('`assembly` field is deprecated for "load", use `name`, `version` and `tarball` instead');
52
64
  }
53
65
  const pkgname = req.name;
54
66
  const pkgver = req.version;
@@ -58,7 +70,7 @@ class Kernel {
58
70
  // module exists, verify version
59
71
  const epkg = fs.readJsonSync(path.join(packageDir, 'package.json'));
60
72
  if (epkg.version !== pkgver) {
61
- throw new Error(`Multiple versions ${pkgver} and ${epkg.version} of the ` +
73
+ throw new JsiiFault(`Multiple versions ${pkgver} and ${epkg.version} of the ` +
62
74
  `package '${pkgname}' cannot be loaded together since this is unsupported by ` +
63
75
  'some runtime environments');
64
76
  }
@@ -74,21 +86,13 @@ class Kernel {
74
86
  const originalUmask = process.umask(0o022);
75
87
  try {
76
88
  // untar the archive to its final location
77
- const { path: extractedTo, cache } = this._debugTime(() => tar.extract(req.tarball, {
89
+ const { cache } = this._debugTime(() => tar.extract(req.tarball, packageDir, {
78
90
  strict: true,
79
91
  strip: 1,
80
92
  unlink: true,
81
93
  }, req.name, req.version), `tar.extract(${req.tarball}) => ${packageDir}`);
82
- // Create the install directory (there may be several path components for @scoped/packages)
83
- fs.mkdirSync(path.dirname(packageDir), { recursive: true });
84
94
  if (cache != null) {
85
95
  this._debug(`Package cache enabled, extraction resulted in a cache ${cache}`);
86
- // Link the package into place.
87
- this._debugTime(() => (0, link_1.link)(extractedTo, packageDir), `link(${extractedTo}, ${packageDir})`);
88
- }
89
- else {
90
- // This is not from cache, so we move it around instead of copying.
91
- (0, fs_1.renameSync)(extractedTo, packageDir);
92
96
  }
93
97
  }
94
98
  finally {
@@ -101,7 +105,7 @@ class Kernel {
101
105
  assmSpec = this._debugTime(() => (0, spec_1.loadAssemblyFromPath)(packageDir), `loadAssemblyFromPath(${packageDir})`);
102
106
  }
103
107
  catch (e) {
104
- throw new Error(`Error for package tarball ${req.tarball}: ${e.message}`);
108
+ throw new JsiiFault(`Error for package tarball ${req.tarball}: ${e.message}`);
105
109
  }
106
110
  // load the module and capture its closure
107
111
  const closure = this._debugTime(() => this.require(packageDir), `require(${packageDir})`);
@@ -119,11 +123,11 @@ class Kernel {
119
123
  // module exists, verify version
120
124
  const epkg = fs.readJsonSync(path.join(packageDir, 'package.json'));
121
125
  if (!epkg.bin) {
122
- throw new Error('There is no bin scripts defined for this package.');
126
+ throw new JsiiFault('There is no bin scripts defined for this package.');
123
127
  }
124
128
  const scriptPath = epkg.bin[req.script];
125
129
  if (!epkg.bin) {
126
- throw new Error(`Script with name ${req.script} was not defined.`);
130
+ throw new JsiiFault(`Script with name ${req.script} was not defined.`);
127
131
  }
128
132
  const result = cp.spawnSync(path.join(packageDir, scriptPath), (_a = req.args) !== null && _a !== void 0 ? _a : [], {
129
133
  encoding: 'utf-8',
@@ -143,7 +147,7 @@ class Kernel {
143
147
  signal: result.signal,
144
148
  };
145
149
  }
146
- throw new Error(`Package with name ${req.assembly} was not loaded.`);
150
+ throw new JsiiFault(`Package with name ${req.assembly} was not loaded.`);
147
151
  }
148
152
  create(req) {
149
153
  return this._create(req);
@@ -160,7 +164,7 @@ class Kernel {
160
164
  this._debug('sget', symbol);
161
165
  const ti = this._typeInfoForProperty(property, fqn);
162
166
  if (!ti.static) {
163
- throw new Error(`property ${symbol} is not static`);
167
+ throw new JsiiFault(`property ${symbol} is not static`);
164
168
  }
165
169
  const prototype = this._findSymbol(fqn);
166
170
  const value = this._ensureSync(`property ${property}`, () => prototype[property]);
@@ -175,10 +179,10 @@ class Kernel {
175
179
  this._debug('sset', symbol);
176
180
  const ti = this._typeInfoForProperty(property, fqn);
177
181
  if (!ti.static) {
178
- throw new Error(`property ${symbol} is not static`);
182
+ throw new JsiiFault(`property ${symbol} is not static`);
179
183
  }
180
184
  if (ti.immutable) {
181
- throw new Error(`static property ${symbol} is readonly`);
185
+ throw new JsiiFault(`static property ${symbol} is readonly`);
182
186
  }
183
187
  const prototype = this._findSymbol(fqn);
184
188
  this._ensureSync(`property ${property}`, () => (prototype[property] = this._toSandbox(value, ti, `assigned to static property ${symbol}`)));
@@ -209,7 +213,7 @@ class Kernel {
209
213
  const { instance, fqn, interfaces } = this.objects.findObject(objref);
210
214
  const propInfo = this._typeInfoForProperty(req.property, fqn, interfaces);
211
215
  if (propInfo.immutable) {
212
- throw new Error(`Cannot set value of immutable property ${req.property} to ${req.value}`);
216
+ throw new JsiiFault(`Cannot set value of immutable property ${req.property} to ${req.value}`);
213
217
  }
214
218
  const propertyToSet = this._findPropertyTarget(instance, property);
215
219
  this._ensureSync(`property '${objref[api_1.TOKEN_REF]}.${propertyToSet}'`, () => (instance[propertyToSet] = this._toSandbox(value, propInfo, `assigned to property ${fqn}.${property}`)));
@@ -223,7 +227,7 @@ class Kernel {
223
227
  const { ti, obj, fn } = this._findInvokeTarget(objref, method, args);
224
228
  // verify this is not an async method
225
229
  if (ti.async) {
226
- throw new Error(`${method} is an async method, use "begin" instead`);
230
+ throw new JsiiFault(`${method} is an async method, use "begin" instead`);
227
231
  }
228
232
  const fqn = (0, objects_1.jsiiTypeFqn)(obj);
229
233
  const ret = this._ensureSync(`method '${objref[api_1.TOKEN_REF]}.${method}'`, () => {
@@ -240,11 +244,11 @@ class Kernel {
240
244
  this._debug('sinvoke', fqn, method, args);
241
245
  const ti = this._typeInfoForMethod(method, fqn);
242
246
  if (!ti.static) {
243
- throw new Error(`${fqn}.${method} is not a static method`);
247
+ throw new JsiiFault(`${fqn}.${method} is not a static method`);
244
248
  }
245
249
  // verify this is not an async method
246
250
  if (ti.async) {
247
- throw new Error(`${method} is an async method, use "begin" instead`);
251
+ throw new JsiiFault(`${method} is an async method, use "begin" instead`);
248
252
  }
249
253
  const prototype = this._findSymbol(fqn);
250
254
  const fn = prototype[method];
@@ -262,12 +266,12 @@ class Kernel {
262
266
  const args = (_a = req.args) !== null && _a !== void 0 ? _a : [];
263
267
  this._debug('begin', objref, method, args);
264
268
  if (this.syncInProgress) {
265
- throw new Error(`Cannot invoke async method '${req.objref[api_1.TOKEN_REF]}.${req.method}' while sync ${this.syncInProgress} is being processed`);
269
+ throw new JsiiFault(`Cannot invoke async method '${req.objref[api_1.TOKEN_REF]}.${req.method}' while sync ${this.syncInProgress} is being processed`);
266
270
  }
267
271
  const { ti, obj, fn } = this._findInvokeTarget(objref, method, args);
268
272
  // verify this is indeed an async method
269
273
  if (!ti.async) {
270
- throw new Error(`Method ${method} is expected to be an async method`);
274
+ throw new JsiiFault(`Method ${method} is expected to be an async method`);
271
275
  }
272
276
  const fqn = (0, objects_1.jsiiTypeFqn)(obj);
273
277
  const promise = fn.apply(obj, this._toSandboxValues(args, `async method ${fqn ? `${fqn}#` : ''}${method}`, ti.parameters));
@@ -288,7 +292,7 @@ class Kernel {
288
292
  this._debug('end', promiseid);
289
293
  const storedPromise = this.promises.get(promiseid);
290
294
  if (storedPromise == null) {
291
- throw new Error(`Cannot find promise with ID: ${promiseid}`);
295
+ throw new JsiiFault(`Cannot find promise with ID: ${promiseid}`);
292
296
  }
293
297
  const { promise, method } = storedPromise;
294
298
  let result;
@@ -298,7 +302,7 @@ class Kernel {
298
302
  }
299
303
  catch (e) {
300
304
  this._debug('promise error:', e);
301
- throw e;
305
+ throw new JsiiFault(e.message);
302
306
  }
303
307
  return {
304
308
  result: this._fromSandbox(result, (_a = method.returns) !== null && _a !== void 0 ? _a : 'void', `returned by async method ${method.name}`),
@@ -328,7 +332,7 @@ class Kernel {
328
332
  this._debug('complete', cbid, err, result);
329
333
  const cb = this.waiting.get(cbid);
330
334
  if (!cb) {
331
- throw new Error(`Callback ${cbid} not found`);
335
+ throw new JsiiFault(`Callback ${cbid} not found`);
332
336
  }
333
337
  if (err) {
334
338
  this._debug('completed with error:', err);
@@ -352,7 +356,7 @@ class Kernel {
352
356
  const assembly = this._assemblyFor(assemblyName);
353
357
  const targets = assembly.metadata.targets;
354
358
  if (!targets) {
355
- throw new Error(`Unexpected - "targets" for ${assemblyName} is missing!`);
359
+ throw new JsiiFault(`Unexpected - "targets" for ${assemblyName} is missing!`);
356
360
  }
357
361
  return { naming: targets };
358
362
  }
@@ -374,7 +378,7 @@ class Kernel {
374
378
  case spec.TypeKind.Class:
375
379
  case spec.TypeKind.Enum:
376
380
  const constructor = this._findSymbol(fqn);
377
- (0, objects_1.tagJsiiConstructor)(constructor, fqn, assm.metadata.version);
381
+ (0, objects_1.tagJsiiConstructor)(constructor, fqn);
378
382
  }
379
383
  }
380
384
  }
@@ -393,9 +397,9 @@ class Kernel {
393
397
  parameters: classType.initializer && classType.initializer.parameters,
394
398
  };
395
399
  case spec.TypeKind.Interface:
396
- throw new Error(`Cannot create an object with an FQN of an interface: ${fqn}`);
400
+ throw new JsiiFault(`Cannot create an object with an FQN of an interface: ${fqn}`);
397
401
  default:
398
- throw new Error(`Unexpected FQN kind: ${fqn}`);
402
+ throw new JsiiFault(`Unexpected FQN kind: ${fqn}`);
399
403
  }
400
404
  }
401
405
  _getPackageDir(pkgname) {
@@ -429,26 +433,26 @@ class Kernel {
429
433
  for (const override of overrides) {
430
434
  if (api.isMethodOverride(override)) {
431
435
  if (api.isPropertyOverride(override)) {
432
- throw new Error(overrideTypeErrorMessage);
436
+ throw new JsiiFault(overrideTypeErrorMessage);
433
437
  }
434
438
  if (methods.has(override.method)) {
435
- throw new Error(`Duplicate override for method '${override.method}'`);
439
+ throw new JsiiFault(`Duplicate override for method '${override.method}'`);
436
440
  }
437
441
  methods.add(override.method);
438
442
  this._applyMethodOverride(obj, objref, fqn, interfaces, override);
439
443
  }
440
444
  else if (api.isPropertyOverride(override)) {
441
445
  if (api.isMethodOverride(override)) {
442
- throw new Error(overrideTypeErrorMessage);
446
+ throw new JsiiFault(overrideTypeErrorMessage);
443
447
  }
444
448
  if (properties.has(override.property)) {
445
- throw Error(`Duplicate override for property '${override.property}'`);
449
+ throw new JsiiFault(`Duplicate override for property '${override.property}'`);
446
450
  }
447
451
  properties.add(override.property);
448
452
  this._applyPropertyOverride(obj, objref, fqn, interfaces, override);
449
453
  }
450
454
  else {
451
- throw new Error(overrideTypeErrorMessage);
455
+ throw new JsiiFault(overrideTypeErrorMessage);
452
456
  }
453
457
  }
454
458
  }
@@ -460,7 +464,7 @@ class Kernel {
460
464
  _applyPropertyOverride(obj, objref, typeFqn, interfaces, override) {
461
465
  // error if we can find a method with this name
462
466
  if (this._tryTypeInfoForMethod(override.property, typeFqn, interfaces)) {
463
- throw new Error(`Trying to override method '${override.property}' as a property`);
467
+ throw new JsiiFault(`Trying to override method '${override.property}' as a property`);
464
468
  }
465
469
  let propInfo = this._tryTypeInfoForProperty(override.property, typeFqn, interfaces);
466
470
  // if this is a private property (i.e. doesn't have `propInfo` the object has a key)
@@ -546,7 +550,7 @@ class Kernel {
546
550
  _applyMethodOverride(obj, objref, typeFqn, interfaces, override) {
547
551
  // error if we can find a property with this name
548
552
  if (this._tryTypeInfoForProperty(override.method, typeFqn, interfaces)) {
549
- throw new Error(`Trying to override property '${override.method}' as a method`);
553
+ throw new JsiiFault(`Trying to override property '${override.method}' as a method`);
550
554
  }
551
555
  let methodInfo = this._tryTypeInfoForMethod(override.method, typeFqn, interfaces);
552
556
  // If this is a private method (doesn't have methodInfo, key resolves on the object), we
@@ -645,7 +649,7 @@ class Kernel {
645
649
  if (!fn) {
646
650
  fn = instance[methodName];
647
651
  if (!fn) {
648
- throw new Error(`Cannot find ${methodName} on object`);
652
+ throw new JsiiFault(`Cannot find ${methodName} on object`);
649
653
  }
650
654
  }
651
655
  return { ti, obj: instance, fn };
@@ -655,7 +659,7 @@ class Kernel {
655
659
  const params = (_a = method === null || method === void 0 ? void 0 : method.parameters) !== null && _a !== void 0 ? _a : [];
656
660
  // error if args > params
657
661
  if (args.length > params.length && !(method && method.variadic)) {
658
- throw new Error(`Too many arguments (method accepts ${params.length} parameters, got ${args.length} arguments)`);
662
+ throw new JsiiFault(`Too many arguments (method accepts ${params.length} parameters, got ${args.length} arguments)`);
659
663
  }
660
664
  for (let i = 0; i < params.length; ++i) {
661
665
  const param = params[i];
@@ -666,19 +670,19 @@ class Kernel {
666
670
  } // No vararg was provided
667
671
  for (let j = i; j < params.length; j++) {
668
672
  if (!param.optional && params[j] === undefined) {
669
- throw new Error(`Unexpected 'undefined' value at index ${j - i} of variadic argument '${param.name}' of type '${spec.describeTypeReference(param.type)}'`);
673
+ throw new JsiiFault(`Unexpected 'undefined' value at index ${j - i} of variadic argument '${param.name}' of type '${spec.describeTypeReference(param.type)}'`);
670
674
  }
671
675
  }
672
676
  }
673
677
  else if (!param.optional && arg === undefined) {
674
- throw new Error(`Not enough arguments. Missing argument for the required parameter '${param.name}' of type '${spec.describeTypeReference(param.type)}'`);
678
+ throw new JsiiFault(`Not enough arguments. Missing argument for the required parameter '${param.name}' of type '${spec.describeTypeReference(param.type)}'`);
675
679
  }
676
680
  }
677
681
  }
678
682
  _assemblyFor(assemblyName) {
679
683
  const assembly = this.assemblies.get(assemblyName);
680
684
  if (!assembly) {
681
- throw new Error(`Could not find assembly: ${assemblyName}`);
685
+ throw new JsiiFault(`Could not find assembly: ${assemblyName}`);
682
686
  }
683
687
  return assembly;
684
688
  }
@@ -694,7 +698,7 @@ class Kernel {
694
698
  curr = curr[name];
695
699
  }
696
700
  if (!curr) {
697
- throw new Error(`Could not find symbol ${fqn}`);
701
+ throw new JsiiFault(`Could not find symbol ${fqn}`);
698
702
  }
699
703
  return curr;
700
704
  }
@@ -704,12 +708,12 @@ class Kernel {
704
708
  const moduleName = components[0];
705
709
  const assembly = this.assemblies.get(moduleName);
706
710
  if (!assembly) {
707
- throw new Error(`Module '${moduleName}' not found`);
711
+ throw new JsiiFault(`Module '${moduleName}' not found`);
708
712
  }
709
713
  const types = (_a = assembly.metadata.types) !== null && _a !== void 0 ? _a : {};
710
714
  const fqnInfo = types[fqn];
711
715
  if (!fqnInfo) {
712
- throw new Error(`Type '${fqn}' not found`);
716
+ throw new JsiiFault(`Type '${fqn}' not found`);
713
717
  }
714
718
  return fqnInfo;
715
719
  }
@@ -719,7 +723,7 @@ class Kernel {
719
723
  const addendum = interfaces && interfaces.length > 0
720
724
  ? ` or interface(s) ${interfaces.join(', ')}`
721
725
  : '';
722
- throw new Error(`Class ${fqn}${addendum} doesn't have a method '${methodName}'`);
726
+ throw new JsiiFault(`Class ${fqn}${addendum} doesn't have a method '${methodName}'`);
723
727
  }
724
728
  return ti;
725
729
  }
@@ -773,7 +777,7 @@ class Kernel {
773
777
  bases = (_a = interfaceTypeInfo.interfaces) !== null && _a !== void 0 ? _a : [];
774
778
  }
775
779
  else {
776
- throw new Error(`Type of kind ${typeInfo.kind} does not have properties`);
780
+ throw new JsiiFault(`Type of kind ${typeInfo.kind} does not have properties`);
777
781
  }
778
782
  for (const p of properties !== null && properties !== void 0 ? properties : []) {
779
783
  if (p.name === property) {
@@ -796,7 +800,7 @@ class Kernel {
796
800
  const addendum = interfaces && interfaces.length > 0
797
801
  ? ` or interface(s) ${interfaces.join(', ')}`
798
802
  : '';
799
- throw new Error(`Type ${fqn}${addendum} doesn't have a property '${property}'`);
803
+ throw new JsiiFault(`Type ${fqn}${addendum} doesn't have a property '${property}'`);
800
804
  }
801
805
  return typeInfo;
802
806
  }
@@ -831,7 +835,7 @@ class Kernel {
831
835
  parametersCopy.push(parametersCopy[parametersCopy.length - 1]);
832
836
  }
833
837
  if (xs.length > parametersCopy.length) {
834
- throw new Error(`Argument list (${JSON.stringify(xs)}) not same size as expected argument list (length ${parametersCopy.length})`);
838
+ throw new JsiiFault(`Argument list (${JSON.stringify(xs)}) not same size as expected argument list (length ${parametersCopy.length})`);
835
839
  }
836
840
  return xs.map((x, i) => boxUnbox(x, parametersCopy[i], `passed to parameter ${parametersCopy[i].name} of ${methodContext}`));
837
841
  }
@@ -863,6 +867,15 @@ class Kernel {
863
867
  try {
864
868
  return fn();
865
869
  }
870
+ catch (e) {
871
+ if (e.name === "@jsii/kernel.Fault" /* JsiiErrorType.JSII_FAULT */) {
872
+ throw new JsiiFault(e);
873
+ }
874
+ // This error can be thrown by the kernel directly, or it can be
875
+ // thrown from user code. If the error comes from the kernel, then its name field will be populated;
876
+ // if the error comes from user code, the name field will not be populated.
877
+ throw new RuntimeError(e);
878
+ }
866
879
  finally {
867
880
  delete this.syncInProgress;
868
881
  }
package/lib/objects.d.ts CHANGED
@@ -17,7 +17,7 @@ export declare function objectReference(obj: unknown): api.ObjRef | undefined;
17
17
  /**
18
18
  * Set the JSII FQN for classes produced by a given constructor
19
19
  */
20
- export declare function tagJsiiConstructor(constructor: any, fqn: string, version: string): void;
20
+ export declare function tagJsiiConstructor(constructor: any, fqn: string): void;
21
21
  /**
22
22
  * Table of JSII objects
23
23
  *
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_RTTI_SYMBOL = Symbol.for('jsii.rtti');
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_RTTI_SYMBOL = Symbol.for('jsii.rtti');
24
26
  * information.
25
27
  */
26
28
  function jsiiTypeFqn(obj) {
27
- var _a;
28
- return (_a = obj.constructor[JSII_RTTI_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
  /**
@@ -72,15 +73,17 @@ function tagObject(obj, objid, interfaces) {
72
73
  /**
73
74
  * Set the JSII FQN for classes produced by a given constructor
74
75
  */
75
- function tagJsiiConstructor(constructor, fqn, version) {
76
- if (Object.prototype.hasOwnProperty.call(constructor, JSII_RTTI_SYMBOL)) {
77
- return;
76
+ function tagJsiiConstructor(constructor, fqn) {
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]}`);
78
79
  }
79
- Object.defineProperty(constructor, JSII_RTTI_SYMBOL, {
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, {
80
83
  configurable: false,
81
84
  enumerable: false,
82
85
  writable: false,
83
- value: { fqn, version },
86
+ value: fqn,
84
87
  });
85
88
  }
86
89
  exports.tagJsiiConstructor = tagJsiiConstructor;
@@ -104,7 +107,7 @@ class ObjectTable {
104
107
  registerObject(obj, fqn, interfaces) {
105
108
  var _a;
106
109
  if (fqn === undefined) {
107
- throw new Error('FQN cannot be undefined');
110
+ throw new kernel_1.JsiiFault('FQN cannot be undefined');
108
111
  }
109
112
  const existingRef = objectReference(obj);
110
113
  if (existingRef) {
@@ -138,12 +141,12 @@ class ObjectTable {
138
141
  findObject(objref) {
139
142
  var _a;
140
143
  if (typeof objref !== 'object' || !(api.TOKEN_REF in objref)) {
141
- throw new Error(`Malformed object reference: ${JSON.stringify(objref)}`);
144
+ throw new kernel_1.JsiiFault(`Malformed object reference: ${JSON.stringify(objref)}`);
142
145
  }
143
146
  const objid = objref[api.TOKEN_REF];
144
147
  const obj = this.objects.get(objid);
145
148
  if (!obj) {
146
- throw new Error(`Object ${objid} not found`);
149
+ throw new kernel_1.JsiiFault(`Object ${objid} not found`);
147
150
  }
148
151
  // If there are "additional" interfaces declared on the objref, merge them
149
152
  // into the returned object. This is used to support client-side forced
@@ -170,7 +173,7 @@ class ObjectTable {
170
173
  */
171
174
  deleteObject({ [api.TOKEN_REF]: objid }) {
172
175
  if (!this.objects.delete(objid)) {
173
- throw new Error(`Object ${objid} not found`);
176
+ throw new kernel_1.JsiiFault(`Object ${objid} not found`);
174
177
  }
175
178
  }
176
179
  get count() {
@@ -204,7 +207,7 @@ class InterfaceCollection {
204
207
  addFromClass(fqn) {
205
208
  const ti = this.resolveType(fqn);
206
209
  if (!spec.isClassType(ti)) {
207
- 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)}`);
208
211
  }
209
212
  if (ti.base) {
210
213
  this.addFromClass(ti.base);
@@ -222,7 +225,7 @@ class InterfaceCollection {
222
225
  addFromInterface(fqn) {
223
226
  const ti = this.resolveType(fqn);
224
227
  if (!spec.isInterfaceType(ti)) {
225
- 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)}`);
226
229
  }
227
230
  if (!ti.interfaces) {
228
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
  });
@@ -1,10 +1,6 @@
1
1
  import * as tar from 'tar';
2
2
  export declare type ExtractOptions = Omit<tar.ExtractOptions & tar.FileOptions, 'file' | 'cwd'>;
3
3
  export interface ExtractResult {
4
- /**
5
- * The path in which the extracted files are located
6
- */
7
- readonly path: string;
8
4
  /**
9
5
  * When `'hit'`, the data was already present in cache and was returned from
10
6
  * cache.
@@ -25,7 +21,7 @@ export interface ExtractResult {
25
21
  *
26
22
  * @returns the result of the extraction.
27
23
  */
28
- export declare function extract(file: string, options: ExtractOptions, ...comments: readonly string[]): ExtractResult;
24
+ export declare function extract(file: string, outDir: string, options: ExtractOptions, ...comments: readonly string[]): ExtractResult;
29
25
  /** @internal */
30
26
  export declare function getPackageCacheEnabled(): boolean;
31
27
  /** @internal */
@@ -3,10 +3,9 @@ var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.setPackageCacheEnabled = exports.getPackageCacheEnabled = exports.extract = void 0;
5
5
  const fs_1 = require("fs");
6
- const os_1 = require("os");
7
- const path_1 = require("path");
8
6
  const tar = require("tar");
9
7
  const disk_cache_1 = require("../disk-cache");
8
+ const link_1 = require("../link");
10
9
  const default_cache_root_1 = require("./default-cache-root");
11
10
  let packageCacheEnabled = ((_a = process.env.JSII_RUNTIME_PACKAGE_CACHE) === null || _a === void 0 ? void 0 : _a.toLocaleUpperCase()) === 'enabled';
12
11
  /**
@@ -18,27 +17,36 @@ let packageCacheEnabled = ((_a = process.env.JSII_RUNTIME_PACKAGE_CACHE) === nul
18
17
  *
19
18
  * @returns the result of the extraction.
20
19
  */
21
- function extract(file, options, ...comments) {
22
- return (packageCacheEnabled ? extractToCache : extractToTemporary)(file, options, ...comments);
20
+ function extract(file, outDir, options, ...comments) {
21
+ (0, fs_1.mkdirSync)(outDir, { recursive: true });
22
+ try {
23
+ return (packageCacheEnabled ? extractViaCache : extractToOutDir)(file, outDir, options, ...comments);
24
+ }
25
+ catch (err) {
26
+ (0, fs_1.rmSync)(outDir, { force: true, recursive: true });
27
+ throw err;
28
+ }
23
29
  }
24
30
  exports.extract = extract;
25
- function extractToCache(file, options = {}, ...comments) {
31
+ function extractViaCache(file, outDir, options = {}, ...comments) {
26
32
  var _a;
27
33
  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) => {
34
+ const dirCache = disk_cache_1.DiskCache.inDirectory(cacheRoot);
35
+ const entry = dirCache.entryFor(file, ...comments);
36
+ const { path, cache } = entry.lock((lock) => {
31
37
  let cache = 'hit';
32
38
  if (!entry.pathExists) {
33
- const tmpPath = `${entry.path}.tmp`;
34
- (0, fs_1.mkdirSync)(tmpPath, { recursive: true });
39
+ // !!!IMPORTANT!!!
40
+ // Extract directly into the final target directory, as certain antivirus
41
+ // software configurations on Windows will make a `renameSync` operation
42
+ // fail with EPERM until the files have been fully analyzed.
43
+ (0, fs_1.mkdirSync)(entry.path, { recursive: true });
35
44
  try {
36
45
  untarInto({
37
46
  ...options,
38
- cwd: tmpPath,
47
+ cwd: entry.path,
39
48
  file,
40
49
  });
41
- (0, fs_1.renameSync)(tmpPath, entry.path);
42
50
  }
43
51
  catch (error) {
44
52
  (0, fs_1.rmSync)(entry.path, { force: true, recursive: true });
@@ -49,11 +57,16 @@ function extractToCache(file, options = {}, ...comments) {
49
57
  lock.touch();
50
58
  return { path: entry.path, cache };
51
59
  });
60
+ (0, link_1.link)(path, outDir);
61
+ return { cache };
52
62
  }
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 };
63
+ function extractToOutDir(file, cwd, options = {}) {
64
+ // !!!IMPORTANT!!!
65
+ // Extract directly into the final target directory, as certain antivirus
66
+ // software configurations on Windows will make a `renameSync` operation
67
+ // fail with EPERM until the files have been fully analyzed.
68
+ untarInto({ ...options, cwd, file });
69
+ return {};
57
70
  }
58
71
  function untarInto(options) {
59
72
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsii/kernel",
3
- "version": "1.67.0",
3
+ "version": "1.69.0",
4
4
  "description": "kernel for jsii execution environment",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -31,19 +31,19 @@
31
31
  "package": "package-js"
32
32
  },
33
33
  "dependencies": {
34
- "@jsii/spec": "^1.67.0",
34
+ "@jsii/spec": "^1.69.0",
35
35
  "fs-extra": "^10.1.0",
36
36
  "lockfile": "^1.0.4",
37
37
  "tar": "^6.1.11"
38
38
  },
39
39
  "devDependencies": {
40
- "@scope/jsii-calc-base": "^1.67.0",
41
- "@scope/jsii-calc-lib": "^1.67.0",
40
+ "@scope/jsii-calc-base": "^1.69.0",
41
+ "@scope/jsii-calc-lib": "^1.69.0",
42
42
  "@types/fs-extra": "^9.0.13",
43
43
  "@types/lockfile": "^1.0.2",
44
44
  "@types/tar": "^6.1.2",
45
- "jest-expect-message": "^1.0.2",
46
- "jsii-build-tools": "^1.67.0",
45
+ "jest-expect-message": "^1.1.2",
46
+ "jsii-build-tools": "^1.69.0",
47
47
  "jsii-calc": "^3.20.120"
48
48
  }
49
49
  }