@sdk-it/spec 0.31.0 → 0.31.2
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.
- package/package.json +4 -3
- package/dist/lib/find-polymorphic-varients.test.d.ts +0 -2
- package/dist/lib/find-polymorphic-varients.test.d.ts.map +0 -1
- package/dist/lib/find-polymorphic-varients.test.js +0 -615
- package/dist/lib/find-polymorphic-varients.test.js.map +0 -7
- package/dist/lib/ir.test.d.ts +0 -2
- package/dist/lib/ir.test.d.ts.map +0 -1
- package/dist/lib/ir.test.js +0 -261
- package/dist/lib/ir.test.js.map +0 -7
- package/dist/lib/metadata.test.d.ts +0 -2
- package/dist/lib/metadata.test.d.ts.map +0 -1
- package/dist/lib/metadata.test.js +0 -359
- package/dist/lib/metadata.test.js.map +0 -7
- package/dist/lib/pagination/pagination-result.test.d.ts +0 -2
- package/dist/lib/pagination/pagination-result.test.d.ts.map +0 -1
- package/dist/lib/pagination/pagination-result.test.js +0 -548
- package/dist/lib/pagination/pagination-result.test.js.map +0 -7
- package/dist/lib/pagination/pagination.test.d.ts +0 -2
- package/dist/lib/pagination/pagination.test.d.ts.map +0 -1
- package/dist/lib/pagination/pagination.test.js +0 -379
- package/dist/lib/pagination/pagination.test.js.map +0 -7
- package/dist/lib/tune.test.d.ts +0 -2
- package/dist/lib/tune.test.d.ts.map +0 -1
- package/dist/lib/tune.test.js +0 -60
- package/dist/lib/tune.test.js.map +0 -7
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { describe, test } from "node:test";
|
|
3
|
-
import {
|
|
4
|
-
CURSOR_LIMIT_REGEXES,
|
|
5
|
-
CURSOR_REGEXES,
|
|
6
|
-
GENERIC_LIMIT_PARAM_REGEXES,
|
|
7
|
-
OFFSET_PARAM_REGEXES,
|
|
8
|
-
PAGE_NUMBER_REGEXES,
|
|
9
|
-
PAGE_SIZE_REGEXES,
|
|
10
|
-
guessPagination
|
|
11
|
-
} from "./guess-pagination.ts";
|
|
12
|
-
function createOperation(params) {
|
|
13
|
-
return {
|
|
14
|
-
"x-fn-name": "testFunction",
|
|
15
|
-
tags: ["test"],
|
|
16
|
-
operationId: "testOperation",
|
|
17
|
-
parameters: params,
|
|
18
|
-
requestBody: { content: {} },
|
|
19
|
-
responses: {}
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function qParam(name) {
|
|
23
|
-
return {
|
|
24
|
-
name,
|
|
25
|
-
in: "query",
|
|
26
|
-
required: false,
|
|
27
|
-
schema: {
|
|
28
|
-
type: "string"
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
function hParam(name) {
|
|
33
|
-
return {
|
|
34
|
-
name,
|
|
35
|
-
in: "header",
|
|
36
|
-
required: false,
|
|
37
|
-
schema: {
|
|
38
|
-
type: "string"
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
function pParam(name) {
|
|
43
|
-
return {
|
|
44
|
-
name,
|
|
45
|
-
in: "path",
|
|
46
|
-
required: false,
|
|
47
|
-
schema: {
|
|
48
|
-
type: "string"
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function getExpectedKeyword(paramName, regexArray) {
|
|
53
|
-
for (const regex of regexArray) {
|
|
54
|
-
const match = paramName.match(regex);
|
|
55
|
-
if (match) {
|
|
56
|
-
return match[0];
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return paramName;
|
|
60
|
-
}
|
|
61
|
-
describe("guessPagination()", () => {
|
|
62
|
-
describe("No Pagination Detected", () => {
|
|
63
|
-
test('should return "none" for an operation with an empty parameters array', () => {
|
|
64
|
-
const op = createOperation([]);
|
|
65
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
66
|
-
});
|
|
67
|
-
test('should return "none" for an operation with undefined parameters', () => {
|
|
68
|
-
const op = createOperation(void 0);
|
|
69
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
70
|
-
});
|
|
71
|
-
test('should return "none" for non-pagination query parameters', () => {
|
|
72
|
-
const op = createOperation([qParam("search"), qParam("filterBy")]);
|
|
73
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
74
|
-
});
|
|
75
|
-
test('should return "none" if relevant parameters are not in "query"', () => {
|
|
76
|
-
const op = createOperation([hParam("offset"), hParam("limit")]);
|
|
77
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
78
|
-
});
|
|
79
|
-
test('should return "none" if only one part of a pair is present (e.g., only offset)', () => {
|
|
80
|
-
assert.deepStrictEqual(
|
|
81
|
-
guessPagination(createOperation([qParam("offset")])),
|
|
82
|
-
{ type: "none" },
|
|
83
|
-
"Only offset"
|
|
84
|
-
);
|
|
85
|
-
assert.deepStrictEqual(
|
|
86
|
-
guessPagination(createOperation([qParam("page")])),
|
|
87
|
-
{ type: "none" },
|
|
88
|
-
"Only page"
|
|
89
|
-
);
|
|
90
|
-
assert.deepStrictEqual(
|
|
91
|
-
guessPagination(createOperation([qParam("cursor")])),
|
|
92
|
-
{ type: "none" },
|
|
93
|
-
"Only cursor"
|
|
94
|
-
);
|
|
95
|
-
assert.deepStrictEqual(
|
|
96
|
-
guessPagination(createOperation([qParam("limit")])),
|
|
97
|
-
{ type: "none" },
|
|
98
|
-
"Only limit"
|
|
99
|
-
);
|
|
100
|
-
});
|
|
101
|
-
test('should return "none" for mixed non-query and insufficient query params', () => {
|
|
102
|
-
const op = createOperation([
|
|
103
|
-
pParam("userId"),
|
|
104
|
-
qParam("offset"),
|
|
105
|
-
hParam("X-Request-ID")
|
|
106
|
-
]);
|
|
107
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
describe("Offset Pagination Detection", () => {
|
|
111
|
-
const testOffsetKeywords = [
|
|
112
|
-
"offset",
|
|
113
|
-
"skip",
|
|
114
|
-
"start",
|
|
115
|
-
"start_index",
|
|
116
|
-
"starting_at",
|
|
117
|
-
"from",
|
|
118
|
-
"Offset",
|
|
119
|
-
"SKIP"
|
|
120
|
-
];
|
|
121
|
-
const testLimitKeywords = [
|
|
122
|
-
"limit",
|
|
123
|
-
"count",
|
|
124
|
-
"size",
|
|
125
|
-
"page_size",
|
|
126
|
-
"pageSize",
|
|
127
|
-
"max_results",
|
|
128
|
-
"take",
|
|
129
|
-
"Limit",
|
|
130
|
-
"COUNT"
|
|
131
|
-
];
|
|
132
|
-
for (const offsetKey of testOffsetKeywords) {
|
|
133
|
-
for (const limitKey of testLimitKeywords) {
|
|
134
|
-
if (offsetKey.toLowerCase() === limitKey.toLowerCase()) continue;
|
|
135
|
-
test(`should detect offset with "${offsetKey}" and "${limitKey}"`, () => {
|
|
136
|
-
const op = createOperation([qParam(offsetKey), qParam(limitKey)]);
|
|
137
|
-
const result = guessPagination(op);
|
|
138
|
-
assert.strictEqual(
|
|
139
|
-
result.type,
|
|
140
|
-
"offset",
|
|
141
|
-
`Failed for ${offsetKey}, ${limitKey}`
|
|
142
|
-
);
|
|
143
|
-
assert.strictEqual(result.offsetParamName, offsetKey);
|
|
144
|
-
assert.strictEqual(
|
|
145
|
-
result.offsetKeyword,
|
|
146
|
-
getExpectedKeyword(offsetKey, OFFSET_PARAM_REGEXES)
|
|
147
|
-
);
|
|
148
|
-
assert.strictEqual(result.limitParamName, limitKey);
|
|
149
|
-
assert.strictEqual(
|
|
150
|
-
result.limitKeyword,
|
|
151
|
-
getExpectedKeyword(limitKey, GENERIC_LIMIT_PARAM_REGEXES)
|
|
152
|
-
);
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
test("should not detect offset if one param is not in query", () => {
|
|
157
|
-
const op = createOperation([hParam("offset"), qParam("limit")]);
|
|
158
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
159
|
-
});
|
|
160
|
-
test("should not detect with two offset-like params and no limit", () => {
|
|
161
|
-
const op = createOperation([qParam("offset"), qParam("skip")]);
|
|
162
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
163
|
-
});
|
|
164
|
-
test("should correctly handle params in different order", () => {
|
|
165
|
-
const op = createOperation([qParam("limit"), qParam("offset")]);
|
|
166
|
-
const result = guessPagination(op);
|
|
167
|
-
assert.strictEqual(result.type, "offset");
|
|
168
|
-
assert.strictEqual(result.offsetParamName, "offset");
|
|
169
|
-
assert.strictEqual(result.limitParamName, "limit");
|
|
170
|
-
});
|
|
171
|
-
test("should handle extra non-pagination params", () => {
|
|
172
|
-
const op = createOperation([
|
|
173
|
-
qParam("filter"),
|
|
174
|
-
qParam("offset"),
|
|
175
|
-
qParam("sort"),
|
|
176
|
-
qParam("limit")
|
|
177
|
-
]);
|
|
178
|
-
const result = guessPagination(op);
|
|
179
|
-
assert.strictEqual(result.type, "offset");
|
|
180
|
-
assert.strictEqual(result.offsetParamName, "offset");
|
|
181
|
-
assert.strictEqual(result.limitParamName, "limit");
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
describe("Page Pagination Detection", () => {
|
|
185
|
-
const testPageNumKeywords = [
|
|
186
|
-
"page",
|
|
187
|
-
"p",
|
|
188
|
-
"page_number",
|
|
189
|
-
"pageNum",
|
|
190
|
-
"page_idx",
|
|
191
|
-
"Page",
|
|
192
|
-
"P"
|
|
193
|
-
];
|
|
194
|
-
const testPageSizeKeywords = [
|
|
195
|
-
"page_size",
|
|
196
|
-
"pageSize",
|
|
197
|
-
"size",
|
|
198
|
-
"limit",
|
|
199
|
-
"count",
|
|
200
|
-
"per_page",
|
|
201
|
-
"per-page",
|
|
202
|
-
"num_items",
|
|
203
|
-
"Size",
|
|
204
|
-
"LIMIT"
|
|
205
|
-
];
|
|
206
|
-
for (const pageKey of testPageNumKeywords) {
|
|
207
|
-
for (const sizeKey of testPageSizeKeywords) {
|
|
208
|
-
if (pageKey.toLowerCase() === sizeKey.toLowerCase()) continue;
|
|
209
|
-
test(`should detect page with "${pageKey}" and "${sizeKey}"`, () => {
|
|
210
|
-
const op = createOperation([qParam(pageKey), qParam(sizeKey)]);
|
|
211
|
-
const result = guessPagination(op);
|
|
212
|
-
assert.strictEqual(
|
|
213
|
-
result.type,
|
|
214
|
-
"page",
|
|
215
|
-
`Failed for ${pageKey}, ${sizeKey}`
|
|
216
|
-
);
|
|
217
|
-
assert.strictEqual(result.pageNumberParamName, pageKey);
|
|
218
|
-
assert.strictEqual(
|
|
219
|
-
result.pageNumberKeyword,
|
|
220
|
-
getExpectedKeyword(pageKey, PAGE_NUMBER_REGEXES)
|
|
221
|
-
);
|
|
222
|
-
assert.strictEqual(result.pageSizeParamName, sizeKey);
|
|
223
|
-
assert.strictEqual(
|
|
224
|
-
result.pageSizeKeyword,
|
|
225
|
-
getExpectedKeyword(sizeKey, PAGE_SIZE_REGEXES)
|
|
226
|
-
);
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
test("should not detect page if one param is not in query", () => {
|
|
231
|
-
const op = createOperation([hParam("page"), qParam("size")]);
|
|
232
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
233
|
-
});
|
|
234
|
-
test("should not detect with two page-number-like params and no size", () => {
|
|
235
|
-
const op = createOperation([qParam("page"), qParam("page_number")]);
|
|
236
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
describe("Cursor Pagination Detection", () => {
|
|
240
|
-
const testCursorKeywords = [
|
|
241
|
-
"cursor",
|
|
242
|
-
"after",
|
|
243
|
-
"before_cursor",
|
|
244
|
-
"next_page_token",
|
|
245
|
-
"pageToken",
|
|
246
|
-
"continuation_token",
|
|
247
|
-
"Cursor",
|
|
248
|
-
"AFTER"
|
|
249
|
-
];
|
|
250
|
-
const testCursorLimitKeywords = [
|
|
251
|
-
"limit",
|
|
252
|
-
"count",
|
|
253
|
-
"size",
|
|
254
|
-
"first",
|
|
255
|
-
"last",
|
|
256
|
-
"page_size",
|
|
257
|
-
"num_items",
|
|
258
|
-
"take",
|
|
259
|
-
"First",
|
|
260
|
-
"LAST"
|
|
261
|
-
];
|
|
262
|
-
for (const cursorKey of testCursorKeywords) {
|
|
263
|
-
for (const limitKey of testCursorLimitKeywords) {
|
|
264
|
-
if (cursorKey.toLowerCase() === limitKey.toLowerCase()) continue;
|
|
265
|
-
test(`should detect cursor with "${cursorKey}" and "${limitKey}"`, () => {
|
|
266
|
-
const op = createOperation([qParam(cursorKey), qParam(limitKey)]);
|
|
267
|
-
const result = guessPagination(op);
|
|
268
|
-
assert.strictEqual(
|
|
269
|
-
result.type,
|
|
270
|
-
"cursor",
|
|
271
|
-
`Failed for ${cursorKey}, ${limitKey}`
|
|
272
|
-
);
|
|
273
|
-
assert.strictEqual(result.cursorParamName, cursorKey);
|
|
274
|
-
assert.strictEqual(
|
|
275
|
-
result.cursorKeyword,
|
|
276
|
-
getExpectedKeyword(cursorKey, CURSOR_REGEXES)
|
|
277
|
-
);
|
|
278
|
-
assert.strictEqual(result.limitParamName, limitKey);
|
|
279
|
-
assert.strictEqual(
|
|
280
|
-
result.limitKeyword,
|
|
281
|
-
getExpectedKeyword(limitKey, CURSOR_LIMIT_REGEXES)
|
|
282
|
-
);
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
test("should not detect cursor if one param is not in query", () => {
|
|
287
|
-
const op = createOperation([hParam("cursor"), qParam("first")]);
|
|
288
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
289
|
-
});
|
|
290
|
-
test("should not detect with two cursor-like params and no limit", () => {
|
|
291
|
-
const op = createOperation([qParam("cursor"), qParam("after")]);
|
|
292
|
-
assert.deepStrictEqual(guessPagination(op), { type: "none" });
|
|
293
|
-
});
|
|
294
|
-
});
|
|
295
|
-
describe("Pagination Type Precedence", () => {
|
|
296
|
-
test('Offset should take precedence over Page (e.g., "skip", "limit", "page")', () => {
|
|
297
|
-
const op = createOperation([
|
|
298
|
-
qParam("skip"),
|
|
299
|
-
qParam("limit"),
|
|
300
|
-
qParam("page")
|
|
301
|
-
]);
|
|
302
|
-
const result = guessPagination(op);
|
|
303
|
-
assert.strictEqual(result.type, "offset");
|
|
304
|
-
if (result.type === "offset") {
|
|
305
|
-
assert.strictEqual(result.offsetParamName, "skip");
|
|
306
|
-
assert.strictEqual(result.limitParamName, "limit");
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
test('Offset should take precedence over Cursor (e.g., "offset", "count", "after_token")', () => {
|
|
310
|
-
const op = createOperation([
|
|
311
|
-
qParam("offset"),
|
|
312
|
-
qParam("count"),
|
|
313
|
-
qParam("after_token")
|
|
314
|
-
]);
|
|
315
|
-
const result = guessPagination(op);
|
|
316
|
-
assert.strictEqual(result.type, "offset");
|
|
317
|
-
if (result.type === "offset") {
|
|
318
|
-
assert.strictEqual(result.offsetParamName, "offset");
|
|
319
|
-
assert.strictEqual(result.limitParamName, "count");
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
test('Page should take precedence over Cursor (e.g., "page", "size", "next_cursor")', () => {
|
|
323
|
-
const op = createOperation([
|
|
324
|
-
qParam("page"),
|
|
325
|
-
qParam("size"),
|
|
326
|
-
qParam("next_cursor")
|
|
327
|
-
]);
|
|
328
|
-
const result = guessPagination(op);
|
|
329
|
-
assert.strictEqual(result.type, "page");
|
|
330
|
-
if (result.type === "page") {
|
|
331
|
-
assert.strictEqual(result.pageNumberParamName, "page");
|
|
332
|
-
assert.strictEqual(result.pageSizeParamName, "size");
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
test('Params like "page" and "limit" should resolve to Page pagination', () => {
|
|
336
|
-
const op = createOperation([qParam("page"), qParam("limit")]);
|
|
337
|
-
const result = guessPagination(op);
|
|
338
|
-
assert.strictEqual(result.type, "page");
|
|
339
|
-
if (result.type === "page") {
|
|
340
|
-
assert.strictEqual(result.pageNumberParamName, "page");
|
|
341
|
-
assert.strictEqual(result.pageSizeParamName, "limit");
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
describe("Regex Specificity and Word Boundaries", () => {
|
|
346
|
-
test('should not match "custom_offset" as "offset" due to word boundary (with real implementation)', () => {
|
|
347
|
-
const op = createOperation([
|
|
348
|
-
qParam("custom_offset_param"),
|
|
349
|
-
qParam("limit")
|
|
350
|
-
]);
|
|
351
|
-
assert.ok(
|
|
352
|
-
true,
|
|
353
|
-
"Test needs real implementation for accurate regex boundary check"
|
|
354
|
-
);
|
|
355
|
-
});
|
|
356
|
-
test('should match "offset_custom" for "offset" keyword (with real implementation)', () => {
|
|
357
|
-
const op = createOperation([qParam("offset_custom"), qParam("limit")]);
|
|
358
|
-
assert.ok(
|
|
359
|
-
true,
|
|
360
|
-
"Test needs real implementation for accurate keyword extraction"
|
|
361
|
-
);
|
|
362
|
-
});
|
|
363
|
-
test('should match "page" exactly for page number, not "my_page_details" (with real implementation)', () => {
|
|
364
|
-
const op = createOperation([qParam("my_page_details"), qParam("size")]);
|
|
365
|
-
assert.ok(
|
|
366
|
-
true,
|
|
367
|
-
"Test needs real implementation for exact regex matching"
|
|
368
|
-
);
|
|
369
|
-
});
|
|
370
|
-
test('should match "p" exactly for page number (with real implementation)', () => {
|
|
371
|
-
const op = createOperation([qParam("p"), qParam("size")]);
|
|
372
|
-
assert.ok(
|
|
373
|
-
true,
|
|
374
|
-
"Test needs real implementation for exact regex matching"
|
|
375
|
-
);
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
});
|
|
379
|
-
//# sourceMappingURL=pagination.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/lib/pagination/pagination.test.ts"],
|
|
4
|
-
"sourcesContent": ["import assert from 'node:assert/strict';\nimport { describe, test } from 'node:test';\nimport type { ParameterObject } from 'openapi3-ts/oas31';\n\nimport type { TunedOperationObject } from '../types.ts';\nimport {\n CURSOR_LIMIT_REGEXES,\n CURSOR_REGEXES,\n GENERIC_LIMIT_PARAM_REGEXES,\n OFFSET_PARAM_REGEXES,\n PAGE_NUMBER_REGEXES,\n PAGE_SIZE_REGEXES,\n guessPagination,\n} from './guess-pagination.ts';\n\nfunction createOperation(params: ParameterObject[]): TunedOperationObject {\n return {\n 'x-fn-name': 'testFunction',\n tags: ['test'],\n operationId: 'testOperation',\n parameters: params,\n requestBody: { content: {} },\n responses: {},\n };\n}\n\nfunction qParam(name: string): ParameterObject {\n return {\n name,\n in: 'query',\n required: false,\n schema: {\n type: 'string',\n },\n };\n}\n\nfunction hParam(name: string): ParameterObject {\n return {\n name,\n in: 'header',\n required: false,\n schema: {\n type: 'string',\n },\n };\n}\nfunction pParam(name: string): ParameterObject {\n return {\n name,\n in: 'path',\n required: false,\n schema: {\n type: 'string',\n },\n };\n}\nfunction getExpectedKeyword(paramName: string, regexArray: RegExp[]): string {\n for (const regex of regexArray) {\n const match = paramName.match(regex);\n if (match) {\n return match[0];\n }\n }\n // This might return undefined if the paramName is not expected to match any regex in the array,\n // which is fine for negative test cases or if the mock doesn't perfectly align.\n // For positive cases, ensure your actual implementation and regexes would provide a match.\n return paramName; // Fallback for mock simplicity, real tests need accurate keyword\n}\n\ndescribe('guessPagination()', () => {\n describe('No Pagination Detected', () => {\n test('should return \"none\" for an operation with an empty parameters array', () => {\n const op = createOperation([]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n\n test('should return \"none\" for an operation with undefined parameters', () => {\n const op = createOperation(undefined as never);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n\n test('should return \"none\" for non-pagination query parameters', () => {\n const op = createOperation([qParam('search'), qParam('filterBy')]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n\n test('should return \"none\" if relevant parameters are not in \"query\"', () => {\n const op = createOperation([hParam('offset'), hParam('limit')]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n\n test('should return \"none\" if only one part of a pair is present (e.g., only offset)', () => {\n assert.deepStrictEqual(\n guessPagination(createOperation([qParam('offset')])),\n { type: 'none' },\n 'Only offset',\n );\n assert.deepStrictEqual(\n guessPagination(createOperation([qParam('page')])),\n { type: 'none' },\n 'Only page',\n );\n assert.deepStrictEqual(\n guessPagination(createOperation([qParam('cursor')])),\n { type: 'none' },\n 'Only cursor',\n );\n assert.deepStrictEqual(\n guessPagination(createOperation([qParam('limit')])),\n { type: 'none' },\n 'Only limit',\n );\n });\n\n test('should return \"none\" for mixed non-query and insufficient query params', () => {\n const op = createOperation([\n pParam('userId'),\n qParam('offset'),\n hParam('X-Request-ID'),\n ]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n });\n\n describe('Offset Pagination Detection', () => {\n const testOffsetKeywords = [\n 'offset',\n 'skip',\n 'start',\n 'start_index',\n 'starting_at',\n 'from',\n 'Offset',\n 'SKIP',\n ];\n const testLimitKeywords = [\n 'limit',\n 'count',\n 'size',\n 'page_size',\n 'pageSize',\n 'max_results',\n 'take',\n 'Limit',\n 'COUNT',\n ];\n\n for (const offsetKey of testOffsetKeywords) {\n for (const limitKey of testLimitKeywords) {\n if (offsetKey.toLowerCase() === limitKey.toLowerCase()) continue;\n\n test(`should detect offset with \"${offsetKey}\" and \"${limitKey}\"`, () => {\n const op = createOperation([qParam(offsetKey), qParam(limitKey)]);\n const result = guessPagination(op);\n // Note: With a simple mock, these detailed assertions might fail.\n // They are designed for the actual implementation.\n assert.strictEqual(\n result.type,\n 'offset',\n `Failed for ${offsetKey}, ${limitKey}`,\n );\n assert.strictEqual(result.offsetParamName, offsetKey);\n assert.strictEqual(\n result.offsetKeyword,\n getExpectedKeyword(offsetKey, OFFSET_PARAM_REGEXES),\n );\n assert.strictEqual(result.limitParamName, limitKey);\n assert.strictEqual(\n result.limitKeyword,\n getExpectedKeyword(limitKey, GENERIC_LIMIT_PARAM_REGEXES),\n );\n });\n }\n }\n\n test('should not detect offset if one param is not in query', () => {\n const op = createOperation([hParam('offset'), qParam('limit')]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n\n test('should not detect with two offset-like params and no limit', () => {\n const op = createOperation([qParam('offset'), qParam('skip')]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n\n test('should correctly handle params in different order', () => {\n const op = createOperation([qParam('limit'), qParam('offset')]);\n const result = guessPagination(op);\n assert.strictEqual(result.type, 'offset');\n assert.strictEqual(result.offsetParamName, 'offset');\n assert.strictEqual(result.limitParamName, 'limit');\n });\n\n test('should handle extra non-pagination params', () => {\n const op = createOperation([\n qParam('filter'),\n qParam('offset'),\n qParam('sort'),\n qParam('limit'),\n ]);\n const result = guessPagination(op);\n assert.strictEqual(result.type, 'offset');\n assert.strictEqual(result.offsetParamName, 'offset');\n assert.strictEqual(result.limitParamName, 'limit');\n });\n });\n\n describe('Page Pagination Detection', () => {\n const testPageNumKeywords = [\n 'page',\n 'p',\n 'page_number',\n 'pageNum',\n 'page_idx',\n 'Page',\n 'P',\n ];\n const testPageSizeKeywords = [\n 'page_size',\n 'pageSize',\n 'size',\n 'limit',\n 'count',\n 'per_page',\n 'per-page',\n 'num_items',\n 'Size',\n 'LIMIT',\n ];\n\n for (const pageKey of testPageNumKeywords) {\n for (const sizeKey of testPageSizeKeywords) {\n if (pageKey.toLowerCase() === sizeKey.toLowerCase()) continue;\n\n test(`should detect page with \"${pageKey}\" and \"${sizeKey}\"`, () => {\n const op = createOperation([qParam(pageKey), qParam(sizeKey)]);\n const result = guessPagination(op);\n assert.strictEqual(\n result.type,\n 'page',\n `Failed for ${pageKey}, ${sizeKey}`,\n );\n assert.strictEqual(result.pageNumberParamName, pageKey);\n assert.strictEqual(\n result.pageNumberKeyword,\n getExpectedKeyword(pageKey, PAGE_NUMBER_REGEXES),\n );\n assert.strictEqual(result.pageSizeParamName, sizeKey);\n assert.strictEqual(\n result.pageSizeKeyword,\n getExpectedKeyword(sizeKey, PAGE_SIZE_REGEXES),\n );\n });\n }\n }\n test('should not detect page if one param is not in query', () => {\n const op = createOperation([hParam('page'), qParam('size')]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n\n test('should not detect with two page-number-like params and no size', () => {\n const op = createOperation([qParam('page'), qParam('page_number')]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n });\n\n describe('Cursor Pagination Detection', () => {\n const testCursorKeywords = [\n 'cursor',\n 'after',\n 'before_cursor',\n 'next_page_token',\n 'pageToken',\n 'continuation_token',\n 'Cursor',\n 'AFTER',\n ];\n const testCursorLimitKeywords = [\n 'limit',\n 'count',\n 'size',\n 'first',\n 'last',\n 'page_size',\n 'num_items',\n 'take',\n 'First',\n 'LAST',\n ];\n\n for (const cursorKey of testCursorKeywords) {\n for (const limitKey of testCursorLimitKeywords) {\n if (cursorKey.toLowerCase() === limitKey.toLowerCase()) continue;\n\n test(`should detect cursor with \"${cursorKey}\" and \"${limitKey}\"`, () => {\n const op = createOperation([qParam(cursorKey), qParam(limitKey)]);\n const result = guessPagination(op);\n assert.strictEqual(\n result.type,\n 'cursor',\n `Failed for ${cursorKey}, ${limitKey}`,\n );\n assert.strictEqual(result.cursorParamName, cursorKey);\n assert.strictEqual(\n result.cursorKeyword,\n getExpectedKeyword(cursorKey, CURSOR_REGEXES),\n );\n assert.strictEqual(result.limitParamName, limitKey);\n assert.strictEqual(\n result.limitKeyword,\n getExpectedKeyword(limitKey, CURSOR_LIMIT_REGEXES),\n );\n });\n }\n }\n test('should not detect cursor if one param is not in query', () => {\n const op = createOperation([hParam('cursor'), qParam('first')]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n\n test('should not detect with two cursor-like params and no limit', () => {\n const op = createOperation([qParam('cursor'), qParam('after')]);\n assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n });\n });\n\n describe('Pagination Type Precedence', () => {\n test('Offset should take precedence over Page (e.g., \"skip\", \"limit\", \"page\")', () => {\n // This test relies on the actual implementation's precedence logic.\n // The simple mock might not reflect this correctly.\n const op = createOperation([\n qParam('skip'),\n qParam('limit'),\n qParam('page'),\n ]);\n const result = guessPagination(op); // Assuming 'skip'/'limit' makes it 'offset'\n assert.strictEqual(result.type, 'offset');\n if (result.type === 'offset') {\n // Type guard for TS\n assert.strictEqual(result.offsetParamName, 'skip');\n assert.strictEqual(result.limitParamName, 'limit');\n }\n });\n\n test('Offset should take precedence over Cursor (e.g., \"offset\", \"count\", \"after_token\")', () => {\n const op = createOperation([\n qParam('offset'),\n qParam('count'),\n qParam('after_token'),\n ]);\n const result = guessPagination(op);\n assert.strictEqual(result.type, 'offset');\n if (result.type === 'offset') {\n assert.strictEqual(result.offsetParamName, 'offset');\n assert.strictEqual(result.limitParamName, 'count');\n }\n });\n\n test('Page should take precedence over Cursor (e.g., \"page\", \"size\", \"next_cursor\")', () => {\n const op = createOperation([\n qParam('page'),\n qParam('size'),\n qParam('next_cursor'),\n ]);\n const result = guessPagination(op);\n assert.strictEqual(result.type, 'page');\n if (result.type === 'page') {\n assert.strictEqual(result.pageNumberParamName, 'page');\n assert.strictEqual(result.pageSizeParamName, 'size');\n }\n });\n\n test('Params like \"page\" and \"limit\" should resolve to Page pagination', () => {\n const op = createOperation([qParam('page'), qParam('limit')]);\n const result = guessPagination(op);\n assert.strictEqual(result.type, 'page');\n if (result.type === 'page') {\n assert.strictEqual(result.pageNumberParamName, 'page');\n assert.strictEqual(result.pageSizeParamName, 'limit');\n }\n });\n });\n\n describe('Regex Specificity and Word Boundaries', () => {\n // These tests are highly dependent on the actual regexes and findParamAndKeyword logic.\n // The simple mock won't pass these accurately.\n test('should not match \"custom_offset\" as \"offset\" due to word boundary (with real implementation)', () => {\n const op = createOperation([\n qParam('custom_offset_param'),\n qParam('limit'),\n ]);\n // Expectation with real implementation:\n // assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n // With current simple mock, this might pass if 'limit' alone is not enough.\n assert.ok(\n true,\n 'Test needs real implementation for accurate regex boundary check',\n );\n });\n\n test('should match \"offset_custom\" for \"offset\" keyword (with real implementation)', () => {\n const op = createOperation([qParam('offset_custom'), qParam('limit')]);\n // Expectation with real implementation:\n // const result = guessPagination(op);\n // assert.strictEqual(result.type, 'offset');\n // assert.strictEqual(result.offsetParamName, 'offset_custom');\n // assert.strictEqual(result.offsetKeyword, 'offset');\n assert.ok(\n true,\n 'Test needs real implementation for accurate keyword extraction',\n );\n });\n\n test('should match \"page\" exactly for page number, not \"my_page_details\" (with real implementation)', () => {\n const op = createOperation([qParam('my_page_details'), qParam('size')]);\n // assert.deepStrictEqual(guessPagination(op), { type: 'none' });\n assert.ok(\n true,\n 'Test needs real implementation for exact regex matching',\n );\n });\n\n test('should match \"p\" exactly for page number (with real implementation)', () => {\n const op = createOperation([qParam('p'), qParam('size')]);\n // const result = guessPagination(op);\n // assert.strictEqual(result.type, 'page');\n // assert.strictEqual(result.pageNumberParamName, 'p');\n // assert.strictEqual(result.pageNumberKeyword, 'p');\n assert.ok(\n true,\n 'Test needs real implementation for exact regex matching',\n );\n });\n });\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/lib/tune.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tune.test.d.ts","sourceRoot":"","sources":["../../src/lib/tune.test.ts"],"names":[],"mappings":""}
|
package/dist/lib/tune.test.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { merge } from "lodash-es";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { toIR } from "./ir.ts";
|
|
4
|
-
function createSpec(openapi) {
|
|
5
|
-
return toIR(
|
|
6
|
-
{
|
|
7
|
-
spec: merge(
|
|
8
|
-
{
|
|
9
|
-
openapi: "3.1.0",
|
|
10
|
-
info: {
|
|
11
|
-
title: "Test API",
|
|
12
|
-
version: "1.0.0"
|
|
13
|
-
},
|
|
14
|
-
components: {
|
|
15
|
-
schemas: {},
|
|
16
|
-
securitySchemes: {}
|
|
17
|
-
},
|
|
18
|
-
paths: {}
|
|
19
|
-
},
|
|
20
|
-
openapi
|
|
21
|
-
)
|
|
22
|
-
},
|
|
23
|
-
true
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
describe("merge allof", () => {
|
|
27
|
-
it("should handle circular allOf references without stack overflow", () => {
|
|
28
|
-
const spec = createSpec({
|
|
29
|
-
components: {
|
|
30
|
-
schemas: {
|
|
31
|
-
A: {
|
|
32
|
-
allOf: [
|
|
33
|
-
{ $ref: "#/components/schemas/B" },
|
|
34
|
-
{
|
|
35
|
-
type: "object",
|
|
36
|
-
properties: {
|
|
37
|
-
nameA: { type: "string" }
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
]
|
|
41
|
-
},
|
|
42
|
-
B: {
|
|
43
|
-
allOf: [
|
|
44
|
-
{ $ref: "#/components/schemas/A" },
|
|
45
|
-
{
|
|
46
|
-
type: "object",
|
|
47
|
-
properties: {
|
|
48
|
-
nameB: { type: "string" }
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
const schemaA = spec.components.schemas.A;
|
|
57
|
-
console.dir(spec.components.schemas, { depth: null });
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
//# sourceMappingURL=tune.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/lib/tune.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { merge } from 'lodash-es';\nimport { describe, it } from 'node:test';\nimport type { OpenAPIObject, SchemaObject } from 'openapi3-ts/oas31';\n\nimport { toIR } from './ir.ts';\nimport type { IR } from './types.ts';\n\nfunction createSpec(openapi?: Partial<OpenAPIObject>): IR {\n return toIR(\n {\n spec: merge(\n {\n openapi: '3.1.0',\n info: {\n title: 'Test API',\n version: '1.0.0',\n },\n components: {\n schemas: {},\n securitySchemes: {},\n },\n paths: {},\n },\n openapi,\n ),\n },\n true,\n );\n}\n\ndescribe('merge allof', () => {\n // it('should merge allOf schemas', () => {\n // const spec = createSpec({\n // components: {\n // schemas: {\n // Base: {\n // type: 'object',\n // properties: {\n // id: { type: 'string' },\n // },\n // },\n // Extended: {\n // allOf: [\n // { $ref: '#/components/schemas/Base' },\n // {\n // type: 'object',\n // properties: {\n // name: { type: 'string' },\n // },\n // },\n // ],\n // },\n // },\n // },\n // });\n\n // const extendedSchema = spec.components.schemas.Extended as SchemaObject;\n // console.log(extendedSchema);\n // assert.deepStrictEqual(extendedSchema.type, 'object');\n // assert.deepStrictEqual(extendedSchema.properties, {\n // id: { type: 'string' },\n // name: { type: 'string' },\n // });\n // });\n // it('should handle empty allOf', () => {\n // const spec = createSpec({\n // components: {\n // schemas: {\n // EmptyAllOf: {\n // allOf: [],\n // },\n // },\n // },\n // });\n\n // const emptySchema = spec.components.schemas.EmptyAllOf as SchemaObject;\n // assert.deepStrictEqual(emptySchema.allOf, undefined);\n // assert.deepStrictEqual(emptySchema.type, undefined);\n // });\n // it('should handle allOf with only references', () => {\n // const spec = createSpec({\n // components: {\n // schemas: {\n // Base: {\n // type: 'object',\n // properties: {\n // id: { type: 'string' },\n // },\n // },\n // Extended: {\n // allOf: [\n // {\n // $ref: '#/components/schemas/Base',\n // },\n // ],\n // },\n // },\n // },\n // });\n\n // const extendedSchema = spec.components.schemas.Extended as SchemaObject;\n // assert.deepStrictEqual(extendedSchema.type, 'object');\n // assert.deepStrictEqual(extendedSchema.properties, {\n // id: {\n // type: 'string',\n // },\n // });\n // });\n\n it('should handle circular allOf references without stack overflow', () => {\n const spec = createSpec({\n components: {\n schemas: {\n A: {\n allOf: [\n { $ref: '#/components/schemas/B' },\n {\n type: 'object',\n properties: {\n nameA: { type: 'string' },\n },\n },\n ],\n },\n B: {\n allOf: [\n { $ref: '#/components/schemas/A' },\n {\n type: 'object',\n properties: {\n nameB: { type: 'string' },\n },\n },\n ],\n },\n },\n },\n });\n\n // This would cause a stack overflow with the current implementation\n const schemaA = spec.components.schemas.A as SchemaObject;\n console.dir(spec.components.schemas, { depth: null });\n // The test should not throw RangeError: Maximum call stack size exceeded\n });\n\n // it('should handle circular allOf references without stack overflow', () => {\n // const spec = createSpec({\n // components: {\n // schemas: {\n // A: {\n // allOf: [\n // { $ref: '#/components/schemas/B' },\n // {\n // type: 'object',\n // properties: {\n // nameA: { type: 'string' },\n // },\n // },\n // ],\n // },\n // B: {\n // allOf: [\n // { $ref: '#/components/schemas/A' },\n // {\n // type: 'object',\n // properties: {\n // nameB: { type: 'string' },\n // },\n // },\n // ],\n // },\n // },\n // },\n // });\n\n // // This would cause a stack overflow with the current implementation\n // const schemaA = spec.components.schemas.A as SchemaObject;\n // console.dir(spec.components.schemas, { depth: null });\n // // The test should not throw RangeError: Maximum call stack size exceeded\n // });\n\n // it('should handle self-referencing allOf', () => {\n // const spec = createSpec({\n // components: {\n // schemas: {\n // SelfRef: {\n // allOf: [\n // { $ref: '#/components/schemas/SelfRef' },\n // {\n // type: 'object',\n // properties: {\n // name: { type: 'string' },\n // },\n // },\n // ],\n // },\n // },\n // },\n // });\n\n // // This would also cause infinite recursion\n // const schema = spec.components.schemas.SelfRef as SchemaObject;\n // });\n});\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,aAAa;AACtB,SAAS,UAAU,UAAU;AAG7B,SAAS,YAAY;AAGrB,SAAS,WAAW,SAAsC;AACxD,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,QACJ;AAAA,UACE,SAAS;AAAA,UACT,MAAM;AAAA,YACJ,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,UACA,YAAY;AAAA,YACV,SAAS,CAAC;AAAA,YACV,iBAAiB,CAAC;AAAA,UACpB;AAAA,UACA,OAAO,CAAC;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,eAAe,MAAM;AA+E5B,KAAG,kEAAkE,MAAM;AACzE,UAAM,OAAO,WAAW;AAAA,MACtB,YAAY;AAAA,QACV,SAAS;AAAA,UACP,GAAG;AAAA,YACD,OAAO;AAAA,cACL,EAAE,MAAM,yBAAyB;AAAA,cACjC;AAAA,gBACE,MAAM;AAAA,gBACN,YAAY;AAAA,kBACV,OAAO,EAAE,MAAM,SAAS;AAAA,gBAC1B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,UACA,GAAG;AAAA,YACD,OAAO;AAAA,cACL,EAAE,MAAM,yBAAyB;AAAA,cACjC;AAAA,gBACE,MAAM;AAAA,gBACN,YAAY;AAAA,kBACV,OAAO,EAAE,MAAM,SAAS;AAAA,gBAC1B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,UAAU,KAAK,WAAW,QAAQ;AACxC,YAAQ,IAAI,KAAK,WAAW,SAAS,EAAE,OAAO,KAAK,CAAC;AAAA,EAEtD,CAAC;AA4DH,CAAC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|