jsii 6.0.0-dev.0 → 6.0.1

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/README.md CHANGED
@@ -111,6 +111,48 @@ Here's a collection of blog posts (in chronological order) related to `jsii`:
111
111
  > :information_source: If you wrote blog posts about `jsii` and would like to have them referenced here, do not hesitate
112
112
  > to file a pull request to add the links here!
113
113
 
114
+ ## :triangular_ruler: Inspecting & Validating tsconfig
115
+
116
+ When you provide your own `tsconfig.json` (via `--tsconfig`), `jsii` validates its `compilerOptions` against a
117
+ [rule set](#arrow_up-upgrading-to-jsii-60) (`strict` by default). Two commands let you inspect those rule sets and
118
+ validate a configuration file directly, without running a full compilation.
119
+
120
+ ### `jsii rules`
121
+
122
+ Prints the validation rules for a rule set, so you can see exactly what each setting enforces:
123
+
124
+ ```sh
125
+ # Print the rules for the strict rule set
126
+ jsii rules strict
127
+
128
+ # Print the rules for all rule sets (strict, generated, minimal, off)
129
+ jsii rules
130
+ ```
131
+
132
+ The output lists, per `compilerOptions` field, whether it must be present and what values are allowed (or disallowed),
133
+ and whether unknown options are rejected for that rule set.
134
+
135
+ ### `jsii validate-tsconfig`
136
+
137
+ Validates an existing TypeScript configuration file against a rule set and reports any violations. It exits with a
138
+ non-zero status when validation fails, which makes it suitable for use in CI or pre-commit checks:
139
+
140
+ ```sh
141
+ # Validate ./tsconfig.json against the strict rule set (the default)
142
+ jsii validate-tsconfig
143
+
144
+ # Validate a specific file
145
+ jsii validate-tsconfig tsconfig.dev.json
146
+
147
+ # Validate against a different rule set (--rule-set, alias -R)
148
+ jsii validate-tsconfig tsconfig.json --rule-set generated
149
+ jsii validate-tsconfig tsconfig.json -R minimal
150
+ ```
151
+
152
+ The available rule sets are `strict`, `generated`, `minimal`, and `off`. They behave exactly as the `--validate-tsconfig`
153
+ option does during compilation; see [Upgrading to jsii 6.0](#arrow_up-upgrading-to-jsii-60) for guidance on the rules
154
+ each set enforces.
155
+
114
156
  ## :mute: Silencing Warnings
115
157
 
116
158
  The `--silence-warnings` option allows you to suppress specific warnings from the compiler output. Silenced warnings
package/lib/main.js CHANGED
@@ -32,10 +32,14 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
39
  require("@jsii/check-node/run");
37
40
  const path = __importStar(require("node:path"));
38
41
  const util = __importStar(require("node:util"));
42
+ const chalk_1 = __importDefault(require("chalk"));
39
43
  const log4js = __importStar(require("log4js"));
40
44
  const package_json_1 = require("typescript/package.json");
41
45
  const yargs = __importStar(require("yargs"));
@@ -44,6 +48,8 @@ const jsii_diagnostic_1 = require("./jsii-diagnostic");
44
48
  const project_info_1 = require("./project-info");
45
49
  const support_1 = require("./support");
46
50
  const tsconfig_1 = require("./tsconfig");
51
+ const rule_set_format_1 = require("./tsconfig/rule-set-format");
52
+ const tsconfig_validator_1 = require("./tsconfig/tsconfig-validator");
47
53
  const utils = __importStar(require("./utils"));
48
54
  const version_1 = require("./version");
49
55
  const warnings_1 = require("./warnings");
@@ -58,12 +64,6 @@ var OPTION_GROUP;
58
64
  OPTION_GROUP["JSII"] = "jsii compiler options:";
59
65
  OPTION_GROUP["TS"] = "TypeScript config options:";
60
66
  })(OPTION_GROUP || (OPTION_GROUP = {}));
