jsii 5.6.2-dev.2 → 5.7.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.

Potentially problematic release.


This version of jsii might be problematic. Click here for more details.

package/README.md CHANGED
@@ -64,7 +64,8 @@ The current status of `jsii` compiler releases is:
64
64
 
65
65
  | Release | Status | EOS | Comment |
66
66
  | ------- | ----------- | ---------- | --------------------------------------------------------------------------------------- |
67
- | `5.6.x` | Current | TBD | ![npm](https://img.shields.io/npm/v/jsii/v5.6-latest?label=jsii%40v5.6-latest&logo=npm) |
67
+ | `5.7.x` | Current | TBD | ![npm](https://img.shields.io/npm/v/jsii/v5.7-latest?label=jsii%40v5.7-latest&logo=npm) |
68
+ | `5.6.x` | Maintenance | 2025-07-01 | ![npm](https://img.shields.io/npm/v/jsii/v5.6-latest?label=jsii%40v5.6-latest&logo=npm) |
68
69
  | `5.5.x` | Maintenance | 2025-05-15 | ![npm](https://img.shields.io/npm/v/jsii/v5.5-latest?label=jsii%40v5.5-latest&logo=npm) |
69
70
  | `5.4.x` | Maintenance | 2025-02-28 | ![npm](https://img.shields.io/npm/v/jsii/v5.4-latest?label=jsii%40v5.4-latest&logo=npm) |
70
71
 
@@ -137,6 +137,12 @@ function wrapMatcher(matcher, message, allowed) {
137
137
  */
138
138
  function looseEqual(a, b) {
139
139
  try {
140
+ // if one of the values is an object (or array), but the other isn't - never consider them the same
141
+ if ([typeof a, typeof b].filter((t) => t === 'object').length === 1) {
142
+ return false;
143
+ }
144
+ // if both values are the same object
145
+ // or if both values are loose equal
140
146
  return Object.is(a, b) || a == b;
141
147
  }
142
148
  catch {
@@ -1 +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\n/**\n * Helper to implement loose equality that is safe for any value\n * Needed because there are some values that are equal as object, but not with ==\n * There are also values that cannot be compared using == and will throw\n */\nfunction looseEqual(a: any, b: any): boolean {\n try {\n return Object.is(a, b) || a == b;\n } catch {\n return false;\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 options?.hints?.([expected]);\n options?.reporter?.(`Expected value ${JSON.stringify(expected)}, got: ${JSON.stringify(actual)}`);\n return looseEqual(actual, expected);\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 // 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) => looseEqual(a, e)));\n }\n\n // all other values and arrays of different shape\n return looseEqual(actual, expected);\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 looseEqual(expected.toLowerCase(), actual.toLowerCase());\n }\n\n // case sensitive\n return looseEqual(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"]}
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\n/**\n * Helper to implement loose equality that is safe for any value\n * Needed because there are some values that are equal as object, but not with ==\n * There are also values that cannot be compared using == and will throw\n */\nfunction looseEqual(a: any, b: any): boolean {\n try {\n // if one of the values is an object (or array), but the other isn't - never consider them the same\n if ([typeof a, typeof b].filter((t) => t === 'object').length === 1) {\n return false;\n }\n // if both values are the same object\n // or if both values are loose equal\n return Object.is(a, b) || a == b;\n } catch {\n return false;\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 options?.hints?.([expected]);\n options?.reporter?.(`Expected value ${JSON.stringify(expected)}, got: ${JSON.stringify(actual)}`);\n return looseEqual(actual, expected);\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 // 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) => looseEqual(a, e)));\n }\n\n // all other values and arrays of different shape\n return looseEqual(actual, expected);\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 looseEqual(expected.toLowerCase(), actual.toLowerCase());\n }\n\n // case sensitive\n return looseEqual(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.6.2-dev.2";
2
+ export declare const SHORT_VERSION = "5.7.0";
3
3
  /** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */
4
- export declare const VERSION = "5.6.2-dev.2 (build d68797d)";
4
+ export declare const VERSION = "5.7.0 (build 58cb06a)";
5
5
  /** The release line identifier for this JSII compiler (e.g: `X.Y`) */
6
- export declare const RELEASE_LINE = "5.6";
6
+ export declare const RELEASE_LINE = "5.7";
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.6.2-dev.2';
7
+ exports.SHORT_VERSION = '5.7.0';
8
8
  /** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */
9
- exports.VERSION = '5.6.2-dev.2 (build d68797d)';
9
+ exports.VERSION = '5.7.0 (build 58cb06a)';
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,2CAA+C;AAE/C,uFAAuF;AAEvF,qEAAqE;AACxD,QAAA,aAAa,GAAG,aAAa,CAAC;AAE3C,yFAAyF;AAC5E,QAAA,OAAO,GAAG,6BAA6B,CAAC;AAErD,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.6.2-dev.2';\n\n/** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */\nexport const VERSION = '5.6.2-dev.2 (build d68797d)';\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,OAAO,CAAC;AAErC,yFAAyF;AAC5E,QAAA,OAAO,GAAG,uBAAuB,CAAC;AAE/C,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.7.0';\n\n/** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */\nexport const VERSION = '5.7.0 (build 58cb06a)';\n\n/** The release line identifier for this JSII compiler (e.g: `X.Y`) */\nexport const RELEASE_LINE = versionMajorMinor;\n"]}
package/package.json CHANGED
@@ -80,7 +80,7 @@
80
80
  "semver-intersect": "^1.5.0",
81
81
  "sort-json": "^2.0.1",
82
82
  "spdx-license-list": "^6.9.0",
83
- "typescript": "~5.6",
83
+ "typescript": "~5.7",
84
84
  "yargs": "^17.7.2"
85
85
  },
86
86
  "engines": {
@@ -92,7 +92,7 @@
92
92
  "publishConfig": {
93
93
  "access": "public"
94
94
  },
95
- "version": "5.6.2-dev.2",
95
+ "version": "5.7.0",
96
96
  "types": "lib/index.d.ts",
97
97
  "exports": {
98
98
  ".": "./lib/index.js",
package/releases.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
- "current": "5.6",
2
+ "current": "5.7",
3
3
  "maintenance": {
4
4
  "5.0": "2024-01-31T00:00:00.000Z",
5
5
  "5.1": "2024-02-28T00:00:00.000Z",
6
6
  "5.2": "2024-06-30T00:00:00.000Z",
7
7
  "5.3": "2024-10-15T00:00:00.000Z",
8
8
  "5.4": "2025-02-28T00:00:00.000Z",
9
- "5.5": "2025-05-15T00:00:00.000Z"
9
+ "5.5": "2025-05-15T00:00:00.000Z",
10
+ "5.6": "2025-07-01T00:00:00.000Z"
10
11
  },
11
12
  "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"."
12
13
  }