@amritk/generate-validators 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import { isSchemaObject } from "@amritk/helpers/schema-guards";
2
+ import { enforcesFormat, NO_FORMATS } from "./enforced-keywords.js";
2
3
  const ANNOTATION_KEYWORDS = /* @__PURE__ */ new Set([
3
4
  "$anchor",
4
5
  "$comment",
@@ -25,14 +26,17 @@ const ANNOTATION_KEYWORDS = /* @__PURE__ */ new Set([
25
26
  "writeOnly",
26
27
  "xml"
27
28
  ]);
28
- const foldsToConstant = (schema) => {
29
+ const foldsToConstant = (schema, formats = NO_FORMATS) => {
29
30
  if (schema === true)
30
31
  return true;
31
32
  if (schema === false)
32
33
  return false;
33
34
  if (!isSchemaObject(schema))
34
35
  return void 0;
35
- return Object.keys(schema).every((key) => ANNOTATION_KEYWORDS.has(key)) ? true : void 0;
36
+ const record = schema;
37
+ if (enforcesFormat(record, formats))
38
+ return void 0;
39
+ return Object.keys(record).every((key) => ANNOTATION_KEYWORDS.has(key)) ? true : void 0;
36
40
  };
37
41
  export {
38
42
  foldsToConstant
@@ -24,6 +24,13 @@ type GenerateValidatorFileOptions = {
24
24
  * {@link UnknownKeysStrategy} for the trade-off between the two.
25
25
  */
26
26
  readonly unknownKeys?: UnknownKeysStrategy;
27
+ /**
28
+ * The `format` names this build enforces. Empty (the default) leaves `format`
29
+ * an annotation, as 2020-12 reads it; a name here makes the generated
30
+ * `validateX` and `isX` both check it, against a `formats.ts` emitted
31
+ * alongside.
32
+ */
33
+ readonly formats?: ReadonlySet<string>;
27
34
  };
28
35
  /**
29
36
  * Generates a complete TypeScript validator file from a JSON Schema.
@@ -1,6 +1,8 @@
1
1
  import { generateTypeDefinition } from "@amritk/helpers/generate-type-definition";
2
2
  import { DEFAULT_UNKNOWN_KEYS } from "@amritk/helpers/unknown-keys-strategy";
3
3
  import { collectValidatorImports } from "./collect-validator-imports.js";
4
+ import { formatCheckName } from "./emit-format-checks.js";
5
+ import { NO_FORMATS } from "./enforced-keywords.js";
4
6
  import { generateBooleanGuard, generateValidatorFunction } from "./generate-validator-function.js";
5
7
  const escapeForWordMatch = (name) => name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6
8
  const generateValidatorFile = (schema, typeName, options) => {
@@ -10,8 +12,9 @@ const generateValidatorFile = (schema, typeName, options) => {
10
12
  ...options?.rootSchema !== void 0 ? { rootSchema: options.rootSchema } : {}
11
13
  });
12
14
  const unknownKeys = options?.unknownKeys ?? DEFAULT_UNKNOWN_KEYS;
13
- const validatorFunction = generateValidatorFunction(schema, typeName, typeSuffix, options?.rootSchema, unknownKeys);
14
- const booleanGuard = generateBooleanGuard(schema, typeName, typeSuffix, unknownKeys);
15
+ const formats = options?.formats ?? NO_FORMATS;
16
+ const validatorFunction = generateValidatorFunction(schema, typeName, typeSuffix, options?.rootSchema, unknownKeys, formats);
17
+ const booleanGuard = generateBooleanGuard(schema, typeName, typeSuffix, unknownKeys, formats);
15
18
  const body = validatorFunction + booleanGuard;
16
19
  const emitted = typeDefinition + body;
17
20
  const mentions = (name) => new RegExp(`\\b${escapeForWordMatch(name)}\\b`).test(emitted);
@@ -30,6 +33,11 @@ const generateValidatorFile = (schema, typeName, options) => {
30
33
  const runtimeHelpers = ["valuesEqual", "allUnique", "escapePointer", "everyItem"].filter((name) => body.includes(`${name}(`));
31
34
  if (runtimeHelpers.length > 0) {
32
35
  result += `import { ${runtimeHelpers.join(", ")} } from './validation-result.js'
36
+ `;
37
+ }
38
+ const formatChecks = [...formats].map(formatCheckName).filter((name) => body.includes(`${name}(`)).sort();
39
+ if (formatChecks.length > 0) {
40
+ result += `import { ${formatChecks.join(", ")} } from './formats.js'
33
41
  `;
34
42
  }
35
43
  for (const imp of refImports) {
@@ -16,7 +16,7 @@ import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
16
16
  * `unknownKeys` picks how a closed object's no-extras test counts keys — see
17
17
  * {@link UnknownKeysStrategy}.
18
18
  */
19
- export declare const generateBooleanGuard: (schema: JSONSchema, typeName: string, _suffix?: string, unknownKeys?: UnknownKeysStrategy) => string;
19
+ export declare const generateBooleanGuard: (schema: JSONSchema, typeName: string, _suffix?: string, unknownKeys?: UnknownKeysStrategy, formats?: ReadonlySet<string>) => string;
20
20
  /**
21
21
  * Generates a TypeScript validator function from a JSON Schema.
22
22
  *
@@ -39,4 +39,4 @@ export declare const generateBooleanGuard: (schema: JSONSchema, typeName: string
39
39
  * // }
40
40
  * ```
41
41
  */
42
- export declare const generateValidatorFunction: (schema: JSONSchema, typeName: string, suffix?: string, rootSchema?: Record<string, unknown>, unknownKeys?: UnknownKeysStrategy) => string;
42
+ export declare const generateValidatorFunction: (schema: JSONSchema, typeName: string, suffix?: string, rootSchema?: Record<string, unknown>, unknownKeys?: UnknownKeysStrategy, formats?: ReadonlySet<string>) => string;