61
- const ruleSets = {
62
- [tsconfig_1.TypeScriptConfigValidationRuleSet.STRICT]: 'Validates the provided config against a strict rule set designed for maximum backwards-compatibility.',
63
- [tsconfig_1.TypeScriptConfigValidationRuleSet.GENERATED]: 'Enforces a config as created by --generate-tsconfig. Use this to stay compatible with the generated config, but have full ownership over the file.',
64
- [tsconfig_1.TypeScriptConfigValidationRuleSet.MINIMAL]: 'Only enforce options that are known to be incompatible with jsii. This rule set is likely to be incomplete and new rules will be added without notice as incompatibilities emerge.',
65
- [tsconfig_1.TypeScriptConfigValidationRuleSet.NONE]: 'Disables all config validation, including options that are known to be incompatible with jsii. Intended for experimentation only. Use at your own risk.',
66
- };
67
67
  (async () => {
68
68
  await (0, support_1.emitSupportPolicyInformation)();
69
69
  await yargs
@@ -131,7 +131,7 @@ const ruleSets = {
131
131
  .conflicts('tsconfig', ['generate-tsconfig', 'project-references'])
132
132
  .option('validate-tsconfig', {
133
133
  group: OPTION_GROUP.TS,
134
- ...choiceWithDesc(ruleSets, 'Validate the provided typescript configuration file against a set of rules.'),
134
+ ...choiceWithDesc(rule_set_format_1.RULE_SET_DESCRIPTIONS, 'Validate the provided typescript configuration file against a set of rules.'),
135
135
  defaultDescription: tsconfig_1.TypeScriptConfigValidationRuleSet.STRICT,
136
136
  })
137
137
  .option('compress-assembly', {
@@ -202,6 +202,60 @@ const ruleSets = {
202
202
  throw e;
203
203
  }
204
204
  }
205
+ })
206
+ .command('validate-tsconfig [TSCONFIG]', 'Validate a TypeScript configuration file against a jsii rule set, without compiling', (cmd) => cmd
207
+ .positional('TSCONFIG', {
208
+ type: 'string',
209
+ desc: 'The TypeScript configuration file to validate',
210
+ default: 'tsconfig.json',
211
+ normalize: true,
212
+ })
213
+ .option('rule-set', {
214
+ group: OPTION_GROUP.TS,
215
+ alias: 'R',
216
+ ...choiceWithDesc(rule_set_format_1.RULE_SET_DESCRIPTIONS, 'The rule set to validate the configuration file against.'),
217
+ default: tsconfig_1.TypeScriptConfigValidationRuleSet.STRICT,
218
+ }), (argv) => {
219
+ try {
220
+ const verbosity = typeof argv.verbose === 'number' ? argv.verbose : 0;
221
+ _configureLog4js(verbosity);
222
+ const configPath = path.resolve(process.cwd(), argv.TSCONFIG);
223
+ const projectRoot = path.dirname(configPath);
224
+ const configName = path.relative(projectRoot, configPath);
225
+ const ruleSet = argv['rule-set'];
226
+ // Validation is disabled for the "off" rule set; mirror the compiler behavior.
227
+ if (ruleSet === tsconfig_1.TypeScriptConfigValidationRuleSet.NONE) {
228
+ utils.logDiagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_4009_DISABLED_TSCONFIG_VALIDATION.create(undefined, configName), projectRoot);
229
+ return;
230
+ }
231
+ const violations = (0, tsconfig_validator_1.validateTypeScriptConfigFile)(configPath, ruleSet);
232
+ if (violations.length > 0) {
233
+ utils.logDiagnostic(jsii_diagnostic_1.JsiiDiagnostic.JSII_4000_FAILED_TSCONFIG_VALIDATION.create(undefined, configName, ruleSet, violations), projectRoot);
234
+ process.exitCode = 1;
235
+ }
236
+ else {
237
+ console.log(`✨ "${configName}" is valid against rule set "${ruleSet}"`);
238
+ }
239
+ }
240
+ catch (e) {
241
+ if (e instanceof utils.JsiiError) {
242
+ const LOG = log4js.getLogger(utils.CLI_LOGGER);
243
+ LOG.error(e.message);
244
+ process.exitCode = -1;
245
+ }
246
+ else {
247
+ throw e;
248
+ }
249
+ }
250
+ })
251
+ .command('rules [RULE_SET]', 'Print the tsconfig validation rules for a rule set (or for all rule sets)', (cmd) => cmd.positional('RULE_SET', {
252
+ ...choiceWithDesc(rule_set_format_1.RULE_SET_DESCRIPTIONS, 'The rule set to print. If omitted, all rule sets are printed.'),
253
+ }), (argv) => {
254
+ const selected = argv.RULE_SET;
255
+ const sets = selected != null
256
+ ? [selected]
257
+ : Object.values(tsconfig_1.TypeScriptConfigValidationRuleSet);
258
+ console.log(`${sets.map(rule_set_format_1.formatRuleSet).join(`\n\n${chalk_1.default.dim('─'.repeat(72))}\n\n`)}\n`);
205
259
  })
206
260
  .help()
207
261
  .version(`${version_1.VERSION}, typescript ${package_json_1.version}`)
package/lib/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["import '@jsii/check-node/run';\n\nimport * as path from 'node:path';\nimport * as util from 'node:util';\nimport * as log4js from 'log4js';\nimport { version as tsVersion } from 'typescript/package.json';\nimport * as yargs from 'yargs';\n\nimport { Compiler } from './compiler';\nimport { configureCategories } from './jsii-diagnostic';\nimport { loadProjectInfo } from './project-info';\nimport { emitSupportPolicyInformation } from './support';\nimport { TypeScriptConfigValidationRuleSet } from './tsconfig';\nimport * as utils from './utils';\nimport { VERSION } from './version';\nimport { parseWarningCodes, silencedWarnings } from './warnings';\n\nfunction choiceWithDesc(\n choices: { [choice: string]: string },\n desc: string,\n): {\n choices: string[];\n desc: string;\n} {\n return {\n choices: Object.keys(choices),\n desc: [desc, ...Object.entries(choices).map(([choice, docs]) => `${choice}: ${docs}`)].join('\\n'),\n };\n}\n\nenum OPTION_GROUP {\n JSII = 'jsii compiler options:',\n TS = 'TypeScript config options:',\n}\n\nconst ruleSets: {\n [choice in TypeScriptConfigValidationRuleSet]: string;\n} = {\n [TypeScriptConfigValidationRuleSet.STRICT]:\n 'Validates the provided config against a strict rule set designed for maximum backwards-compatibility.',\n [TypeScriptConfigValidationRuleSet.GENERATED]:\n 'Enforces a config as created by --generate-tsconfig. Use this to stay compatible with the generated config, but have full ownership over the file.',\n [TypeScriptConfigValidationRuleSet.MINIMAL]:\n 'Only enforce options that are known to be incompatible with jsii. This rule set is likely to be incomplete and new rules will be added without notice as incompatibilities emerge.',\n [TypeScriptConfigValidationRuleSet.NONE]:\n 'Disables all config validation, including options that are known to be incompatible with jsii. Intended for experimentation only. Use at your own risk.',\n};\n\n(async () => {\n await emitSupportPolicyInformation();\n\n await yargs\n .env('JSII')\n .command(\n ['$0 [PROJECT_ROOT]', 'compile [PROJECT_ROOT]'],\n 'Compiles a jsii/TypeScript project',\n (argv) =>\n argv\n .positional('PROJECT_ROOT', {\n type: 'string',\n desc: 'The root of the project to be compiled',\n default: '.',\n normalize: true,\n })\n .option('watch', {\n alias: 'w',\n type: 'boolean',\n desc: 'Watch for file changes and recompile automatically',\n })\n .option('project-references', {\n group: OPTION_GROUP.JSII,\n alias: 'r',\n type: 'boolean',\n desc: 'Generate TypeScript project references (also [package.json].jsii.projectReferences)\\nHas no effect if --tsconfig is provided',\n })\n .option('fix-peer-dependencies', {\n type: 'boolean',\n default: true,\n desc: 'This option no longer has any effect.',\n hidden: true,\n })\n .options('fail-on-warnings', {\n group: OPTION_GROUP.JSII,\n alias: 'Werr',\n type: 'boolean',\n desc: 'Treat warnings as errors',\n })\n .option('silence-warnings', {\n group: OPTION_GROUP.JSII,\n alias: 'Wno',\n type: 'array',\n default: [],\n desc: 'List of warnings to silence. Accepts JSII codes (e.g. JSII5018), numbers (e.g. 5018), or diagnostic names (e.g. reserved-word, language-compatibility)',\n })\n .option('strip-deprecated', {\n group: OPTION_GROUP.JSII,\n type: 'string',\n desc: '[EXPERIMENTAL] Hides all @deprecated members from the API (implementations remain). If an optional file name is given, only FQNs present in the file will be stripped.',\n })\n .option('add-deprecation-warnings', {\n group: OPTION_GROUP.JSII,\n type: 'boolean',\n default: false,\n desc: '[EXPERIMENTAL] Injects warning statements for all deprecated elements, to be printed at runtime',\n })\n .option('generate-tsconfig', {\n group: OPTION_GROUP.TS,\n type: 'string',\n defaultDescription: 'tsconfig.json',\n desc: 'Name of the typescript configuration file to generate with compiler settings',\n })\n .option('tsconfig', {\n group: OPTION_GROUP.TS,\n alias: 'c',\n type: 'string',\n desc: 'Use this typescript configuration file to compile the jsii project.',\n })\n .conflicts('tsconfig', ['generate-tsconfig', 'project-references'])\n .option('validate-tsconfig', {\n group: OPTION_GROUP.TS,\n ...choiceWithDesc(ruleSets, 'Validate the provided typescript configuration file against a set of rules.'),\n defaultDescription: TypeScriptConfigValidationRuleSet.STRICT,\n })\n .option('compress-assembly', {\n group: OPTION_GROUP.JSII,\n type: 'boolean',\n default: false,\n desc: 'Emit a compressed version of the assembly',\n })\n .option('verbose', {\n alias: 'v',\n type: 'count',\n desc: 'Increase the verbosity of output',\n global: true,\n }),\n async (argv) => {\n try {\n _configureLog4js(argv.verbose);\n\n if (argv['generate-tsconfig'] != null && argv.tsconfig != null) {\n throw new utils.JsiiError('Options --generate-tsconfig and --tsconfig are mutually exclusive', true);\n }\n\n const projectRoot = path.normalize(path.resolve(process.cwd(), argv.PROJECT_ROOT));\n\n const { projectInfo, diagnostics: projectInfoDiagnostics } = loadProjectInfo(projectRoot);\n\n // disable all silenced warnings\n for (const key of argv['silence-warnings']) {\n for (const code of parseWarningCodes(String(key))) {\n silencedWarnings.add(code);\n }\n }\n\n configureCategories(projectInfo.diagnostics ?? {});\n\n const typeScriptConfig = argv.tsconfig ?? projectInfo.packageJson.jsii?.tsconfig;\n const validateTypeScriptConfig =\n (argv['validate-tsconfig'] as TypeScriptConfigValidationRuleSet) ??\n projectInfo.packageJson.jsii?.validateTsconfig ??\n TypeScriptConfigValidationRuleSet.STRICT;\n\n const compiler = new Compiler({\n projectInfo,\n projectReferences: argv['project-references'],\n failOnWarnings: argv['fail-on-warnings'],\n stripDeprecated: argv['strip-deprecated'] != null,\n stripDeprecatedAllowListFile: argv['strip-deprecated'],\n addDeprecationWarnings: argv['add-deprecation-warnings'],\n generateTypeScriptConfig: argv['generate-tsconfig'],\n typeScriptConfig,\n validateTypeScriptConfig,\n compressAssembly: argv['compress-assembly'],\n });\n\n const startTime = Date.now();\n const emitResult = argv.watch ? await compiler.watch() : compiler.emit();\n\n const allDiagnostics = [...projectInfoDiagnostics, ...emitResult.diagnostics];\n\n for (const diagnostic of allDiagnostics) {\n utils.logDiagnostic(diagnostic, projectRoot);\n }\n\n console.log(utils.formatCompilationSummary(allDiagnostics, emitResult.emitSkipped, Date.now() - startTime));\n\n if (emitResult.emitSkipped) {\n process.exitCode = 1;\n }\n } catch (e: unknown) {\n if (e instanceof utils.JsiiError) {\n if (e.showHelp) {\n console.log();\n yargs.showHelp();\n console.log();\n }\n\n const LOG = log4js.getLogger(utils.CLI_LOGGER);\n LOG.error(e.message);\n\n process.exitCode = -1;\n } else {\n throw e;\n }\n }\n },\n )\n .help()\n .version(`${VERSION}, typescript ${tsVersion}`)\n .parse();\n})().catch((e) => {\n console.error(`Error: ${e.stack}`);\n process.exitCode = -1;\n});\n\nfunction _configureLog4js(verbosity: number) {\n const stderrColor = !!process.stderr.isTTY;\n const stdoutColor = !!process.stdout.isTTY;\n\n log4js.addLayout('passThroughNoColor', () => {\n return (loggingEvent) => utils.stripAnsi(util.format(...loggingEvent.data));\n });\n\n log4js.configure({\n appenders: {\n console: {\n type: 'stderr',\n layout: { type: stderrColor ? 'colored' : 'basic' },\n },\n\n [utils.DIAGNOSTICS]: {\n type: 'stdout',\n layout: {\n type: stdoutColor ? 'messagePassThrough' : ('passThroughNoColor' as any),\n },\n },\n [utils.CLI_LOGGER]: {\n type: 'stderr',\n layout: {\n type: 'pattern',\n pattern: stdoutColor ? '%[[%p]%] %m' : '[%p] %m',\n },\n },\n },\n categories: {\n default: { appenders: ['console'], level: _logLevel() },\n [utils.CLI_LOGGER]: {\n appenders: [utils.CLI_LOGGER],\n level: _logLevel(),\n },\n // The diagnostics logger must be set to INFO or more verbose, or watch won't show important messages\n [utils.DIAGNOSTICS]: {\n appenders: [utils.DIAGNOSTICS],\n level: _logLevel(Math.max(verbosity, 1)),\n },\n },\n });\n\n function _logLevel(verbosityLevel = verbosity): keyof log4js.Levels {\n switch (verbosityLevel) {\n case 0:\n return 'WARN';\n case 1:\n return 'INFO';\n case 2:\n return 'DEBUG';\n case 3:\n return 'TRACE';\n default:\n return 'ALL';\n }\n }\n}\n"]}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["import '@jsii/check-node/run';\n\nimport * as path from 'node:path';\nimport * as util from 'node:util';\nimport chalk from 'chalk';\nimport * as log4js from 'log4js';\nimport { version as tsVersion } from 'typescript/package.json';\nimport * as yargs from 'yargs';\n\nimport { Compiler } from './compiler';\nimport { configureCategories, JsiiDiagnostic } from './jsii-diagnostic';\nimport { loadProjectInfo } from './project-info';\nimport { emitSupportPolicyInformation } from './support';\nimport { TypeScriptConfigValidationRuleSet } from './tsconfig';\nimport { formatRuleSet, RULE_SET_DESCRIPTIONS } from './tsconfig/rule-set-format';\nimport { validateTypeScriptConfigFile } from './tsconfig/tsconfig-validator';\nimport * as utils from './utils';\nimport { VERSION } from './version';\nimport { parseWarningCodes, silencedWarnings } from './warnings';\n\nfunction choiceWithDesc(\n choices: { [choice: string]: string },\n desc: string,\n): {\n choices: string[];\n desc: string;\n} {\n return {\n choices: Object.keys(choices),\n desc: [desc, ...Object.entries(choices).map(([choice, docs]) => `${choice}: ${docs}`)].join('\\n'),\n };\n}\n\nenum OPTION_GROUP {\n JSII = 'jsii compiler options:',\n TS = 'TypeScript config options:',\n}\n\n(async () => {\n await emitSupportPolicyInformation();\n\n await yargs\n .env('JSII')\n .command(\n ['$0 [PROJECT_ROOT]', 'compile [PROJECT_ROOT]'],\n 'Compiles a jsii/TypeScript project',\n (argv) =>\n argv\n .positional('PROJECT_ROOT', {\n type: 'string',\n desc: 'The root of the project to be compiled',\n default: '.',\n normalize: true,\n })\n .option('watch', {\n alias: 'w',\n type: 'boolean',\n desc: 'Watch for file changes and recompile automatically',\n })\n .option('project-references', {\n group: OPTION_GROUP.JSII,\n alias: 'r',\n type: 'boolean',\n desc: 'Generate TypeScript project references (also [package.json].jsii.projectReferences)\\nHas no effect if --tsconfig is provided',\n })\n .option('fix-peer-dependencies', {\n type: 'boolean',\n default: true,\n desc: 'This option no longer has any effect.',\n hidden: true,\n })\n .options('fail-on-warnings', {\n group: OPTION_GROUP.JSII,\n alias: 'Werr',\n type: 'boolean',\n desc: 'Treat warnings as errors',\n })\n .option('silence-warnings', {\n group: OPTION_GROUP.JSII,\n alias: 'Wno',\n type: 'array',\n default: [],\n desc: 'List of warnings to silence. Accepts JSII codes (e.g. JSII5018), numbers (e.g. 5018), or diagnostic names (e.g. reserved-word, language-compatibility)',\n })\n .option('strip-deprecated', {\n group: OPTION_GROUP.JSII,\n type: 'string',\n desc: '[EXPERIMENTAL] Hides all @deprecated members from the API (implementations remain). If an optional file name is given, only FQNs present in the file will be stripped.',\n })\n .option('add-deprecation-warnings', {\n group: OPTION_GROUP.JSII,\n type: 'boolean',\n default: false,\n desc: '[EXPERIMENTAL] Injects warning statements for all deprecated elements, to be printed at runtime',\n })\n .option('generate-tsconfig', {\n group: OPTION_GROUP.TS,\n type: 'string',\n defaultDescription: 'tsconfig.json',\n desc: 'Name of the typescript configuration file to generate with compiler settings',\n })\n .option('tsconfig', {\n group: OPTION_GROUP.TS,\n alias: 'c',\n type: 'string',\n desc: 'Use this typescript configuration file to compile the jsii project.',\n })\n .conflicts('tsconfig', ['generate-tsconfig', 'project-references'])\n .option('validate-tsconfig', {\n group: OPTION_GROUP.TS,\n ...choiceWithDesc(\n RULE_SET_DESCRIPTIONS,\n 'Validate the provided typescript configuration file against a set of rules.',\n ),\n defaultDescription: TypeScriptConfigValidationRuleSet.STRICT,\n })\n .option('compress-assembly', {\n group: OPTION_GROUP.JSII,\n type: 'boolean',\n default: false,\n desc: 'Emit a compressed version of the assembly',\n })\n .option('verbose', {\n alias: 'v',\n type: 'count',\n desc: 'Increase the verbosity of output',\n global: true,\n }),\n async (argv) => {\n try {\n _configureLog4js(argv.verbose);\n\n if (argv['generate-tsconfig'] != null && argv.tsconfig != null) {\n throw new utils.JsiiError('Options --generate-tsconfig and --tsconfig are mutually exclusive', true);\n }\n\n const projectRoot = path.normalize(path.resolve(process.cwd(), argv.PROJECT_ROOT));\n\n const { projectInfo, diagnostics: projectInfoDiagnostics } = loadProjectInfo(projectRoot);\n\n // disable all silenced warnings\n for (const key of argv['silence-warnings']) {\n for (const code of parseWarningCodes(String(key))) {\n silencedWarnings.add(code);\n }\n }\n\n configureCategories(projectInfo.diagnostics ?? {});\n\n const typeScriptConfig = argv.tsconfig ?? projectInfo.packageJson.jsii?.tsconfig;\n const validateTypeScriptConfig =\n (argv['validate-tsconfig'] as TypeScriptConfigValidationRuleSet) ??\n projectInfo.packageJson.jsii?.validateTsconfig ??\n TypeScriptConfigValidationRuleSet.STRICT;\n\n const compiler = new Compiler({\n projectInfo,\n projectReferences: argv['project-references'],\n failOnWarnings: argv['fail-on-warnings'],\n stripDeprecated: argv['strip-deprecated'] != null,\n stripDeprecatedAllowListFile: argv['strip-deprecated'],\n addDeprecationWarnings: argv['add-deprecation-warnings'],\n generateTypeScriptConfig: argv['generate-tsconfig'],\n typeScriptConfig,\n validateTypeScriptConfig,\n compressAssembly: argv['compress-assembly'],\n });\n\n const startTime = Date.now();\n const emitResult = argv.watch ? await compiler.watch() : compiler.emit();\n\n const allDiagnostics = [...projectInfoDiagnostics, ...emitResult.diagnostics];\n\n for (const diagnostic of allDiagnostics) {\n utils.logDiagnostic(diagnostic, projectRoot);\n }\n\n console.log(utils.formatCompilationSummary(allDiagnostics, emitResult.emitSkipped, Date.now() - startTime));\n\n if (emitResult.emitSkipped) {\n process.exitCode = 1;\n }\n } catch (e: unknown) {\n if (e instanceof utils.JsiiError) {\n if (e.showHelp) {\n console.log();\n yargs.showHelp();\n console.log();\n }\n\n const LOG = log4js.getLogger(utils.CLI_LOGGER);\n LOG.error(e.message);\n\n process.exitCode = -1;\n } else {\n throw e;\n }\n }\n },\n )\n .command(\n 'validate-tsconfig [TSCONFIG]',\n 'Validate a TypeScript configuration file against a jsii rule set, without compiling',\n (cmd) =>\n cmd\n .positional('TSCONFIG', {\n type: 'string',\n desc: 'The TypeScript configuration file to validate',\n default: 'tsconfig.json',\n normalize: true,\n })\n .option('rule-set', {\n group: OPTION_GROUP.TS,\n alias: 'R',\n ...choiceWithDesc(RULE_SET_DESCRIPTIONS, 'The rule set to validate the configuration file against.'),\n default: TypeScriptConfigValidationRuleSet.STRICT,\n }),\n (argv) => {\n try {\n const verbosity = typeof argv.verbose === 'number' ? argv.verbose : 0;\n _configureLog4js(verbosity);\n\n const configPath = path.resolve(process.cwd(), argv.TSCONFIG);\n const projectRoot = path.dirname(configPath);\n const configName = path.relative(projectRoot, configPath);\n const ruleSet = argv['rule-set'] as TypeScriptConfigValidationRuleSet;\n\n // Validation is disabled for the \"off\" rule set; mirror the compiler behavior.\n if (ruleSet === TypeScriptConfigValidationRuleSet.NONE) {\n utils.logDiagnostic(\n JsiiDiagnostic.JSII_4009_DISABLED_TSCONFIG_VALIDATION.create(undefined, configName),\n projectRoot,\n );\n return;\n }\n\n const violations = validateTypeScriptConfigFile(configPath, ruleSet);\n if (violations.length > 0) {\n utils.logDiagnostic(\n JsiiDiagnostic.JSII_4000_FAILED_TSCONFIG_VALIDATION.create(undefined, configName, ruleSet, violations),\n projectRoot,\n );\n process.exitCode = 1;\n } else {\n console.log(`✨ \"${configName}\" is valid against rule set \"${ruleSet}\"`);\n }\n } catch (e: unknown) {\n if (e instanceof utils.JsiiError) {\n const LOG = log4js.getLogger(utils.CLI_LOGGER);\n LOG.error(e.message);\n process.exitCode = -1;\n } else {\n throw e;\n }\n }\n },\n )\n .command(\n 'rules [RULE_SET]',\n 'Print the tsconfig validation rules for a rule set (or for all rule sets)',\n (cmd) =>\n cmd.positional('RULE_SET', {\n ...choiceWithDesc(RULE_SET_DESCRIPTIONS, 'The rule set to print. If omitted, all rule sets are printed.'),\n }),\n (argv) => {\n const selected = argv.RULE_SET as TypeScriptConfigValidationRuleSet | undefined;\n const sets =\n selected != null\n ? [selected]\n : (Object.values(TypeScriptConfigValidationRuleSet) as TypeScriptConfigValidationRuleSet[]);\n\n console.log(`${sets.map(formatRuleSet).join(`\\n\\n${chalk.dim('─'.repeat(72))}\\n\\n`)}\\n`);\n },\n )\n .help()\n .version(`${VERSION}, typescript ${tsVersion}`)\n .parse();\n})().catch((e) => {\n console.error(`Error: ${e.stack}`);\n process.exitCode = -1;\n});\n\nfunction _configureLog4js(verbosity: number) {\n const stderrColor = !!process.stderr.isTTY;\n const stdoutColor = !!process.stdout.isTTY;\n\n log4js.addLayout('passThroughNoColor', () => {\n return (loggingEvent) => utils.stripAnsi(util.format(...loggingEvent.data));\n });\n\n log4js.configure({\n appenders: {\n console: {\n type: 'stderr',\n layout: { type: stderrColor ? 'colored' : 'basic' },\n },\n\n [utils.DIAGNOSTICS]: {\n type: 'stdout',\n layout: {\n type: stdoutColor ? 'messagePassThrough' : ('passThroughNoColor' as any),\n },\n },\n [utils.CLI_LOGGER]: {\n type: 'stderr',\n layout: {\n type: 'pattern',\n pattern: stdoutColor ? '%[[%p]%] %m' : '[%p] %m',\n },\n },\n },\n categories: {\n default: { appenders: ['console'], level: _logLevel() },\n [utils.CLI_LOGGER]: {\n appenders: [utils.CLI_LOGGER],\n level: _logLevel(),\n },\n // The diagnostics logger must be set to INFO or more verbose, or watch won't show important messages\n [utils.DIAGNOSTICS]: {\n appenders: [utils.DIAGNOSTICS],\n level: _logLevel(Math.max(verbosity, 1)),\n },\n },\n });\n\n function _logLevel(verbosityLevel = verbosity): keyof log4js.Levels {\n switch (verbosityLevel) {\n case 0:\n return 'WARN';\n case 1:\n return 'INFO';\n case 2:\n return 'DEBUG';\n case 3:\n return 'TRACE';\n default:\n return 'ALL';\n }\n }\n}\n"]}
@@ -0,0 +1,34 @@
1
+ import { TypeScriptConfigValidationRuleSet } from '.';
2
+ import { RuleDescription } from './validator';
3
+ /**
4
+ * Human-readable descriptions for each tsconfig validation rule set.
5
+ *
6
+ * These are surfaced both as CLI option help (e.g. for `--validate-tsconfig` and
7
+ * `--rule-set`) and as the heading when printing a rule set via `formatRuleSet`.
8
+ */
9
+ export declare const RULE_SET_DESCRIPTIONS: {
10
+ [choice in TypeScriptConfigValidationRuleSet]: string;
11
+ };
12
+ /**
13
+ * Render a single rule set (its `compilerOptions` rules) as a human-readable block.
14
+ *
15
+ * @param ruleSet the rule set to render
16
+ * @returns a multi-line string suitable for printing to the console
17
+ */
18
+ export declare function formatRuleSet(ruleSet: TypeScriptConfigValidationRuleSet): string;
19
+ /**
20
+ * Render a single rule's constraint as a human-readable phrase.
21
+ *
22
+ * @param rule the rule description to render
23
+ * @returns a phrase such as `must be one of: es2022, es2023` or `not allowed`
24
+ */
25
+ export declare function formatConstraint(rule: RuleDescription): string;
26
+ /**
27
+ * Render a single hinted value as a highlighted code literal. Strings are shown
28
+ * verbatim (as a user writes them in tsconfig.json), everything else is JSON-encoded.
29
+ *
30
+ * @param value the hinted value to render
31
+ * @returns the value as a (possibly colorized) code literal
32
+ */
33
+ export declare function formatRuleValue(value: any): string;
34
+ //# sourceMappingURL=rule-set-format.d.ts.map
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RULE_SET_DESCRIPTIONS = void 0;
7
+ exports.formatRuleSet = formatRuleSet;
8
+ exports.formatConstraint = formatConstraint;
9
+ exports.formatRuleValue = formatRuleValue;
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const _1 = require(".");
12
+ const tsconfig_validator_1 = require("./tsconfig-validator");
13
+ const validator_1 = require("./validator");
14
+ /**
15
+ * Human-readable descriptions for each tsconfig validation rule set.
16
+ *
17
+ * These are surfaced both as CLI option help (e.g. for `--validate-tsconfig` and
18
+ * `--rule-set`) and as the heading when printing a rule set via `formatRuleSet`.
19
+ */
20
+ exports.RULE_SET_DESCRIPTIONS = {
21
+ [_1.TypeScriptConfigValidationRuleSet.STRICT]: 'Validates the provided config against a strict rule set designed for maximum backwards-compatibility.',
22
+ [_1.TypeScriptConfigValidationRuleSet.GENERATED]: 'Enforces a config as created by --generate-tsconfig. Use this to stay compatible with the generated config, but have full ownership over the file.',
23
+ [_1.TypeScriptConfigValidationRuleSet.MINIMAL]: 'Only enforce options that are known to be incompatible with jsii. This rule set is likely to be incomplete and new rules will be added without notice as incompatibilities emerge.',
24
+ [_1.TypeScriptConfigValidationRuleSet.NONE]: 'Disables all config validation, including options that are known to be incompatible with jsii. Intended for experimentation only. Use at your own risk.',
25
+ };
26
+ /**
27
+ * Render a single rule set (its `compilerOptions` rules) as a human-readable block.
28
+ *
29
+ * @param ruleSet the rule set to render
30
+ * @returns a multi-line string suitable for printing to the console
31
+ */
32
+ function formatRuleSet(ruleSet) {
33
+ const lines = [`${chalk_1.default.bold('Rule set:')} ${chalk_1.default.bold.cyan(ruleSet)}`];
34
+ const description = exports.RULE_SET_DESCRIPTIONS[ruleSet];
35
+ if (description) {
36
+ lines.push(chalk_1.default.dim(description));
37
+ }
38
+ const rules = (0, tsconfig_validator_1.describeRuleSet)(ruleSet);
39
+ if (rules.length === 0) {
40
+ lines.push('');
41
+ lines.push(chalk_1.default.dim(' No rules. Configuration validation is disabled for this rule set.'));
42
+ return lines.join('\n');
43
+ }
44
+ const unknownRejected = (0, tsconfig_validator_1.getCompilerOptionsRuleSet)(ruleSet).options.unexpectedFields === validator_1.RuleType.FAIL;
45
+ lines.push('');
46
+ lines.push(chalk_1.default.dim(`Applies to: compilerOptions (other options: ${unknownRejected ? 'rejected' : 'allowed'})`));
47
+ lines.push('');
48
+ // Group rules by field, preserving the order in which each field first appears.
49
+ const byField = new Map();
50
+ for (const rule of rules) {
51
+ const list = byField.get(rule.field) ?? [];
52
+ list.push(rule);
53
+ byField.set(rule.field, list);
54
+ }
55
+ const width = Math.max(...[...byField.keys()].map((field) => field.length));
56
+ for (const [field, fieldRules] of byField) {
57
+ const phrases = fieldRules.map(formatConstraint);
58
+ // A required field is surfaced as an explicit "required" constraint at the front.
59
+ if (fieldRules.some((rule) => rule.required)) {
60
+ phrases.unshift(chalk_1.default.italic('required'));
61
+ }
62
+ // Dedupe identical phrases (some fields are constrained by several rules that overlap).
63
+ const constraints = [...new Set(phrases)].join('; ');
64
+ lines.push(` ${chalk_1.default.bold(field.padEnd(width))} ${constraints}`);
65
+ }
66
+ return lines.join('\n');
67
+ }
68
+ /**
69
+ * Render a single rule's constraint as a human-readable phrase.
70
+ *
71
+ * @param rule the rule description to render
72
+ * @returns a phrase such as `must be one of: es2022, es2023` or `not allowed`
73
+ */
74
+ function formatConstraint(rule) {
75
+ const { type, values } = rule;
76
+ // No hints means the matcher accepts anything (e.g. Match.ANY).
77
+ if (values === undefined) {
78
+ return type === validator_1.RuleType.PASS ? chalk_1.default.italic('any value') : 'must not be set to the matched value';
79
+ }
80
+ // Only null/undefined hints means the option must be absent (e.g. Match.MISSING).
81
+ if (values.length > 0 && values.every((value) => value == null)) {
82
+ return chalk_1.default.italic('not allowed');
83
+ }
84
+ const formatted = values.map(formatRuleValue);
85
+ if (type === validator_1.RuleType.FAIL) {
86
+ return formatted.length > 1 ? `must not be one of: ${formatted.join(', ')}` : `must not be ${formatted[0]}`;
87
+ }
88
+ return formatted.length > 1 ? `must be one of: ${formatted.join(', ')}` : `must be ${formatted[0]}`;
89
+ }
90
+ /**
91
+ * Render a single hinted value as a highlighted code literal. Strings are shown
92
+ * verbatim (as a user writes them in tsconfig.json), everything else is JSON-encoded.
93
+ *
94
+ * @param value the hinted value to render
95
+ * @returns the value as a (possibly colorized) code literal
96
+ */
97
+ function formatRuleValue(value) {
98
+ const literal = typeof value === 'string' ? value : JSON.stringify(value);
99
+ return chalk_1.default.cyan(literal);
100
+ }
101
+ //# sourceMappingURL=rule-set-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-set-format.js","sourceRoot":"","sources":["../../src/tsconfig/rule-set-format.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { TypeScriptConfigValidationRuleSet } from '.';\nimport { describeRuleSet, getCompilerOptionsRuleSet } from './tsconfig-validator';\nimport { RuleDescription, RuleType } from './validator';\n\n/**\n * Human-readable descriptions for each tsconfig validation rule set.\n *\n * These are surfaced both as CLI option help (e.g. for `--validate-tsconfig` and\n * `--rule-set`) and as the heading when printing a rule set via `formatRuleSet`.\n */\nexport const RULE_SET_DESCRIPTIONS: {\n [choice in TypeScriptConfigValidationRuleSet]: string;\n} = {\n [TypeScriptConfigValidationRuleSet.STRICT]:\n 'Validates the provided config against a strict rule set designed for maximum backwards-compatibility.',\n [TypeScriptConfigValidationRuleSet.GENERATED]:\n 'Enforces a config as created by --generate-tsconfig. Use this to stay compatible with the generated config, but have full ownership over the file.',\n [TypeScriptConfigValidationRuleSet.MINIMAL]:\n 'Only enforce options that are known to be incompatible with jsii. This rule set is likely to be incomplete and new rules will be added without notice as incompatibilities emerge.',\n [TypeScriptConfigValidationRuleSet.NONE]:\n 'Disables all config validation, including options that are known to be incompatible with jsii. Intended for experimentation only. Use at your own risk.',\n};\n\n/**\n * Render a single rule set (its `compilerOptions` rules) as a human-readable block.\n *\n * @param ruleSet the rule set to render\n * @returns a multi-line string suitable for printing to the console\n */\nexport function formatRuleSet(ruleSet: TypeScriptConfigValidationRuleSet): string {\n const lines: string[] = [`${chalk.bold('Rule set:')} ${chalk.bold.cyan(ruleSet)}`];\n\n const description = RULE_SET_DESCRIPTIONS[ruleSet];\n if (description) {\n lines.push(chalk.dim(description));\n }\n\n const rules = describeRuleSet(ruleSet);\n if (rules.length === 0) {\n lines.push('');\n lines.push(chalk.dim(' No rules. Configuration validation is disabled for this rule set.'));\n return lines.join('\\n');\n }\n\n const unknownRejected = getCompilerOptionsRuleSet(ruleSet).options.unexpectedFields === RuleType.FAIL;\n lines.push('');\n lines.push(chalk.dim(`Applies to: compilerOptions (other options: ${unknownRejected ? 'rejected' : 'allowed'})`));\n lines.push('');\n\n // Group rules by field, preserving the order in which each field first appears.\n const byField = new Map<string, RuleDescription[]>();\n for (const rule of rules) {\n const list = byField.get(rule.field) ?? [];\n list.push(rule);\n byField.set(rule.field, list);\n }\n\n const width = Math.max(...[...byField.keys()].map((field) => field.length));\n for (const [field, fieldRules] of byField) {\n const phrases = fieldRules.map(formatConstraint);\n // A required field is surfaced as an explicit \"required\" constraint at the front.\n if (fieldRules.some((rule) => rule.required)) {\n phrases.unshift(chalk.italic('required'));\n }\n // Dedupe identical phrases (some fields are constrained by several rules that overlap).\n const constraints = [...new Set(phrases)].join('; ');\n lines.push(` ${chalk.bold(field.padEnd(width))} ${constraints}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Render a single rule's constraint as a human-readable phrase.\n *\n * @param rule the rule description to render\n * @returns a phrase such as `must be one of: es2022, es2023` or `not allowed`\n */\nexport function formatConstraint(rule: RuleDescription): string {\n const { type, values } = rule;\n\n // No hints means the matcher accepts anything (e.g. Match.ANY).\n if (values === undefined) {\n return type === RuleType.PASS ? chalk.italic('any value') : 'must not be set to the matched value';\n }\n\n // Only null/undefined hints means the option must be absent (e.g. Match.MISSING).\n if (values.length > 0 && values.every((value) => value == null)) {\n return chalk.italic('not allowed');\n }\n\n const formatted = values.map(formatRuleValue);\n if (type === RuleType.FAIL) {\n return formatted.length > 1 ? `must not be one of: ${formatted.join(', ')}` : `must not be ${formatted[0]}`;\n }\n return formatted.length > 1 ? `must be one of: ${formatted.join(', ')}` : `must be ${formatted[0]}`;\n}\n\n/**\n * Render a single hinted value as a highlighted code literal. Strings are shown\n * verbatim (as a user writes them in tsconfig.json), everything else is JSON-encoded.\n *\n * @param value the hinted value to render\n * @returns the value as a (possibly colorized) code literal\n */\nexport function formatRuleValue(value: any): string {\n const literal = typeof value === 'string' ? value : JSON.stringify(value);\n return chalk.cyan(literal);\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { TypeScriptConfig, TypeScriptConfigValidationRuleSet } from '.';
2
+ import { RuleDescription, RuleSet, Violation } from './validator';
2
3
  export declare class TypeScriptConfigValidator {
3
4
  ruleSet: TypeScriptConfigValidationRuleSet;
4
5
  private readonly validator;
@@ -13,4 +14,42 @@ export declare class TypeScriptConfigValidator {
13
14
  */
14
15
  validate(tsconfig: TypeScriptConfig): void;
15
16
  }
17
+ /**
18
+ * Returns the `compilerOptions` rule set that backs the given validation setting.
19
+ *
20
+ * These are the substantive, set-specific rules (the top-level rules such as
21
+ * `files`/`include`/`exclude` are identical across all sets). The `off` rule set
22
+ * is empty, as it disables validation.
23
+ *
24
+ * @param ruleSet the validation setting to look up
25
+ * @returns the `RuleSet` applied to `compilerOptions`
26
+ */
27
+ export declare function getCompilerOptionsRuleSet(ruleSet: TypeScriptConfigValidationRuleSet): RuleSet;
28
+ /**
29
+ * Produces a human-readable description of every `compilerOptions` rule in a rule set.
30
+ *
31
+ * @param ruleSet the validation setting to describe
32
+ * @returns a description for every rule in the set
33
+ */
34
+ export declare function describeRuleSet(ruleSet: TypeScriptConfigValidationRuleSet): RuleDescription[];
35
+ /**
36
+ * Reads and parses a `tsconfig.json` file from disk into the format expected by
37
+ * the validator. This resolves `extends` and normalizes the options the same way
38
+ * the compiler does, so validation behaves identically to a real compilation.
39
+ *
40
+ * @param configPath the path to the tsconfig file to read
41
+ * @throws {@link JsiiError} if the file cannot be read or parsed
42
+ * @returns the parsed TypeScript configuration
43
+ */
44
+ export declare function readTypeScriptConfig(configPath: string): TypeScriptConfig;
45
+ /**
46
+ * Reads a `tsconfig.json` file from disk and validates its `compilerOptions`
47
+ * against the given rule set, without running a compilation.
48
+ *
49
+ * @param configPath the path to the tsconfig file to validate
50
+ * @param ruleSet the rule set to validate against
51
+ * @throws {@link JsiiError} if the file cannot be read or parsed
52
+ * @returns the list of rule violations (empty if the config is valid)
53
+ */
54
+ export declare function validateTypeScriptConfigFile(configPath: string, ruleSet: TypeScriptConfigValidationRuleSet): Violation[];
16
55
  //# sourceMappingURL=tsconfig-validator.d.ts.map
@@ -1,9 +1,50 @@
1
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
5
38
  Object.defineProperty(exports, "__esModule", { value: true });
6
39
  exports.TypeScriptConfigValidator = void 0;
40
+ exports.getCompilerOptionsRuleSet = getCompilerOptionsRuleSet;
41
+ exports.describeRuleSet = describeRuleSet;
42
+ exports.readTypeScriptConfig = readTypeScriptConfig;
43
+ exports.validateTypeScriptConfigFile = validateTypeScriptConfigFile;
44
+ const path = __importStar(require("node:path"));
45
+ const ts = __importStar(require("typescript"));
46
+ const compiler_options_1 = require("./compiler-options");
47
+ const utils_1 = require("../utils");
7
48
  const generated_public_1 = __importDefault(require("./rulesets/generated.public"));
8
49
  const minimal_public_1 = __importDefault(require("./rulesets/minimal.public"));
9
50
  const strict_public_1 = __importDefault(require("./rulesets/strict.public"));
@@ -49,4 +90,78 @@ class TypeScriptConfigValidator {
49
90
  }
50
91
  }
