jsii 5.4.16-dev.2 → 5.4.16-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/lib/case.d.ts +1 -0
  2. package/lib/case.js +2 -1
  3. package/lib/case.js.map +1 -1
  4. package/lib/compiler.d.ts +38 -14
  5. package/lib/compiler.js +114 -108
  6. package/lib/compiler.js.map +1 -1
  7. package/lib/jsii-diagnostic.d.ts +3 -0
  8. package/lib/jsii-diagnostic.js +15 -1
  9. package/lib/jsii-diagnostic.js.map +1 -1
  10. package/lib/main.js +45 -2
  11. package/lib/main.js.map +1 -1
  12. package/lib/project-info.d.ts +5 -0
  13. package/lib/project-info.js +13 -0
  14. package/lib/project-info.js.map +1 -1
  15. package/lib/tsconfig/compiler-options.d.ts +54 -0
  16. package/lib/tsconfig/compiler-options.js +136 -0
  17. package/lib/tsconfig/compiler-options.js.map +1 -0
  18. package/lib/tsconfig/index.d.ts +18 -0
  19. package/lib/tsconfig/index.js +11 -0
  20. package/lib/tsconfig/index.js.map +1 -0
  21. package/lib/tsconfig/rulesets/configurable.d.ts +4 -0
  22. package/lib/tsconfig/rulesets/configurable.js +22 -0
  23. package/lib/tsconfig/rulesets/configurable.js.map +1 -0
  24. package/lib/tsconfig/rulesets/generated.public.d.ts +4 -0
  25. package/lib/tsconfig/rulesets/generated.public.js +28 -0
  26. package/lib/tsconfig/rulesets/generated.public.js.map +1 -0
  27. package/lib/tsconfig/rulesets/incompatible-options.d.ts +4 -0
  28. package/lib/tsconfig/rulesets/incompatible-options.js +11 -0
  29. package/lib/tsconfig/rulesets/incompatible-options.js.map +1 -0
  30. package/lib/tsconfig/rulesets/minimal.public.d.ts +4 -0
  31. package/lib/tsconfig/rulesets/minimal.public.js +11 -0
  32. package/lib/tsconfig/rulesets/minimal.public.js.map +1 -0
  33. package/lib/tsconfig/rulesets/strict.public.d.ts +4 -0
  34. package/lib/tsconfig/rulesets/strict.public.js +29 -0
  35. package/lib/tsconfig/rulesets/strict.public.js.map +1 -0
  36. package/lib/tsconfig/tsconfig-validator.d.ts +16 -0
  37. package/lib/tsconfig/tsconfig-validator.js +46 -0
  38. package/lib/tsconfig/tsconfig-validator.js.map +1 -0
  39. package/lib/tsconfig/validator.d.ts +155 -0
  40. package/lib/tsconfig/validator.js +301 -0
  41. package/lib/tsconfig/validator.js.map +1 -0
  42. package/lib/version.d.ts +2 -2
  43. package/lib/version.js +2 -2
  44. package/lib/version.js.map +1 -1
  45. package/package.json +2 -1
