@tsofist/schema-forge 2.4.3 → 2.5.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.
@@ -1,7 +1,7 @@
1
1
  import '../util/patch.extended-annotations-reader';
2
2
  import { SchemaObject } from 'ajv';
3
- import { ChainNodeParser, CompletedConfig, Context, SubNodeParser, TupleType } from 'ts-json-schema-generator';
4
- import { Node, TupleTypeNode } from 'typescript';
3
+ import { CompletedConfig } from 'ts-json-schema-generator';
4
+ import { SchemaForgeOptions } from '../types';
5
5
  import { TypeExposeKind } from './types';
6
6
  interface Options {
7
7
  tsconfig: string;
@@ -14,13 +14,7 @@ interface Options {
14
14
  openapiCompatible?: boolean;
15
15
  sortObjectProperties?: boolean;
16
16
  allowUseFallbackDescription?: boolean;
17
+ shrinkDefinitionNames: SchemaForgeOptions['shrinkDefinitionNames'];
17
18
  }
18
19
  export declare function generateSchemaByDraftTypes(options: Options): Promise<SchemaObject>;
19
- export declare class TupleTypeParser implements SubNodeParser {
20
- protected readonly childNodeParser: ChainNodeParser;
21
- protected readonly allowUseFallbackDescription: boolean | undefined;
22
- constructor(childNodeParser: ChainNodeParser, allowUseFallbackDescription: boolean | undefined);
23
- supportsNode(node: Node): boolean;
24
- createType(node: TupleTypeNode, context: Context): TupleType;
25
- }
26
20
  export {};
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TupleTypeParser = void 0;
4
3
  exports.generateSchemaByDraftTypes = generateSchemaByDraftTypes;
5
4
  require("../util/patch.extended-annotations-reader");
6
5
  const error_1 = require("@tsofist/stem/lib/error");
7
6
  const ajv_1 = require("ajv");
7
+ const jsonpath_plus_1 = require("jsonpath-plus");
8
8
  const ts_json_schema_generator_1 = require("ts-json-schema-generator");
9
9
  const typescript_1 = require("typescript");
10
10
  const sort_properties_1 = require("../util/sort-properties");
@@ -54,15 +54,48 @@ async function generateSchemaByDraftTypes(options) {
54
54
  const schema = generator.createSchema(definitionName);
55
55
  Object.assign(result.definitions, schema.definitions);
56
56
  }
57
+ if (options.shrinkDefinitionNames) {
58
+ const replacement = new Set();
59
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
60
+ for (const name of Object.keys(result.definitions)) {
61
+ const r = options.shrinkDefinitionNames(name);
62
+ if (r) {
63
+ if (replacement.has(r) || r in result.definitions) {
64
+ (0, error_1.raise)(`Duplicate replacement definition name: ${r}`);
65
+ }
66
+ // rename property
67
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
68
+ result.definitions[r] = result.definitions[name];
69
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
70
+ delete result.definitions[name];
71
+ // rename references
72
+ const targets = (0, jsonpath_plus_1.JSONPath)({
73
+ path: `$..[?(@ && @.$ref == "#/definitions/${escapeDefinitionNameForJSONPath(name)}")]`,
74
+ json: result,
75
+ eval: 'safe',
76
+ });
77
+ targets?.forEach((item) => {
78
+ item.$ref = item.$ref.replace(`#/definitions/${name}`, `#/definitions/${r}`);
79
+ });
80
+ }
81
+ }
82
+ }
57
83
  result.definitions = Object.fromEntries(Object.entries((result.definitions || {})).sort());
58
84
  if (options.sortObjectProperties)
59
85
  (0, sort_properties_1.sortProperties)(result.definitions);
60
86
  await new ajv_1.default({
61
87
  strict: true,
62
88
  allErrors: true,
89
+ strictSchema: true,
90
+ strictTypes: false,
91
+ strictTuples: false,
92
+ allowUnionTypes: true,
63
93
  }).validateSchema(result, true);
64
94
  return result;
65
95
  }