51
92
  exports.TypeScriptConfigValidator = TypeScriptConfigValidator;
93
+ /**
94
+ * Returns the `compilerOptions` rule set that backs the given validation setting.
95
+ *
96
+ * These are the substantive, set-specific rules (the top-level rules such as
97
+ * `files`/`include`/`exclude` are identical across all sets). The `off` rule set
98
+ * is empty, as it disables validation.
99
+ *
100
+ * @param ruleSet the validation setting to look up
101
+ * @returns the `RuleSet` applied to `compilerOptions`
102
+ */
103
+ function getCompilerOptionsRuleSet(ruleSet) {
104
+ return RuleSets[ruleSet];
105
+ }
106
+ /**
107
+ * Produces a human-readable description of every `compilerOptions` rule in a rule set.
108
+ *
109
+ * @param ruleSet the validation setting to describe
110
+ * @returns a description for every rule in the set
111
+ */
112
+ function describeRuleSet(ruleSet) {
113
+ return getCompilerOptionsRuleSet(ruleSet).describe();
114
+ }
115
+ /**
116
+ * Reads and parses a `tsconfig.json` file from disk into the format expected by
117
+ * the validator. This resolves `extends` and normalizes the options the same way
118
+ * the compiler does, so validation behaves identically to a real compilation.
119
+ *
120
+ * @param configPath the path to the tsconfig file to read
121
+ * @throws {@link JsiiError} if the file cannot be read or parsed
122
+ * @returns the parsed TypeScript configuration
123
+ */
124
+ function readTypeScriptConfig(configPath) {
125
+ const absolutePath = path.resolve(configPath);
126
+ const { config, error } = ts.readConfigFile(absolutePath, ts.sys.readFile);
127
+ if (error) {
128
+ throw new utils_1.JsiiError(`Failed to read tsconfig at "${configPath}": ${ts.flattenDiagnosticMessageText(error.messageText, '\n')}`);
129
+ }
130
+ const basePath = path.dirname(absolutePath);
131
+ const extended = ts.parseJsonConfigFileContent(config, ts.sys, basePath);
132
+ // the tsconfig parser adds this in, but it is not an expected compilerOption
133
+ delete extended.options.configFilePath;
134
+ return {
135
+ compilerOptions: extended.options,
136
+ watchOptions: extended.watchOptions,
137
+ include: extended.fileNames,
138
+ };
139
+ }
140
+ /**
141
+ * Reads a `tsconfig.json` file from disk and validates its `compilerOptions`
142
+ * against the given rule set, without running a compilation.
143
+ *
144
+ * @param configPath the path to the tsconfig file to validate
145
+ * @param ruleSet the rule set to validate against
146
+ * @throws {@link JsiiError} if the file cannot be read or parsed
147
+ * @returns the list of rule violations (empty if the config is valid)
148
+ */
149
+ function validateTypeScriptConfigFile(configPath, ruleSet) {
150
+ const config = readTypeScriptConfig(configPath);
151
+ const validator = new TypeScriptConfigValidator(ruleSet);
152
+ try {
153
+ validator.validate({
154
+ ...config,
155
+ // convert the internal format to the user format which is what the validator operates on
156
+ compilerOptions: (0, compiler_options_1.convertForJson)(config.compilerOptions),
157
+ });
158
+ return [];
159
+ }
160
+ catch (error) {
161
+ if (error instanceof validator_1.ValidationError) {
162
+ return error.violations;
163
+ }
164
+ throw error;
165
+ }
166
+ }
52
167
  //# sourceMappingURL=tsconfig-validator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tsconfig-validator.js","sourceRoot":"","sources":["../../src/tsconfig/tsconfig-validator.ts"],"names":[],"mappings":";;;;;;AACA,mFAAoD;AACpD,+EAAgD;AAChD,6EAA8C;AAC9C,2CAAwE;AAExE,MAAM,QAAQ,GAEV;IACF,SAAS,EAAT,0BAAS;IACT,MAAM,EAAN,uBAAM;IACN,OAAO,EAAP,wBAAO;IACP,GAAG,EAAE,IAAI,mBAAO,EAAE;CACnB,CAAC;AAEF,MAAa,yBAAyB;IAIV;IAHT,SAAS,CAAkB;IAC3B,eAAe,CAAkB;IAElD,YAA0B,OAA0C;QAA1C,YAAO,GAAP,OAAO,CAAmC;QAClE,MAAM,aAAa,GAAG,IAAI,mBAAO,CAAC;YAChC,gBAAgB,EAAE,oBAAQ,CAAC,IAAI;SAChC,CAAC,CAAC;QACH,aAAa,CAAC,UAAU,CAAC,OAAO,EAAE,iBAAK,CAAC,GAAG,CAAC,CAAC;QAC7C,aAAa,CAAC,UAAU,CAAC,SAAS,EAAE,iBAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,aAAa,CAAC,UAAU,CAAC,SAAS,EAAE,iBAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,aAAa,CAAC,UAAU,CAAC,SAAS,EAAE,iBAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,aAAa,CAAC,UAAU,CAAC,YAAY,EAAE,iBAAK,CAAC,GAAG,CAAC,CAAC;QAClD,aAAa,CAAC,UAAU,CAAC,cAAc,EAAE,iBAAK,CAAC,GAAG,CAAC,CAAC;QACpD,aAAa,CAAC,UAAU,CAAC,iBAAiB,EAAE,iBAAK,CAAC,OAAO,CAAC,CAAC;QAE3D,IAAI,CAAC,eAAe,GAAG,IAAI,2BAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC;QACjF,aAAa,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,eAAe,EAAE,EAAE;YAC9D,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,GAAG,IAAI,2BAAe,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAClE,CAAC;IAED;;;;;;OAMG;IACI,QAAQ,CAAC,QAA0B;QACxC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;CACF;AAnCD,8DAmCC","sourcesContent":["import { TypeScriptConfig, TypeScriptConfigValidationRuleSet } from '.';\nimport generated from './rulesets/generated.public';\nimport minimal from './rulesets/minimal.public';\nimport strict from './rulesets/strict.public';\nimport { Match, ObjectValidator, RuleSet, RuleType } from './validator';\n\nconst RuleSets: {\n [name in TypeScriptConfigValidationRuleSet]: RuleSet;\n} = {\n generated,\n strict,\n minimal,\n off: new RuleSet(),\n};\n\nexport class TypeScriptConfigValidator {\n private readonly validator: ObjectValidator;\n private readonly compilerOptions: ObjectValidator;\n\n public constructor(public ruleSet: TypeScriptConfigValidationRuleSet) {\n const topLevelRules = new RuleSet({\n unexpectedFields: RuleType.PASS,\n });\n topLevelRules.shouldPass('files', Match.ANY);\n topLevelRules.shouldPass('extends', Match.ANY);\n topLevelRules.shouldPass('include', Match.ANY);\n topLevelRules.shouldPass('exclude', Match.ANY);\n topLevelRules.shouldPass('references', Match.ANY);\n topLevelRules.shouldPass('watchOptions', Match.ANY);\n topLevelRules.shouldPass('typeAcquisition', Match.MISSING);\n\n this.compilerOptions = new ObjectValidator(RuleSets[ruleSet], 'compilerOptions');\n topLevelRules.shouldPass('compilerOptions', (compilerOptions) => {\n this.compilerOptions.validate(compilerOptions);\n return true;\n });\n\n this.validator = new ObjectValidator(topLevelRules, 'tsconfig');\n }\n\n /**\n * Validated the provided config against the set of rules.\n *\n * @throws when the config is invalid\n *\n * @param tsconfig the tsconfig to be validated, this MUST be a tsconfig as a user would have written it in tsconfig.\n */\n public validate(tsconfig: TypeScriptConfig) {\n this.validator.validate(tsconfig);\n }\n}\n"]}