@@ -0,0 +1,301 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObjectValidator = exports.ValidationError = exports.Match = exports.RuleSet = exports.RuleType = void 0;
4
+ var RuleType;
5
+ (function (RuleType) {
6
+ RuleType[RuleType["PASS"] = 0] = "PASS";
7
+ RuleType[RuleType["FAIL"] = 1] = "FAIL";
8
+ })(RuleType || (exports.RuleType = RuleType = {}));
9
+ class RuleSet {
10
+ get rules() {
11
+ return this._rules;
12
+ }
13
+ /**
14
+ * Return all fields for which a rule exists
15
+ */
16
+ get fields() {
17
+ return [...new Set(this._rules.map((r) => r.field))];
18
+ }
19
+ /**
20
+ * Return a list of fields that are allowed, or undefined if all are allowed.
21
+ */
22
+ get allowedFields() {
23
+ if (this.options.unexpectedFields === RuleType.FAIL) {
24
+ return this.fields;
25
+ }
26
+ return undefined;
27
+ }
28
+ /**
29
+ * Find all required fields by evaluating every rule in th set against undefined.
30
+ * If the rule fails, the key must be required.
31
+ *
32
+ * @returns A list of keys that must be included or undefined
33
+ */
34
+ get requiredFields() {
35
+ const required = [];
36
+ for (const rule of this._rules) {
37
+ const key = rule.field;
38
+ const matcherResult = rule.matcher(undefined);
39
+ switch (rule.type) {
40
+ case RuleType.PASS:
41
+ if (!matcherResult) {
42
+ required.push(key);
43
+ }
44
+ break;
45
+ case RuleType.FAIL:
46
+ if (matcherResult) {
47
+ required.push(key);
48
+ }
49
+ break;
50
+ default:
51
+ continue;
52
+ }
53
+ }
54
+ return required;
55
+ }
56
+ constructor(options = {
57
+ unexpectedFields: RuleType.PASS,
58
+ }) {
59
+ this.options = options;
60
+ this._rules = [];
61
+ }
62
+ /**
63
+ * Requires the matcher to pass for the given field.
64
+ * Otherwise a violation is detected.
65
+ *
66
+ * @param field The field the rule applies to
67
+ * @param matcher The matcher function
68
+ */
69
+ shouldPass(field, matcher) {
70
+ this._rules.push({ field, matcher, type: RuleType.PASS });
71
+ }
72
+ /**
73
+ * Detects a violation if the matcher is matching for a certain field.
74
+ *
75
+ * @param field The field the rule applies to
76
+ * @param matcher The matcher function
77
+ */
78
+ shouldFail(field, matcher) {
79
+ this._rules.push({ field, matcher, type: RuleType.FAIL });
80
+ }
81
+ /**
82
+ * Imports all rules from an other rule set.
83
+ * Note that any options from the other rule set will be ignored.
84
+ *
85
+ * @param other The other rule set to import rules from.
86
+ */
87
+ import(other) {
88
+ this._rules.push(...other.rules);
89
+ }
90
+ /**
91
+ * Records the field hints for the given rule set.
92
+ * Hints are values that are guaranteed to pass the rule.
93
+ * The list of hints is not guaranteed to be complete nor does it guarantee to return any values.
94
+ * This can be used to create synthetic values for testing for error messages.
95
+ *
96
+ * @returns A record of fields and allowed values
97
+ */
98
+ getFieldHints() {
99
+ const fieldHints = {};
100
+ for (const rule of this._rules) {
101
+ // We are only interested in PASS rules here.
102
+ // For FAILs we still don't know which values would pass.
103
+ if (rule.type === RuleType.PASS) {
104
+ // run the matcher to record hints
105
+ rule.matcher(undefined, {
106
+ hints: (receivedHints) => {
107
+ var _a;
108
+ // if we have recorded hints, add them to the map
109
+ if (receivedHints) {
110
+ fieldHints[_a = rule.field] ?? (fieldHints[_a] = []);
111
+ fieldHints[rule.field].push(...receivedHints);
112
+ }
113
+ },
114
+ });
115
+ }
116
+ }
117
+ return fieldHints;
118
+ }
119
+ }
120
+ exports.RuleSet = RuleSet;
121
+ /**
122
+ * Helper to wrap a matcher with error reporting and hints
123
+ */
124
+ function wrapMatcher(matcher, message, allowed) {
125
+ return (value, options) => {
126
+ options?.reporter?.(message(value));
127
+ if (allowed) {
128
+ options?.hints?.(allowed);
129
+ }
130
+ return matcher(value);
131
+ };
132
+ }
133
+ class Match {
134
+ /**
135
+ * Value is optional, but if present should match
136
+ */
137
+ static optional(matcher) {
138
+ return (value, options) => {
139
+ if (value == null) {
140
+ return true;
141
+ }
142
+ return matcher(value, options);
143
+ };
144
+ }
145
+ /**
146
+ * Value must be one of the allowed options
147
+ */
148
+ static oneOf(...allowed) {
149
+ return wrapMatcher((actual) => allowed.includes(actual), (actual) => `Expected value to be one of ${JSON.stringify(allowed)}, got: ${JSON.stringify(actual)}`, allowed);
150
+ }
151
+ /**
152
+ * Value must be loosely equal to the expected value
153
+ * Arrays are compared by elements
154
+ */
155
+ static eq(expected) {
156
+ return (actual, options) => {
157
+ if (Array.isArray(expected)) {
158
+ return Match.arrEq(expected)(actual, options);
159
+ }
160
+ try {
161
+ options?.hints?.([expected]);
162
+ options?.reporter?.(`Expected value ${JSON.stringify(expected)}, got: ${JSON.stringify(actual)}`);
163
+ return actual == expected;
164
+ }
165
+ catch {
166
+ // some values cannot compared using loose quality, in this case the matcher just fails
167
+ return false;
168
+ }
169
+ };
170
+ }
171
+ /**
172
+ * Value must be loosely equal to the expected value
173
+ * Arrays are compared by elements
174
+ */
175
+ static arrEq(expected) {
176
+ return wrapMatcher((actual) => {
177
+ try {
178
+ // if both are arrays and of the same length, compare elements
179
+ // if one of them is not, or they are a different length,
180
+ // skip comparing elements as the the equality check later will fail
181
+ if (Array.isArray(expected) && Array.isArray(actual) && expected.length == actual.length) {
182
+ // compare all elements with loose typing
183
+ return expected.every((e) => actual.some((a) => a == e));
184
+ }
185
+ // all other values and arrays of different shape
186
+ return actual == expected;
187
+ }
188
+ catch {
189
+ // some values cannot compared using loose quality, in this case the matcher just fails
190
+ return false;
191
+ }
192
+ }, (actual) => `Expected array matching ${JSON.stringify(expected)}, got: ${JSON.stringify(actual)}`, [expected]);
193
+ }
194
+ /**
195
+ * Compare strings, allows setting cases sensitivity
196
+ */
197
+ static strEq(expected, caseSensitive = false) {
198
+ return wrapMatcher((actual) => {
199
+ // case insensitive
200
+ if (!caseSensitive && typeof actual === 'string') {
201
+ return expected.toLowerCase() == actual.toLowerCase();
202
+ }
203
+ // case sensitive
204
+ return actual == expected;
205
+ }, (actual) => `Expected string ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`, [expected]);
206
+ }
207
+ }
208
+ exports.Match = Match;
209
+ /**
210
+ * Allows any value
211
+ */
212
+ Match.ANY = (_val, _options) => true;
213
+ // eslint-disable-next-line @typescript-eslint/member-ordering
214
+ Match.TRUE = Match.eq(true);
215
+ // eslint-disable-next-line @typescript-eslint/member-ordering
216
+ Match.FALSE = Match.eq(false);
217
+ /**
218
+ * Missing (undefined) value
219
+ */
220
+ // eslint-disable-next-line @typescript-eslint/member-ordering
221
+ Match.MISSING = wrapMatcher((actual) => actual === null || actual === undefined, (actual) => `Expected value to be present, got ${JSON.stringify(actual)}`, [undefined, null]);
222
+ class ValidationError extends Error {
223
+ constructor(violations) {
224
+ // error message is a list of violations
225
+ super('Data is invalid:\n' + violations.map((v) => v.field + ': ' + v.message).join('\n'));
226
+ this.violations = violations;
227
+ // Set the prototype explicitly.
228
+ Object.setPrototypeOf(this, ValidationError.prototype);
229
+ }
230
+ }
231
+ exports.ValidationError = ValidationError;
232
+ class ObjectValidator {
233
+ constructor(ruleSet, dataName = 'data') {
234
+ this.ruleSet = ruleSet;
235
+ this.dataName = dataName;
236
+ }
237
+ /**
238
+ * Validated the provided data against the set of rules.
239
+ *
240
+ * @throws when the data is invalid
241
+ *
242
+ * @param data the data to be validated
243
+ */
244
+ validate(data) {
245
+ // make sure data is an object
246
+ if (!(typeof data === 'object' && !Array.isArray(data) && data !== null)) {
247
+ throw new ValidationError([
248
+ { field: this.dataName, message: 'Provided data must be an object, got: ' + JSON.stringify(data) },
249
+ ]);
250
+ }
251
+ const checkedFields = new Set();
252
+ const violations = [];
253
+ // first check all defined rules
254
+ for (const rule of this.ruleSet.rules) {
255
+ const value = data[rule.field];
256
+ // Use a fallback message, but allow the matcher to report a better arrow
257
+ let violationMessage = 'Value is not allowed, got: ' + JSON.stringify(value);
258
+ const matchResult = rule.matcher(value, {
259
+ reporter: (message) => {
260
+ violationMessage = message;
261
+ },
262
+ });
263
+ switch (rule.type) {
264
+ case RuleType.PASS:
265
+ if (!matchResult) {
266
+ violations.push({
267
+ field: rule.field,
268
+ message: violationMessage,
269
+ });
270
+ }
271
+ break;
272
+ case RuleType.FAIL:
273
+ if (matchResult) {
274
+ violations.push({
275
+ field: rule.field,
276
+ message: violationMessage,
277
+ });
278
+ }
279
+ break;
280
+ default:
281
+ continue;
282
+ }
283
+ checkedFields.add(rule.field);
284
+ }
285
+ // finally check fields without any rules if they should fail the validation
286
+ if (this.ruleSet.options.unexpectedFields === RuleType.FAIL) {
287
+ const receivedFields = Object.keys(data);
288
+ for (const field of receivedFields) {
289
+ if (!checkedFields.has(field)) {
290
+ violations.push({ field: field, message: `Unexpected field, got: ${field}` });
291
+ }
292
+ }
293
+ }
294
+ // if we have encountered a violation, throw an error
295
+ if (violations.length > 0) {
296
+ throw new ValidationError(violations);
297
+ }
298
+ }
299
+ }
300
+ exports.ObjectValidator = ObjectValidator;
301
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/tsconfig/validator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A function that receives 3 arguments and validates if the provided value matches.\n * @param value The value to validate\n * @params options Additional options to influence the matcher behavior.\n * @returns true if the value matches\n */\ntype Matcher = (value: any, options?: MatcherOptions) => boolean;\n\ninterface MatcherOptions {\n /**\n * A function that will be called by the matcher with a a violation message.\n * This function is always called, regardless of the outcome of the matcher.\n * It is up to the caller of the matcher to decide if the message should be used or not.\n *\n * @param message The message describing the possible failure.\n */\n reporter?: (message: string) => void;\n /**\n * A function that might receive explicitly allowed values.\n * This can be used to generate synthetics values that would match the matcher.\n * It is not guaranteed that hints are received or that hints are complete.\n *\n * @param allowed The list values that a matcher offers as definitely allowed.\n */\n hints?: (allowed: any[]) => void;\n}\n\nexport enum RuleType {\n PASS,\n FAIL,\n}\n\nexport interface RuleSetOptions {\n /**\n * Defines the behavior for any encountered fields for which no rules are defined.\n * The default is to pass these fields without validation,\n * but this can also be set to fail any unexpected fields.\n *\n * @default RuleType.PASS\n */\n readonly unexpectedFields: RuleType;\n}\n\ninterface Rule {\n field: string;\n type: RuleType;\n matcher: Matcher;\n}\n\nexport class RuleSet {\n private _rules: Array<Rule> = [];\n public get rules(): Array<Rule> {\n return this._rules;\n }\n\n /**\n * Return all fields for which a rule exists\n */\n public get fields(): Array<string> {\n return [...new Set(this._rules.map((r) => r.field))];\n }\n\n /**\n * Return a list of fields that are allowed, or undefined if all are allowed.\n */\n public get allowedFields(): Array<string> | undefined {\n if (this.options.unexpectedFields === RuleType.FAIL) {\n return this.fields;\n }\n\n return undefined;\n }\n\n /**\n * Find all required fields by evaluating every rule in th set against undefined.\n * If the rule fails, the key must be required.\n *\n * @returns A list of keys that must be included or undefined\n */\n public get requiredFields(): Array<string> {\n const required: string[] = [];\n\n for (const rule of this._rules) {\n const key = rule.field;\n const matcherResult = rule.matcher(undefined);\n\n switch (rule.type) {\n case RuleType.PASS:\n if (!matcherResult) {\n required.push(key);\n }\n break;\n case RuleType.FAIL:\n if (matcherResult) {\n required.push(key);\n }\n break;\n default:\n continue;\n }\n }\n\n return required;\n }\n\n public constructor(\n public readonly options: RuleSetOptions = {\n unexpectedFields: RuleType.PASS,\n },\n ) {}\n\n /**\n * Requires the matcher to pass for the given field.\n * Otherwise a violation is detected.\n *\n * @param field The field the rule applies to\n * @param matcher The matcher function\n */\n public shouldPass(field: string, matcher: Matcher) {\n this._rules.push({ field, matcher, type: RuleType.PASS });\n }\n\n /**\n * Detects a violation if the matcher is matching for a certain field.\n *\n * @param field The field the rule applies to\n * @param matcher The matcher function\n */\n public shouldFail(field: string, matcher: Matcher) {\n this._rules.push({ field, matcher, type: RuleType.FAIL });\n }\n\n /**\n * Imports all rules from an other rule set.\n * Note that any options from the other rule set will be ignored.\n *\n * @param other The other rule set to import rules from.\n */\n public import(other: RuleSet) {\n this._rules.push(...other.rules);\n }\n\n /**\n * Records the field hints for the given rule set.\n * Hints are values that are guaranteed to pass the rule.\n * The list of hints is not guaranteed to be complete nor does it guarantee to return any values.\n * This can be used to create synthetic values for testing for error messages.\n *\n * @returns A record of fields and allowed values\n */\n public getFieldHints(): Record<string, any[]> {\n const fieldHints: Record<string, any[]> = {};\n\n for (const rule of this._rules) {\n // We are only interested in PASS rules here.\n // For FAILs we still don't know which values would pass.\n if (rule.type === RuleType.PASS) {\n // run the matcher to record hints\n rule.matcher(undefined, {\n hints: (receivedHints: any[]) => {\n // if we have recorded hints, add them to the map\n if (receivedHints) {\n fieldHints[rule.field] ??= [];\n fieldHints[rule.field].push(...receivedHints);\n }\n },\n });\n }\n }\n\n return fieldHints;\n }\n}\n\n/**\n * Helper to wrap a matcher with error reporting and hints\n */\nfunction wrapMatcher(matcher: Matcher, message: (actual: any) => string, allowed?: any[]): Matcher {\n return (value, options) => {\n options?.reporter?.(message(value));\n if (allowed) {\n options?.hints?.(allowed);\n }\n return matcher(value);\n };\n}\n\nexport class Match {\n /**\n * Value is optional, but if present should match\n */\n public static optional(matcher: Matcher): Matcher {\n return (value, options) => {\n if (value == null) {\n return true;\n }\n return matcher(value, options);\n };\n }\n\n /**\n * Value must be one of the allowed options\n */\n public static oneOf(...allowed: Array<string | number>): Matcher {\n return wrapMatcher(\n (actual) => allowed.includes(actual),\n (actual) => `Expected value to be one of ${JSON.stringify(allowed)}, got: ${JSON.stringify(actual)}`,\n allowed,\n );\n }\n\n /**\n * Value must be loosely equal to the expected value\n * Arrays are compared by elements\n */\n public static eq(expected: any): Matcher {\n return (actual, options) => {\n if (Array.isArray(expected)) {\n return Match.arrEq(expected)(actual, options);\n }\n\n try {\n options?.hints?.([expected]);\n options?.reporter?.(`Expected value ${JSON.stringify(expected)}, got: ${JSON.stringify(actual)}`);\n return actual == expected;\n } catch {\n // some values cannot compared using loose quality, in this case the matcher just fails\n return false;\n }\n };\n }\n\n /**\n * Value must be loosely equal to the expected value\n * Arrays are compared by elements\n */\n public static arrEq(expected: any[]): Matcher {\n return wrapMatcher(\n (actual) => {\n try {\n // if both are arrays and of the same length, compare elements\n // if one of them is not, or they are a different length,\n // skip comparing elements as the the equality check later will fail\n if (Array.isArray(expected) && Array.isArray(actual) && expected.length == actual.length) {\n // compare all elements with loose typing\n return expected.every((e) => actual.some((a) => a == e));\n }\n\n // all other values and arrays of different shape\n return actual == expected;\n } catch {\n // some values cannot compared using loose quality, in this case the matcher just fails\n return false;\n }\n },\n (actual) => `Expected array matching ${JSON.stringify(expected)}, got: ${JSON.stringify(actual)}`,\n [expected],\n );\n }\n\n /**\n * Compare strings, allows setting cases sensitivity\n */\n public static strEq(expected: string, caseSensitive = false): Matcher {\n return wrapMatcher(\n (actual) => {\n // case insensitive\n if (!caseSensitive && typeof actual === 'string') {\n return expected.toLowerCase() == actual.toLowerCase();\n }\n\n // case sensitive\n return actual == expected;\n },\n (actual: any) => `Expected string ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`,\n [expected],\n );\n }\n\n /**\n * Allows any value\n */\n public static ANY: Matcher = (_val, _options) => true;\n\n // eslint-disable-next-line @typescript-eslint/member-ordering\n public static TRUE: Matcher = Match.eq(true);\n // eslint-disable-next-line @typescript-eslint/member-ordering\n public static FALSE: Matcher = Match.eq(false);\n\n /**\n * Missing (undefined) value\n */\n // eslint-disable-next-line @typescript-eslint/member-ordering\n public static MISSING = wrapMatcher(\n (actual) => actual === null || actual === undefined,\n (actual) => `Expected value to be present, got ${JSON.stringify(actual)}`,\n [undefined, null],\n );\n}\n\nexport interface Violation {\n field: string;\n message: string;\n}\n\nexport class ValidationError extends Error {\n constructor(public readonly violations: Violation[]) {\n // error message is a list of violations\n super('Data is invalid:\\n' + violations.map((v) => v.field + ': ' + v.message).join('\\n'));\n\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, ValidationError.prototype);\n }\n}\n\nexport class ObjectValidator {\n public constructor(public ruleSet: RuleSet, private readonly dataName: string = 'data') {}\n\n /**\n * Validated the provided data against the set of rules.\n *\n * @throws when the data is invalid\n *\n * @param data the data to be validated\n */\n public validate(data: { [field: string]: any }) {\n // make sure data is an object\n if (!(typeof data === 'object' && !Array.isArray(data) && data !== null)) {\n throw new ValidationError([\n { field: this.dataName, message: 'Provided data must be an object, got: ' + JSON.stringify(data) },\n ]);\n }\n\n const checkedFields = new Set();\n const violations: Violation[] = [];\n\n // first check all defined rules\n for (const rule of this.ruleSet.rules) {\n const value = data[rule.field];\n\n // Use a fallback message, but allow the matcher to report a better arrow\n let violationMessage = 'Value is not allowed, got: ' + JSON.stringify(value);\n const matchResult = rule.matcher(value, {\n reporter: (message: string) => {\n violationMessage = message;\n },\n });\n\n switch (rule.type) {\n case RuleType.PASS:\n if (!matchResult) {\n violations.push({\n field: rule.field,\n message: violationMessage,\n });\n }\n break;\n case RuleType.FAIL:\n if (matchResult) {\n violations.push({\n field: rule.field,\n message: violationMessage,\n });\n }\n break;\n default:\n continue;\n }\n\n checkedFields.add(rule.field);\n }\n\n // finally check fields without any rules if they should fail the validation\n if (this.ruleSet.options.unexpectedFields === RuleType.FAIL) {\n const receivedFields = Object.keys(data);\n for (const field of receivedFields) {\n if (!checkedFields.has(field)) {\n violations.push({ field: field, message: `Unexpected field, got: ${field}` });\n }\n }\n }\n\n // if we have encountered a violation, throw an error\n if (violations.length > 0) {\n throw new ValidationError(violations);\n }\n }\n}\n"]}
package/lib/version.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /** The short version number for this JSII compiler (e.g: `X.Y.Z`) */
2
- export declare const SHORT_VERSION = "5.4.16-dev.2";
2
+ export declare const SHORT_VERSION = "5.4.16-dev.3";
3
3
  /** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */
4
- export declare const VERSION = "5.4.16-dev.2 (build c762304)";
4
+ export declare const VERSION = "5.4.16-dev.3 (build 14a51b9)";
5
5
  /** The release line identifier for this JSII compiler (e.g: `X.Y`) */
6
6
  export declare const RELEASE_LINE = "5.4";
7
7
  //# sourceMappingURL=version.d.ts.map
package/lib/version.js CHANGED
@@ -4,9 +4,9 @@ exports.RELEASE_LINE = exports.VERSION = exports.SHORT_VERSION = void 0;
4
4
  const typescript_1 = require("typescript");
5
5
  // GENERATED: This file is generated by build-tools/code-gen.ts -- Do not edit by hand!
6
6
  /** The short version number for this JSII compiler (e.g: `X.Y.Z`) */
7
- exports.SHORT_VERSION = '5.4.16-dev.2';
7
+ exports.SHORT_VERSION = '5.4.16-dev.3';
8
8
  /** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */
9
- exports.VERSION = '5.4.16-dev.2 (build c762304)';
9
+ exports.VERSION = '5.4.16-dev.3 (build 14a51b9)';
10
10
  /** The release line identifier for this JSII compiler (e.g: `X.Y`) */
11
11
  exports.RELEASE_LINE = typescript_1.versionMajorMinor;
12
12
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2CAA8C;AAE9C,uFAAuF;AAEvF,qEAAqE;AACxD,QAAA,aAAa,GAAG,cAAc,CAAC;AAE5C,yFAAyF;AAC5E,QAAA,OAAO,GAAG,8BAA8B,CAAC;AAEtD,sEAAsE;AACzD,QAAA,YAAY,GAAG,8BAAiB,CAAC","sourcesContent":["import { versionMajorMinor } from 'typescript'\n\n// GENERATED: This file is generated by build-tools/code-gen.ts -- Do not edit by hand!\n\n/** The short version number for this JSII compiler (e.g: `X.Y.Z`) */\nexport const SHORT_VERSION = '5.4.16-dev.2';\n\n/** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */\nexport const VERSION = '5.4.16-dev.2 (build c762304)';\n\n/** The release line identifier for this JSII compiler (e.g: `X.Y`) */\nexport const RELEASE_LINE = versionMajorMinor;\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAA,2CAA+C;AAE/C,uFAAuF;AAEvF,qEAAqE;AACxD,QAAA,aAAa,GAAG,cAAc,CAAC;AAE5C,yFAAyF;AAC5E,QAAA,OAAO,GAAG,8BAA8B,CAAC;AAEtD,sEAAsE;AACzD,QAAA,YAAY,GAAG,8BAAiB,CAAC","sourcesContent":["import { versionMajorMinor } from 'typescript';\n\n// GENERATED: This file is generated by build-tools/code-gen.ts -- Do not edit by hand!\n\n/** The short version number for this JSII compiler (e.g: `X.Y.Z`) */\nexport const SHORT_VERSION = '5.4.16-dev.3';\n\n/** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */\nexport const VERSION = '5.4.16-dev.3 (build 14a51b9)';\n\n/** The release line identifier for this JSII compiler (e.g: `X.Y`) */\nexport const RELEASE_LINE = versionMajorMinor;\n"]}
package/package.json CHANGED
@@ -56,6 +56,7 @@
56
56
  "eslint-plugin-import": "^2.29.1",
57
57
  "eslint-plugin-prettier": "^4.2.1",
58
58
  "eslint-plugin-unicorn": "^46.0.1",
59
+ "fast-check": "^3.18.0",
59
60
  "glob": "^10.3.15",
60
61
  "jest": "^29.7.0",
61
62
  "jsii-1.x": "npm:jsii@1",
@@ -89,7 +90,7 @@
89
90
  "main": "lib/index.js",
90
91
  "license": "Apache-2.0",
91
92
  "homepage": "https://aws.github.io/jsii",
92
- "version": "5.4.16-dev.2",
93
+ "version": "5.4.16-dev.3",
93
94
  "types": "lib/index.d.ts",
94
95
  "exports": {
95
96
  ".": "./lib/index.js",