fork of hey-api/openapi-ts because I need some additional things
1import { pathToJsonPointer } from '../utils/ref';
2import type { IR } from './types';
3
4export interface SchemaProcessor {
5 /** Current inherited context (set by withContext) */
6 readonly context: {
7 readonly anchor: string | undefined;
8 readonly tags: ReadonlyArray<string> | undefined;
9 };
10 /** Check if pointer was already emitted */
11 hasEmitted: (path: ReadonlyArray<string | number>) => boolean;
12 /** Mark pointer as emitted. Returns false if already emitted. */
13 markEmitted: (path: ReadonlyArray<string | number>) => boolean;
14 /** Execute with inherited context for nested extractions */
15 withContext: <T>(ctx: { anchor?: string; tags?: ReadonlyArray<string> }, fn: () => T) => T;
16}
17
18export interface SchemaProcessorContext {
19 meta: { resource: string; resourceId: string; role?: string };
20 namingAnchor?: string;
21 path: ReadonlyArray<string | number>;
22 schema: IR.SchemaObject;
23 tags?: ReadonlyArray<string>;
24}
25
26export interface SchemaProcessorResult<
27 Context extends SchemaProcessorContext = SchemaProcessorContext,
28> {
29 process: (ctx: Context) => void;
30}
31
32export type SchemaExtractor<Context extends SchemaProcessorContext = SchemaProcessorContext> = (
33 ctx: Context,
34) => IR.SchemaObject;
35
36export function createSchemaProcessor(): SchemaProcessor {
37 const emitted = new Set<string>();
38 let contextTags: ReadonlyArray<string> | undefined;
39 let contextAnchor: string | undefined;
40
41 return {
42 get context() {
43 return {
44 anchor: contextAnchor,
45 tags: contextTags,
46 };
47 },
48 hasEmitted(path) {
49 return emitted.has(pathToJsonPointer(path));
50 },
51 markEmitted(path) {
52 const pointer = pathToJsonPointer(path);
53 if (emitted.has(pointer)) return false;
54 emitted.add(pointer);
55 return true;
56 },
57 withContext(ctx, fn) {
58 const prevTags = contextTags;
59 const prevAnchor = contextAnchor;
60 contextTags = ctx.tags;
61 contextAnchor = ctx.anchor;
62 try {
63 return fn();
64 } finally {
65 contextTags = prevTags;
66 contextAnchor = prevAnchor;
67 }
68 },
69 };
70}