1
+ {"version":3,"file":"tsconfig-validator.js","sourceRoot":"","sources":["../../src/tsconfig/tsconfig-validator.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'node:path';\nimport * as ts from 'typescript';\nimport { TypeScriptConfig, TypeScriptConfigValidationRuleSet } from '.';\nimport { convertForJson } from './compiler-options';\nimport { JsiiError } from '../utils';\nimport generated from './rulesets/generated.public';\nimport minimal from './rulesets/minimal.public';\nimport strict from './rulesets/strict.public';\nimport { Match, ObjectValidator, RuleDescription, RuleSet, RuleType, ValidationError, Violation } from './validator';\n\nconst RuleSets: {\n [name in TypeScriptConfigValidationRuleSet]: RuleSet;\n} = {\n generated,\n strict,\n minimal,\n off: new RuleSet(),\n};\n\nexport class TypeScriptConfigValidator {\n private readonly validator: ObjectValidator;\n private readonly compilerOptions: ObjectValidator;\n\n public constructor(public ruleSet: TypeScriptConfigValidationRuleSet) {\n const topLevelRules = new RuleSet({\n unexpectedFields: RuleType.PASS,\n });\n topLevelRules.shouldPass('files', Match.ANY);\n topLevelRules.shouldPass('extends', Match.ANY);\n topLevelRules.shouldPass('include', Match.ANY);\n topLevelRules.shouldPass('exclude', Match.ANY);\n topLevelRules.shouldPass('references', Match.ANY);\n topLevelRules.shouldPass('watchOptions', Match.ANY);\n topLevelRules.shouldPass('typeAcquisition', Match.MISSING);\n\n this.compilerOptions = new ObjectValidator(RuleSets[ruleSet], 'compilerOptions');\n topLevelRules.shouldPass('compilerOptions', (compilerOptions) => {\n this.compilerOptions.validate(compilerOptions);\n return true;\n });\n\n this.validator = new ObjectValidator(topLevelRules, 'tsconfig');\n }\n\n /**\n * Validated the provided config against the set of rules.\n *\n * @throws when the config is invalid\n *\n * @param tsconfig the tsconfig to be validated, this MUST be a tsconfig as a user would have written it in tsconfig.\n */\n public validate(tsconfig: TypeScriptConfig) {\n this.validator.validate(tsconfig);\n }\n}\n\n/**\n * Returns the `compilerOptions` rule set that backs the given validation setting.\n *\n * These are the substantive, set-specific rules (the top-level rules such as\n * `files`/`include`/`exclude` are identical across all sets). The `off` rule set\n * is empty, as it disables validation.\n *\n * @param ruleSet the validation setting to look up\n * @returns the `RuleSet` applied to `compilerOptions`\n */\nexport function getCompilerOptionsRuleSet(ruleSet: TypeScriptConfigValidationRuleSet): RuleSet {\n return RuleSets[ruleSet];\n}\n\n/**\n * Produces a human-readable description of every `compilerOptions` rule in a rule set.\n *\n * @param ruleSet the validation setting to describe\n * @returns a description for every rule in the set\n */\nexport function describeRuleSet(ruleSet: TypeScriptConfigValidationRuleSet): RuleDescription[] {\n return getCompilerOptionsRuleSet(ruleSet).describe();\n}\n\n/**\n * Reads and parses a `tsconfig.json` file from disk into the format expected by\n * the validator. This resolves `extends` and normalizes the options the same way\n * the compiler does, so validation behaves identically to a real compilation.\n *\n * @param configPath the path to the tsconfig file to read\n * @throws {@link JsiiError} if the file cannot be read or parsed\n * @returns the parsed TypeScript configuration\n */\nexport function readTypeScriptConfig(configPath: string): TypeScriptConfig {\n const absolutePath = path.resolve(configPath);\n const { config, error } = ts.readConfigFile(absolutePath, ts.sys.readFile);\n if (error) {\n throw new JsiiError(\n `Failed to read tsconfig at \"${configPath}\": ${ts.flattenDiagnosticMessageText(error.messageText, '\\n')}`,\n );\n }\n\n const basePath = path.dirname(absolutePath);\n const extended = ts.parseJsonConfigFileContent(config, ts.sys, basePath);\n // the tsconfig parser adds this in, but it is not an expected compilerOption\n delete extended.options.configFilePath;\n\n return {\n compilerOptions: extended.options,\n watchOptions: extended.watchOptions,\n include: extended.fileNames,\n };\n}\n\n/**\n * Reads a `tsconfig.json` file from disk and validates its `compilerOptions`\n * against the given rule set, without running a compilation.\n *\n * @param configPath the path to the tsconfig file to validate\n * @param ruleSet the rule set to validate against\n * @throws {@link JsiiError} if the file cannot be read or parsed\n * @returns the list of rule violations (empty if the config is valid)\n */\nexport function validateTypeScriptConfigFile(\n configPath: string,\n ruleSet: TypeScriptConfigValidationRuleSet,\n): Violation[] {\n const config = readTypeScriptConfig(configPath);\n const validator = new TypeScriptConfigValidator(ruleSet);\n try {\n validator.validate({\n ...config,\n // convert the internal format to the user format which is what the validator operates on\n compilerOptions: convertForJson(config.compilerOptions),\n });\n return [];\n } catch (error: unknown) {\n if (error instanceof ValidationError) {\n return error.violations;\n }\n throw error;\n }\n}\n"]}
@@ -42,6 +42,30 @@ interface Rule {
42
42
  type: RuleType;
43
43
  matcher: Matcher;
44
44
  }
