@scalar/mock-server 0.7.2 → 0.8.0
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/CHANGELOG.md +22 -0
- package/dist/create-mock-server.d.ts.map +1 -1
- package/dist/create-mock-server.js +32 -5
- package/dist/create-mock-server.js.map +2 -2
- package/dist/libs/store.d.ts +35 -0
- package/dist/libs/store.d.ts.map +1 -0
- package/dist/libs/store.js +70 -0
- package/dist/libs/store.js.map +7 -0
- package/dist/routes/mock-any-response.d.ts +2 -2
- package/dist/routes/mock-any-response.d.ts.map +1 -1
- package/dist/routes/mock-any-response.js.map +2 -2
- package/dist/routes/mock-handler-response.d.ts +10 -0
- package/dist/routes/mock-handler-response.d.ts.map +1 -0
- package/dist/routes/mock-handler-response.js +110 -0
- package/dist/routes/mock-handler-response.js.map +7 -0
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/build-handler-context.d.ts +31 -0
- package/dist/utils/build-handler-context.d.ts.map +1 -0
- package/dist/utils/build-handler-context.js +75 -0
- package/dist/utils/build-handler-context.js.map +7 -0
- package/dist/utils/build-seed-context.d.ts +35 -0
- package/dist/utils/build-seed-context.d.ts.map +1 -0
- package/dist/utils/build-seed-context.js +53 -0
- package/dist/utils/build-seed-context.js.map +7 -0
- package/dist/utils/execute-handler.d.ts +14 -0
- package/dist/utils/execute-handler.d.ts.map +1 -0
- package/dist/utils/execute-handler.js +20 -0
- package/dist/utils/execute-handler.js.map +7 -0
- package/dist/utils/execute-seed.d.ts +14 -0
- package/dist/utils/execute-seed.d.ts.map +1 -0
- package/dist/utils/execute-seed.js +24 -0
- package/dist/utils/execute-seed.js.map +7 -0
- package/dist/utils/get-operation.d.ts +2 -2
- package/dist/utils/get-operation.d.ts.map +1 -1
- package/dist/utils/get-operation.js.map +2 -2
- package/dist/utils/handle-authentication.d.ts +2 -2
- package/dist/utils/handle-authentication.d.ts.map +1 -1
- package/dist/utils/handle-authentication.js +38 -31
- package/dist/utils/handle-authentication.js.map +2 -2
- package/dist/utils/process-openapi-document.d.ts +11 -0
- package/dist/utils/process-openapi-document.d.ts.map +1 -0
- package/dist/utils/process-openapi-document.js +59 -0
- package/dist/utils/process-openapi-document.js.map +7 -0
- package/dist/utils/store-wrapper.d.ts +31 -0
- package/dist/utils/store-wrapper.d.ts.map +1 -0
- package/dist/utils/store-wrapper.js +40 -0
- package/dist/utils/store-wrapper.js.map +7 -0
- package/package.json +9 -6
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
import { createStoreWrapper } from './store-wrapper.js';
|
|
3
|
+
/**
|
|
4
|
+
* Seed helper function type.
|
|
5
|
+
*/
|
|
6
|
+
type SeedHelper = {
|
|
7
|
+
/**
|
|
8
|
+
* Create n items using a factory function.
|
|
9
|
+
*/
|
|
10
|
+
count: (n: number, factory: () => any) => any[];
|
|
11
|
+
/**
|
|
12
|
+
* Create items from an array of objects.
|
|
13
|
+
*/
|
|
14
|
+
(items: any[]): any[];
|
|
15
|
+
/**
|
|
16
|
+
* Create a single item using a factory function (shorthand for count(1, factory)).
|
|
17
|
+
*/
|
|
18
|
+
(factory: () => any): any;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Context object provided to x-seed code.
|
|
22
|
+
*/
|
|
23
|
+
export type SeedContext = {
|
|
24
|
+
store: ReturnType<typeof createStoreWrapper>['wrappedStore'];
|
|
25
|
+
faker: typeof faker;
|
|
26
|
+
seed: SeedHelper;
|
|
27
|
+
schema: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Build the seed context with a seed helper function.
|
|
31
|
+
* The seed helper automatically uses the schema key as the collection name.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildSeedContext(schemaKey: string): SeedContext;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=build-seed-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-seed-context.d.ts","sourceRoot":"","sources":["../../src/utils/build-seed-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAGvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEpD;;GAEG;AACH,KAAK,UAAU,GAAG;IAChB;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,EAAE,CAAA;IAC/C;;OAEG;IACH,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,CAAA;IACrB;;OAEG;IACH,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,GAAG,CAAA;CAC1B,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,cAAc,CAAC,CAAA;IAC5D,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAgE/D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { faker } from "@faker-js/faker";
|
|
2
|
+
import { store } from "../libs/store.js";
|
|
3
|
+
import { createStoreWrapper } from "./store-wrapper.js";
|
|
4
|
+
function buildSeedContext(schemaKey) {
|
|
5
|
+
const { wrappedStore } = createStoreWrapper(store);
|
|
6
|
+
const seedHelper = (arg1, arg2) => {
|
|
7
|
+
if (typeof arg1 === "number" && typeof arg2 === "function") {
|
|
8
|
+
const count = arg1;
|
|
9
|
+
const factory = arg2;
|
|
10
|
+
const items = [];
|
|
11
|
+
for (let i = 0; i < count; i++) {
|
|
12
|
+
const item = factory();
|
|
13
|
+
const created = wrappedStore.create(schemaKey, item);
|
|
14
|
+
items.push(created);
|
|
15
|
+
}
|
|
16
|
+
return items;
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(arg1)) {
|
|
19
|
+
const items = [];
|
|
20
|
+
for (const item of arg1) {
|
|
21
|
+
const created = wrappedStore.create(schemaKey, item);
|
|
22
|
+
items.push(created);
|
|
23
|
+
}
|
|
24
|
+
return items;
|
|
25
|
+
}
|
|
26
|
+
if (typeof arg1 === "function") {
|
|
27
|
+
const factory = arg1;
|
|
28
|
+
const item = factory();
|
|
29
|
+
const created = wrappedStore.create(schemaKey, item);
|
|
30
|
+
return created;
|
|
31
|
+
}
|
|
32
|
+
throw new Error("Invalid seed() usage. Use seed.count(n, factory), seed(array), or seed(factory)");
|
|
33
|
+
};
|
|
34
|
+
seedHelper.count = (n, factory) => {
|
|
35
|
+
const items = [];
|
|
36
|
+
for (let i = 0; i < n; i++) {
|
|
37
|
+
const item = factory();
|
|
38
|
+
const created = wrappedStore.create(schemaKey, item);
|
|
39
|
+
items.push(created);
|
|
40
|
+
}
|
|
41
|
+
return items;
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
store: wrappedStore,
|
|
45
|
+
faker,
|
|
46
|
+
seed: seedHelper,
|
|
47
|
+
schema: schemaKey
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
buildSeedContext
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=build-seed-context.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/build-seed-context.ts"],
|
|
4
|
+
"sourcesContent": ["import { faker } from '@faker-js/faker'\n\nimport { store } from '../libs/store'\nimport { createStoreWrapper } from './store-wrapper'\n\n/**\n * Seed helper function type.\n */\ntype SeedHelper = {\n /**\n * Create n items using a factory function.\n */\n count: (n: number, factory: () => any) => any[]\n /**\n * Create items from an array of objects.\n */\n (items: any[]): any[]\n /**\n * Create a single item using a factory function (shorthand for count(1, factory)).\n */\n (factory: () => any): any\n}\n\n/**\n * Context object provided to x-seed code.\n */\nexport type SeedContext = {\n store: ReturnType<typeof createStoreWrapper>['wrappedStore']\n faker: typeof faker\n seed: SeedHelper\n schema: string\n}\n\n/**\n * Build the seed context with a seed helper function.\n * The seed helper automatically uses the schema key as the collection name.\n */\nexport function buildSeedContext(schemaKey: string): SeedContext {\n const { wrappedStore } = createStoreWrapper(store)\n\n /**\n * Seed helper function that provides a Laravel-inspired API.\n */\n const seedHelper = ((arg1: number | any[] | (() => any), arg2?: () => any) => {\n // Case 1: seed.count(n, factory)\n if (typeof arg1 === 'number' && typeof arg2 === 'function') {\n const count = arg1\n const factory = arg2\n const items: any[] = []\n\n for (let i = 0; i < count; i++) {\n const item = factory()\n const created = wrappedStore.create(schemaKey, item)\n items.push(created)\n }\n\n return items\n }\n\n // Case 2: seed(array)\n if (Array.isArray(arg1)) {\n const items: any[] = []\n\n for (const item of arg1) {\n const created = wrappedStore.create(schemaKey, item)\n items.push(created)\n }\n\n return items\n }\n\n // Case 3: seed(factory) - single item\n if (typeof arg1 === 'function') {\n const factory = arg1\n const item = factory()\n const created = wrappedStore.create(schemaKey, item)\n return created\n }\n\n throw new Error('Invalid seed() usage. Use seed.count(n, factory), seed(array), or seed(factory)')\n }) as SeedHelper\n\n // Add count method to the function\n seedHelper.count = (n: number, factory: () => any) => {\n const items: any[] = []\n\n for (let i = 0; i < n; i++) {\n const item = factory()\n const created = wrappedStore.create(schemaKey, item)\n items.push(created)\n }\n\n return items\n }\n\n return {\n store: wrappedStore,\n faker,\n seed: seedHelper,\n schema: schemaKey,\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,aAAa;AAEtB,SAAS,aAAa;AACtB,SAAS,0BAA0B;AAkC5B,SAAS,iBAAiB,WAAgC;AAC/D,QAAM,EAAE,aAAa,IAAI,mBAAmB,KAAK;AAKjD,QAAM,aAAc,CAAC,MAAoC,SAAqB;AAE5E,QAAI,OAAO,SAAS,YAAY,OAAO,SAAS,YAAY;AAC1D,YAAM,QAAQ;AACd,YAAM,UAAU;AAChB,YAAM,QAAe,CAAC;AAEtB,eAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,cAAM,OAAO,QAAQ;AACrB,cAAM,UAAU,aAAa,OAAO,WAAW,IAAI;AACnD,cAAM,KAAK,OAAO;AAAA,MACpB;AAEA,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,YAAM,QAAe,CAAC;AAEtB,iBAAW,QAAQ,MAAM;AACvB,cAAM,UAAU,aAAa,OAAO,WAAW,IAAI;AACnD,cAAM,KAAK,OAAO;AAAA,MACpB;AAEA,aAAO;AAAA,IACT;AAGA,QAAI,OAAO,SAAS,YAAY;AAC9B,YAAM,UAAU;AAChB,YAAM,OAAO,QAAQ;AACrB,YAAM,UAAU,aAAa,OAAO,WAAW,IAAI;AACnD,aAAO;AAAA,IACT;AAEA,UAAM,IAAI,MAAM,iFAAiF;AAAA,EACnG;AAGA,aAAW,QAAQ,CAAC,GAAW,YAAuB;AACpD,UAAM,QAAe,CAAC;AAEtB,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,OAAO,QAAQ;AACrB,YAAM,UAAU,aAAa,OAAO,WAAW,IAAI;AACnD,YAAM,KAAK,OAAO;AAAA,IACpB;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HandlerContext } from './build-handler-context.js';
|
|
2
|
+
/**
|
|
3
|
+
* Result of executing a handler, including the result and operation tracking.
|
|
4
|
+
*/
|
|
5
|
+
type HandlerExecutionResult = {
|
|
6
|
+
result: any;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Execute handler code in a sandboxed environment.
|
|
10
|
+
* The code has access only to the provided context (store, faker, req, res).
|
|
11
|
+
*/
|
|
12
|
+
export declare function executeHandler(code: string, context: HandlerContext): Promise<HandlerExecutionResult>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=execute-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute-handler.d.ts","sourceRoot":"","sources":["../../src/utils/execute-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAE7D;;GAEG;AACH,KAAK,sBAAsB,GAAG;IAC5B,MAAM,EAAE,GAAG,CAAA;CACZ,CAAA;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAqB3G"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
async function executeHandler(code, context) {
|
|
2
|
+
const handlerFunction = new Function(
|
|
3
|
+
"store",
|
|
4
|
+
"faker",
|
|
5
|
+
"req",
|
|
6
|
+
"res",
|
|
7
|
+
`
|
|
8
|
+
${code}
|
|
9
|
+
`
|
|
10
|
+
);
|
|
11
|
+
const result = handlerFunction(context.store, context.faker, context.req, context.res);
|
|
12
|
+
if (result instanceof Promise) {
|
|
13
|
+
return { result: await result };
|
|
14
|
+
}
|
|
15
|
+
return { result };
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
executeHandler
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=execute-handler.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/execute-handler.ts"],
|
|
4
|
+
"sourcesContent": ["import type { HandlerContext } from './build-handler-context'\n\n/**\n * Result of executing a handler, including the result and operation tracking.\n */\ntype HandlerExecutionResult = {\n result: any\n}\n\n/**\n * Execute handler code in a sandboxed environment.\n * The code has access only to the provided context (store, faker, req, res).\n */\nexport async function executeHandler(code: string, context: HandlerContext): Promise<HandlerExecutionResult> {\n // Create a function that executes the handler code with the context\n // Using Function constructor to create a sandboxed environment\n // The code is wrapped in a function body that returns the result\n const handlerFunction = new Function(\n 'store',\n 'faker',\n 'req',\n 'res',\n `\n ${code}\n `,\n )\n const result = handlerFunction(context.store, context.faker, context.req, context.res)\n\n // If the result is a Promise, await it\n if (result instanceof Promise) {\n return { result: await result }\n }\n\n return { result }\n}\n"],
|
|
5
|
+
"mappings": "AAaA,eAAsB,eAAe,MAAc,SAA0D;AAI3G,QAAM,kBAAkB,IAAI;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,IAAI;AAAA;AAAA,EAER;AACA,QAAM,SAAS,gBAAgB,QAAQ,OAAO,QAAQ,OAAO,QAAQ,KAAK,QAAQ,GAAG;AAGrF,MAAI,kBAAkB,SAAS;AAC7B,WAAO,EAAE,QAAQ,MAAM,OAAO;AAAA,EAChC;AAEA,SAAO,EAAE,OAAO;AAClB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SeedContext } from './build-seed-context.js';
|
|
2
|
+
/**
|
|
3
|
+
* Result of executing a seed handler.
|
|
4
|
+
*/
|
|
5
|
+
type SeedExecutionResult = {
|
|
6
|
+
result: any;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Execute seed code in a sandboxed environment.
|
|
10
|
+
* The code has access only to the provided context (store, faker, seed, schema).
|
|
11
|
+
*/
|
|
12
|
+
export declare function executeSeed(code: string, context: SeedContext): Promise<SeedExecutionResult>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=execute-seed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute-seed.d.ts","sourceRoot":"","sources":["../../src/utils/execute-seed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,GAAG,CAAA;CACZ,CAAA;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA4BlG"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
async function executeSeed(code, context) {
|
|
2
|
+
const seedFunction = new Function(
|
|
3
|
+
"store",
|
|
4
|
+
"faker",
|
|
5
|
+
"seed",
|
|
6
|
+
"schema",
|
|
7
|
+
`
|
|
8
|
+
${code}
|
|
9
|
+
`
|
|
10
|
+
);
|
|
11
|
+
try {
|
|
12
|
+
const result = seedFunction(context.store, context.faker, context.seed, context.schema);
|
|
13
|
+
if (result instanceof Promise) {
|
|
14
|
+
return { result: await result };
|
|
15
|
+
}
|
|
16
|
+
return { result };
|
|
17
|
+
} catch (error) {
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
executeSeed
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=execute-seed.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/execute-seed.ts"],
|
|
4
|
+
"sourcesContent": ["import type { SeedContext } from './build-seed-context'\n\n/**\n * Result of executing a seed handler.\n */\ntype SeedExecutionResult = {\n result: any\n}\n\n/**\n * Execute seed code in a sandboxed environment.\n * The code has access only to the provided context (store, faker, seed, schema).\n */\nexport async function executeSeed(code: string, context: SeedContext): Promise<SeedExecutionResult> {\n // Create a function that executes the seed code with the context\n // Using Function constructor to create a sandboxed environment\n // The code is wrapped in a function body that returns the result\n const seedFunction = new Function(\n 'store',\n 'faker',\n 'seed',\n 'schema',\n `\n ${code}\n `,\n )\n\n // Execute the seed function with the context\n try {\n const result = seedFunction(context.store, context.faker, context.seed, context.schema)\n\n // If the result is a Promise, await it\n if (result instanceof Promise) {\n return { result: await result }\n }\n\n return { result }\n } catch (error) {\n // Re-throw to be caught by the caller\n throw error\n }\n}\n"],
|
|
5
|
+
"mappings": "AAaA,eAAsB,YAAY,MAAc,SAAoD;AAIlG,QAAM,eAAe,IAAI;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,IAAI;AAAA;AAAA,EAER;AAGA,MAAI;AACF,UAAM,SAAS,aAAa,QAAQ,OAAO,QAAQ,OAAO,QAAQ,MAAM,QAAQ,MAAM;AAGtF,QAAI,kBAAkB,SAAS;AAC7B,aAAO,EAAE,QAAQ,MAAM,OAAO;AAAA,IAChC;AAEA,WAAO,EAAE,OAAO;AAAA,EAClB,SAAS,OAAO;AAEd,UAAM;AAAA,EACR;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OpenAPIV3_1 } from '@scalar/openapi-types';
|
|
2
2
|
import { type HttpMethod } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Takes a dereferenced OpenAPI document and returns all operations.
|
|
5
5
|
* Ignores other attributes, like summary, parameters, etc.
|
|
6
6
|
*/
|
|
7
|
-
export declare function getOperations(path?:
|
|
7
|
+
export declare function getOperations(path?: OpenAPIV3_1.PathItemObject): Record<HttpMethod, OpenAPIV3_1.OperationObject>;
|
|
8
8
|
//# sourceMappingURL=get-operation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-operation.d.ts","sourceRoot":"","sources":["../../src/utils/get-operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"get-operation.d.ts","sourceRoot":"","sources":["../../src/utils/get-operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,SAAS,CAAA;AAEtD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,cAAc,GAAG,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,eAAe,CAAC,CAUhH"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/get-operation.ts"],
|
|
4
|
-
"sourcesContent": ["import type {
|
|
5
|
-
"mappings": "AAEA,SAA0B,mBAAmB;AAMtC,SAAS,
|
|
4
|
+
"sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\n\nimport { type HttpMethod, httpMethods } from '@/types'\n\n/**\n * Takes a dereferenced OpenAPI document and returns all operations.\n * Ignores other attributes, like summary, parameters, etc.\n */\nexport function getOperations(path?: OpenAPIV3_1.PathItemObject): Record<HttpMethod, OpenAPIV3_1.OperationObject> {\n const operations = {} as Record<HttpMethod, OpenAPIV3_1.OperationObject>\n\n for (const method of httpMethods) {\n if (path?.[method]) {\n operations[method] = path?.[method]\n }\n }\n\n return operations\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAA0B,mBAAmB;AAMtC,SAAS,cAAc,MAAoF;AAChH,QAAM,aAAa,CAAC;AAEpB,aAAW,UAAU,aAAa;AAChC,QAAI,OAAO,MAAM,GAAG;AAClB,iBAAW,MAAM,IAAI,OAAO,MAAM;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OpenAPIV3_1 } from '@scalar/openapi-types';
|
|
2
2
|
import type { Context } from 'hono';
|
|
3
3
|
/**
|
|
4
4
|
* Handles authentication for incoming requests based on the OpenAPI document.
|
|
5
5
|
*/
|
|
6
|
-
export declare function handleAuthentication(schema?:
|
|
6
|
+
export declare function handleAuthentication(schema?: OpenAPIV3_1.Document, operation?: OpenAPIV3_1.OperationObject): (c: Context, next: () => Promise<void>) => Promise<Response | void>;
|
|
7
7
|
//# sourceMappingURL=handle-authentication.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-authentication.d.ts","sourceRoot":"","sources":["../../src/utils/handle-authentication.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"handle-authentication.d.ts","sourceRoot":"","sources":["../../src/utils/handle-authentication.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGnC;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,eAAe,IAC3F,GAAG,OAAO,EAAE,MAAM,MAAM,OAAO,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CA6H/E"}
|
|
@@ -9,16 +9,20 @@ function handleAuthentication(schema, operation) {
|
|
|
9
9
|
let securitySchemeAuthenticated = true;
|
|
10
10
|
for (const [schemeName] of Object.entries(securityRequirement)) {
|
|
11
11
|
const scheme = schema?.components?.securitySchemes?.[schemeName];
|
|
12
|
-
if (scheme) {
|
|
13
|
-
|
|
12
|
+
if (scheme && "$ref" in scheme) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (scheme && "type" in scheme) {
|
|
16
|
+
const securityScheme = scheme;
|
|
17
|
+
switch (securityScheme.type) {
|
|
14
18
|
case "http":
|
|
15
|
-
if (scheme.scheme === "basic") {
|
|
19
|
+
if ("scheme" in securityScheme && securityScheme.scheme === "basic") {
|
|
16
20
|
authScheme = "Basic";
|
|
17
21
|
const authHeader = c.req.header("Authorization");
|
|
18
22
|
if (authHeader?.startsWith("Basic ")) {
|
|
19
23
|
isAuthenticated = true;
|
|
20
24
|
}
|
|
21
|
-
} else if (scheme.scheme === "bearer") {
|
|
25
|
+
} else if ("scheme" in securityScheme && securityScheme.scheme === "bearer") {
|
|
22
26
|
authScheme = "Bearer";
|
|
23
27
|
const authHeader = c.req.header("Authorization");
|
|
24
28
|
if (authHeader?.startsWith("Bearer ")) {
|
|
@@ -27,21 +31,23 @@ function handleAuthentication(schema, operation) {
|
|
|
27
31
|
}
|
|
28
32
|
break;
|
|
29
33
|
case "apiKey":
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
if ("name" in securityScheme && "in" in securityScheme && securityScheme.name) {
|
|
35
|
+
authScheme = `ApiKey ${securityScheme.name}`;
|
|
36
|
+
if (securityScheme.in === "header") {
|
|
37
|
+
const apiKey = c.req.header(securityScheme.name);
|
|
38
|
+
if (apiKey) {
|
|
39
|
+
isAuthenticated = true;
|
|
40
|
+
}
|
|
41
|
+
} else if (securityScheme.in === "query") {
|
|
42
|
+
const apiKey = c.req.query(securityScheme.name);
|
|
43
|
+
if (apiKey) {
|
|
44
|
+
isAuthenticated = true;
|
|
45
|
+
}
|
|
46
|
+
} else if (securityScheme.in === "cookie") {
|
|
47
|
+
const apiKey = getCookie(c, securityScheme.name);
|
|
48
|
+
if (apiKey) {
|
|
49
|
+
isAuthenticated = true;
|
|
50
|
+
}
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
break;
|
|
@@ -71,18 +77,19 @@ function handleAuthentication(schema, operation) {
|
|
|
71
77
|
}
|
|
72
78
|
if (!isAuthenticated) {
|
|
73
79
|
let wwwAuthenticateValue = authScheme;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
80
|
+
if (authScheme.startsWith("ApiKey")) {
|
|
81
|
+
wwwAuthenticateValue += ` realm="Scalar Mock Server", error="invalid_token", error_description="Invalid or missing API key"`;
|
|
82
|
+
} else {
|
|
83
|
+
switch (authScheme) {
|
|
84
|
+
case "Basic":
|
|
85
|
+
wwwAuthenticateValue += ' realm="Scalar Mock Server", charset="UTF-8"';
|
|
86
|
+
break;
|
|
87
|
+
case "Bearer":
|
|
88
|
+
wwwAuthenticateValue += ' realm="Scalar Mock Server", error="invalid_token", error_description="The access token is invalid or has expired"';
|
|
89
|
+
break;
|
|
90
|
+
default:
|
|
91
|
+
wwwAuthenticateValue = 'Bearer realm="Scalar Mock Server"';
|
|
92
|
+
}
|
|
86
93
|
}
|
|
87
94
|
c.header("WWW-Authenticate", wwwAuthenticateValue);
|
|
88
95
|
return c.json(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/handle-authentication.ts"],
|
|
4
|
-
"sourcesContent": ["import type {
|
|
5
|
-
"mappings": "AAEA,SAAS,iBAAiB;AAKnB,SAAS,qBAAqB,
|
|
4
|
+
"sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\nimport type { Context } from 'hono'\nimport { getCookie } from 'hono/cookie'\n\n/**\n * Handles authentication for incoming requests based on the OpenAPI document.\n */\nexport function handleAuthentication(schema?: OpenAPIV3_1.Document, operation?: OpenAPIV3_1.OperationObject) {\n return async (c: Context, next: () => Promise<void>): Promise<Response | void> => {\n const operationSecuritySchemes = operation?.security || schema?.security\n\n if (operationSecuritySchemes && operationSecuritySchemes.length > 0) {\n let isAuthenticated = false\n let authScheme = ''\n\n for (const securityRequirement of operationSecuritySchemes) {\n let securitySchemeAuthenticated = true\n\n for (const [schemeName] of Object.entries(securityRequirement)) {\n const scheme = schema?.components?.securitySchemes?.[schemeName]\n\n // Skip if scheme is a reference object (should be dereferenced already, but check to be safe)\n if (scheme && '$ref' in scheme) {\n continue\n }\n\n if (scheme && 'type' in scheme) {\n const securityScheme = scheme as OpenAPIV3_1.SecuritySchemeObject\n\n switch (securityScheme.type) {\n case 'http':\n if ('scheme' in securityScheme && securityScheme.scheme === 'basic') {\n authScheme = 'Basic'\n const authHeader = c.req.header('Authorization')\n\n if (authHeader?.startsWith('Basic ')) {\n isAuthenticated = true\n }\n } else if ('scheme' in securityScheme && securityScheme.scheme === 'bearer') {\n authScheme = 'Bearer'\n const authHeader = c.req.header('Authorization')\n\n if (authHeader?.startsWith('Bearer ')) {\n isAuthenticated = true\n }\n }\n break\n case 'apiKey':\n if ('name' in securityScheme && 'in' in securityScheme && securityScheme.name) {\n authScheme = `ApiKey ${securityScheme.name}`\n\n if (securityScheme.in === 'header') {\n const apiKey = c.req.header(securityScheme.name)\n if (apiKey) {\n isAuthenticated = true\n }\n } else if (securityScheme.in === 'query') {\n const apiKey = c.req.query(securityScheme.name)\n\n if (apiKey) {\n isAuthenticated = true\n }\n } else if (securityScheme.in === 'cookie') {\n const apiKey = getCookie(c, securityScheme.name)\n\n if (apiKey) {\n isAuthenticated = true\n }\n }\n }\n break\n case 'oauth2':\n authScheme = 'Bearer'\n // Handle OAuth 2.0 flows, including password grant\n if (c.req.header('Authorization')?.startsWith('Bearer ')) {\n isAuthenticated = true\n }\n break\n case 'openIdConnect':\n authScheme = 'Bearer'\n // Handle OpenID Connect similar to OAuth2\n if (c.req.header('Authorization')?.startsWith('Bearer ')) {\n isAuthenticated = true\n }\n break\n }\n }\n\n if (!isAuthenticated) {\n securitySchemeAuthenticated = false\n break\n }\n }\n\n if (securitySchemeAuthenticated) {\n isAuthenticated = true\n break\n }\n }\n\n if (!isAuthenticated) {\n let wwwAuthenticateValue = authScheme\n\n if (authScheme.startsWith('ApiKey')) {\n wwwAuthenticateValue += ` realm=\"Scalar Mock Server\", error=\"invalid_token\", error_description=\"Invalid or missing API key\"`\n } else {\n switch (authScheme) {\n case 'Basic':\n wwwAuthenticateValue += ' realm=\"Scalar Mock Server\", charset=\"UTF-8\"'\n break\n case 'Bearer':\n wwwAuthenticateValue +=\n ' realm=\"Scalar Mock Server\", error=\"invalid_token\", error_description=\"The access token is invalid or has expired\"'\n break\n default:\n wwwAuthenticateValue = 'Bearer realm=\"Scalar Mock Server\"'\n }\n }\n\n c.header('WWW-Authenticate', wwwAuthenticateValue)\n return c.json(\n {\n error: 'Unauthorized',\n message: 'Authentication is required to access this resource.',\n },\n 401,\n )\n }\n }\n\n // If all checks pass, continue to the next middleware\n await next()\n }\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,iBAAiB;AAKnB,SAAS,qBAAqB,QAA+B,WAAyC;AAC3G,SAAO,OAAO,GAAY,SAAwD;AAChF,UAAM,2BAA2B,WAAW,YAAY,QAAQ;AAEhE,QAAI,4BAA4B,yBAAyB,SAAS,GAAG;AACnE,UAAI,kBAAkB;AACtB,UAAI,aAAa;AAEjB,iBAAW,uBAAuB,0BAA0B;AAC1D,YAAI,8BAA8B;AAElC,mBAAW,CAAC,UAAU,KAAK,OAAO,QAAQ,mBAAmB,GAAG;AAC9D,gBAAM,SAAS,QAAQ,YAAY,kBAAkB,UAAU;AAG/D,cAAI,UAAU,UAAU,QAAQ;AAC9B;AAAA,UACF;AAEA,cAAI,UAAU,UAAU,QAAQ;AAC9B,kBAAM,iBAAiB;AAEvB,oBAAQ,eAAe,MAAM;AAAA,cAC3B,KAAK;AACH,oBAAI,YAAY,kBAAkB,eAAe,WAAW,SAAS;AACnE,+BAAa;AACb,wBAAM,aAAa,EAAE,IAAI,OAAO,eAAe;AAE/C,sBAAI,YAAY,WAAW,QAAQ,GAAG;AACpC,sCAAkB;AAAA,kBACpB;AAAA,gBACF,WAAW,YAAY,kBAAkB,eAAe,WAAW,UAAU;AAC3E,+BAAa;AACb,wBAAM,aAAa,EAAE,IAAI,OAAO,eAAe;AAE/C,sBAAI,YAAY,WAAW,SAAS,GAAG;AACrC,sCAAkB;AAAA,kBACpB;AAAA,gBACF;AACA;AAAA,cACF,KAAK;AACH,oBAAI,UAAU,kBAAkB,QAAQ,kBAAkB,eAAe,MAAM;AAC7E,+BAAa,UAAU,eAAe,IAAI;AAE1C,sBAAI,eAAe,OAAO,UAAU;AAClC,0BAAM,SAAS,EAAE,IAAI,OAAO,eAAe,IAAI;AAC/C,wBAAI,QAAQ;AACV,wCAAkB;AAAA,oBACpB;AAAA,kBACF,WAAW,eAAe,OAAO,SAAS;AACxC,0BAAM,SAAS,EAAE,IAAI,MAAM,eAAe,IAAI;AAE9C,wBAAI,QAAQ;AACV,wCAAkB;AAAA,oBACpB;AAAA,kBACF,WAAW,eAAe,OAAO,UAAU;AACzC,0BAAM,SAAS,UAAU,GAAG,eAAe,IAAI;AAE/C,wBAAI,QAAQ;AACV,wCAAkB;AAAA,oBACpB;AAAA,kBACF;AAAA,gBACF;AACA;AAAA,cACF,KAAK;AACH,6BAAa;AAEb,oBAAI,EAAE,IAAI,OAAO,eAAe,GAAG,WAAW,SAAS,GAAG;AACxD,oCAAkB;AAAA,gBACpB;AACA;AAAA,cACF,KAAK;AACH,6BAAa;AAEb,oBAAI,EAAE,IAAI,OAAO,eAAe,GAAG,WAAW,SAAS,GAAG;AACxD,oCAAkB;AAAA,gBACpB;AACA;AAAA,YACJ;AAAA,UACF;AAEA,cAAI,CAAC,iBAAiB;AACpB,0CAA8B;AAC9B;AAAA,UACF;AAAA,QACF;AAEA,YAAI,6BAA6B;AAC/B,4BAAkB;AAClB;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,iBAAiB;AACpB,YAAI,uBAAuB;AAE3B,YAAI,WAAW,WAAW,QAAQ,GAAG;AACnC,kCAAwB;AAAA,QAC1B,OAAO;AACL,kBAAQ,YAAY;AAAA,YAClB,KAAK;AACH,sCAAwB;AACxB;AAAA,YACF,KAAK;AACH,sCACE;AACF;AAAA,YACF;AACE,qCAAuB;AAAA,UAC3B;AAAA,QACF;AAEA,UAAE,OAAO,oBAAoB,oBAAoB;AACjD,eAAO,EAAE;AAAA,UACP;AAAA,YACE,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,KAAK;AAAA,EACb;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { OpenAPIV3_1 } from '@scalar/openapi-types';
|
|
2
|
+
/**
|
|
3
|
+
* Processes an OpenAPI document by bundling external references, upgrading to OpenAPI 3.1,
|
|
4
|
+
* and dereferencing the document.
|
|
5
|
+
*
|
|
6
|
+
* @param document - The OpenAPI document to process. Can be a string (URL/path) or an object.
|
|
7
|
+
* @returns A promise that resolves to the dereferenced OpenAPI 3.1 document.
|
|
8
|
+
* @throws Error if the document cannot be processed or is invalid.
|
|
9
|
+
*/
|
|
10
|
+
export declare function processOpenApiDocument(document: string | Record<string, any> | undefined): Promise<OpenAPIV3_1.Document>;
|
|
11
|
+
//# sourceMappingURL=process-openapi-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-openapi-document.d.ts","sourceRoot":"","sources":["../../src/utils/process-openapi-document.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGxD;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GACjD,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAoE/B"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { bundle } from "@scalar/json-magic/bundle";
|
|
2
|
+
import { parseJson } from "@scalar/json-magic/bundle/plugins/node";
|
|
3
|
+
import { parseYaml } from "@scalar/json-magic/bundle/plugins/node";
|
|
4
|
+
import { readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
5
|
+
import { fetchUrls } from "@scalar/json-magic/bundle/plugins/node";
|
|
6
|
+
import { dereference } from "@scalar/openapi-parser";
|
|
7
|
+
import { upgrade } from "@scalar/openapi-upgrader";
|
|
8
|
+
async function processOpenApiDocument(document) {
|
|
9
|
+
if (!document || typeof document === "object" && Object.keys(document).length === 0) {
|
|
10
|
+
return {
|
|
11
|
+
openapi: "3.1.0",
|
|
12
|
+
info: {
|
|
13
|
+
title: "Mock API",
|
|
14
|
+
version: "1.0.0"
|
|
15
|
+
},
|
|
16
|
+
paths: {}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
let bundled;
|
|
20
|
+
try {
|
|
21
|
+
bundled = await bundle(document, {
|
|
22
|
+
plugins: [parseJson(), parseYaml(), readFiles(), fetchUrls()],
|
|
23
|
+
treeShake: false
|
|
24
|
+
});
|
|
25
|
+
} catch (error) {
|
|
26
|
+
throw new Error(`Failed to bundle OpenAPI document: ${error instanceof Error ? error.message : String(error)}`);
|
|
27
|
+
}
|
|
28
|
+
if (!bundled || typeof bundled !== "object") {
|
|
29
|
+
throw new Error("Bundled document is invalid: expected an object");
|
|
30
|
+
}
|
|
31
|
+
let upgraded;
|
|
32
|
+
try {
|
|
33
|
+
upgraded = upgrade(bundled, "3.1");
|
|
34
|
+
} catch (error) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Failed to upgrade OpenAPI document to 3.1: ${error instanceof Error ? error.message : String(error)}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (!upgraded) {
|
|
40
|
+
throw new Error("Upgraded document is invalid: upgrade returned null or undefined");
|
|
41
|
+
}
|
|
42
|
+
const dereferenceResult = dereference(upgraded);
|
|
43
|
+
if (dereferenceResult.errors && dereferenceResult.errors.length > 0) {
|
|
44
|
+
const errorMessages = dereferenceResult.errors.map((err) => err.message).join(", ");
|
|
45
|
+
throw new Error(`Failed to dereference OpenAPI document: ${errorMessages}`);
|
|
46
|
+
}
|
|
47
|
+
const schema = dereferenceResult.schema;
|
|
48
|
+
if (!schema) {
|
|
49
|
+
throw new Error("Dereference result does not contain a schema");
|
|
50
|
+
}
|
|
51
|
+
if (typeof schema !== "object") {
|
|
52
|
+
throw new Error("Dereferenced schema is invalid: expected an object");
|
|
53
|
+
}
|
|
54
|
+
return schema;
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
processOpenApiDocument
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=process-openapi-document.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/process-openapi-document.ts"],
|
|
4
|
+
"sourcesContent": ["import { bundle } from '@scalar/json-magic/bundle'\nimport { parseJson } from '@scalar/json-magic/bundle/plugins/node'\nimport { parseYaml } from '@scalar/json-magic/bundle/plugins/node'\nimport { readFiles } from '@scalar/json-magic/bundle/plugins/node'\nimport { fetchUrls } from '@scalar/json-magic/bundle/plugins/node'\nimport { dereference } from '@scalar/openapi-parser'\nimport type { OpenAPIV3_1 } from '@scalar/openapi-types'\nimport { upgrade } from '@scalar/openapi-upgrader'\n\n/**\n * Processes an OpenAPI document by bundling external references, upgrading to OpenAPI 3.1,\n * and dereferencing the document.\n *\n * @param document - The OpenAPI document to process. Can be a string (URL/path) or an object.\n * @returns A promise that resolves to the dereferenced OpenAPI 3.1 document.\n * @throws Error if the document cannot be processed or is invalid.\n */\nexport async function processOpenApiDocument(\n document: string | Record<string, any> | undefined,\n): Promise<OpenAPIV3_1.Document> {\n // Handle empty/undefined input gracefully\n if (!document || (typeof document === 'object' && Object.keys(document).length === 0)) {\n // Return a minimal valid OpenAPI 3.1 document\n return {\n openapi: '3.1.0',\n info: {\n title: 'Mock API',\n version: '1.0.0',\n },\n paths: {},\n }\n }\n\n let bundled: Record<string, any>\n\n try {\n // Bundle external references with Node.js plugins\n // Include parseJson and parseYaml to handle string inputs\n bundled = await bundle(document, {\n plugins: [parseJson(), parseYaml(), readFiles(), fetchUrls()],\n treeShake: false,\n })\n } catch (error) {\n throw new Error(`Failed to bundle OpenAPI document: ${error instanceof Error ? error.message : String(error)}`)\n }\n\n if (!bundled || typeof bundled !== 'object') {\n throw new Error('Bundled document is invalid: expected an object')\n }\n\n let upgraded: OpenAPIV3_1.Document\n\n try {\n // Upgrade to OpenAPI 3.1\n upgraded = upgrade(bundled, '3.1')\n } catch (error) {\n throw new Error(\n `Failed to upgrade OpenAPI document to 3.1: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n\n if (!upgraded) {\n throw new Error('Upgraded document is invalid: upgrade returned null or undefined')\n }\n\n // Dereference the document\n const dereferenceResult = dereference(upgraded)\n\n // Check for dereference errors\n if (dereferenceResult.errors && dereferenceResult.errors.length > 0) {\n const errorMessages = dereferenceResult.errors.map((err) => err.message).join(', ')\n throw new Error(`Failed to dereference OpenAPI document: ${errorMessages}`)\n }\n\n // Extract the schema from the dereference result\n const schema = dereferenceResult.schema\n\n if (!schema) {\n throw new Error('Dereference result does not contain a schema')\n }\n\n // Ensure the schema is a valid OpenAPI 3.1 document\n if (typeof schema !== 'object') {\n throw new Error('Dereferenced schema is invalid: expected an object')\n }\n\n return schema as OpenAPIV3_1.Document\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAE5B,SAAS,eAAe;AAUxB,eAAsB,uBACpB,UAC+B;AAE/B,MAAI,CAAC,YAAa,OAAO,aAAa,YAAY,OAAO,KAAK,QAAQ,EAAE,WAAW,GAAI;AAErF,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAAA,MACA,OAAO,CAAC;AAAA,IACV;AAAA,EACF;AAEA,MAAI;AAEJ,MAAI;AAGF,cAAU,MAAM,OAAO,UAAU;AAAA,MAC/B,SAAS,CAAC,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;AAAA,MAC5D,WAAW;AAAA,IACb,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,sCAAsC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,EAChH;AAEA,MAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AAEA,MAAI;AAEJ,MAAI;AAEF,eAAW,QAAQ,SAAS,KAAK;AAAA,EACnC,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,8CAA8C,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IACtG;AAAA,EACF;AAEA,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AAGA,QAAM,oBAAoB,YAAY,QAAQ;AAG9C,MAAI,kBAAkB,UAAU,kBAAkB,OAAO,SAAS,GAAG;AACnE,UAAM,gBAAgB,kBAAkB,OAAO,IAAI,CAAC,QAAQ,IAAI,OAAO,EAAE,KAAK,IAAI;AAClF,UAAM,IAAI,MAAM,2CAA2C,aAAa,EAAE;AAAA,EAC5E;AAGA,QAAM,SAAS,kBAAkB;AAEjC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAGA,MAAI,OAAO,WAAW,UAAU;AAC9B,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Store } from '../libs/store.js';
|
|
2
|
+
/**
|
|
3
|
+
* Public interface of the Store class (methods only, no private properties).
|
|
4
|
+
*/
|
|
5
|
+
type StoreInterface = Pick<Store, 'list' | 'get' | 'create' | 'update' | 'delete' | 'clear'>;
|
|
6
|
+
/**
|
|
7
|
+
* Represents a single store operation with its result.
|
|
8
|
+
*/
|
|
9
|
+
type StoreOperation = {
|
|
10
|
+
/** The operation method name that was called. */
|
|
11
|
+
operation: 'get' | 'create' | 'update' | 'delete' | 'list';
|
|
12
|
+
/** The result of the operation. */
|
|
13
|
+
result: any;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Tracks all store operations performed.
|
|
17
|
+
*/
|
|
18
|
+
export type StoreOperationTracking = {
|
|
19
|
+
/** All operations performed, in order. */
|
|
20
|
+
operations: StoreOperation[];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Creates a wrapped store that tracks operations.
|
|
24
|
+
* Returns both the wrapped store and a tracking object that gets updated as operations are performed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createStoreWrapper(store: Store): {
|
|
27
|
+
wrappedStore: StoreInterface;
|
|
28
|
+
tracking: StoreOperationTracking;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=store-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-wrapper.d.ts","sourceRoot":"","sources":["../../src/utils/store-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAE1C;;GAEG;AACH,KAAK,cAAc,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAA;AAE5F;;GAEG;AACH,KAAK,cAAc,GAAG;IACpB,iDAAiD;IACjD,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAA;IAC1D,mCAAmC;IACnC,MAAM,EAAE,GAAG,CAAA;CACZ,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,0CAA0C;IAC1C,UAAU,EAAE,cAAc,EAAE,CAAA;CAC7B,CAAA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG;IAChD,YAAY,EAAE,cAAc,CAAA;IAC5B,QAAQ,EAAE,sBAAsB,CAAA;CACjC,CA2CA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
function createStoreWrapper(store) {
|
|
2
|
+
const tracking = {
|
|
3
|
+
operations: []
|
|
4
|
+
};
|
|
5
|
+
const wrappedStore = {
|
|
6
|
+
list(collection) {
|
|
7
|
+
const result = store.list(collection);
|
|
8
|
+
tracking.operations.push({ operation: "list", result });
|
|
9
|
+
return result;
|
|
10
|
+
},
|
|
11
|
+
get(collection, id) {
|
|
12
|
+
const result = store.get(collection, id);
|
|
13
|
+
tracking.operations.push({ operation: "get", result });
|
|
14
|
+
return result;
|
|
15
|
+
},
|
|
16
|
+
create(collection, data) {
|
|
17
|
+
const result = store.create(collection, data);
|
|
18
|
+
tracking.operations.push({ operation: "create", result });
|
|
19
|
+
return result;
|
|
20
|
+
},
|
|
21
|
+
update(collection, id, data) {
|
|
22
|
+
const result = store.update(collection, id, data);
|
|
23
|
+
tracking.operations.push({ operation: "update", result });
|
|
24
|
+
return result;
|
|
25
|
+
},
|
|
26
|
+
delete(collection, id) {
|
|
27
|
+
const result = store.delete(collection, id);
|
|
28
|
+
tracking.operations.push({ operation: "delete", result });
|
|
29
|
+
return result;
|
|
30
|
+
},
|
|
31
|
+
clear(collection) {
|
|
32
|
+
store.clear(collection);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return { wrappedStore, tracking };
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
createStoreWrapper
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=store-wrapper.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/store-wrapper.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Store } from '../libs/store'\n\n/**\n * Public interface of the Store class (methods only, no private properties).\n */\ntype StoreInterface = Pick<Store, 'list' | 'get' | 'create' | 'update' | 'delete' | 'clear'>\n\n/**\n * Represents a single store operation with its result.\n */\ntype StoreOperation = {\n /** The operation method name that was called. */\n operation: 'get' | 'create' | 'update' | 'delete' | 'list'\n /** The result of the operation. */\n result: any\n}\n\n/**\n * Tracks all store operations performed.\n */\nexport type StoreOperationTracking = {\n /** All operations performed, in order. */\n operations: StoreOperation[]\n}\n\n/**\n * Creates a wrapped store that tracks operations.\n * Returns both the wrapped store and a tracking object that gets updated as operations are performed.\n */\nexport function createStoreWrapper(store: Store): {\n wrappedStore: StoreInterface\n tracking: StoreOperationTracking\n} {\n const tracking: StoreOperationTracking = {\n operations: [],\n }\n\n const wrappedStore = {\n list(collection: string) {\n const result = store.list(collection)\n tracking.operations.push({ operation: 'list', result })\n return result\n },\n\n get(collection: string, id: string) {\n const result = store.get(collection, id)\n tracking.operations.push({ operation: 'get', result })\n return result\n },\n\n create(collection: string, data: any) {\n const result = store.create(collection, data)\n tracking.operations.push({ operation: 'create', result })\n return result\n },\n\n update(collection: string, id: string, data: any) {\n const result = store.update(collection, id, data)\n tracking.operations.push({ operation: 'update', result })\n return result\n },\n\n delete(collection: string, id: string) {\n const result = store.delete(collection, id)\n tracking.operations.push({ operation: 'delete', result })\n return result\n },\n\n clear(collection?: string) {\n store.clear(collection)\n // clear() doesn't set tracking as it's not a typical CRUD operation\n },\n }\n\n return { wrappedStore, tracking }\n}\n"],
|
|
5
|
+
"mappings": "AA6BO,SAAS,mBAAmB,OAGjC;AACA,QAAM,WAAmC;AAAA,IACvC,YAAY,CAAC;AAAA,EACf;AAEA,QAAM,eAAe;AAAA,IACnB,KAAK,YAAoB;AACvB,YAAM,SAAS,MAAM,KAAK,UAAU;AACpC,eAAS,WAAW,KAAK,EAAE,WAAW,QAAQ,OAAO,CAAC;AACtD,aAAO;AAAA,IACT;AAAA,IAEA,IAAI,YAAoB,IAAY;AAClC,YAAM,SAAS,MAAM,IAAI,YAAY,EAAE;AACvC,eAAS,WAAW,KAAK,EAAE,WAAW,OAAO,OAAO,CAAC;AACrD,aAAO;AAAA,IACT;AAAA,IAEA,OAAO,YAAoB,MAAW;AACpC,YAAM,SAAS,MAAM,OAAO,YAAY,IAAI;AAC5C,eAAS,WAAW,KAAK,EAAE,WAAW,UAAU,OAAO,CAAC;AACxD,aAAO;AAAA,IACT;AAAA,IAEA,OAAO,YAAoB,IAAY,MAAW;AAChD,YAAM,SAAS,MAAM,OAAO,YAAY,IAAI,IAAI;AAChD,eAAS,WAAW,KAAK,EAAE,WAAW,UAAU,OAAO,CAAC;AACxD,aAAO;AAAA,IACT;AAAA,IAEA,OAAO,YAAoB,IAAY;AACrC,YAAM,SAAS,MAAM,OAAO,YAAY,EAAE;AAC1C,eAAS,WAAW,KAAK,EAAE,WAAW,UAAU,OAAO,CAAC;AACxD,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,YAAqB;AACzB,YAAM,MAAM,UAAU;AAAA,IAExB;AAAA,EACF;AAEA,SAAO,EAAE,cAAc,SAAS;AAClC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|