96
+ function escapeDefinitionNameForJSONPath(value) {
97
+ return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
98
+ }
66
99
  class TupleTypeParser {
67
100
  constructor(childNodeParser, allowUseFallbackDescription) {
68
101
  Object.defineProperty(this, "childNodeParser", {
@@ -87,8 +120,6 @@ class TupleTypeParser {
87
120
  if ((0, typescript_1.isNamedTupleMember)(element)) {
88
121
  const description = (0, tsc_1.readJSDocDescription)(element, this.allowUseFallbackDescription);
89
122
  const nullable = type instanceof ts_json_schema_generator_1.AnnotatedType ? type.isNullable() : false;
90
- if (nullable)
91
- console.log(description, nullable);
92
123
  return description ? new ts_json_schema_generator_1.AnnotatedType(type, { description }, nullable) : type;
93
124
  }
94
125
  return type;
@@ -96,7 +127,6 @@ class TupleTypeParser {
96
127
  return new ts_json_schema_generator_1.TupleType(items);
97
128
  }
98
129
  }
99
- exports.TupleTypeParser = TupleTypeParser;
100
130
  class ArrayLiteralExpressionIdentifierParser {
101
131
  constructor(checker) {
102
132
  Object.defineProperty(this, "checker", {
package/lib/generator.js CHANGED
@@ -3,10 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.forgeSchema = forgeSchema;
4
4
  exports.loadJSONSchema = loadJSONSchema;
5
5
  exports.loadJSONSchemaSync = loadJSONSchemaSync;
6
- const fs_1 = require("fs");
7
- const promises_1 = require("fs/promises");
8
6
  const node_crypto_1 = require("node:crypto");
9
- const promises_2 = require("node:fs/promises");
7
+ const node_fs_1 = require("node:fs");
8
+ const promises_1 = require("node:fs/promises");
10
9
  const as_array_1 = require("@tsofist/stem/lib/as-array");
11
10
  const error_1 = require("@tsofist/stem/lib/error");
12
11
  const noop_1 = require("@tsofist/stem/lib/noop");
@@ -53,6 +52,7 @@ async function forgeSchema(options) {
53
52
  openapiCompatible: options.openapiCompatible,
54
53
  sortObjectProperties: options.sortObjectProperties,
55
54
  allowUseFallbackDescription: options.allowUseFallbackDescription,
55
+ shrinkDefinitionNames: options.shrinkDefinitionNames,
56
56
  })),
57
57
  ...(options.schemaMetadata || {}),
58
58
  };
@@ -106,7 +106,7 @@ async function forgeSchema(options) {
106
106
  }
107
107
  finally {
108
108
  if (!KEEP_ARTEFACTS) {
109
- await Promise.all(files.map((fileName) => (0, promises_2.unlink)(fileName).catch(noop_1.noop)));
109
+ await Promise.all(files.map((fileName) => (0, promises_1.unlink)(fileName).catch(noop_1.noop)));
110
110
  }
111
111
  }
112
112
  return {
@@ -118,7 +118,7 @@ async function forgeSchema(options) {
118
118
  }
119
119
  finally {
120
120
  if (tsconfig && tsconfigGenerated) {
121
- await (0, promises_2.unlink)(tsconfig).catch(noop_1.noop);
121
+ await (0, promises_1.unlink)(tsconfig).catch(noop_1.noop);
122
122
  }
123
123
  }
124
124
  }
@@ -127,7 +127,7 @@ async function loadJSONSchema(files) {
127
127
  }
128
128
  function loadJSONSchemaSync(files) {
129
129
  return files.map((fn) => {
130
- const content = (0, fs_1.readFileSync)(fn, { encoding: 'utf8' });
130
+ const content = (0, node_fs_1.readFileSync)(fn, { encoding: 'utf8' });
131
131
  return JSON.parse(content);
132
132
  });
133
133
  }
@@ -176,6 +176,11 @@ describe('generator for a5', () => {
176
176
  outputSchemaMetadataFile,
177
177
  expose: 'all',
178
178
  explicitPublic: true,
179
+ shrinkDefinitionNames: (definitionName) => {
180
+ if (definitionName === 'NamesType')
181
+ return 'NT';
182
+ return undefined;
183
+ },
179
184
  });
180
185
  validator = (0, validator_1.createSchemaForgeValidator)({}, true);
181
186
  const schema = await (0, generator_1.loadJSONSchema)([outputSchemaFile]);
@@ -195,7 +200,7 @@ describe('generator for a5', () => {
195
200
  'DomainNum',
196
201
  'DomainValue',
197
202
  'DomainValuesType',
198
- 'NamesType',
203
+ 'NT', // 'NamesType',
199
204
  'NamesTypeAbnormal',
200
205
  'NumN',
201
206
  'Nums',
@@ -205,7 +210,7 @@ describe('generator for a5', () => {
205
210
  'VariadicList',
206
211
  'VariadicList1',
207
212
  ]);
208
- expect(validator.getValidator('test#/definitions/NamesType').schema).toStrictEqual({
213
+ expect(validator.getValidator('test#/definitions/NT').schema).toStrictEqual({
209
214
  type: 'string',
210
215
  enum: ['v:name1', 'v:name2'],
211
216
  });
@@ -217,7 +222,7 @@ describe('generator for a5', () => {
217
222
  $ref: '#/definitions/DomainValuesType',
218
223
  },
219
224
  name0: {
220
- $ref: '#/definitions/NamesType',
225
+ $ref: '#/definitions/NT',
221
226
  },
222
227
  name1: {
223
228
  type: 'string',
@@ -51,6 +51,7 @@ export type DBEntityOptions = {
51
51
  * Use string literal to set index name.
52
52
  */
53
53
  indexes?: {
54
- [column: string]: DBIndexOptionsDef<true>;
54
+ [field: string]: DBIndexOptionsDef<true>;
55
55
  };
56
56
  };
57
+ export type DBEntityOptionsDef = DBEntityOptions | string;
package/lib/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Nullable, PRec } from '@tsofist/stem';
1
+ import { NonEmptyString, Nullable, PRec } from '@tsofist/stem';
2
2
  import { ErrorCode } from '@tsofist/stem/lib/error';
3
3
  import { ErrorObject, ErrorsTextOptions, SchemaObject, ValidateFunction } from 'ajv';
4
4
  import { SchemaForgeBaseOptions } from './generator/types';
@@ -73,6 +73,12 @@ export interface SchemaForgeOptions extends SchemaForgeBaseOptions {
73
73
  * @default false
74
74
  */
75
75
  readonly sortObjectProperties?: boolean;
76
+ /**
77
+ * If you want to shrink the schema definition names, you have to provide a replacement function.
78
+ *
79
+ * WARN: this functionality is not compatible (yet) with `encodeRefs=true` option.
80
+ */
81
+ readonly shrinkDefinitionNames?: (definitionName: string) => undefined | NonEmptyString;
76
82
  }
77
83
  export interface SchemaForgeMetadata {
78
84
  $id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsofist/schema-forge",
3
- "version": "2.4.3",
3
+ "version": "2.5.1",
4
4
  "description": "Generate JSON schema from TypeScript types",
5
5
  "author": "Andrew Berdnikov <tsofistgudmen@gmail.com>",
6
6
  "license": "LGPL-3.0",
@@ -25,6 +25,7 @@
25
25
  "ajv": "^8.17.1",
26
26
  "ajv-formats": "^3.0.1",
27
27
  "json-schema-faker": "^0.5.8",
28
+ "jsonpath-plus": "^10.3.0",
28
29
  "ts-json-schema-generator": "~2.3.0",
29
30
  "tslib": "^2.8.1"
30
31
  },