45
+ /**
46
+ * A human-readable description of a single rule.
47
+ * Intended for displaying a rule set to a user, e.g. via the CLI.
48
+ */
49
+ export interface RuleDescription {
50
+ /**
51
+ * The field (compilerOption) the rule applies to.
52
+ */
53
+ readonly field: string;
54
+ /**
55
+ * Whether the value must match (`PASS`) or must not match (`FAIL`) the constraint.
56
+ */
57
+ readonly type: RuleType;
58
+ /**
59
+ * Whether the field is required to be present for the rule to pass.
60
+ */
61
+ readonly required: boolean;
62
+ /**
63
+ * The values the matcher offered as hints.
64
+ * For `PASS` rules these are allowed values, for `FAIL` rules these are disallowed values.
65
+ * `undefined` when the matcher did not offer any hints (e.g. any value is accepted).
66
+ */
67
+ readonly values?: any[];
68
+ }
45
69
  export declare class RuleSet {
46
70
  readonly options: RuleSetOptions;
47
71
  private _rules;
@@ -93,6 +117,16 @@ export declare class RuleSet {
93
117
  * @returns A record of fields and allowed values
94
118
  */
95
119
  getFieldHints(): Record<string, any[]>;
120
+ /**
121
+ * Produces a human-readable description of every rule in the set.
122
+ *
123
+ * This is derived directly from the rules (it does not duplicate them), so it
124
+ * stays in sync as rules are added or changed. It is primarily intended for
125
+ * surfacing a rule set to a user, e.g. via the CLI.
126
+ *
127
+ * @returns A description for every rule, in the order the rules were added.
128
+ */
129
+ describe(): RuleDescription[];
96
130
  }
97
131
  export declare class Match {
98
132
  /**
@@ -6,6 +6,12 @@ var RuleType;
6
6
  RuleType[RuleType["PASS"] = 0] = "PASS";
7
7
  RuleType[RuleType["FAIL"] = 1] = "FAIL";
8
8
  })(RuleType || (exports.RuleType = RuleType = {}));
9
+ /**
10
+ * A sentinel value used to probe matchers for hints.
11
+ * It is intentionally not `null`/`undefined` so that `Match.optional` delegates
12
+ * to its inner matcher (which is where the hints are recorded).
13
+ */
14
+ const DESCRIBE_PROBE = Symbol('jsii.tsconfig.describe.probe');
9
15
  class RuleSet {
10
16
  options;
11
17
  _rules = [];
@@ -116,6 +122,39 @@ class RuleSet {
116
122
  }
117
123
  return fieldHints;
118
124
  }
125
+ /**
126
+ * Produces a human-readable description of every rule in the set.
127
+ *
128
+ * This is derived directly from the rules (it does not duplicate them), so it
129
+ * stays in sync as rules are added or changed. It is primarily intended for
130
+ * surfacing a rule set to a user, e.g. via the CLI.
131
+ *
132
+ * @returns A description for every rule, in the order the rules were added.
133
+ */
134
+ describe() {
135
+ return this._rules.map((rule) => {
136
+ // Probe the matcher for the values it considers relevant (hints).
137
+ const values = [];
138
+ let hinted = false;
139
+ rule.matcher(DESCRIBE_PROBE, {
140
+ hints: (allowed) => {
141
+ hinted = true;
142
+ if (allowed) {
143
+ values.push(...allowed);
144
+ }
145
+ },
146
+ });
147
+ // A field is required if the rule is not satisfied when the value is absent.
148
+ const passesWhenAbsent = rule.matcher(undefined);
149
+ const required = rule.type === RuleType.PASS ? !passesWhenAbsent : passesWhenAbsent;
150
+ return {
151
+ field: rule.field,
152
+ type: rule.type,
153
+ required,
154
+ values: hinted ? values : undefined,
155
+ };
156
+ });
157
+ }
119
158
  }
120
159
  exports.RuleSet = RuleSet;
121
160
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/tsconfig/validator.ts"],"names":[],"mappings":";;;AA2BA,IAAY,QAGX;AAHD,WAAY,QAAQ;IAClB,uCAAI,CAAA;IACJ,uCAAI,CAAA;AACN,CAAC,EAHW,QAAQ,wBAAR,QAAQ,QAGnB;AAmBD,MAAa,OAAO;IAyDA;IAxDV,MAAM,GAAgB,EAAE,CAAC;IACjC,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAW,MAAM;QACf,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,IAAW,aAAa;QACtB,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,IAAW,cAAc;QACvB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;YACvB,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAE9C,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,KAAK,QAAQ,CAAC,IAAI;oBAChB,IAAI,CAAC,aAAa,EAAE,CAAC;wBACnB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACrB,CAAC;oBACD,MAAM;gBACR,KAAK,QAAQ,CAAC,IAAI;oBAChB,IAAI,aAAa,EAAE,CAAC;wBAClB,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACrB,CAAC;oBACD,MAAM;gBACR;oBACE,SAAS;YACb,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,YACkB,UAA0B;QACxC,gBAAgB,EAAE,QAAQ,CAAC,IAAI;KAChC;QAFe,YAAO,GAAP,OAAO,CAEtB;IACA,CAAC;IAEJ;;;;;;OAMG;IACI,UAAU,CAAC,KAAa,EAAE,OAAgB;QAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;OAKG;IACI,UAAU,CAAC,KAAa,EAAE,OAAgB;QAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,KAAc;QAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;;;;;;OAOG;IACI,aAAa;QAClB,MAAM,UAAU,GAA0B,EAAE,CAAC;QAE7C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/B,6CAA6C;YAC7C,yDAAyD;YACzD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAChC,kCAAkC;gBAClC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;oBACtB,KAAK,EAAE,CAAC,aAAoB,EAAE,EAAE;wBAC9B,iDAAiD;wBACjD,IAAI,aAAa,EAAE,CAAC;4BAClB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;4BAC9B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;wBAChD,CAAC;oBACH,CAAC;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF;AA3HD,0BA2HC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,OAAgB,EAAE,OAAgC,EAAE,OAAe;IACtF,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,OAAO,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACpC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,CAAM,EAAE,CAAM;IAChC,IAAI,CAAC;QACH,mGAAmG;QACnG,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,qCAAqC;QACrC,oCAAoC;QACpC,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAa,KAAK;IAChB;;OAEG;IACI,MAAM,CAAC,QAAQ,CAAC,OAAgB;QACrC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YACxB,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACjC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAK,CAAC,GAAG,QAAmB;QACxC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClF,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,GAAG,OAA+B;QACpD,OAAO,WAAW,CAChB,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EACpC,CAAC,MAAM,EAAE,EAAE,CAAC,+BAA+B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EACpG,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,EAAE,CAAC,QAAa;QAC5B,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;YACzB,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,OAAO,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChD,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC7B,OAAO,EAAE,QAAQ,EAAE,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClG,OAAO,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACtC,CAAC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,KAAK,CAAC,QAAe;QACjC,OAAO,WAAW,CAChB,CAAC,MAAM,EAAE,EAAE;YACT,8DAA8D;YAC9D,yDAAyD;YACzD,oEAAoE;YACpE,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACzF,yCAAyC;gBACzC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACrE,CAAC;YAED,iDAAiD;YACjD,OAAO,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACtC,CAAC,EACD,CAAC,MAAM,EAAE,EAAE,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EACjG,CAAC,QAAQ,CAAC,CACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,QAAgB,EAAE,aAAa,GAAG,KAAK;QACzD,OAAO,WAAW,CAChB,CAAC,MAAM,EAAE,EAAE;YACT,mBAAmB;YACnB,IAAI,CAAC,aAAa,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACjD,OAAO,UAAU,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YAClE,CAAC;YAED,iBAAiB;YACjB,OAAO,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACtC,CAAC,EACD,CAAC,MAAW,EAAE,EAAE,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAC7F,CAAC,QAAQ,CAAC,CACX,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,GAAG,GAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC;IAEtD,8DAA8D;IACvD,MAAM,CAAC,IAAI,GAAY,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC7C,8DAA8D;IACvD,MAAM,CAAC,KAAK,GAAY,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IAE/C;;OAEG;IACH,8DAA8D;IACvD,MAAM,CAAC,OAAO,GAAG,WAAW,CACjC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,EACnD,CAAC,MAAM,EAAE,EAAE,CAAC,qCAAqC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EACzE,CAAC,SAAS,EAAE,IAAI,CAAC,CAClB,CAAC;;AA5GJ,sBA6GC;AAOD,MAAa,eAAgB,SAAQ,KAAK;IACZ;IAA5B,YAA4B,UAAuB;QACjD,wCAAwC;QACxC,KAAK,CAAC,oBAAoB,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAFjE,eAAU,GAAV,UAAU,CAAa;QAIjD,gCAAgC;QAChC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;CACF;AARD,0CAQC;AAED,MAAa,eAAe;IACA;IAAmC;IAA7D,YAA0B,OAAgB,EAAmB,WAAmB,MAAM;QAA5D,YAAO,GAAP,OAAO,CAAS;QAAmB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAE1F;;;;;;OAMG;IACI,QAAQ,CAAC,IAA8B;QAC5C,8BAA8B;QAC9B,IAAI,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,eAAe,CAAC;gBACxB,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,wCAAwC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;aACnG,CAAC,CAAC;QACL,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAChC,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,gCAAgC;QAChC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE/B,yEAAyE;YACzE,IAAI,gBAAgB,GAAG,6BAA6B,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7E,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;gBACtC,QAAQ,EAAE,CAAC,OAAe,EAAE,EAAE;oBAC5B,gBAAgB,GAAG,OAAO,CAAC;gBAC7B,CAAC;aACF,CAAC,CAAC;YAEH,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,KAAK,QAAQ,CAAC,IAAI;oBAChB,IAAI,CAAC,WAAW,EAAE,CAAC;wBACjB,UAAU,CAAC,IAAI,CAAC;4BACd,KAAK,EAAE,IAAI,CAAC,KAAK;4BACjB,OAAO,EAAE,gBAAgB;yBAC1B,CAAC,CAAC;oBACL,CAAC;oBACD,MAAM;gBACR,KAAK,QAAQ,CAAC,IAAI;oBAChB,IAAI,WAAW,EAAE,CAAC;wBAChB,UAAU,CAAC,IAAI,CAAC;4BACd,KAAK,EAAE,IAAI,CAAC,KAAK;4BACjB,OAAO,EAAE,gBAAgB;yBAC1B,CAAC,CAAC;oBACL,CAAC;oBACD,MAAM;gBACR;oBACE,SAAS;YACb,CAAC;YAED,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,4EAA4E;QAC5E,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC5D,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;gBACnC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC9B,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,0BAA0B,KAAK,EAAE,EAAE,CAAC,CAAC;gBAChF,CAAC;YACH,CAAC;QACH,CAAC;QAED,qDAAqD;QACrD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;CACF;AAxED,0CAwEC","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 match at least one of the provided matchers.\n * All matchers are evaluated (no short-circuit) so their hints are collected.\n */\n public static anyOf(...matchers: Matcher[]): Matcher {\n return (value, options) => matchers.map((m) => m(value, options)).some(Boolean);\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\n/**\n * A human-readable description of a single rule.\n * Intended for displaying a rule set to a user, e.g. via the CLI.\n */\nexport interface RuleDescription {\n /**\n * The field (compilerOption) the rule applies to.\n */\n readonly field: string;\n\n /**\n * Whether the value must match (`PASS`) or must not match (`FAIL`) the constraint.\n */\n readonly type: RuleType;\n\n /**\n * Whether the field is required to be present for the rule to pass.\n */\n readonly required: boolean;\n\n /**\n * The values the matcher offered as hints.\n * For `PASS` rules these are allowed values, for `FAIL` rules these are disallowed values.\n * `undefined` when the matcher did not offer any hints (e.g. any value is accepted).\n */\n readonly values?: any[];\n}\n\n/**\n * A sentinel value used to probe matchers for hints.\n * It is intentionally not `null`/`undefined` so that `Match.optional` delegates\n * to its inner matcher (which is where the hints are recorded).\n */\nconst DESCRIBE_PROBE = Symbol('jsii.tsconfig.describe.probe');\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 * Produces a human-readable description of every rule in the set.\n *\n * This is derived directly from the rules (it does not duplicate them), so it\n * stays in sync as rules are added or changed. It is primarily intended for\n * surfacing a rule set to a user, e.g. via the CLI.\n *\n * @returns A description for every rule, in the order the rules were added.\n */\n public describe(): RuleDescription[] {\n return this._rules.map((rule) => {\n // Probe the matcher for the values it considers relevant (hints).\n const values: any[] = [];\n let hinted = false;\n rule.matcher(DESCRIBE_PROBE, {\n hints: (allowed) => {\n hinted = true;\n if (allowed) {\n values.push(...allowed);\n }\n },\n });\n\n // A field is required if the rule is not satisfied when the value is absent.\n const passesWhenAbsent = rule.matcher(undefined);\n const required = rule.type === RuleType.PASS ? !passesWhenAbsent : passesWhenAbsent;\n\n return {\n field: rule.field,\n type: rule.type,\n required,\n values: hinted ? values : undefined,\n };\n });\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 match at least one of the provided matchers.\n * All matchers are evaluated (no short-circuit) so their hints are collected.\n */\n public static anyOf(...matchers: Matcher[]): Matcher {\n return (value, options) => matchers.map((m) => m(value, options)).some(Boolean);\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 = "6.0.0-dev.0";
2
+ export declare const SHORT_VERSION = "6.0.1";
3
3
  /** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */
4
- export declare const VERSION = "6.0.0-dev.0 (build 8262a16)";
4
+ export declare const VERSION = "6.0.1 (build aa3cfca)";
5
5
  /** The release line identifier for this JSII compiler (e.g: `X.Y`) */
6
6
  export declare const RELEASE_LINE = "6.0";
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 = '6.0.0-dev.0';
7
+ exports.SHORT_VERSION = '6.0.1';
8
8
  /** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */
9
- exports.VERSION = '6.0.0-dev.0 (build 8262a16)';
9
+ exports.VERSION = '6.0.1 (build aa3cfca)';
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 = '6.0.0-dev.0';\n\n/** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */\nexport const VERSION = '6.0.0-dev.0 (build 8262a16)';\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 = '6.0.1';\n\n/** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */\nexport const VERSION = '6.0.1 (build aa3cfca)';\n\n/** The release line identifier for this JSII compiler (e.g: `X.Y`) */\nexport const RELEASE_LINE = versionMajorMinor;\n"]}
package/package.json CHANGED
@@ -66,13 +66,13 @@
66
66
  "ts-node": "^10.9.2"
67
67
  },
68
68
  "dependencies": {
69
- "@jsii/check-node": "1.133.0",
70
- "@jsii/spec": "1.133.0",
69
+ "@jsii/check-node": "1.134.0",
70
+ "@jsii/spec": "1.134.0",
71
71
  "case": "^1.6.3",
72
72
  "chalk": "^4",
73
73
  "fast-deep-equal": "^3.1.3",
74
74
  "log4js": "^6.9.1",
75
- "semver": "^7.8.1",
75
+ "semver": "^7.8.2",
76
76
  "semver-intersect": "^1.5.0",
77
77
  "sort-json": "^2.0.1",
78
78
  "spdx-license-list": "^6.11.0",
@@ -95,7 +95,7 @@
95
95
  "publishConfig": {
96
96
  "access": "public"
97
97
  },
98
- "version": "6.0.0-dev.0",
98
+ "version": "6.0.1",
99
99
  "packageManager": "yarn@4.13.0",
100
100
  "types": "lib/index.d.ts",
101
101
  "exports": {
@@ -104,6 +104,5 @@
104
104
  "./package.json": "./package.json",
105
105
  "./common": "./lib/common/index.js"
106
106
  },
107
- "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"yarn projen\".",
108
- "stableVersion": "0.0.0"
107
+ "//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"yarn projen\"."
109
108
  }