@sdk-it/core 0.21.0 → 0.22.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.
@@ -0,0 +1,293 @@
1
+ import { strict as assert } from "node:assert";
2
+ import { describe, it } from "node:test";
3
+ import ts from "typescript";
4
+ import { isInterfaceType } from "./program.js";
5
+ describe("isInterfaceType Helper Function - Error-First Testing", () => {
6
+ describe("Error Cases and Invalid Inputs", () => {
7
+ it("throws TypeError when type.symbol is undefined", () => {
8
+ const mockType = {
9
+ isClassOrInterface: () => true,
10
+ symbol: void 0
11
+ };
12
+ assert.throws(
13
+ () => {
14
+ isInterfaceType(mockType);
15
+ },
16
+ TypeError,
17
+ "Should throw TypeError when accessing flags on undefined symbol"
18
+ );
19
+ });
20
+ it("throws TypeError when type.symbol is null", () => {
21
+ const mockType = {
22
+ isClassOrInterface: () => true,
23
+ symbol: null
24
+ };
25
+ assert.throws(
26
+ () => {
27
+ isInterfaceType(mockType);
28
+ },
29
+ TypeError,
30
+ "Should throw TypeError when accessing flags on null symbol"
31
+ );
32
+ });
33
+ it("handles malformed type object missing isClassOrInterface method", () => {
34
+ const mockType = {
35
+ // Missing isClassOrInterface method
36
+ symbol: {
37
+ flags: ts.SymbolFlags.Interface
38
+ }
39
+ };
40
+ assert.throws(
41
+ () => {
42
+ isInterfaceType(mockType);
43
+ },
44
+ TypeError,
45
+ "Should throw when isClassOrInterface is not a function"
46
+ );
47
+ });
48
+ it("handles type with symbol missing flags property", () => {
49
+ const mockType = {
50
+ isClassOrInterface: () => true,
51
+ symbol: {}
52
+ // Missing flags property
53
+ };
54
+ const result = isInterfaceType(mockType);
55
+ assert.strictEqual(
56
+ result,
57
+ false,
58
+ "Should return false when flags property is missing"
59
+ );
60
+ });
61
+ it("handles type with symbol having non-numeric flags", () => {
62
+ const mockType = {
63
+ isClassOrInterface: () => true,
64
+ symbol: {
65
+ flags: "invalid"
66
+ }
67
+ };
68
+ const result = isInterfaceType(mockType);
69
+ assert.strictEqual(
70
+ result,
71
+ false,
72
+ "Should return false when flags is not a number"
73
+ );
74
+ });
75
+ });
76
+ describe("System Invariants", () => {
77
+ it("INVARIANT: Interface flag must be present for true result", () => {
78
+ const interfaceType = {
79
+ isClassOrInterface: () => true,
80
+ symbol: {
81
+ flags: ts.SymbolFlags.Interface
82
+ }
83
+ };
84
+ const result = isInterfaceType(interfaceType);
85
+ assert.strictEqual(
86
+ result,
87
+ true,
88
+ "INVARIANT VIOLATED: Interface flag present but function returned false"
89
+ );
90
+ });
91
+ it("INVARIANT: Non-interface flags must result in false", () => {
92
+ const nonInterfaceFlags = [
93
+ ts.SymbolFlags.Class,
94
+ ts.SymbolFlags.Function,
95
+ ts.SymbolFlags.Variable,
96
+ ts.SymbolFlags.Property,
97
+ ts.SymbolFlags.Enum,
98
+ ts.SymbolFlags.Module,
99
+ ts.SymbolFlags.Namespace,
100
+ ts.SymbolFlags.Type,
101
+ ts.SymbolFlags.Alias,
102
+ ts.SymbolFlags.None
103
+ ];
104
+ nonInterfaceFlags.forEach((flag) => {
105
+ const mockType = {
106
+ isClassOrInterface: () => true,
107
+ symbol: {
108
+ flags: flag
109
+ }
110
+ };
111
+ const result = isInterfaceType(mockType);
112
+ assert.strictEqual(
113
+ result,
114
+ false,
115
+ `INVARIANT VIOLATED: Non-interface flag ${ts.SymbolFlags[flag]} (${flag}) returned true`
116
+ );
117
+ });
118
+ });
119
+ it("INVARIANT: isClassOrInterface() false must always result in false", () => {
120
+ const mockType = {
121
+ isClassOrInterface: () => false,
122
+ symbol: {
123
+ flags: ts.SymbolFlags.Interface
124
+ }
125
+ };
126
+ const result = isInterfaceType(mockType);
127
+ assert.strictEqual(
128
+ result,
129
+ false,
130
+ "INVARIANT VIOLATED: isClassOrInterface() false should always result in false"
131
+ );
132
+ });
133
+ });
134
+ describe("Complex Flag Combinations", () => {
135
+ it("correctly handles combined flags including Interface", () => {
136
+ const combinedFlags = [
137
+ ts.SymbolFlags.Interface | ts.SymbolFlags.Type,
138
+ ts.SymbolFlags.Interface | ts.SymbolFlags.Alias,
139
+ ts.SymbolFlags.Interface | ts.SymbolFlags.Class,
140
+ // Edge case
141
+ ts.SymbolFlags.Interface | ts.SymbolFlags.Function
142
+ ];
143
+ combinedFlags.forEach((flags, index) => {
144
+ const mockType = {
145
+ isClassOrInterface: () => true,
146
+ symbol: { flags }
147
+ };
148
+ const result = isInterfaceType(mockType);
149
+ assert.strictEqual(
150
+ result,
151
+ true,
152
+ `Combined flags case ${index + 1}: Interface flag present, should return true`
153
+ );
154
+ });
155
+ });
156
+ it("correctly handles combined flags excluding Interface", () => {
157
+ const combinedFlagsNoInterface = [
158
+ ts.SymbolFlags.Class | ts.SymbolFlags.Type,
159
+ ts.SymbolFlags.Function | ts.SymbolFlags.Variable,
160
+ ts.SymbolFlags.Enum | ts.SymbolFlags.Module,
161
+ ts.SymbolFlags.Alias | ts.SymbolFlags.Namespace
162
+ ];
163
+ combinedFlagsNoInterface.forEach((flags, index) => {
164
+ const mockType = {
165
+ isClassOrInterface: () => true,
166
+ symbol: { flags }
167
+ };
168
+ const result = isInterfaceType(mockType);
169
+ assert.strictEqual(
170
+ result,
171
+ false,
172
+ `Combined flags case ${index + 1}: No Interface flag, should return false`
173
+ );
174
+ });
175
+ });
176
+ it("handles edge case with maximum flag value", () => {
177
+ const mockType = {
178
+ isClassOrInterface: () => true,
179
+ symbol: {
180
+ flags: Number.MAX_SAFE_INTEGER
181
+ }
182
+ };
183
+ const hasInterfaceFlag = (Number.MAX_SAFE_INTEGER & ts.SymbolFlags.Interface) !== 0;
184
+ const result = isInterfaceType(mockType);
185
+ assert.strictEqual(
186
+ result,
187
+ hasInterfaceFlag,
188
+ "Edge case with maximum flag value should follow bitwise logic"
189
+ );
190
+ });
191
+ it("handles zero flags correctly", () => {
192
+ const mockType = {
193
+ isClassOrInterface: () => true,
194
+ symbol: {
195
+ flags: 0
196
+ }
197
+ };
198
+ const result = isInterfaceType(mockType);
199
+ assert.strictEqual(result, false, "Zero flags should result in false");
200
+ });
201
+ });
202
+ describe("Boundary Conditions", () => {
203
+ it("tests exact Interface flag value", () => {
204
+ const mockType = {
205
+ isClassOrInterface: () => true,
206
+ symbol: {
207
+ flags: ts.SymbolFlags.Interface
208
+ }
209
+ };
210
+ const result = isInterfaceType(mockType);
211
+ assert.strictEqual(
212
+ result,
213
+ true,
214
+ "Exact Interface flag should return true"
215
+ );
216
+ });
217
+ it("tests Interface flag minus one", () => {
218
+ const mockType = {
219
+ isClassOrInterface: () => true,
220
+ symbol: {
221
+ flags: ts.SymbolFlags.Interface - 1
222
+ }
223
+ };
224
+ const result = isInterfaceType(mockType);
225
+ assert.strictEqual(
226
+ result,
227
+ false,
228
+ "Interface flag minus one should not match"
229
+ );
230
+ });
231
+ it("tests Interface flag plus one", () => {
232
+ const flagValue = ts.SymbolFlags.Interface + 1;
233
+ const mockType = {
234
+ isClassOrInterface: () => true,
235
+ symbol: {
236
+ flags: flagValue
237
+ }
238
+ };
239
+ const hasInterfaceFlag = (flagValue & ts.SymbolFlags.Interface) !== 0;
240
+ const result = isInterfaceType(mockType);
241
+ assert.strictEqual(
242
+ result,
243
+ hasInterfaceFlag,
244
+ "Interface flag plus one should follow bitwise logic"
245
+ );
246
+ });
247
+ });
248
+ describe("Happy Path Scenarios", () => {
249
+ it("correctly identifies interface types", () => {
250
+ const mockType = {
251
+ isClassOrInterface: () => true,
252
+ symbol: {
253
+ flags: ts.SymbolFlags.Interface
254
+ }
255
+ };
256
+ const result = isInterfaceType(mockType);
257
+ assert.strictEqual(
258
+ result,
259
+ true,
260
+ "Should correctly identify interface types"
261
+ );
262
+ });
263
+ it("correctly rejects class types", () => {
264
+ const mockType = {
265
+ isClassOrInterface: () => true,
266
+ symbol: {
267
+ flags: ts.SymbolFlags.Class
268
+ }
269
+ };
270
+ const result = isInterfaceType(mockType);
271
+ assert.strictEqual(
272
+ result,
273
+ false,
274
+ "Should correctly reject class types"
275
+ );
276
+ });
277
+ it("correctly rejects primitive types", () => {
278
+ const mockType = {
279
+ isClassOrInterface: () => false,
280
+ symbol: {
281
+ flags: ts.SymbolFlags.None
282
+ }
283
+ };
284
+ const result = isInterfaceType(mockType);
285
+ assert.strictEqual(
286
+ result,
287
+ false,
288
+ "Should correctly reject primitive types"
289
+ );
290
+ });
291
+ });
292
+ });
293
+ //# sourceMappingURL=program.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/program.test.ts"],
4
+ "sourcesContent": ["import { strict as assert } from 'node:assert';\nimport { describe, it } from 'node:test';\nimport ts from 'typescript';\nimport { isInterfaceType } from './program.js';\n\ndescribe('isInterfaceType Helper Function - Error-First Testing', () => {\n // Phase 1: Error-First Testing - Attack Before You Defend\n describe('Error Cases and Invalid Inputs', () => {\n it('throws TypeError when type.symbol is undefined', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: undefined,\n } as unknown as ts.Type;\n\n assert.throws(\n () => {\n isInterfaceType(mockType);\n },\n TypeError,\n 'Should throw TypeError when accessing flags on undefined symbol',\n );\n });\n\n it('throws TypeError when type.symbol is null', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: null,\n } as unknown as ts.Type;\n\n assert.throws(\n () => {\n isInterfaceType(mockType);\n },\n TypeError,\n 'Should throw TypeError when accessing flags on null symbol',\n );\n });\n\n it('handles malformed type object missing isClassOrInterface method', () => {\n const mockType = {\n // Missing isClassOrInterface method\n symbol: {\n flags: ts.SymbolFlags.Interface,\n },\n } as unknown as ts.Type;\n\n assert.throws(\n () => {\n isInterfaceType(mockType);\n },\n TypeError,\n 'Should throw when isClassOrInterface is not a function',\n );\n });\n\n it('handles type with symbol missing flags property', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {}, // Missing flags property\n } as unknown as ts.Type;\n\n // Should default to falsy flags (undefined & Interface === 0)\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n false,\n 'Should return false when flags property is missing',\n );\n });\n\n it('handles type with symbol having non-numeric flags', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: 'invalid' as unknown,\n },\n } as unknown as ts.Type;\n\n // Bitwise AND with string should result in 0 (falsy)\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n false,\n 'Should return false when flags is not a number',\n );\n });\n });\n\n // Phase 2: System Invariants Testing\n describe('System Invariants', () => {\n it('INVARIANT: Interface flag must be present for true result', () => {\n // Test that ONLY when Interface flag is present, result is true\n const interfaceType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: ts.SymbolFlags.Interface,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(interfaceType);\n assert.strictEqual(\n result,\n true,\n 'INVARIANT VIOLATED: Interface flag present but function returned false',\n );\n });\n\n it('INVARIANT: Non-interface flags must result in false', () => {\n const nonInterfaceFlags = [\n ts.SymbolFlags.Class,\n ts.SymbolFlags.Function,\n ts.SymbolFlags.Variable,\n ts.SymbolFlags.Property,\n ts.SymbolFlags.Enum,\n ts.SymbolFlags.Module,\n ts.SymbolFlags.Namespace,\n ts.SymbolFlags.Type,\n ts.SymbolFlags.Alias,\n ts.SymbolFlags.None,\n ];\n\n nonInterfaceFlags.forEach((flag) => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: flag,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n false,\n `INVARIANT VIOLATED: Non-interface flag ${ts.SymbolFlags[flag]} (${flag}) returned true`,\n );\n });\n });\n\n it('INVARIANT: isClassOrInterface() false must always result in false', () => {\n // Even with Interface flag, if isClassOrInterface is false, result must be false\n const mockType = {\n isClassOrInterface: () => false,\n symbol: {\n flags: ts.SymbolFlags.Interface,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n false,\n 'INVARIANT VIOLATED: isClassOrInterface() false should always result in false',\n );\n });\n });\n\n // Phase 3: State Transitions and Complex Scenarios\n describe('Complex Flag Combinations', () => {\n it('correctly handles combined flags including Interface', () => {\n const combinedFlags = [\n ts.SymbolFlags.Interface | ts.SymbolFlags.Type,\n ts.SymbolFlags.Interface | ts.SymbolFlags.Alias,\n ts.SymbolFlags.Interface | ts.SymbolFlags.Class, // Edge case\n ts.SymbolFlags.Interface | ts.SymbolFlags.Function,\n ];\n\n combinedFlags.forEach((flags, index) => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: { flags },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n true,\n `Combined flags case ${index + 1}: Interface flag present, should return true`,\n );\n });\n });\n\n it('correctly handles combined flags excluding Interface', () => {\n const combinedFlagsNoInterface = [\n ts.SymbolFlags.Class | ts.SymbolFlags.Type,\n ts.SymbolFlags.Function | ts.SymbolFlags.Variable,\n ts.SymbolFlags.Enum | ts.SymbolFlags.Module,\n ts.SymbolFlags.Alias | ts.SymbolFlags.Namespace,\n ];\n\n combinedFlagsNoInterface.forEach((flags, index) => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: { flags },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n false,\n `Combined flags case ${index + 1}: No Interface flag, should return false`,\n );\n });\n });\n\n it('handles edge case with maximum flag value', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: Number.MAX_SAFE_INTEGER,\n },\n } as unknown as ts.Type;\n\n // If Interface flag bit is set in MAX_SAFE_INTEGER, result should be true\n const hasInterfaceFlag =\n (Number.MAX_SAFE_INTEGER & ts.SymbolFlags.Interface) !== 0;\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n hasInterfaceFlag,\n 'Edge case with maximum flag value should follow bitwise logic',\n );\n });\n\n it('handles zero flags correctly', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: 0,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(result, false, 'Zero flags should result in false');\n });\n });\n\n // Phase 4: Boundary Testing\n describe('Boundary Conditions', () => {\n it('tests exact Interface flag value', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: ts.SymbolFlags.Interface,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n true,\n 'Exact Interface flag should return true',\n );\n });\n\n it('tests Interface flag minus one', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: ts.SymbolFlags.Interface - 1,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n false,\n 'Interface flag minus one should not match',\n );\n });\n\n it('tests Interface flag plus one', () => {\n const flagValue = ts.SymbolFlags.Interface + 1;\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: flagValue,\n },\n } as unknown as ts.Type;\n\n // Depends on whether the +1 creates a different valid flag\n const hasInterfaceFlag = (flagValue & ts.SymbolFlags.Interface) !== 0;\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n hasInterfaceFlag,\n 'Interface flag plus one should follow bitwise logic',\n );\n });\n });\n\n // Phase 5: Happy Path Tests (Last)\n describe('Happy Path Scenarios', () => {\n it('correctly identifies interface types', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: ts.SymbolFlags.Interface,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n true,\n 'Should correctly identify interface types',\n );\n });\n\n it('correctly rejects class types', () => {\n const mockType = {\n isClassOrInterface: () => true,\n symbol: {\n flags: ts.SymbolFlags.Class,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n false,\n 'Should correctly reject class types',\n );\n });\n\n it('correctly rejects primitive types', () => {\n const mockType = {\n isClassOrInterface: () => false,\n symbol: {\n flags: ts.SymbolFlags.None,\n },\n } as unknown as ts.Type;\n\n const result = isInterfaceType(mockType);\n assert.strictEqual(\n result,\n false,\n 'Should correctly reject primitive types',\n );\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/dist/lib/ref.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { HeaderObject, OpenAPIObject, ParameterObject, ReferenceObject, RequestBodyObject, SchemaObject } from 'openapi3-ts/oas31';
1
+ import type { HeaderObject, OpenAPIObject, ParameterObject, ReferenceObject, RequestBodyObject, SchemaObject, SecuritySchemeObject } from 'openapi3-ts/oas31';
2
2
  export declare function isRef(obj: any): obj is ReferenceObject;
3
3
  export declare function notRef(obj: any): obj is SchemaObject;
4
4
  export declare function cleanRef(ref: string): string;
@@ -7,6 +7,8 @@ export declare function parseRef(ref: string): {
7
7
  namespace: string;
8
8
  path: string;
9
9
  };
10
+ export declare function resolveRef<T extends SchemaObject | HeaderObject | ParameterObject | ReferenceObject | RequestBodyObject = SchemaObject>(spec: OpenAPIObject, maybeRef: SchemaObject | ReferenceObject | ParameterObject | SecuritySchemeObject): T;
10
11
  export declare function followRef<T extends SchemaObject | HeaderObject | ParameterObject | ReferenceObject | RequestBodyObject = SchemaObject>(spec: OpenAPIObject, ref: string): T;
12
+ export declare function tapRef<T extends SchemaObject | HeaderObject | ParameterObject | ReferenceObject | RequestBodyObject = SchemaObject>(spec: OpenAPIObject, maybeRef: SchemaObject | ReferenceObject): T;
11
13
  export declare function distillRef<T extends SchemaObject | HeaderObject | ParameterObject | ReferenceObject | RequestBodyObject = SchemaObject>(spec: OpenAPIObject, ref: string): T;
12
14
  //# sourceMappingURL=ref.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../src/lib/ref.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,YAAY,EACb,MAAM,mBAAmB,CAAC;AAI3B,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,eAAe,CAEtD;AACD,wBAAgB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,YAAY,CAEpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,UAEnC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM;;;;EASnC;AACD,wBAAgB,SAAS,CACvB,CAAC,SACG,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,eAAe,GACf,iBAAiB,GAAG,YAAY,EACpC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAOrC;AACD,wBAAgB,UAAU,CACxB,CAAC,SACG,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,eAAe,GACf,iBAAiB,GAAG,YAAY,EACpC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CA8CrC"}
1
+ {"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../src/lib/ref.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAI3B,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,eAAe,CAEtD;AACD,wBAAgB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,YAAY,CAEpD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,UAEnC;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM;;;;EAgBnC;AAED,wBAAgB,UAAU,CACxB,CAAC,SACG,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,eAAe,GACf,iBAAiB,GAAG,YAAY,EAEpC,IAAI,EAAE,aAAa,EACnB,QAAQ,EACJ,YAAY,GACZ,eAAe,GACf,eAAe,GACf,oBAAoB,GACvB,CAAC,CAKH;AAED,wBAAgB,SAAS,CACvB,CAAC,SACG,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,eAAe,GACf,iBAAiB,GAAG,YAAY,EACpC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAOrC;AAED,wBAAgB,MAAM,CACpB,CAAC,SACG,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,eAAe,GACf,iBAAiB,GAAG,YAAY,EACpC,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,GAAG,eAAe,GAAG,CAAC,CAMlE;AAED,wBAAgB,UAAU,CACxB,CAAC,SACG,YAAY,GACZ,YAAY,GACZ,eAAe,GACf,eAAe,GACf,iBAAiB,GAAG,YAAY,EACpC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CA8CrC"}
package/dist/lib/ref.js CHANGED
@@ -11,22 +11,42 @@ function cleanRef(ref) {
11
11
  }
12
12
  function parseRef(ref) {
13
13
  const parts = ref.split("/");
14
+ const names = [];
14
15
  const [model] = parts.splice(-1);
16
+ names.push(model);
17
+ while (parts.lastIndexOf("properties") !== -1) {
18
+ parts.splice(parts.lastIndexOf("properties"), 1);
19
+ const [model2] = parts.splice(-1);
20
+ names.push(model2);
21
+ }
15
22
  const [namespace] = parts.splice(-1);
16
23
  return {
17
- model,
24
+ model: names.reverse().join(" "),
18
25
  namespace,
19
26
  path: cleanRef(parts.join("/"))
20
27
  };
21
28
  }
29
+ function resolveRef(spec, maybeRef) {
30
+ if (isRef(maybeRef)) {
31
+ return followRef(spec, maybeRef.$ref);
32
+ }
33
+ return maybeRef;
34
+ }
22
35
  function followRef(spec, ref) {
23
36
  const pathParts = cleanRef(ref).split("/");
24
37
  const entry = get(spec, pathParts);
25
- if (entry && "$ref" in entry) {
38
+ if (isRef(entry)) {
26
39
  return followRef(spec, entry.$ref);
27
40
  }
28
41
  return entry;
29
42
  }
43
+ function tapRef(spec, maybeRef) {
44
+ if (isRef(maybeRef)) {
45
+ const pathParts = cleanRef(maybeRef.$ref).split("/");
46
+ return get(spec, pathParts);
47
+ }
48
+ return maybeRef;
49
+ }
30
50
  function distillRef(spec, ref) {
31
51
  const def = followRef(spec, ref);
32
52
  if (!def) {
@@ -78,6 +98,8 @@ export {
78
98
  followRef,
79
99
  isRef,
80
100
  notRef,
81
- parseRef
101
+ parseRef,
102
+ resolveRef,
103
+ tapRef
82
104
  };
83
105
  //# sourceMappingURL=ref.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/ref.ts"],
4
- "sourcesContent": ["import { get } from 'lodash-es';\nimport type {\n HeaderObject,\n OpenAPIObject,\n ParameterObject,\n ReferenceObject,\n RequestBodyObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { isEmpty } from './utils.js';\n\nexport function isRef(obj: any): obj is ReferenceObject {\n return obj && '$ref' in obj;\n}\nexport function notRef(obj: any): obj is SchemaObject {\n return !isRef(obj);\n}\n\nexport function cleanRef(ref: string) {\n return ref.replace(/^#\\//, '');\n}\n\nexport function parseRef(ref: string) {\n const parts = ref.split('/');\n const [model] = parts.splice(-1);\n const [namespace] = parts.splice(-1);\n return {\n model,\n namespace,\n path: cleanRef(parts.join('/')),\n };\n}\nexport function followRef<\n T extends\n | SchemaObject\n | HeaderObject\n | ParameterObject\n | ReferenceObject\n | RequestBodyObject = SchemaObject,\n>(spec: OpenAPIObject, ref: string): T {\n const pathParts = cleanRef(ref).split('/');\n const entry = get(spec, pathParts) as T | ReferenceObject;\n if (entry && '$ref' in entry) {\n return followRef<T>(spec, entry.$ref!);\n }\n return entry;\n}\nexport function distillRef<\n T extends\n | SchemaObject\n | HeaderObject\n | ParameterObject\n | ReferenceObject\n | RequestBodyObject = SchemaObject,\n>(spec: OpenAPIObject, ref: string): T {\n const def = followRef<T>(spec, ref);\n if (!def) {\n return def;\n }\n\n if ('properties' in def) {\n def.properties ??= {};\n for (const key in def.properties) {\n const prop = def.properties[key];\n if (isRef(prop)) {\n def.properties[key] = distillRef(spec, prop.$ref);\n }\n }\n }\n if ('items' in def) {\n if (isRef(def.items)) {\n def.items = distillRef<SchemaObject>(spec, def.items.$ref);\n }\n }\n if ('allOf' in def && !isEmpty(def.allOf)) {\n def.allOf = def.allOf.map((item) => {\n if (isRef(item)) {\n return distillRef<SchemaObject>(spec, item.$ref);\n }\n return item;\n });\n }\n if ('oneOf' in def && !isEmpty(def.oneOf)) {\n def.oneOf = def.oneOf.map((item) => {\n if (isRef(item)) {\n return distillRef<SchemaObject>(spec, item.$ref);\n }\n return item;\n });\n }\n if ('anyOf' in def && !isEmpty(def.anyOf)) {\n def.anyOf = def.anyOf.map((item) => {\n if (isRef(item)) {\n return distillRef<SchemaObject>(spec, item.$ref);\n }\n return item;\n });\n }\n\n return def;\n}\n"],
5
- "mappings": "AAAA,SAAS,WAAW;AAUpB,SAAS,eAAe;AAEjB,SAAS,MAAM,KAAkC;AACtD,SAAO,OAAO,UAAU;AAC1B;AACO,SAAS,OAAO,KAA+B;AACpD,SAAO,CAAC,MAAM,GAAG;AACnB;AAEO,SAAS,SAAS,KAAa;AACpC,SAAO,IAAI,QAAQ,QAAQ,EAAE;AAC/B;AAEO,SAAS,SAAS,KAAa;AACpC,QAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,QAAM,CAAC,KAAK,IAAI,MAAM,OAAO,EAAE;AAC/B,QAAM,CAAC,SAAS,IAAI,MAAM,OAAO,EAAE;AACnC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,SAAS,MAAM,KAAK,GAAG,CAAC;AAAA,EAChC;AACF;AACO,SAAS,UAOd,MAAqB,KAAgB;AACrC,QAAM,YAAY,SAAS,GAAG,EAAE,MAAM,GAAG;AACzC,QAAM,QAAQ,IAAI,MAAM,SAAS;AACjC,MAAI,SAAS,UAAU,OAAO;AAC5B,WAAO,UAAa,MAAM,MAAM,IAAK;AAAA,EACvC;AACA,SAAO;AACT;AACO,SAAS,WAOd,MAAqB,KAAgB;AACrC,QAAM,MAAM,UAAa,MAAM,GAAG;AAClC,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,KAAK;AACvB,QAAI,eAAe,CAAC;AACpB,eAAW,OAAO,IAAI,YAAY;AAChC,YAAM,OAAO,IAAI,WAAW,GAAG;AAC/B,UAAI,MAAM,IAAI,GAAG;AACf,YAAI,WAAW,GAAG,IAAI,WAAW,MAAM,KAAK,IAAI;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AACA,MAAI,WAAW,KAAK;AAClB,QAAI,MAAM,IAAI,KAAK,GAAG;AACpB,UAAI,QAAQ,WAAyB,MAAM,IAAI,MAAM,IAAI;AAAA,IAC3D;AAAA,EACF;AACA,MAAI,WAAW,OAAO,CAAC,QAAQ,IAAI,KAAK,GAAG;AACzC,QAAI,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS;AAClC,UAAI,MAAM,IAAI,GAAG;AACf,eAAO,WAAyB,MAAM,KAAK,IAAI;AAAA,MACjD;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,MAAI,WAAW,OAAO,CAAC,QAAQ,IAAI,KAAK,GAAG;AACzC,QAAI,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS;AAClC,UAAI,MAAM,IAAI,GAAG;AACf,eAAO,WAAyB,MAAM,KAAK,IAAI;AAAA,MACjD;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,MAAI,WAAW,OAAO,CAAC,QAAQ,IAAI,KAAK,GAAG;AACzC,QAAI,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS;AAClC,UAAI,MAAM,IAAI,GAAG;AACf,eAAO,WAAyB,MAAM,KAAK,IAAI;AAAA,MACjD;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,SAAO;AACT;",
6
- "names": []
4
+ "sourcesContent": ["import { get } from 'lodash-es';\nimport type {\n HeaderObject,\n OpenAPIObject,\n ParameterObject,\n ReferenceObject,\n RequestBodyObject,\n SchemaObject,\n SecuritySchemeObject,\n} from 'openapi3-ts/oas31';\n\nimport { isEmpty } from './utils.js';\n\nexport function isRef(obj: any): obj is ReferenceObject {\n return obj && '$ref' in obj;\n}\nexport function notRef(obj: any): obj is SchemaObject {\n return !isRef(obj);\n}\n\nexport function cleanRef(ref: string) {\n return ref.replace(/^#\\//, '');\n}\n\nexport function parseRef(ref: string) {\n const parts = ref.split('/');\n const names: string[] = [];\n const [model] = parts.splice(-1);\n names.push(model);\n while (parts.lastIndexOf('properties') !== -1) {\n parts.splice(parts.lastIndexOf('properties'), 1);\n const [model] = parts.splice(-1);\n names.push(model);\n }\n const [namespace] = parts.splice(-1);\n return {\n model: names.reverse().join(' '),\n namespace,\n path: cleanRef(parts.join('/')),\n };\n}\n\nexport function resolveRef<\n T extends\n | SchemaObject\n | HeaderObject\n | ParameterObject\n | ReferenceObject\n | RequestBodyObject = SchemaObject,\n>(\n spec: OpenAPIObject,\n maybeRef:\n | SchemaObject\n | ReferenceObject\n | ParameterObject\n | SecuritySchemeObject,\n): T {\n if (isRef(maybeRef)) {\n return followRef<T>(spec, maybeRef.$ref!);\n }\n return maybeRef as T;\n}\n\nexport function followRef<\n T extends\n | SchemaObject\n | HeaderObject\n | ParameterObject\n | ReferenceObject\n | RequestBodyObject = SchemaObject,\n>(spec: OpenAPIObject, ref: string): T {\n const pathParts = cleanRef(ref).split('/');\n const entry = get(spec, pathParts) as T | ReferenceObject;\n if (isRef(entry)) {\n return followRef<T>(spec, entry.$ref!);\n }\n return entry;\n}\n\nexport function tapRef<\n T extends\n | SchemaObject\n | HeaderObject\n | ParameterObject\n | ReferenceObject\n | RequestBodyObject = SchemaObject,\n>(spec: OpenAPIObject, maybeRef: SchemaObject | ReferenceObject): T {\n if (isRef(maybeRef)) {\n const pathParts = cleanRef(maybeRef.$ref).split('/');\n return get(spec, pathParts) as T;\n }\n return maybeRef as T;\n}\n\nexport function distillRef<\n T extends\n | SchemaObject\n | HeaderObject\n | ParameterObject\n | ReferenceObject\n | RequestBodyObject = SchemaObject,\n>(spec: OpenAPIObject, ref: string): T {\n const def = followRef<T>(spec, ref);\n if (!def) {\n return def;\n }\n\n if ('properties' in def) {\n def.properties ??= {};\n for (const key in def.properties) {\n const prop = def.properties[key];\n if (isRef(prop)) {\n def.properties[key] = distillRef(spec, prop.$ref);\n }\n }\n }\n if ('items' in def) {\n if (isRef(def.items)) {\n def.items = distillRef<SchemaObject>(spec, def.items.$ref);\n }\n }\n if ('allOf' in def && !isEmpty(def.allOf)) {\n def.allOf = def.allOf.map((item) => {\n if (isRef(item)) {\n return distillRef<SchemaObject>(spec, item.$ref);\n }\n return item;\n });\n }\n if ('oneOf' in def && !isEmpty(def.oneOf)) {\n def.oneOf = def.oneOf.map((item) => {\n if (isRef(item)) {\n return distillRef<SchemaObject>(spec, item.$ref);\n }\n return item;\n });\n }\n if ('anyOf' in def && !isEmpty(def.anyOf)) {\n def.anyOf = def.anyOf.map((item) => {\n if (isRef(item)) {\n return distillRef<SchemaObject>(spec, item.$ref);\n }\n return item;\n });\n }\n\n return def;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["model"]
7
7
  }
@@ -11,4 +11,11 @@ export declare function isEmpty(value: unknown): value is null | undefined | '';
11
11
  export declare function pascalcase(value: string): string;
12
12
  export declare function spinalcase(value: string): string;
13
13
  export declare function snakecase(value: string): string;
14
+ export declare function camelcase(value: string): string;
15
+ /**
16
+ * Joins an array of strings so that elements containing only digits
17
+ * are concatenated without a separator, while all other elements
18
+ * are prefixed by the separator (unless they're the very first element).
19
+ */
20
+ export declare function joinSkipDigits(arr: string[], separator: string): string;
14
21
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,IAAI,EAAE,CAAC,EAAE,EACT,QAAQ,GAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAkB,GACrD,CAAC,EAAE,CAEL;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAE9E,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACvD,GAAG,EAAE,CAAC,EACN,QAAQ,GAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,MAAyB,UAKpE;AAED,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE,EAAE,CAAC,aAAa,EACzB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,EAAE,CAAC,IAAI,KACV,YAAY,EAAE,CAAC;AACpB,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;AAE9E,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,EAAE,CAAC,aAAa,EACzB,OAAO,EAAE,WAAW,KACjB,YAAY,EAAE,CAAC;AAEpB,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,SAAS,GAAG,EAAE,CAWtE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,UAEvC;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,UAEvC;AACD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,UAEtC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,IAAI,EAAE,CAAC,EAAE,EACT,QAAQ,GAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAkB,GACrD,CAAC,EAAE,CAEL;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAE9E,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACvD,GAAG,EAAE,CAAC,EACN,QAAQ,GAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,MAAyB,UAKpE;AAED,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE,EAAE,CAAC,aAAa,EACzB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,EAAE,CAAC,IAAI,KACV,YAAY,EAAE,CAAC;AACpB,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;AAE9E,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,EAAE,CAAC,aAAa,EACzB,OAAO,EAAE,WAAW,KACjB,YAAY,EAAE,CAAC;AAEpB,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,SAAS,GAAG,EAAE,CAWtE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,UAEvC;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,UAEvC;AACD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,UAEtC;AACD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAgBvE"}
package/dist/lib/utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ camelcase as _camelcase,
2
3
  pascalcase as _pascalcase,
3
4
  snakecase as _snakecase,
4
5
  spinalcase as _spinalcase
@@ -30,8 +31,28 @@ function spinalcase(value) {
30
31
  function snakecase(value) {
31
32
  return _snakecase(value.split("/").join(" "));
32
33
  }
34
+ function camelcase(value) {
35
+ const cleaned = value.replace(/[^A-Za-z0-9]+(?=\d)/g, "");
36
+ return _camelcase(cleaned);
37
+ }
38
+ function joinSkipDigits(arr, separator) {
39
+ if (arr.length === 0)
40
+ return "";
41
+ let result = arr[0];
42
+ for (let i = 1; i < arr.length; i++) {
43
+ const el = arr[i];
44
+ if (/^\d+$/.test(el)) {
45
+ result += el;
46
+ } else {
47
+ result += separator + el;
48
+ }
49
+ }
50
+ return result;
51
+ }
33
52
  export {
53
+ camelcase,
34
54
  isEmpty,
55
+ joinSkipDigits,
35
56
  pascalcase,
36
57
  removeDuplicates,
37
58
  snakecase,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/utils.ts"],
4
- "sourcesContent": ["import {\n pascalcase as _pascalcase,\n snakecase as _snakecase,\n spinalcase as _spinalcase,\n} from 'stringcase';\nimport type ts from 'typescript';\n\nimport type { TypeDeriver } from './deriver';\nimport type { ResponseItem } from './paths';\n\nexport function removeDuplicates<T>(\n data: T[],\n accessor: (item: T) => T[keyof T] | T = (item) => item,\n): T[] {\n return [...new Map(data.map((x) => [accessor(x), x])).values()];\n}\n\nexport type InferRecordValue<T> = T extends Record<string, infer U> ? U : any;\n\nexport function toLitObject<T extends Record<string, any>>(\n obj: T,\n accessor: (value: InferRecordValue<T>) => string = (value) => value,\n) {\n return `{${Object.keys(obj)\n .map((key) => `${key}: ${accessor(obj[key])}`)\n .join(', ')}}`;\n}\n\nexport type NaunceResponseAnalyzerFn = (\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n node: ts.Node,\n) => ResponseItem[];\nexport type NaunceResponseAnalyzer = Record<string, NaunceResponseAnalyzerFn>;\n\nexport type ResponseAnalyzerFn = (\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n) => ResponseItem[];\n\nexport function isEmpty(value: unknown): value is null | undefined | '' {\n if (value === null || value === undefined || value === '') {\n return true;\n }\n if (Array.isArray(value) && value.length === 0) {\n return true;\n }\n if (typeof value === 'object' && Object.keys(value).length === 0) {\n return true;\n }\n return false;\n}\n\nexport function pascalcase(value: string) {\n return _pascalcase(value.split('/').join(' '));\n}\nexport function spinalcase(value: string) {\n return _spinalcase(value.split('/').join(' '));\n}\nexport function snakecase(value: string) {\n return _snakecase(value.split('/').join(' '));\n}\n"],
5
- "mappings": "AAAA;AAAA,EACE,cAAc;AAAA,EACd,aAAa;AAAA,EACb,cAAc;AAAA,OACT;AAMA,SAAS,iBACd,MACA,WAAwC,CAAC,SAAS,MAC7C;AACL,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;AAChE;AAIO,SAAS,YACd,KACA,WAAmD,CAAC,UAAU,OAC9D;AACA,SAAO,IAAI,OAAO,KAAK,GAAG,EACvB,IAAI,CAAC,QAAQ,GAAG,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC,EAAE,EAC5C,KAAK,IAAI,CAAC;AACf;AAcO,SAAS,QAAQ,OAAgD;AACtE,MAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,IAAI;AACzD,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAAG;AAC9C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AAChE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,WAAW,OAAe;AACxC,SAAO,YAAY,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AAC/C;AACO,SAAS,WAAW,OAAe;AACxC,SAAO,YAAY,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AAC/C;AACO,SAAS,UAAU,OAAe;AACvC,SAAO,WAAW,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AAC9C;",
4
+ "sourcesContent": ["import {\n camelcase as _camelcase,\n pascalcase as _pascalcase,\n snakecase as _snakecase,\n spinalcase as _spinalcase,\n} from 'stringcase';\nimport type ts from 'typescript';\n\nimport type { TypeDeriver } from './deriver';\nimport type { ResponseItem } from './paths';\n\nexport function removeDuplicates<T>(\n data: T[],\n accessor: (item: T) => T[keyof T] | T = (item) => item,\n): T[] {\n return [...new Map(data.map((x) => [accessor(x), x])).values()];\n}\n\nexport type InferRecordValue<T> = T extends Record<string, infer U> ? U : any;\n\nexport function toLitObject<T extends Record<string, any>>(\n obj: T,\n accessor: (value: InferRecordValue<T>) => string = (value) => value,\n) {\n return `{${Object.keys(obj)\n .map((key) => `${key}: ${accessor(obj[key])}`)\n .join(', ')}}`;\n}\n\nexport type NaunceResponseAnalyzerFn = (\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n node: ts.Node,\n) => ResponseItem[];\nexport type NaunceResponseAnalyzer = Record<string, NaunceResponseAnalyzerFn>;\n\nexport type ResponseAnalyzerFn = (\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n) => ResponseItem[];\n\nexport function isEmpty(value: unknown): value is null | undefined | '' {\n if (value === null || value === undefined || value === '') {\n return true;\n }\n if (Array.isArray(value) && value.length === 0) {\n return true;\n }\n if (typeof value === 'object' && Object.keys(value).length === 0) {\n return true;\n }\n return false;\n}\n\nexport function pascalcase(value: string) {\n return _pascalcase(value.split('/').join(' '));\n}\nexport function spinalcase(value: string) {\n return _spinalcase(value.split('/').join(' '));\n}\nexport function snakecase(value: string) {\n return _snakecase(value.split('/').join(' '));\n}\nexport function camelcase(value: string): string {\n // remove any \u201Cspecial\u201D chars immediately preceding a digit\n const cleaned = value.replace(/[^A-Za-z0-9]+(?=\\d)/g, '');\n return _camelcase(cleaned);\n}\n\n/**\n * Joins an array of strings so that elements containing only digits\n * are concatenated without a separator, while all other elements\n * are prefixed by the separator (unless they're the very first element).\n */\nexport function joinSkipDigits(arr: string[], separator: string): string {\n if (arr.length === 0) return '';\n\n let result = arr[0];\n for (let i = 1; i < arr.length; i++) {\n const el = arr[i];\n // If this element is digits-only, append it directly\n if (/^\\d+$/.test(el)) {\n result += el;\n } else {\n // Otherwise, prepend the separator and append the element\n result += separator + el;\n }\n }\n\n return result;\n}\n"],
5
+ "mappings": "AAAA;AAAA,EACE,aAAa;AAAA,EACb,cAAc;AAAA,EACd,aAAa;AAAA,EACb,cAAc;AAAA,OACT;AAMA,SAAS,iBACd,MACA,WAAwC,CAAC,SAAS,MAC7C;AACL,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;AAChE;AAIO,SAAS,YACd,KACA,WAAmD,CAAC,UAAU,OAC9D;AACA,SAAO,IAAI,OAAO,KAAK,GAAG,EACvB,IAAI,CAAC,QAAQ,GAAG,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,CAAC,EAAE,EAC5C,KAAK,IAAI,CAAC;AACf;AAcO,SAAS,QAAQ,OAAgD;AACtE,MAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,IAAI;AACzD,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,GAAG;AAC9C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AAChE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,WAAW,OAAe;AACxC,SAAO,YAAY,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AAC/C;AACO,SAAS,WAAW,OAAe;AACxC,SAAO,YAAY,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AAC/C;AACO,SAAS,UAAU,OAAe;AACvC,SAAO,WAAW,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,CAAC;AAC9C;AACO,SAAS,UAAU,OAAuB;AAE/C,QAAM,UAAU,MAAM,QAAQ,wBAAwB,EAAE;AACxD,SAAO,WAAW,OAAO;AAC3B;AAOO,SAAS,eAAe,KAAe,WAA2B;AACvE,MAAI,IAAI,WAAW;AAAG,WAAO;AAE7B,MAAI,SAAS,IAAI,CAAC;AAClB,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAM,KAAK,IAAI,CAAC;AAEhB,QAAI,QAAQ,KAAK,EAAE,GAAG;AACpB,gBAAU;AAAA,IACZ,OAAO;AAEL,gBAAU,YAAY;AAAA,IACxB;AAAA,EACF;AAEA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdk-it/core",
3
- "version": "0.21.0",
3
+ "version": "0.22.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",