diff --git a/.changeset/lazy-cows-repeat.md b/.changeset/lazy-cows-repeat.md
new file mode 100644
index 0000000..6df1863
--- /dev/null
+++ b/.changeset/lazy-cows-repeat.md
@@ -0,0 +1,5 @@
+---
+"openapi-ts-json-schema": minor
+---
+
+`metaData.schemas` entry registered by id instead of `$ref`
diff --git a/README.md b/README.md
index 75ed666..0e29e88 100644
--- a/README.md
+++ b/README.md
@@ -69,7 +69,7 @@ if (validate(data)) {
| **definitionPathsToGenerateFrom** _(required)_ | `string[]` | OpenApi definition object paths to generate the JSON schemas from. Only matching paths will be generated. Supports dot notation: `["components.schemas"]`. | - |
| **refHandling** | | | |
| **refHandling.strategy** | `"import" \| "inline" \| "keep"` | `"import"`: generate and import `$ref` schemas.
`"inline"`: inline `$ref` schemas.
`"keep"`: keep `$ref` values. | `"import"` |
-| **refHandling.refMapper** | `(input: {ref: string}) => string` | Customize generated `$ref` values (only `keep` strategy) | - |
+| **refHandling.refMapper** | `(input: {id: string}) => string` | Customize generated `$ref` values (only `keep` strategy) | - |
| **schemaPatcher** | `(params: { schema: JSONSchema }) => void` | Dynamically patch generated JSON schemas. The provided function will be invoked against every single JSON schema node. | - |
| **outputPath** | `string` | Path where the generated schemas will be saved. Defaults to `/schemas-autogenerated` in the same directory of `openApiSchema`. | - |
| **plugins** | `ReturnType[]` | A set of optional plugins to generate extra custom output. See [plugins docs](./docs/plugins.md). | - |
@@ -112,7 +112,7 @@ Beside generating the expected schema files under `outputPath`, `openapiToTsJson
metaData: {
// Meta data of the generated schemas
schemas: Map<
- // OpenAPI ref. Eg: "#/components/schemas/MySchema"
+ // Schema internal di. Eg: "/components/schemas/MySchema"
string,
{
id: string;
diff --git a/docs/developer-notes.md b/docs/developer-notes.md
index 8dd85e3..c3a75dd 100644
--- a/docs/developer-notes.md
+++ b/docs/developer-notes.md
@@ -1,5 +1,13 @@
# Developer's notes
+## Internal schema ids
+
+Each processed schemas is assigned with a unique internal id holding schema name and path information `//`.
+
+Eg: `/components/schemas/SchemaName`.
+
+Internal ids are used to refer to any specific schemas and retrieve schema path and name.
+
## Remote $ref handling
Remote/external `$ref`s (`Pet.yaml`, `definitions.json#/Pet`) get always immediately dereferenced by fetching the specs and inlining the relevant schemas.
@@ -11,34 +19,34 @@ Remote/external `$ref`s (`Pet.yaml`, `definitions.json#/Pet`) get always immedia
At the time of writing the implementation is build around `@apidevtools/json-schema-ref-parser`'s `dereference` method options and works as follows:
1. Schemas get deferenced with `@apidevtools/json-schema-ref-parser`'s `dereference` method which inlines relevant `$ref` schemas
-2. Inlined schemas get marked with a symbol property holding the original `$ref` value (`#/foo/Bar`)
+2. Inlined schemas get marked with a symbol property holding the internal schema id (`/components/schemas/Bar`)
```ts
{
bar: {
- [Symbol('ref')]: '#/components/schemas/Bar',
+ [Symbol('id')]: '/components/schemas/Bar',
// ...Inlined schema props
}
}
```
-3. Inlined and dereferenced schemas get traversed and all schemas marked with `Symbol('ref')` prop get replaced with a **string placeholder** holding the original `$ref` value. Note that string placeholders can be safely stringified.
+1. Inlined and dereferenced schemas get traversed and all schemas marked with `Symbol('id')` prop get replaced with a **string placeholder** holding the original internal schema id. Note that string placeholders can be safely stringified.
```ts
{
- bar: '_OTJS-START_#/components/schemas/Bar_OTJS-END_';
+ bar: '_OTJS-START_/components/schemas/Bar_OTJS-END_';
}
```
Note: alias definitions (eg. `Foo: "#components/schemas/Bar"`) will result in a plain **string placeholder**.
```ts
-'_OTJS-START_#/components/schemas/Bar_OTJS-END_';
+'_OTJS-START_/components/schemas/Bar_OTJS-END_';
```
-4. Inlined and dereferenced schemas get stringified and parsed to retrieve **string placeholders** and the contained original `$ref` value
+1. Inlined and dereferenced schemas get stringified and parsed to retrieve **string placeholders** and their internal id value
-5. For each **string placeholder** found, an import statement to the relevant `$ref` schema is prepended and the placeholder replaced with the imported schema name.
+2. For each **string placeholder** found, an import statement to the relevant `$ref` schema is prepended and the placeholder replaced with the imported schema name.
```ts
import Bar from '../foo/Bar';
@@ -48,8 +56,6 @@ export default {
} as const
```
-This process could be definitely shorter if `@apidevtools/json-schema-ref-parser`'s `dereference` method allowed to access the parent object holding the `$ref` value to be replaced. In that case step 2 could be skipped and the ref object could be immediately replaced with the relevant **string placeholder**.
-
## `refHandling`: keep
`keep` option was implemented as last, and it currently follows the same flow as the `import` except for point 5, where schemas with **string placeholders** are replaced with the an actual `$ref` value.
diff --git a/src/openapiToTsJsonSchema.ts b/src/openapiToTsJsonSchema.ts
index b6bfba1..704b5f9 100644
--- a/src/openapiToTsJsonSchema.ts
+++ b/src/openapiToTsJsonSchema.ts
@@ -5,14 +5,15 @@ import get from 'lodash.get';
import {
clearFolder,
makeTsJsonSchemaFiles,
- REF_SYMBOL,
+ SCHEMA_ID_SYMBOL,
convertOpenApiToJsonSchema,
convertOpenApiPathsParameters,
addSchemaToMetaData,
- pathToRef,
+ makeId,
formatTypeScript,
saveFile,
makeRelativeModulePath,
+ refToId,
} from './utils';
import type {
SchemaMetaDataMap,
@@ -82,17 +83,19 @@ export async function openapiToTsJsonSchema(
dereference: {
// @ts-expect-error onDereference seems not to be properly typed
onDereference: (ref, inlinedSchema) => {
+ const id = refToId(ref);
+
// Keep track of inlined refs
- if (!inlinedRefs.has(ref)) {
+ if (!inlinedRefs.has(id)) {
// Make a shallow copy of the ref schema to save it from the mutations below
- inlinedRefs.set(ref, { ...inlinedSchema });
+ inlinedRefs.set(id, { ...inlinedSchema });
/**
* "import" refHandling support:
- * mark inlined ref objects with a "REF_SYMBOL" to retrieve their
+ * mark inlined ref objects with a "SCHEMA_ID_SYMBOL" to retrieve their
* original $ref value once inlined
*/
- inlinedSchema[REF_SYMBOL] = ref;
+ inlinedSchema[SCHEMA_ID_SYMBOL] = id;
/**
* "inline" refHandling support:
@@ -122,9 +125,9 @@ export async function openapiToTsJsonSchema(
* $ref schemas to be generated no matter of
*/
if (refHandling.strategy === 'import' || refHandling.strategy === 'keep') {
- for (const [ref, schema] of inlinedRefs) {
+ for (const [id, schema] of inlinedRefs) {
addSchemaToMetaData({
- ref,
+ id,
schemaMetaDataMap,
schema,
outputPath,
@@ -141,17 +144,17 @@ export async function openapiToTsJsonSchema(
for (const schemaName in definitionSchemas) {
// Create expected OpenAPI ref
- const ref = pathToRef({
+ const id = makeId({
schemaRelativeDirName: definitionPath,
schemaName,
});
addSchemaToMetaData({
- ref,
+ id,
schemaMetaDataMap,
schema: definitionSchemas[schemaName],
outputPath,
- isRef: inlinedRefs.has(ref),
+ isRef: inlinedRefs.has(id),
});
}
}
diff --git a/src/plugins/fastifyIntegrationPlugin.ts b/src/plugins/fastifyIntegrationPlugin.ts
index 768b498..666c823 100644
--- a/src/plugins/fastifyIntegrationPlugin.ts
+++ b/src/plugins/fastifyIntegrationPlugin.ts
@@ -1,5 +1,4 @@
import type { Plugin } from '../types';
-import { refToId } from '../utils';
const OUTPUT_FILE_NAME = 'fastify-integration.ts';
const OPEN_API_COMPONENTS_SCHEMAS_PATH = '/components/schemas/';
@@ -19,12 +18,12 @@ const fastifyIntegrationPlugin: Plugin = ({
// Force "keep" refHandling
options.refHandling = {
strategy: 'keep',
- refMapper: ({ ref }) => {
+ refMapper: ({ id }) => {
/**
* Replace original $ref values with internal schema id which
* the schema is registered with via Fastify's `addSchema`
*/
- return refToId(ref);
+ return id;
},
};
},
diff --git a/src/types.ts b/src/types.ts
index 498ae2a..da57a9e 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -6,7 +6,7 @@ export type SchemaPatcher = (params: { schema: JSONSchema }) => void;
export type RefHandling =
| { strategy: 'import' }
| { strategy: 'inline' }
- | { strategy: 'keep'; refMapper?: (input: { ref: string }) => string };
+ | { strategy: 'keep'; refMapper?: (input: { id: string }) => string };
import type {
makeRelativeModulePath,
diff --git a/src/utils/addSchemaToMetaData.ts b/src/utils/addSchemaToMetaData.ts
index a9208fd..f1b0b62 100644
--- a/src/utils/addSchemaToMetaData.ts
+++ b/src/utils/addSchemaToMetaData.ts
@@ -1,37 +1,36 @@
import path from 'node:path';
// @ts-expect-error no type defs for namify
import namify from 'namify';
-import { parseRef, refToPath, filenamify, refToId } from '.';
+import { filenamify, parseId } from '.';
import type { SchemaMetaDataMap, SchemaMetaData, JSONSchema } from '../types';
/*
* Just an utility function to add entries to SchemaMetaDataMap Map keyed by ref
*/
export function addSchemaToMetaData({
- ref,
+ id,
schemaMetaDataMap,
schema,
isRef,
// Options
outputPath,
}: {
- ref: string;
+ id: string;
schemaMetaDataMap: SchemaMetaDataMap;
schema: JSONSchema;
isRef: boolean;
outputPath: string;
}): void {
// Do not override existing meta info of inlined schemas
- if (!schemaMetaDataMap.has(ref)) {
- const refPath = parseRef(ref);
- const { schemaRelativeDirName, schemaName } = refToPath(ref);
+ if (!schemaMetaDataMap.has(id)) {
+ const { schemaRelativeDirName, schemaName } = parseId(id);
const absoluteDirName = path.join(outputPath, schemaRelativeDirName);
const schemaFileName = filenamify(schemaName);
const absoluteImportPath = path.join(absoluteDirName, schemaFileName);
const metaInfo: SchemaMetaData = {
- id: refToId(ref),
- uniqueName: namify(refPath),
+ id,
+ uniqueName: namify(id),
isRef,
originalSchema: schema,
@@ -40,6 +39,6 @@ export function addSchemaToMetaData({
absolutePath: absoluteImportPath + '.ts',
};
- schemaMetaDataMap.set(ref, metaInfo);
+ schemaMetaDataMap.set(id, metaInfo);
}
}
diff --git a/src/utils/index.ts b/src/utils/index.ts
index faa14be..dd65883 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -3,14 +3,13 @@ export { makeTsJsonSchema } from './makeTsJsonSchema';
export { convertOpenApiPathsParameters } from './convertOpenApiPathsParameters';
export { convertOpenApiToJsonSchema } from './convertOpenApiToJsonSchema';
export { makeTsJsonSchemaFiles } from './makeTsJsonSchemaFiles';
-export { parseRef } from './parseRef';
-export { refToPath } from './refToPath';
+export { parseId } from './parseId';
export { refToId } from './refToId';
-export { pathToRef } from './pathToRef';
+export { makeId } from './makeId';
export {
- REF_SYMBOL,
+ SCHEMA_ID_SYMBOL,
PLACEHOLDER_REGEX,
- refToPlaceholder,
+ idToPlaceholder,
} from './refReplacementUtils';
export { replaceInlinedRefsWithStringPlaceholder } from './makeTsJsonSchema/replaceInlinedRefsWithStringPlaceholder';
export { replacePlaceholdersWithImportedSchemas } from './makeTsJsonSchema/replacePlaceholdersWithImportedSchemas';
diff --git a/src/utils/pathToRef.ts b/src/utils/makeId.ts
similarity index 75%
rename from src/utils/pathToRef.ts
rename to src/utils/makeId.ts
index bdd4248..3e122d4 100644
--- a/src/utils/pathToRef.ts
+++ b/src/utils/makeId.ts
@@ -1,11 +1,11 @@
import path from 'node:path';
-import { filenamify } from './';
+import { filenamify } from '.';
/**
- * Generate a local OpenAPI ref from a relative path and a schema name
+ * Generate a local OpenAPI ref from a schema internal id
*/
const TRALING_SLASH_REGEX = /\/$/;
-export function pathToRef({
+export function makeId({
schemaRelativeDirName,
schemaName,
}: {
@@ -13,7 +13,7 @@ export function pathToRef({
schemaName: string;
}): string {
return (
- '#/' +
+ '/' +
path
.normalize(schemaRelativeDirName)
// Supporting definitionPathsToGenerateFrom dot notation
diff --git a/src/utils/makeTsJsonSchema/getId.ts b/src/utils/makeTsJsonSchema/getId.ts
new file mode 100644
index 0000000..a64736a
--- /dev/null
+++ b/src/utils/makeTsJsonSchema/getId.ts
@@ -0,0 +1,15 @@
+import { SCHEMA_ID_SYMBOL, isObject } from '..';
+
+/**
+ * Retrieve SCHEMA_ID_SYMBOL prop value
+ */
+export function getId(node: unknown): string | undefined {
+ if (
+ isObject(node) &&
+ SCHEMA_ID_SYMBOL in node &&
+ typeof node[SCHEMA_ID_SYMBOL] === 'string'
+ ) {
+ return node[SCHEMA_ID_SYMBOL];
+ }
+ return undefined;
+}
diff --git a/src/utils/makeTsJsonSchema/getRef.ts b/src/utils/makeTsJsonSchema/getRef.ts
deleted file mode 100644
index 67d45c5..0000000
--- a/src/utils/makeTsJsonSchema/getRef.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { REF_SYMBOL } from '..';
-import { isObject } from '../';
-
-/**
- * Retrieve REF_SYMBOL prop value
- */
-export function getRef(node: unknown): string | undefined {
- if (
- isObject(node) &&
- REF_SYMBOL in node &&
- typeof node[REF_SYMBOL] === 'string'
- ) {
- return node[REF_SYMBOL];
- }
- return undefined;
-}
diff --git a/src/utils/makeTsJsonSchema/makeCircularRefReplacer.ts b/src/utils/makeTsJsonSchema/makeCircularRefReplacer.ts
index a26c5d5..e0f16b7 100644
--- a/src/utils/makeTsJsonSchema/makeCircularRefReplacer.ts
+++ b/src/utils/makeTsJsonSchema/makeCircularRefReplacer.ts
@@ -1,4 +1,4 @@
-import { getRef } from './getRef';
+import { getId } from './getId';
/**
* JSON.stringify replacer
@@ -23,13 +23,13 @@ export function makeCircularRefReplacer(): (
// @NOTE Should we make recursion depth configurable?
if (ancestors.includes(value)) {
- const ref = getRef(value);
+ const id = getId(value);
return {
// Drop an inline comment about recursion interruption
[Symbol.for('before')]: [
{
type: 'LineComment',
- value: ` Circular recursion interrupted (${ref})`,
+ value: ` Circular recursion interrupted. Schema id: "${id}"`,
},
],
};
diff --git a/src/utils/makeTsJsonSchema/replaceInlinedRefsWithStringPlaceholder.ts b/src/utils/makeTsJsonSchema/replaceInlinedRefsWithStringPlaceholder.ts
index 50435b4..6114ab9 100644
--- a/src/utils/makeTsJsonSchema/replaceInlinedRefsWithStringPlaceholder.ts
+++ b/src/utils/makeTsJsonSchema/replaceInlinedRefsWithStringPlaceholder.ts
@@ -1,32 +1,32 @@
import mapObject from 'map-obj';
-import { refToPlaceholder } from '..';
-import { getRef } from './getRef';
+import { idToPlaceholder } from '..';
+import { getId } from './getId';
import type { JSONSchema, JSONSchemaWithPlaceholders } from '../../types';
/**
* Get any JSON schema node and:
- * - Return ref placeholder is the entity is an inlined ref schema objects (with REF_SYMBOL prop)
+ * - Return ref placeholder is the entity is an inlined ref schema objects (with SCHEMA_ID_SYMBOL prop)
* - Return provided node in all other cases
*/
function replaceInlinedSchemaWithPlaceholder(
node: Node,
): Node | string {
- const ref = getRef(node);
- if (ref === undefined) {
+ const id = getId(node);
+ if (id === undefined) {
return node;
}
- return refToPlaceholder(ref);
+ return idToPlaceholder(id);
}
/**
* Iterate a JSON schema to replace inlined ref schema objects
- * (marked with a REF_SYMBOL property holding the original $ref value)
- * with a string placeholder with a reference to the original $ref value ("_OTJS-START_#/ref/value_OTJS-END_")
+ * (marked with a SCHEMA_ID_SYMBOL property holding the original $ref value)
+ * with a string placeholder with a reference to the original $ref value ("_OTJS-START_/id/value_OTJS-END_")
*/
export function replaceInlinedRefsWithStringPlaceholder(
schema: JSONSchema,
): JSONSchemaWithPlaceholders {
- if (getRef(schema)) {
+ if (getId(schema)) {
return replaceInlinedSchemaWithPlaceholder(schema);
}
diff --git a/src/utils/makeTsJsonSchema/replacePlaceholdersWithImportedSchemas.ts b/src/utils/makeTsJsonSchema/replacePlaceholdersWithImportedSchemas.ts
index 267680e..c48dcfc 100644
--- a/src/utils/makeTsJsonSchema/replacePlaceholdersWithImportedSchemas.ts
+++ b/src/utils/makeTsJsonSchema/replacePlaceholdersWithImportedSchemas.ts
@@ -16,8 +16,8 @@ export function replacePlaceholdersWithImportedSchemas({
const importStatements = new Set();
// Replace placeholder occurrences with the relevant imported schema name
- let schema = schemaAsText.replaceAll(PLACEHOLDER_REGEX, (_match, ref) => {
- const importedSchema = schemaMetaDataMap.get(ref);
+ let schema = schemaAsText.replaceAll(PLACEHOLDER_REGEX, (_match, id) => {
+ const importedSchema = schemaMetaDataMap.get(id);
/* c8 ignore start */
if (!importedSchema) {
diff --git a/src/utils/makeTsJsonSchema/replacePlaceholdersWithRefs.ts b/src/utils/makeTsJsonSchema/replacePlaceholdersWithRefs.ts
index 7603149..263760a 100644
--- a/src/utils/makeTsJsonSchema/replacePlaceholdersWithRefs.ts
+++ b/src/utils/makeTsJsonSchema/replacePlaceholdersWithRefs.ts
@@ -5,14 +5,14 @@ import { PLACEHOLDER_REGEX } from '..';
*/
export function replacePlaceholdersWithRefs({
schemaAsText,
- refMapper = ({ ref }) => ref,
+ refMapper = ({ id }) => `#${id}`,
}: {
schemaAsText: string;
- refMapper?: (input: { ref: string }) => string;
+ refMapper?: (input: { id: string }) => string;
}): string {
// Replace placeholder occurrences with a JSON schema $ref object
- let schema = schemaAsText.replaceAll(PLACEHOLDER_REGEX, (_match, ref) => {
- return `{ $ref: "${refMapper({ ref })}" }`;
+ let schema = schemaAsText.replaceAll(PLACEHOLDER_REGEX, (_match, id) => {
+ return `{ $ref: "${refMapper({ id })}" }`;
});
return schema;
diff --git a/src/utils/parseId.ts b/src/utils/parseId.ts
new file mode 100644
index 0000000..dc6bd30
--- /dev/null
+++ b/src/utils/parseId.ts
@@ -0,0 +1,21 @@
+import path from 'node:path';
+
+/**
+ * Parses internal schema ids (/components/schema/Foo) to the derive the expected schema output path
+ * this library saves generated JSON schemas to (...outputPath/components.schema/Foo)
+ */
+export function parseId(id: string): {
+ schemaRelativeDirName: string;
+ schemaName: string;
+} {
+ if (!id.startsWith('/')) {
+ throw new Error(`[openapi-ts-json-schema] Unsupported id value: "${id}"`);
+ }
+
+ const idPath = id.replace('/', '');
+
+ return {
+ schemaRelativeDirName: path.dirname(idPath),
+ schemaName: path.basename(idPath),
+ };
+}
diff --git a/src/utils/parseRef.ts b/src/utils/parseRef.ts
deleted file mode 100644
index 2fdf9cb..0000000
--- a/src/utils/parseRef.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * Parses OpenApi ref:
- * "#/components/schema/Foo" --> "components/schema/Foo"
- */
-export function parseRef(ref: string): string {
- if (!ref.startsWith('#/')) {
- throw new Error(`[openapi-ts-json-schema] Unsupported ref value: "${ref}"`);
- }
-
- const refPath = ref.replace('#/', '');
- return refPath;
-}
diff --git a/src/utils/refReplacementUtils.ts b/src/utils/refReplacementUtils.ts
index df4e6ca..c490385 100644
--- a/src/utils/refReplacementUtils.ts
+++ b/src/utils/refReplacementUtils.ts
@@ -1,16 +1,16 @@
-export const REF_SYMBOL = Symbol('ref');
+export const SCHEMA_ID_SYMBOL = Symbol('id');
-const REF_MARKER_START = '_OTJS-START_';
-const REF_MARKER_END = '_OTJS-END_';
+const SCHEMA_ID_MARKER_START = '_OTJS-START_';
+const SCHEMA_ID_MARKER_END = '_OTJS-END_';
export const PLACEHOLDER_REGEX = new RegExp(
- `["']${REF_MARKER_START}(?[.+)${REF_MARKER_END}["']`,
+ `["']${SCHEMA_ID_MARKER_START}(?.+)${SCHEMA_ID_MARKER_END}["']`,
'g',
);
/**
- * Generate a string placeholder containing the ref value to be retrieved later
+ * Generate a string placeholder containing the internal schema id value to be retrieved later
*/
-export function refToPlaceholder(ref: string): string {
- return REF_MARKER_START + ref + REF_MARKER_END;
+export function idToPlaceholder(id: string): string {
+ return SCHEMA_ID_MARKER_START + id + SCHEMA_ID_MARKER_END;
}
diff --git a/src/utils/refToId.ts b/src/utils/refToId.ts
index dedc401..558a149 100644
--- a/src/utils/refToId.ts
+++ b/src/utils/refToId.ts
@@ -1,4 +1,15 @@
-import { parseRef } from '.';
+/**
+ * Parses OpenApi ref:
+ * "#/components/schema/Foo" --> "components/schema/Foo"
+ */
+function parseRef(ref: string): string {
+ if (!ref.startsWith('#/')) {
+ throw new Error(`[openapi-ts-json-schema] Unsupported ref value: "${ref}"`);
+ }
+
+ const refPath = ref.replace('#/', '');
+ return refPath;
+}
/**
* Generate an internal schema ID from a given schema ref:
diff --git a/src/utils/refToPath.ts b/src/utils/refToPath.ts
deleted file mode 100644
index bbe1b4e..0000000
--- a/src/utils/refToPath.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import path from 'node:path';
-import { parseRef } from '.';
-
-/**
- * Parses OpenAPI local refs (#/components/schema/Foo) to the derive the expected schema output path
- * this library saves generated JSON schemas to (...outputPath/components.schema/Foo)
- *
- * @NOTE Remote and url refs should have been already resolved and inlined
- */
-export function refToPath(ref: string): {
- schemaRelativeDirName: string;
- schemaName: string;
-} {
- const refPath = parseRef(ref);
- return {
- schemaRelativeDirName: path.dirname(refPath),
- schemaName: path.basename(refPath),
- };
-}
diff --git a/test/circularReference.test.ts b/test/circularReference.test.ts
index d5d3076..0cc7b3b 100644
--- a/test/circularReference.test.ts
+++ b/test/circularReference.test.ts
@@ -62,13 +62,13 @@ describe('Circular reference', () => {
const expectedInlinedRef = `
nextMonth: {
- // Circular recursion interrupted (#/components/schemas/February)
+ // Circular recursion interrupted. Schema id: "/components/schemas/February"
},
nextMonthTwo: {
- // Circular recursion interrupted (#/components/schemas/February)
+ // Circular recursion interrupted. Schema id: "/components/schemas/February"
},
nextMonthThree: {
- // Circular recursion interrupted (#/components/schemas/February)
+ // Circular recursion interrupted. Schema id: "/components/schemas/February"
},`;
expect(februarySchemaAsText).toEqual(
diff --git a/test/metaData.test.ts b/test/metaData.test.ts
index 656c89e..80506dc 100644
--- a/test/metaData.test.ts
+++ b/test/metaData.test.ts
@@ -15,10 +15,8 @@ describe('Returned "metaData"', async () => {
silent: true,
});
- const answerMetaData = metaData.schemas.get('#/components/schemas/Answer');
- const januaryMetaData = metaData.schemas.get(
- '#/components/schemas/January',
- );
+ const answerMetaData = metaData.schemas.get('/components/schemas/Answer');
+ const januaryMetaData = metaData.schemas.get('/components/schemas/January');
expect(answerMetaData).toBeDefined();
expect(januaryMetaData).toBeDefined();
diff --git a/test/refHandling-keep.test.ts b/test/refHandling-keep.test.ts
index 94bd30c..241969a 100644
--- a/test/refHandling-keep.test.ts
+++ b/test/refHandling-keep.test.ts
@@ -155,7 +155,7 @@ describe('refHandling option === "keep"', () => {
silent: true,
refHandling: {
strategy: 'keep',
- refMapper: ({ ref }) => `foo_${ref}_bar`,
+ refMapper: ({ id }) => `foo_#${id}_bar`,
},
});
diff --git a/test/unit/addSchemaToMetaData.test.ts b/test/unit/addSchemaToMetaData.test.ts
index 800ee39..f37ecd7 100644
--- a/test/unit/addSchemaToMetaData.test.ts
+++ b/test/unit/addSchemaToMetaData.test.ts
@@ -5,7 +5,7 @@ import type { SchemaMetaData } from '../../src/types';
describe('addSchemaToMetaData', () => {
it('generates expected metadata', () => {
- const ref = '#/components/schemas/Foo';
+ const id = '/components/schemas/Foo';
const schemaMetaDataMap = new Map();
const outputPath = path.normalize('/absolute/output/path');
const schema = {
@@ -16,14 +16,14 @@ describe('addSchemaToMetaData', () => {
};
addSchemaToMetaData({
- ref,
+ id,
schemaMetaDataMap,
schema,
outputPath,
isRef: true,
});
- const actual = schemaMetaDataMap.get(ref);
+ const actual = schemaMetaDataMap.get(id);
const expected: SchemaMetaData = {
id: '/components/schemas/Foo',
uniqueName: 'componentsSchemasFoo',
diff --git a/test/unit/pathToRef.test.ts b/test/unit/makeId.test.ts
similarity index 66%
rename from test/unit/pathToRef.test.ts
rename to test/unit/makeId.test.ts
index 93859fe..9d5842a 100644
--- a/test/unit/pathToRef.test.ts
+++ b/test/unit/makeId.test.ts
@@ -1,38 +1,38 @@
import { describe, it, expect } from 'vitest';
-import { pathToRef } from '../../src/utils';
+import { makeId } from '../../src/utils';
-describe('pathToRef', () => {
+describe('makeId', () => {
it.each([
{
schemaRelativeDirName: 'components/schemas',
schemaName: 'Foo',
- expected: '#/components/schemas/Foo',
+ expected: '/components/schemas/Foo',
},
{
schemaRelativeDirName: 'components/schemas/',
schemaName: 'Foo',
- expected: '#/components/schemas/Foo',
+ expected: '/components/schemas/Foo',
},
{
schemaRelativeDirName: 'components.schemas',
schemaName: 'Foo',
- expected: '#/components/schemas/Foo',
+ expected: '/components/schemas/Foo',
},
// Windows path separators
{
schemaRelativeDirName: 'components\\schemas',
schemaName: 'Foo',
- expected: '#/components/schemas/Foo',
+ expected: '/components/schemas/Foo',
},
{
schemaRelativeDirName: 'components\\schemas\\',
schemaName: 'Foo',
- expected: '#/components/schemas/Foo',
+ expected: '/components/schemas/Foo',
},
])(
- 'generates expected ref',
+ 'generates expected internal id',
({ schemaRelativeDirName, schemaName, expected }) => {
- const actual = pathToRef({
+ const actual = makeId({
schemaRelativeDirName,
schemaName,
});
diff --git a/test/unit/parseId.test.ts b/test/unit/parseId.test.ts
new file mode 100644
index 0000000..df5f7d7
--- /dev/null
+++ b/test/unit/parseId.test.ts
@@ -0,0 +1,25 @@
+import { describe, it, expect } from 'vitest';
+import { parseId } from '../../src/utils';
+
+describe('parseId', () => {
+ describe('Valid id', () => {
+ it('returns, ref path', () => {
+ const actual = parseId('/components/schemas/Foo');
+ const expected = {
+ schemaRelativeDirName: 'components/schemas',
+ schemaName: 'Foo',
+ };
+ expect(actual).toEqual(expected);
+ });
+ });
+
+ describe('Invalid id', () => {
+ it('throws error', () => {
+ expect(() => parseId('#/components/schemas/Foo')).toThrow(
+ new Error(
+ `[openapi-ts-json-schema] Unsupported id value: "#/components/schemas/Foo"`,
+ ),
+ );
+ });
+ });
+});
diff --git a/test/unit/parseRef.test.ts b/test/unit/refToId.test.ts
similarity index 60%
rename from test/unit/parseRef.test.ts
rename to test/unit/refToId.test.ts
index c041892..6675c2f 100644
--- a/test/unit/parseRef.test.ts
+++ b/test/unit/refToId.test.ts
@@ -1,18 +1,18 @@
import { describe, it, expect } from 'vitest';
-import { parseRef } from '../../src/utils';
+import { refToId } from '../../src/utils';
-describe('parseRef', () => {
+describe('refToId', () => {
describe('Valid ref', () => {
it('returns, ref path', () => {
- const actual = parseRef('#/components/schemas/Foo');
- const expected = 'components/schemas/Foo';
+ const actual = refToId('#/components/schemas/Foo');
+ const expected = '/components/schemas/Foo';
expect(actual).toBe(expected);
});
});
describe('Invalid ref', () => {
it('throws error', () => {
- expect(() => parseRef('/components/schemas/Foo')).toThrow(
+ expect(() => refToId('/components/schemas/Foo')).toThrow(
new Error(
`[openapi-ts-json-schema] Unsupported ref value: "/components/schemas/Foo"`,
),
diff --git a/test/unit/refToPath.test.ts b/test/unit/refToPath.test.ts
deleted file mode 100644
index cc1f6f7..0000000
--- a/test/unit/refToPath.test.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { describe, it, expect } from 'vitest';
-import { refToPath } from '../../src/utils';
-
-describe('refToPath', () => {
- it('generates expected ref paths', () => {
- const actual = refToPath('#/components/schema/Foo');
- const expected = {
- schemaRelativeDirName: 'components/schema',
- schemaName: 'Foo',
- };
-
- expect(actual).toEqual(expected);
- });
-});
diff --git a/test/unit/replaceInlinedRefsWithStringPlaceholder.test.ts b/test/unit/replaceInlinedRefsWithStringPlaceholder.test.ts
index e25090d..4aa8977 100644
--- a/test/unit/replaceInlinedRefsWithStringPlaceholder.test.ts
+++ b/test/unit/replaceInlinedRefsWithStringPlaceholder.test.ts
@@ -1,21 +1,21 @@
import { describe, it, expect } from 'vitest';
import {
replaceInlinedRefsWithStringPlaceholder,
- REF_SYMBOL,
+ SCHEMA_ID_SYMBOL,
} from '../../src/utils';
describe('replaceInlinedRefsWithStringPlaceholder', () => {
- describe('nested object market with REF_SYMBOL', () => {
+ describe('nested object market with SCHEMA_ID_SYMBOL', () => {
it('replaces objects with expected string placeholder', () => {
const actual = replaceInlinedRefsWithStringPlaceholder({
schemas: {
object: {
foo: 'bar',
- [REF_SYMBOL]: '#/ref/in/object',
+ [SCHEMA_ID_SYMBOL]: '/ref/in/object',
},
array: [
'foo',
- { hello: 'world', [REF_SYMBOL]: '#/ref/in/array' },
+ { hello: 'world', [SCHEMA_ID_SYMBOL]: '/ref/in/array' },
'bar',
],
},
@@ -23,8 +23,8 @@ describe('replaceInlinedRefsWithStringPlaceholder', () => {
const expected = {
schemas: {
- object: '_OTJS-START_#/ref/in/object_OTJS-END_',
- array: ['foo', '_OTJS-START_#/ref/in/array_OTJS-END_', 'bar'],
+ object: '_OTJS-START_/ref/in/object_OTJS-END_',
+ array: ['foo', '_OTJS-START_/ref/in/array_OTJS-END_', 'bar'],
},
};
@@ -32,14 +32,14 @@ describe('replaceInlinedRefsWithStringPlaceholder', () => {
});
});
- describe('root object market with REF_SYMBOL (alias definitions)', () => {
+ describe('root object market with SCHEMA_ID_SYMBOL (alias definitions)', () => {
it('replaces object with expected string placeholder', () => {
- // @ts-expect-error REF_SYMBOL is not a valid JSON schema prop
+ // @ts-expect-error SCHEMA_ID_SYMBOL is not a valid JSON schema prop
const actual = replaceInlinedRefsWithStringPlaceholder({
type: 'object',
- [REF_SYMBOL]: '#/ref/in/root/object',
+ [SCHEMA_ID_SYMBOL]: '/ref/in/root/object',
});
- const expected = '_OTJS-START_#/ref/in/root/object_OTJS-END_';
+ const expected = '_OTJS-START_/ref/in/root/object_OTJS-END_';
expect(actual).toEqual(expected);
});
]