ts-ag 0.0.1-dev.1 → 0.0.1-dev.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/dist/browser.d.ts +1 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lambda/client-types.d.ts +49 -35
- package/dist/lambda/client-types.d.ts.map +1 -1
- package/dist/lambda/client-types.js +3 -1
- package/dist/lambda/client.d.ts +4 -15
- package/dist/lambda/client.d.ts.map +1 -1
- package/dist/lambda/client.js +10 -6
- package/dist/lambda/errors.d.ts +46 -0
- package/dist/lambda/errors.d.ts.map +1 -0
- package/dist/lambda/errors.js +38 -0
- package/dist/lambda/handlerUtils.d.ts +18 -1
- package/dist/lambda/handlerUtils.d.ts.map +1 -1
- package/dist/lambda/index.d.ts +2 -0
- package/dist/lambda/index.d.ts.map +1 -1
- package/dist/lambda/index.js +2 -0
- package/dist/lambda/response.d.ts +127 -0
- package/dist/lambda/response.d.ts.map +1 -0
- package/dist/lambda/response.js +76 -0
- package/dist/rehype/browser.d.ts +2 -0
- package/dist/rehype/browser.d.ts.map +1 -0
- package/dist/rehype/browser.js +1 -0
- package/dist/rehype/flat-toc.d.ts +20 -0
- package/dist/rehype/flat-toc.d.ts.map +1 -0
- package/dist/rehype/flat-toc.js +58 -0
- package/dist/rehype/index.d.ts +2 -0
- package/dist/rehype/index.d.ts.map +1 -0
- package/dist/rehype/index.js +1 -0
- package/dist/scripts/clean.d.ts +3 -0
- package/dist/scripts/clean.d.ts.map +1 -0
- package/dist/scripts/clean.js +64 -0
- package/dist/ts-alias.js +0 -0
- package/dist/utils/fs.d.ts +9 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +38 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +1 -0
- package/package.json +12 -2
- package/src/browser.ts +1 -0
- package/src/index.ts +2 -0
- package/src/lambda/client-types.ts +74 -32
- package/src/lambda/client.ts +18 -15
- package/src/lambda/errors.ts +58 -0
- package/src/lambda/handlerUtils.ts +34 -11
- package/src/lambda/index.ts +2 -0
- package/src/lambda/response.ts +81 -0
- package/src/rehype/browser.ts +1 -0
- package/src/rehype/flat-toc.ts +78 -0
- package/src/rehype/index.ts +1 -0
- package/src/scripts/clean.ts +75 -0
- package/src/utils/fs.ts +42 -0
- package/src/utils/index.ts +1 -0
package/dist/browser.d.ts
CHANGED
package/dist/browser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAA"}
|
package/dist/browser.js
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,28 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
* Converts a RawApiGatewayHandler response type to a fetch like response type.
|
|
3
|
-
*/
|
|
4
|
-
type ConvertToFetch<T> = T extends {
|
|
5
|
-
statusCode: number;
|
|
6
|
-
body: object;
|
|
7
|
-
headers: object;
|
|
8
|
-
} ? {
|
|
9
|
-
ok: T['statusCode'] extends 200 | 201 | 204 ? true : false;
|
|
10
|
-
json: () => Promise<T['body']>;
|
|
11
|
-
status: T['statusCode'];
|
|
12
|
-
} : T;
|
|
13
|
-
export type CleanResponse = Omit<Response, 'status' | 'ok' | 'json'>;
|
|
14
|
-
export type FetchResponse<T extends (...args: any) => any> = ConvertToFetch<Awaited<ReturnType<T>>> & CleanResponse;
|
|
1
|
+
import type { ErrorBody, SuccessCode, ErrorCode } from './handlerUtils.js';
|
|
15
2
|
/**
|
|
16
3
|
* Extracts the requestInput type from an API endpoint definition
|
|
17
4
|
* @template E - Union type of all API endpoints
|
|
18
5
|
* @template P - Path string literal type (e.g. 'payments/account')
|
|
19
6
|
* @template M - HTTP method string literal type (e.g. 'GET', 'POST')
|
|
20
7
|
*/
|
|
21
|
-
export type ApiInput<E extends {
|
|
22
|
-
path: string;
|
|
23
|
-
method: string;
|
|
24
|
-
requestInput: any;
|
|
25
|
-
}, P extends E['path'], M extends E['method']> = Extract<E, {
|
|
8
|
+
export type ApiInput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<E, {
|
|
26
9
|
path: P;
|
|
27
10
|
method: M;
|
|
28
11
|
}>['requestInput'];
|
|
@@ -32,11 +15,7 @@ export type ApiInput<E extends {
|
|
|
32
15
|
* @template P - Path string literal type (e.g. 'payments/account')
|
|
33
16
|
* @template M - HTTP method string literal type (e.g. 'GET', 'POST')
|
|
34
17
|
*/
|
|
35
|
-
export type ApiOutput<E extends {
|
|
36
|
-
path: string;
|
|
37
|
-
method: string;
|
|
38
|
-
requestOutput: any;
|
|
39
|
-
}, P extends E['path'], M extends E['method']> = Extract<E, {
|
|
18
|
+
export type ApiOutput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<E, {
|
|
40
19
|
path: P;
|
|
41
20
|
method: M;
|
|
42
21
|
}>['requestOutput'];
|
|
@@ -46,11 +25,7 @@ export type ApiOutput<E extends {
|
|
|
46
25
|
* @template P - Path string literal type (e.g. 'payments/account')
|
|
47
26
|
* @template M - HTTP method string literal type (e.g. 'GET', 'POST')
|
|
48
27
|
*/
|
|
49
|
-
export type ApiResponse<E extends {
|
|
50
|
-
path: string;
|
|
51
|
-
method: string;
|
|
52
|
-
response: any;
|
|
53
|
-
}, P extends E['path'], M extends E['method']> = Extract<E, {
|
|
28
|
+
export type ApiResponse<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<E, {
|
|
54
29
|
path: P;
|
|
55
30
|
method: M;
|
|
56
31
|
}>['response'];
|
|
@@ -60,15 +35,54 @@ export type ApiResponse<E extends {
|
|
|
60
35
|
* @template P - Path string literal type (e.g. 'payments/account')
|
|
61
36
|
* @template M - HTTP method string literal type (e.g. 'GET', 'POST')
|
|
62
37
|
*/
|
|
63
|
-
export type ApiSuccessBody<E extends {
|
|
64
|
-
path: string;
|
|
65
|
-
method: string;
|
|
66
|
-
response: any;
|
|
67
|
-
}, P extends E['path'], M extends E['method']> = Extract<Extract<E, {
|
|
38
|
+
export type ApiSuccessBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<Extract<E, {
|
|
68
39
|
path: P;
|
|
69
40
|
method: M;
|
|
70
41
|
}>['response'], {
|
|
71
|
-
status:
|
|
42
|
+
status: SuccessCode;
|
|
72
43
|
}>['json'] extends () => Promise<infer R> ? R : unknown;
|
|
44
|
+
/**
|
|
45
|
+
* Extracts the sucessful body type from an API endpoint definition
|
|
46
|
+
* @template E - Union type of all API endpoints
|
|
47
|
+
* @template P - Path string literal type (e.g. 'payments/account')
|
|
48
|
+
* @template M - HTTP method string literal type (e.g. 'GET', 'POST')
|
|
49
|
+
*/
|
|
50
|
+
export type ApiErrorBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<Extract<E, {
|
|
51
|
+
path: P;
|
|
52
|
+
method: M;
|
|
53
|
+
}>['response'], {
|
|
54
|
+
status: ErrorCode;
|
|
55
|
+
}>['json'] extends () => Promise<infer R> ? R : unknown;
|
|
56
|
+
/**
|
|
57
|
+
* Converts a RawApiGatewayHandler response type to a fetch like response type.
|
|
58
|
+
*/
|
|
59
|
+
type ConvertToFetch<T> = T extends {
|
|
60
|
+
statusCode: number;
|
|
61
|
+
body: object;
|
|
62
|
+
headers: object;
|
|
63
|
+
} ? {
|
|
64
|
+
ok: T['statusCode'] extends SuccessCode ? true : false;
|
|
65
|
+
json: () => Promise<T['body']>;
|
|
66
|
+
status: T['statusCode'];
|
|
67
|
+
} : T;
|
|
68
|
+
export type CleanResponse = Omit<Response, 'status' | 'ok' | 'json'>;
|
|
69
|
+
export type FetchResponse<T extends (...args: any) => any> = ConvertToFetch<Awaited<ReturnType<T>>> & CleanResponse;
|
|
70
|
+
export declare const HTTPMethods: readonly ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"];
|
|
71
|
+
export type HTTPMethod = (typeof HTTPMethods)[number];
|
|
72
|
+
export type ApiEndpoints = {
|
|
73
|
+
path: string;
|
|
74
|
+
method: HTTPMethod;
|
|
75
|
+
requestInput: Record<string, any>;
|
|
76
|
+
requestOutput: object;
|
|
77
|
+
response: FetchResponse<() => Promise<{
|
|
78
|
+
headers: object;
|
|
79
|
+
statusCode: SuccessCode;
|
|
80
|
+
body: any;
|
|
81
|
+
} | {
|
|
82
|
+
headers: object;
|
|
83
|
+
statusCode: ErrorCode;
|
|
84
|
+
body: ErrorBody;
|
|
85
|
+
}>>;
|
|
86
|
+
};
|
|
73
87
|
export {};
|
|
74
88
|
//# sourceMappingURL=client-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-types.d.ts","sourceRoot":"","sources":["../../src/lambda/client-types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client-types.d.ts","sourceRoot":"","sources":["../../src/lambda/client-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAK3E;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,OAAO,CAChG,CAAC,EACD;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CACvB,CAAC,cAAc,CAAC,CAAC;AAElB;;;;;GAKG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,OAAO,CACjG,CAAC,EACD;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CACvB,CAAC,eAAe,CAAC,CAAC;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,OAAO,CACnG,CAAC,EACD;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CACvB,CAAC,UAAU,CAAC,CAAC;AAEd;;;;;GAKG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,OAAO,CACtG,OAAO,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC,UAAU,CAAC,EAC9C;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CACxB,CAAC,MAAM,CAAC,SAAS,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GACpC,CAAC,GACD,OAAO,CAAC;AAEZ;;;;;GAKG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,OAAO,CACpG,OAAO,CAAC,CAAC,EAAE;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC,UAAU,CAAC,EAC9C;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CACtB,CAAC,MAAM,CAAC,SAAS,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GACpC,CAAC,GACD,OAAO,CAAC;AAEZ;;GAEG;AACH,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpF;IACE,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,SAAS,WAAW,GAAG,IAAI,GAAG,KAAK,CAAC;IACvD,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/B,MAAM,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;CACzB,GACD,CAAC,CAAC;AAEN,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAM,CAAC,CAAC;AACrE,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC;AAKpH,eAAO,MAAM,WAAW,uEAAwE,CAAC;AACjG,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtD,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,aAAa,CAErB,MAAM,OAAO,CACT;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,WAAW,CAAC;QACxB,IAAI,EAAE,GAAG,CAAC;KACX,GACD;QACE,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,SAAS,CAAC;QACtB,IAAI,EAAE,SAAS,CAAC;KACjB,CACJ,CACF,CAAC;CACH,CAAC"}
|
package/dist/lambda/client.d.ts
CHANGED
|
@@ -1,26 +1,15 @@
|
|
|
1
1
|
import * as v from 'valibot';
|
|
2
|
-
import type { ApiInput, ApiResponse } from './client-types.js';
|
|
2
|
+
import type { ApiEndpoints, ApiInput, ApiResponse } from './client-types.js';
|
|
3
3
|
declare const HTTPMethods: readonly ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"];
|
|
4
4
|
type HTTPMethod = (typeof HTTPMethods)[number];
|
|
5
|
-
export type ApiRequestFunction<API extends {
|
|
6
|
-
path: string;
|
|
7
|
-
method: string;
|
|
8
|
-
requestInput: any;
|
|
9
|
-
requestOutput: any;
|
|
10
|
-
response: any;
|
|
11
|
-
}> = <Path extends API['path'], Method extends Extract<API, {
|
|
5
|
+
export type ApiRequestFunction<API extends ApiEndpoints> = <Path extends API['path'], Method extends Extract<API, {
|
|
12
6
|
path: Path;
|
|
13
7
|
}>['method']>(path: Path, method: Method, input: ApiInput<API, Path, Method>, headers?: HeadersInit) => Promise<ApiResponse<API, Path, Method>>;
|
|
8
|
+
export type ApiSchema = v.GenericSchema | v.GenericSchemaAsync;
|
|
14
9
|
/**
|
|
15
10
|
* @returns A function that can be used to make API requests with type safety
|
|
16
11
|
* @example const clientApiRequest = createApiRequest<ApiEndpoints>();
|
|
17
12
|
*/
|
|
18
|
-
export declare function createApiRequest<API extends
|
|
19
|
-
path: string;
|
|
20
|
-
method: string;
|
|
21
|
-
requestInput: any;
|
|
22
|
-
requestOutput: any;
|
|
23
|
-
response: any;
|
|
24
|
-
}>(schemas: Partial<Record<API['path'], Partial<Record<HTTPMethod, v.GenericSchema | (() => v.GenericSchema)>>>>, apiUrl: string, env: string): ApiRequestFunction<API>;
|
|
13
|
+
export declare function createApiRequest<API extends ApiEndpoints>(schemas: Partial<Record<API['path'], Partial<Record<HTTPMethod, ApiSchema>>>>, apiUrl: string, env: string): ApiRequestFunction<API>;
|
|
25
14
|
export {};
|
|
26
15
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lambda/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lambda/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAwD7E,QAAA,MAAM,WAAW,uEAAwE,CAAC;AAC1F,KAAK,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/C,MAAM,MAAM,kBAAkB,CAAC,GAAG,SAAS,YAAY,IAAI,CACzD,IAAI,SAAS,GAAG,CAAC,MAAM,CAAC,EACxB,MAAM,SAAS,OAAO,CAAC,GAAG,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC,QAAQ,CAAC,EAErD,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,EAClC,OAAO,CAAC,EAAE,WAAW,KAClB,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AAE7C,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,kBAAkB,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,SAAS,YAAY,EACvD,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAC7E,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,kBAAkB,CAAC,GAAG,CAAC,CAmBzB"}
|
package/dist/lambda/client.js
CHANGED
|
@@ -4,7 +4,10 @@ const bodyMethods = ['POST', 'PUT', 'PATCH'];
|
|
|
4
4
|
const queryMethods = ['GET', 'DELETE'];
|
|
5
5
|
async function _apiRequest(path, method, input, schema, environment, apiUrl, headers) {
|
|
6
6
|
if (schema) {
|
|
7
|
-
|
|
7
|
+
if (schema.async === true)
|
|
8
|
+
v.parseAsync(schema, input);
|
|
9
|
+
else
|
|
10
|
+
v.parse(schema, input);
|
|
8
11
|
}
|
|
9
12
|
let url = `${apiUrl}${path}`;
|
|
10
13
|
if (queryMethods.includes(method)) {
|
|
@@ -43,11 +46,12 @@ const HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']
|
|
|
43
46
|
*/
|
|
44
47
|
export function createApiRequest(schemas, apiUrl, env) {
|
|
45
48
|
return async function apiRequest(path, method, input, headers) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
const schema = schemas[path]?.[method];
|
|
50
|
+
if (schema === undefined)
|
|
51
|
+
throw new Error('Schema is undefined in api request');
|
|
52
|
+
// if (typeof schema === 'function') {
|
|
53
|
+
// schema = schema();
|
|
54
|
+
// }
|
|
51
55
|
return _apiRequest(path, method, input, schema, env, apiUrl, headers);
|
|
52
56
|
};
|
|
53
57
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These are the various errors that should be returned from anything called by a lambda function.
|
|
3
|
+
*
|
|
4
|
+
* Pass a lambda error to the errorResponse function to get a suitable response to return from the lambda handler.
|
|
5
|
+
*
|
|
6
|
+
* The separation means that they can be returned from functions that are certainly run inside a lambda fucntion but theyre not the actual return of the lambda.
|
|
7
|
+
* Im not sure it this is optimal behaviour and if not we will migrate to only using the errorResponse function
|
|
8
|
+
*/
|
|
9
|
+
export declare const badRequestError: (message: string, fieldName?: string, fieldValue?: string) => {
|
|
10
|
+
type: "BadRequest";
|
|
11
|
+
message: string;
|
|
12
|
+
fieldName: string | undefined;
|
|
13
|
+
fieldValue: string | undefined;
|
|
14
|
+
};
|
|
15
|
+
export declare const unauthorizedError: (message: string) => {
|
|
16
|
+
type: "Unauthorized";
|
|
17
|
+
message: string;
|
|
18
|
+
};
|
|
19
|
+
export declare const forbiddenError: (message: string) => {
|
|
20
|
+
type: "Forbidden";
|
|
21
|
+
message: string;
|
|
22
|
+
};
|
|
23
|
+
export declare const notFoundError: (message: string, fieldName?: string, fieldValue?: string) => {
|
|
24
|
+
type: "NotFound";
|
|
25
|
+
message: string;
|
|
26
|
+
fieldName: string | undefined;
|
|
27
|
+
fieldValue: string | undefined;
|
|
28
|
+
};
|
|
29
|
+
export declare const conflictError: (message: string, fieldName?: string, fieldValue?: string) => {
|
|
30
|
+
type: "Conflict";
|
|
31
|
+
message: string;
|
|
32
|
+
fieldName: string | undefined;
|
|
33
|
+
fieldValue: string | undefined;
|
|
34
|
+
};
|
|
35
|
+
export declare const internalServerError: (message: string) => {
|
|
36
|
+
type: "InternalServerError";
|
|
37
|
+
message: string;
|
|
38
|
+
};
|
|
39
|
+
export type BadRequestError = ReturnType<typeof badRequestError>;
|
|
40
|
+
export type UnauthorizedError = ReturnType<typeof unauthorizedError>;
|
|
41
|
+
export type ForbiddenError = ReturnType<typeof forbiddenError>;
|
|
42
|
+
export type NotFoundError = ReturnType<typeof notFoundError>;
|
|
43
|
+
export type ConflictError = ReturnType<typeof conflictError>;
|
|
44
|
+
export type InternalServerError = ReturnType<typeof internalServerError>;
|
|
45
|
+
export type LambdaError = BadRequestError | UnauthorizedError | ForbiddenError | NotFoundError | ConflictError | InternalServerError;
|
|
46
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lambda/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,EAAE,aAAa,MAAM;;;;;CAKtF,CAAC;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM;;;CAG/C,CAAC;AAEH,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM;;;CAG5C,CAAC;AAEH,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,EAAE,aAAa,MAAM;;;;;CAKpF,CAAC;AAEH,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,EAAE,aAAa,MAAM;;;;;CAKpF,CAAC;AAEH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM;;;CAGjD,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AACjE,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACrE,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC/D,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAC7D,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAC7D,MAAM,MAAM,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEzE,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,aAAa,GACb,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These are the various errors that should be returned from anything called by a lambda function.
|
|
3
|
+
*
|
|
4
|
+
* Pass a lambda error to the errorResponse function to get a suitable response to return from the lambda handler.
|
|
5
|
+
*
|
|
6
|
+
* The separation means that they can be returned from functions that are certainly run inside a lambda fucntion but theyre not the actual return of the lambda.
|
|
7
|
+
* Im not sure it this is optimal behaviour and if not we will migrate to only using the errorResponse function
|
|
8
|
+
*/
|
|
9
|
+
export const badRequestError = (message, fieldName, fieldValue) => ({
|
|
10
|
+
type: 'BadRequest',
|
|
11
|
+
message,
|
|
12
|
+
fieldName,
|
|
13
|
+
fieldValue
|
|
14
|
+
});
|
|
15
|
+
export const unauthorizedError = (message) => ({
|
|
16
|
+
type: 'Unauthorized',
|
|
17
|
+
message
|
|
18
|
+
});
|
|
19
|
+
export const forbiddenError = (message) => ({
|
|
20
|
+
type: 'Forbidden',
|
|
21
|
+
message
|
|
22
|
+
});
|
|
23
|
+
export const notFoundError = (message, fieldName, fieldValue) => ({
|
|
24
|
+
type: 'NotFound',
|
|
25
|
+
message,
|
|
26
|
+
fieldName,
|
|
27
|
+
fieldValue
|
|
28
|
+
});
|
|
29
|
+
export const conflictError = (message, fieldName, fieldValue) => ({
|
|
30
|
+
type: 'Conflict',
|
|
31
|
+
message,
|
|
32
|
+
fieldName,
|
|
33
|
+
fieldValue
|
|
34
|
+
});
|
|
35
|
+
export const internalServerError = (message) => ({
|
|
36
|
+
type: 'InternalServerError',
|
|
37
|
+
message
|
|
38
|
+
});
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import type { APIGatewayProxyResultV2, Context } from 'aws-lambda';
|
|
2
|
+
export type SuccessCode = 200 | 201 | 204;
|
|
3
|
+
export type ErrorCode = 400 | 401 | 403 | 404 | 409 | 500;
|
|
4
|
+
export type ErrorBody = {
|
|
5
|
+
message: string;
|
|
6
|
+
field?: {
|
|
7
|
+
name: string;
|
|
8
|
+
value: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
2
11
|
/**
|
|
3
12
|
* A type for the raw proxy result - just using an object not a stirng for the body
|
|
4
13
|
*/
|
|
5
14
|
export type RawProxyResultV2 = {
|
|
6
|
-
statusCode
|
|
15
|
+
statusCode: ErrorCode;
|
|
16
|
+
headers?: {
|
|
17
|
+
[header: string]: boolean | number | string;
|
|
18
|
+
} | undefined;
|
|
19
|
+
body?: ErrorBody;
|
|
20
|
+
isBase64Encoded?: boolean | undefined;
|
|
21
|
+
cookies?: string[] | undefined;
|
|
22
|
+
} | {
|
|
23
|
+
statusCode: SuccessCode;
|
|
7
24
|
headers?: {
|
|
8
25
|
[header: string]: boolean | number | string;
|
|
9
26
|
} | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlerUtils.d.ts","sourceRoot":"","sources":["../../src/lambda/handlerUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGnE;;GAEG;AACH,MAAM,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"handlerUtils.d.ts","sourceRoot":"","sources":["../../src/lambda/handlerUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGnE,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC1C,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE1D,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB;IACE,UAAU,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EACJ;QACE,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;KAC7C,GACD,SAAS,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CAChC,GACD;IACE,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,CAAC,EACJ;QACE,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;KAC7C,GACD,SAAS,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CAChC,CAAC;AAGN,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAGpG,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEhG;;;;;;;;;;;;;EAaE;AACF,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAQrF"}
|
package/dist/lambda/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lambda/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lambda/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
|
package/dist/lambda/index.js
CHANGED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { SafeParseResult } from 'valibot';
|
|
2
|
+
import { type LambdaError } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* Takes a lambda error and gives an error response suitable to be returned from the lambda handler
|
|
5
|
+
*/
|
|
6
|
+
export declare function errorResponse(e: LambdaError, headers: any): {
|
|
7
|
+
headers: any;
|
|
8
|
+
statusCode: 400;
|
|
9
|
+
body: {
|
|
10
|
+
field?: undefined;
|
|
11
|
+
message: string;
|
|
12
|
+
} | {
|
|
13
|
+
field: {
|
|
14
|
+
name: string;
|
|
15
|
+
value: string;
|
|
16
|
+
};
|
|
17
|
+
message: string;
|
|
18
|
+
};
|
|
19
|
+
} | {
|
|
20
|
+
headers: any;
|
|
21
|
+
statusCode: 401;
|
|
22
|
+
body: {
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
} | {
|
|
26
|
+
headers: any;
|
|
27
|
+
statusCode: 403;
|
|
28
|
+
body: {
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
} | {
|
|
32
|
+
headers: any;
|
|
33
|
+
statusCode: 404;
|
|
34
|
+
body: {
|
|
35
|
+
field?: undefined;
|
|
36
|
+
message: string;
|
|
37
|
+
} | {
|
|
38
|
+
field: {
|
|
39
|
+
name: string;
|
|
40
|
+
value: string;
|
|
41
|
+
};
|
|
42
|
+
message: string;
|
|
43
|
+
};
|
|
44
|
+
} | {
|
|
45
|
+
headers: any;
|
|
46
|
+
statusCode: 409;
|
|
47
|
+
body: {
|
|
48
|
+
field?: undefined;
|
|
49
|
+
message: string;
|
|
50
|
+
} | {
|
|
51
|
+
field: {
|
|
52
|
+
name: string;
|
|
53
|
+
value: string;
|
|
54
|
+
};
|
|
55
|
+
message: string;
|
|
56
|
+
};
|
|
57
|
+
} | {
|
|
58
|
+
headers: any;
|
|
59
|
+
statusCode: 500;
|
|
60
|
+
body: {
|
|
61
|
+
message: string;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Helper function to get a reasonable default error response from a valibot parse result
|
|
66
|
+
*/
|
|
67
|
+
export declare function valibotErrorResponse(res: Extract<SafeParseResult<any>, {
|
|
68
|
+
success: false;
|
|
69
|
+
}>, headers: any): {
|
|
70
|
+
headers: any;
|
|
71
|
+
statusCode: 400;
|
|
72
|
+
body: {
|
|
73
|
+
field?: undefined;
|
|
74
|
+
message: string;
|
|
75
|
+
} | {
|
|
76
|
+
field: {
|
|
77
|
+
name: string;
|
|
78
|
+
value: string;
|
|
79
|
+
};
|
|
80
|
+
message: string;
|
|
81
|
+
};
|
|
82
|
+
} | {
|
|
83
|
+
headers: any;
|
|
84
|
+
statusCode: 401;
|
|
85
|
+
body: {
|
|
86
|
+
message: string;
|
|
87
|
+
};
|
|
88
|
+
} | {
|
|
89
|
+
headers: any;
|
|
90
|
+
statusCode: 403;
|
|
91
|
+
body: {
|
|
92
|
+
message: string;
|
|
93
|
+
};
|
|
94
|
+
} | {
|
|
95
|
+
headers: any;
|
|
96
|
+
statusCode: 404;
|
|
97
|
+
body: {
|
|
98
|
+
field?: undefined;
|
|
99
|
+
message: string;
|
|
100
|
+
} | {
|
|
101
|
+
field: {
|
|
102
|
+
name: string;
|
|
103
|
+
value: string;
|
|
104
|
+
};
|
|
105
|
+
message: string;
|
|
106
|
+
};
|
|
107
|
+
} | {
|
|
108
|
+
headers: any;
|
|
109
|
+
statusCode: 409;
|
|
110
|
+
body: {
|
|
111
|
+
field?: undefined;
|
|
112
|
+
message: string;
|
|
113
|
+
} | {
|
|
114
|
+
field: {
|
|
115
|
+
name: string;
|
|
116
|
+
value: string;
|
|
117
|
+
};
|
|
118
|
+
message: string;
|
|
119
|
+
};
|
|
120
|
+
} | {
|
|
121
|
+
headers: any;
|
|
122
|
+
statusCode: 500;
|
|
123
|
+
body: {
|
|
124
|
+
message: string;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/lambda/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAahE;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsDzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE;IAAE,OAAO,EAAE,KAAK,CAAA;CAAE,CAAC,EAAE,OAAO,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIxG"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { badRequestError } from './errors.js';
|
|
2
|
+
function field(obj) {
|
|
3
|
+
return obj.fieldName === undefined || obj.fieldValue === undefined
|
|
4
|
+
? {}
|
|
5
|
+
: {
|
|
6
|
+
field: {
|
|
7
|
+
name: obj.fieldName,
|
|
8
|
+
value: obj.fieldValue
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Takes a lambda error and gives an error response suitable to be returned from the lambda handler
|
|
14
|
+
*/
|
|
15
|
+
export function errorResponse(e, headers) {
|
|
16
|
+
switch (e.type) {
|
|
17
|
+
case 'BadRequest':
|
|
18
|
+
return {
|
|
19
|
+
headers,
|
|
20
|
+
statusCode: 400,
|
|
21
|
+
body: {
|
|
22
|
+
message: e.message,
|
|
23
|
+
...field(e)
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
case 'Unauthorized':
|
|
27
|
+
return {
|
|
28
|
+
headers,
|
|
29
|
+
statusCode: 401,
|
|
30
|
+
body: {
|
|
31
|
+
message: e.message
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
case 'Forbidden':
|
|
35
|
+
return {
|
|
36
|
+
headers,
|
|
37
|
+
statusCode: 403,
|
|
38
|
+
body: {
|
|
39
|
+
message: e.message
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
case 'NotFound':
|
|
43
|
+
return {
|
|
44
|
+
headers,
|
|
45
|
+
statusCode: 404,
|
|
46
|
+
body: {
|
|
47
|
+
message: e.message,
|
|
48
|
+
...field(e)
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
case 'Conflict':
|
|
52
|
+
return {
|
|
53
|
+
headers,
|
|
54
|
+
statusCode: 409,
|
|
55
|
+
body: {
|
|
56
|
+
message: e.message,
|
|
57
|
+
...field(e)
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
default:
|
|
61
|
+
return {
|
|
62
|
+
headers,
|
|
63
|
+
statusCode: 500,
|
|
64
|
+
body: {
|
|
65
|
+
message: 'Unknown error'
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Helper function to get a reasonable default error response from a valibot parse result
|
|
72
|
+
*/
|
|
73
|
+
export function valibotErrorResponse(res, headers) {
|
|
74
|
+
const issue = res.issues[0];
|
|
75
|
+
return errorResponse(badRequestError('Invalid parameters', issue.path[0].key, issue.message), headers);
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/rehype/browser.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './flat-toc.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Root, Element } from 'hast';
|
|
2
|
+
import type { Plugin } from 'unified';
|
|
3
|
+
/**
|
|
4
|
+
* This rehype plugin extracts the headings from the markdown elements but also the raw elements.
|
|
5
|
+
* So we get html headings in the TOC as well
|
|
6
|
+
*
|
|
7
|
+
* It sets the file.data.fm.toc to a flat map of the toc
|
|
8
|
+
*/
|
|
9
|
+
export declare const extractToc: Plugin<[], Root>;
|
|
10
|
+
export type Toc = TocEntry[];
|
|
11
|
+
export type TocEntry = {
|
|
12
|
+
level: number;
|
|
13
|
+
id: string;
|
|
14
|
+
value: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Parses raw HTML and returns a flat array of all heading (h1-h6) elements as HAST nodes.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseRaw(raw: string): Element[];
|
|
20
|
+
//# sourceMappingURL=flat-toc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flat-toc.d.ts","sourceRoot":"","sources":["../../src/rehype/flat-toc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAe,OAAO,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKtC;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,CAOvC,CAAC;AACF,MAAM,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC;AAC7B,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AA6BF;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAoB/C"}
|