mobx-tanstack-query-api 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/codegen/index.d.ts +25 -0
- package/codegen/index.d.ts.map +1 -0
- package/codegen/index.js +89 -0
- package/codegen/templates/new-request-info.tmpl.d.ts +9 -0
- package/codegen/templates/new-request-info.tmpl.d.ts.map +1 -0
- package/codegen/templates/new-request-info.tmpl.js +167 -0
- package/codegen/templates/request-info-jsdoc.tmpl.d.ts +10 -0
- package/codegen/templates/request-info-jsdoc.tmpl.d.ts.map +1 -0
- package/codegen/templates/request-info-jsdoc.tmpl.js +92 -0
- package/codegen/templates/request-info-per-file.tmpl.d.ts +9 -0
- package/codegen/templates/request-info-per-file.tmpl.d.ts.map +1 -0
- package/codegen/templates/request-info-per-file.tmpl.js +28 -0
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -0
- package/index.js +1 -0
- package/package.json +102 -0
- package/runtime/http-client.d.ts +64 -0
- package/runtime/http-client.d.ts.map +1 -0
- package/runtime/http-client.js +172 -0
- package/runtime/index.d.ts +3 -0
- package/runtime/index.d.ts.map +1 -0
- package/runtime/index.js +2 -0
- package/runtime/request-info.d.ts +57 -0
- package/runtime/request-info.d.ts.map +1 -0
- package/runtime/request-info.js +189 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sergey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# mobx-tanstack-query-api
|
|
2
|
+
|
|
3
|
+
[![NPM version][npm-image]][npm-url] [![build status][github-build-actions-image]][github-actions-url] [![npm download][download-image]][download-url] [![bundle size][bundlephobia-image]][bundlephobia-url]
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[npm-image]: http://img.shields.io/npm/v/mobx-tanstack-query-api.svg
|
|
7
|
+
[npm-url]: http://npmjs.org/package/mobx-tanstack-query-api
|
|
8
|
+
[github-build-actions-image]: https://github.com/js2me/mobx-tanstack-query-api/workflows/Build/badge.svg
|
|
9
|
+
[github-actions-url]: https://github.com/js2me/mobx-tanstack-query-api/actions
|
|
10
|
+
[download-image]: https://img.shields.io/npm/dm/mobx-tanstack-query-api.svg
|
|
11
|
+
[download-url]: https://npmjs.org/package/mobx-tanstack-query-api
|
|
12
|
+
[bundlephobia-url]: https://bundlephobia.com/result?p=mobx-tanstack-query-api
|
|
13
|
+
[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/mobx-tanstack-query-api
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
API codegen from swagger
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { GenerateApiParams as GenerateApiParamsFromSwagger, ParsedRoute } from 'swagger-typescript-api';
|
|
2
|
+
import { AnyObject } from 'yummies/utils/types';
|
|
3
|
+
export interface QueryApiParams {
|
|
4
|
+
requestPathPrefix?: string;
|
|
5
|
+
requestPathSuffix?: string;
|
|
6
|
+
requestInfoPrefix?: string;
|
|
7
|
+
outputType: 'request-info-per-file';
|
|
8
|
+
getRequestInfoMeta?: (route: ParsedRoute) => {
|
|
9
|
+
typeName: string;
|
|
10
|
+
importTypePath: string;
|
|
11
|
+
tmplData: string;
|
|
12
|
+
};
|
|
13
|
+
getRequestMeta?: (route: ParsedRoute) => {
|
|
14
|
+
typeName: string;
|
|
15
|
+
importTypePath: string;
|
|
16
|
+
tmplData: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
type GenerateApiParams = Omit<GenerateApiParamsFromSwagger, 'output' | 'moduleNameFirstTag' | 'moduleNameIndex' | 'url' | 'input' | 'spec'> & {
|
|
20
|
+
output: string;
|
|
21
|
+
input: string | AnyObject;
|
|
22
|
+
} & QueryApiParams;
|
|
23
|
+
export declare const generateApi: (inputParams: GenerateApiParams) => Promise<void>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,IAAI,4BAA4B,EACjD,WAAW,EAEZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAWhD,MAAM,WAAW,cAAc;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,uBAAuB,CAAC;IAEpC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK;QAC3C,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK;QACvC,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,KAAK,iBAAiB,GAAG,IAAI,CAC3B,4BAA4B,EAC5B,QAAQ,GAAG,oBAAoB,GAAG,iBAAiB,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAC/E,GAAG;IACF,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,GAAG,cAAc,CAAC;AAEnB,eAAO,MAAM,WAAW,gBAAuB,iBAAiB,kBAiH/D,CAAC"}
|
package/codegen/index.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { generateApi as generateApiFromSwagger, } from 'swagger-typescript-api';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { requestInfoPerFileTmpl } from './templates/request-info-per-file.tmpl.js';
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
export const generateApi = async (inputParams) => {
|
|
8
|
+
const { output, input, ...params } = inputParams;
|
|
9
|
+
const paths = {
|
|
10
|
+
templates: path.resolve(__dirname, 'templates'),
|
|
11
|
+
requestInfoClass: path.resolve(__dirname, 'templates/request-info-class.ejs'),
|
|
12
|
+
httpClient: path.resolve(__dirname, 'templates/http-client.ejs'),
|
|
13
|
+
createRequestInfoInstance: path.resolve(__dirname, 'templates/create-request-info-instance.ejs'),
|
|
14
|
+
outputRequestsDir: path.resolve(output, 'requests'),
|
|
15
|
+
};
|
|
16
|
+
const codegenParams = {
|
|
17
|
+
httpClientType: 'fetch',
|
|
18
|
+
cleanOutput: true,
|
|
19
|
+
modular: true,
|
|
20
|
+
patch: true,
|
|
21
|
+
typeSuffix: 'DC',
|
|
22
|
+
disableStrictSSL: false,
|
|
23
|
+
singleHttpClient: true,
|
|
24
|
+
extractRequestBody: true,
|
|
25
|
+
extractRequestParams: true,
|
|
26
|
+
extractResponseBody: true,
|
|
27
|
+
extractResponseError: true,
|
|
28
|
+
generateResponses: true,
|
|
29
|
+
generateClient: false,
|
|
30
|
+
addReadonly: true,
|
|
31
|
+
moduleNameFirstTag: true,
|
|
32
|
+
sortTypes: true,
|
|
33
|
+
templates: paths.templates.toString(),
|
|
34
|
+
primitiveTypeConstructs: (constructs) => {
|
|
35
|
+
return {
|
|
36
|
+
...constructs,
|
|
37
|
+
object: () => `Record<string, any>`,
|
|
38
|
+
float: () => `number`,
|
|
39
|
+
...params?.primitiveTypeConstructs?.(constructs),
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
...params,
|
|
43
|
+
};
|
|
44
|
+
let codegenProcess;
|
|
45
|
+
const inputData = {};
|
|
46
|
+
if (typeof input === 'string') {
|
|
47
|
+
inputData.input = input;
|
|
48
|
+
inputData.url = input;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
inputData.spec = input;
|
|
52
|
+
}
|
|
53
|
+
const generated = await generateApiFromSwagger({
|
|
54
|
+
...codegenParams,
|
|
55
|
+
...inputData,
|
|
56
|
+
hooks: {
|
|
57
|
+
onInit: (configuration, codeGenProcessFromInit) => {
|
|
58
|
+
codegenProcess = codeGenProcessFromInit;
|
|
59
|
+
return codegenParams?.hooks?.onInit?.(configuration, codeGenProcessFromInit);
|
|
60
|
+
},
|
|
61
|
+
onPrepareConfig: (config) => {
|
|
62
|
+
config.routes.combined?.forEach((routeInfo) => {
|
|
63
|
+
routeInfo.routes.sort((routeA, routeB) => routeA.routeName.usage.localeCompare(routeB.routeName.usage));
|
|
64
|
+
});
|
|
65
|
+
return codegenParams?.hooks?.onPrepareConfig?.(config);
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
const codegenFs = codegenProcess.fileSystem;
|
|
70
|
+
codegenFs.cleanDir(output);
|
|
71
|
+
codegenFs.createDir(output);
|
|
72
|
+
codegenFs.createDir(paths.outputRequestsDir.toString());
|
|
73
|
+
const allRoutes = Object.values(generated.configuration.routes)
|
|
74
|
+
.flat()
|
|
75
|
+
.flatMap((routeGroup) => 'routes' in routeGroup ? routeGroup.routes : routeGroup);
|
|
76
|
+
for await (const route of allRoutes) {
|
|
77
|
+
const requestInfoPerFileContent = await requestInfoPerFileTmpl({
|
|
78
|
+
...generated,
|
|
79
|
+
route,
|
|
80
|
+
apiParams: inputParams,
|
|
81
|
+
});
|
|
82
|
+
codegenFs.createFile({
|
|
83
|
+
path: paths.outputRequestsDir.toString(),
|
|
84
|
+
fileName: `${generated.configuration.utils._.kebabCase(route.routeName.usage)}.ts`,
|
|
85
|
+
withPrefix: false,
|
|
86
|
+
content: requestInfoPerFileContent,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GenerateApiConfiguration, ParsedRoute } from 'swagger-typescript-api';
|
|
2
|
+
import type { QueryApiParams } from '../index.js';
|
|
3
|
+
export interface NewRequestInfoTmplParams {
|
|
4
|
+
route: ParsedRoute;
|
|
5
|
+
configuration: GenerateApiConfiguration;
|
|
6
|
+
apiParams: QueryApiParams;
|
|
7
|
+
}
|
|
8
|
+
export declare const newRequestInfoTmpl: ({ route, configuration, apiParams, }: NewRequestInfoTmplParams) => string;
|
|
9
|
+
//# sourceMappingURL=new-request-info.tmpl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new-request-info.tmpl.d.ts","sourceRoot":"","sources":["../../../src/codegen/templates/new-request-info.tmpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,WAAW,CAAC;IACnB,aAAa,EAAE,wBAAwB,CAAC;IACxC,SAAS,EAAE,cAAc,CAAC;CAC3B;AAiBD,eAAO,MAAM,kBAAkB,yCAI5B,wBAAwB,WAyM1B,CAAC"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// RequestParams["type"]
|
|
2
|
+
const requestContentKind = {
|
|
3
|
+
URL_ENCODED: 'application/x-www-form-urlencoded',
|
|
4
|
+
FORM_DATA: 'multipart/form-data',
|
|
5
|
+
TEXT: 'text/plain',
|
|
6
|
+
BINARY: 'application/octet-stream',
|
|
7
|
+
};
|
|
8
|
+
// RequestParams["format"]
|
|
9
|
+
const responseContentKind = {
|
|
10
|
+
TEXT: '"text"',
|
|
11
|
+
IMAGE: '"blob"',
|
|
12
|
+
FORM_DATA: '"formData"',
|
|
13
|
+
BYTES: '"bytes"',
|
|
14
|
+
};
|
|
15
|
+
export const newRequestInfoTmpl = ({ route, configuration, apiParams, }) => {
|
|
16
|
+
const { utils } = configuration;
|
|
17
|
+
const { _ } = utils;
|
|
18
|
+
const positiveResponseTypes = route.raw.responsesTypes?.filter((it) => +it.status >= 200 && +it.status < 300);
|
|
19
|
+
const { requestBodyInfo, responseBodyInfo } = route;
|
|
20
|
+
const routeRequest = route.request;
|
|
21
|
+
const routeResponse = route.response;
|
|
22
|
+
const { parameters, path, method, payload, query, requestParams, security } = routeRequest;
|
|
23
|
+
const { raw } = route;
|
|
24
|
+
const queryName = query?.name || 'query';
|
|
25
|
+
const pathParams = _.values(parameters);
|
|
26
|
+
const pathParamsNames = _.map(pathParams, 'name');
|
|
27
|
+
const requestConfigParam = {
|
|
28
|
+
name: 'request',
|
|
29
|
+
optional: true,
|
|
30
|
+
type: 'RequestParams',
|
|
31
|
+
defaultValue: '{}',
|
|
32
|
+
};
|
|
33
|
+
const getArgs = ({ withPayload, withRequestConfigParam, withRequestParams, }) => {
|
|
34
|
+
return _.sortBy(_.compact([
|
|
35
|
+
...(withRequestParams && requestParams
|
|
36
|
+
? [
|
|
37
|
+
{
|
|
38
|
+
name: pathParams.length > 0
|
|
39
|
+
? `{ ${_.join(pathParamsNames, ', ')}, ...${queryName} }`
|
|
40
|
+
: queryName,
|
|
41
|
+
optional: false,
|
|
42
|
+
type: utils.getInlineParseContent(requestParams),
|
|
43
|
+
},
|
|
44
|
+
]
|
|
45
|
+
: pathParams),
|
|
46
|
+
withPayload && payload,
|
|
47
|
+
withRequestConfigParam && requestConfigParam,
|
|
48
|
+
]), [(o) => o.optional]);
|
|
49
|
+
};
|
|
50
|
+
const requestOutputDataType = positiveResponseTypes.map((it) => it.type).join('|') || 'any';
|
|
51
|
+
const requestOutputErrorType = routeResponse.errorType;
|
|
52
|
+
let requestInputCombinedType;
|
|
53
|
+
const requestInfoFnArgNames = getArgs({
|
|
54
|
+
withRequestParams: true,
|
|
55
|
+
withRequestConfigParam: true,
|
|
56
|
+
withPayload: true,
|
|
57
|
+
}).map(({ name }) => name);
|
|
58
|
+
const pathParamsToInline = path.split('/').slice(1);
|
|
59
|
+
let lastDynamicStructPos = 0;
|
|
60
|
+
const pathParamsStructs = pathParamsToInline.map((param, i) => {
|
|
61
|
+
if (param.includes('${')) {
|
|
62
|
+
const paramName = param.replace('${', '').replace('}', '');
|
|
63
|
+
return {
|
|
64
|
+
type: 'dynamic',
|
|
65
|
+
key: paramName,
|
|
66
|
+
i,
|
|
67
|
+
param: lastDynamicStructPos++,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
type: 'static',
|
|
72
|
+
value: param,
|
|
73
|
+
i,
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
const queryParamStruct = query == null
|
|
77
|
+
? null
|
|
78
|
+
: {
|
|
79
|
+
type: 'dynamic',
|
|
80
|
+
key: 'params',
|
|
81
|
+
i: pathParamsToInline.length,
|
|
82
|
+
param: lastDynamicStructPos > 0 ? lastDynamicStructPos - 1 : 0,
|
|
83
|
+
};
|
|
84
|
+
if (queryParamStruct && !lastDynamicStructPos) {
|
|
85
|
+
lastDynamicStructPos++;
|
|
86
|
+
}
|
|
87
|
+
let requestInputType = `{
|
|
88
|
+
${getArgs({
|
|
89
|
+
withRequestParams: true,
|
|
90
|
+
withRequestConfigParam: true,
|
|
91
|
+
withPayload: true,
|
|
92
|
+
})
|
|
93
|
+
.map(({ name, optional, type, defaultValue }) => {
|
|
94
|
+
const isCombinedType = name.includes('...') || name === 'query';
|
|
95
|
+
if (isCombinedType) {
|
|
96
|
+
requestInputCombinedType = { name, optional, type, defaultValue };
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
return `${name}${optional ? '?' : ''}:${type}`;
|
|
100
|
+
})
|
|
101
|
+
.filter(Boolean)
|
|
102
|
+
.join(', ')}
|
|
103
|
+
}`;
|
|
104
|
+
if (requestInputCombinedType) {
|
|
105
|
+
requestInputType = `${requestInputCombinedType.type} & ${requestInputType}`;
|
|
106
|
+
}
|
|
107
|
+
const requestKeyType = `[
|
|
108
|
+
${getArgs({
|
|
109
|
+
withRequestParams: true,
|
|
110
|
+
withRequestConfigParam: true,
|
|
111
|
+
withPayload: true,
|
|
112
|
+
})
|
|
113
|
+
.map(({ name, optional, type }) => {
|
|
114
|
+
return `${name.includes('...') || name === 'query' ? 'params' : name}${optional ? '?' : ''}:${type}`;
|
|
115
|
+
})
|
|
116
|
+
.join(', ')}
|
|
117
|
+
]`;
|
|
118
|
+
const requestInfoMeta = apiParams.getRequestInfoMeta?.(route);
|
|
119
|
+
const requestMeta = apiParams.getRequestMeta?.(route);
|
|
120
|
+
const resultPath = (apiParams.requestPathPrefix ?? '') +
|
|
121
|
+
path +
|
|
122
|
+
(apiParams.requestPathSuffix ?? '');
|
|
123
|
+
const bodyContentType = requestContentKind[requestBodyInfo.contentKind] || null;
|
|
124
|
+
const responseFormat = responseContentKind[responseBodyInfo.success?.schema?.contentKind] || null;
|
|
125
|
+
return `
|
|
126
|
+
new RequestInfo<
|
|
127
|
+
${requestOutputDataType},
|
|
128
|
+
${requestOutputErrorType},
|
|
129
|
+
${requestInputType},
|
|
130
|
+
${requestKeyType},
|
|
131
|
+
${requestInfoMeta?.typeName ?? 'any'}
|
|
132
|
+
>(
|
|
133
|
+
{
|
|
134
|
+
params: (${requestInfoFnArgNames.join(', ')}) => ({
|
|
135
|
+
path: \`${resultPath}\`,
|
|
136
|
+
method: '${_.upperCase(method)}',
|
|
137
|
+
${requestMeta?.tmplData ? `meta: ${requestMeta.tmplData},` : ''}
|
|
138
|
+
${query == null ? '' : `query: ${query.name},`}
|
|
139
|
+
${payload?.name ? `body: ${payload.name},` : ''}
|
|
140
|
+
${security ? 'secure: true,' : ''}
|
|
141
|
+
${bodyContentType ? `contentType: ${bodyContentType},` : ''}
|
|
142
|
+
${responseFormat ? `format: ${responseFormat},` : ''}
|
|
143
|
+
...${requestInfoFnArgNames.at(-1)},
|
|
144
|
+
}),
|
|
145
|
+
operationId: "${raw.operationId}",
|
|
146
|
+
tags: [
|
|
147
|
+
${raw.tags?.map((tag) => `"${tag}"`).join(',')}
|
|
148
|
+
],
|
|
149
|
+
meta: ${requestInfoMeta?.tmplData ?? '{} as any'},
|
|
150
|
+
keys: [
|
|
151
|
+
${_.compact([
|
|
152
|
+
...pathParamsStructs.map((struct) => {
|
|
153
|
+
if (struct.type === 'dynamic') {
|
|
154
|
+
return `{ name: '${struct.key}', param: ${struct.param} }`;
|
|
155
|
+
}
|
|
156
|
+
return `"${struct.value}"`;
|
|
157
|
+
}),
|
|
158
|
+
queryParamStruct &&
|
|
159
|
+
`{ name: "${queryParamStruct.key}", rest: true }`,
|
|
160
|
+
requestConfigParam &&
|
|
161
|
+
`{ name: "${requestConfigParam.name}", param: ${lastDynamicStructPos} }`,
|
|
162
|
+
]).join(',')}
|
|
163
|
+
],
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
`;
|
|
167
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ParsedRoute, GenerateApiConfiguration } from 'swagger-typescript-api';
|
|
2
|
+
import { QueryApiParams } from '../index.js';
|
|
3
|
+
export interface RequestInfoJSDocTmplParams {
|
|
4
|
+
route: ParsedRoute;
|
|
5
|
+
configuration: GenerateApiConfiguration;
|
|
6
|
+
apiParams: QueryApiParams;
|
|
7
|
+
offset?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const requestInfoJSDocTmpl: ({ route, configuration, offset, }: RequestInfoJSDocTmplParams) => string;
|
|
10
|
+
//# sourceMappingURL=request-info-jsdoc.tmpl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-info-jsdoc.tmpl.d.ts","sourceRoot":"","sources":["../../../src/codegen/templates/request-info-jsdoc.tmpl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAG/E,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,WAAW,CAAC;IACnB,aAAa,EAAE,wBAAwB,CAAC;IACxC,SAAS,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,oBAAoB,sCAI9B,0BAA0B,WAkH5B,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export const requestInfoJSDocTmpl = ({ route, configuration, offset = 0, }) => {
|
|
2
|
+
const { routeName } = route;
|
|
3
|
+
const rawRoute = route.raw;
|
|
4
|
+
const routeRequest = route.request;
|
|
5
|
+
const { utils } = configuration;
|
|
6
|
+
const { _, formatDescription } = utils;
|
|
7
|
+
const jsDocLines = [];
|
|
8
|
+
if (rawRoute.description) {
|
|
9
|
+
jsDocLines.push({
|
|
10
|
+
name: 'description',
|
|
11
|
+
content: formatDescription(rawRoute.description, true),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
jsDocLines.push({
|
|
16
|
+
content: 'No description',
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
if (rawRoute.operationId) {
|
|
20
|
+
jsDocLines.push({
|
|
21
|
+
name: 'operationId',
|
|
22
|
+
content: rawRoute.operationId,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (_.size(rawRoute.tags)) {
|
|
26
|
+
jsDocLines.push({
|
|
27
|
+
name: 'tags',
|
|
28
|
+
content: rawRoute.tags.join(', '),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (rawRoute.summary) {
|
|
32
|
+
jsDocLines.push({
|
|
33
|
+
name: 'summary',
|
|
34
|
+
content: rawRoute.summary,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
jsDocLines.push({
|
|
38
|
+
name: 'request',
|
|
39
|
+
content: `${_.upperCase(routeRequest.method)}:${rawRoute.route}`,
|
|
40
|
+
});
|
|
41
|
+
if (rawRoute.deprecated) {
|
|
42
|
+
jsDocLines.push({
|
|
43
|
+
name: 'deprecated',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (routeName.duplicate) {
|
|
47
|
+
jsDocLines.push({
|
|
48
|
+
name: 'duplicate',
|
|
49
|
+
}, {
|
|
50
|
+
name: 'originalName',
|
|
51
|
+
content: routeName.original,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (routeRequest.security) {
|
|
55
|
+
jsDocLines.push({
|
|
56
|
+
name: 'secure',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (rawRoute.responsesTypes.length > 0) {
|
|
60
|
+
jsDocLines.push({
|
|
61
|
+
name: 'responses',
|
|
62
|
+
});
|
|
63
|
+
rawRoute.responsesTypes.forEach((response) => {
|
|
64
|
+
jsDocLines.push({
|
|
65
|
+
name: `**${response.status}**`,
|
|
66
|
+
content: `${_.replace(_.replace(response.type, /\/\*/g, String.raw `\*`), /\*\//g, '*\\')} ${response.description}`,
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const jsdocContent = jsDocLines.map((it) => {
|
|
71
|
+
let line = ' * ';
|
|
72
|
+
if (it.name) {
|
|
73
|
+
line += `@${it.name} `;
|
|
74
|
+
}
|
|
75
|
+
const content = (it.content ?? '').trimEnd();
|
|
76
|
+
if (content) {
|
|
77
|
+
line += content;
|
|
78
|
+
}
|
|
79
|
+
return line;
|
|
80
|
+
});
|
|
81
|
+
const result = `
|
|
82
|
+
/**
|
|
83
|
+
${jsdocContent.join('\n')}
|
|
84
|
+
*/`;
|
|
85
|
+
if (offset > 0) {
|
|
86
|
+
return result
|
|
87
|
+
.split('\n')
|
|
88
|
+
.map((line) => line.padStart(offset))
|
|
89
|
+
.join('\n');
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ParsedRoute, GenerateApiConfiguration, GenerateApiOutput } from 'swagger-typescript-api';
|
|
2
|
+
import type { QueryApiParams } from '../index.js';
|
|
3
|
+
export interface RequestInfoPerFileTmplParams extends GenerateApiOutput {
|
|
4
|
+
route: ParsedRoute;
|
|
5
|
+
configuration: GenerateApiConfiguration;
|
|
6
|
+
apiParams: QueryApiParams;
|
|
7
|
+
}
|
|
8
|
+
export declare const requestInfoPerFileTmpl: ({ route, configuration, apiParams, formatTSContent, }: RequestInfoPerFileTmplParams) => Promise<string>;
|
|
9
|
+
//# sourceMappingURL=request-info-per-file.tmpl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-info-per-file.tmpl.d.ts","sourceRoot":"","sources":["../../../src/codegen/templates/request-info-per-file.tmpl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,wBAAwB,EACxB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,MAAM,WAAW,4BAA6B,SAAQ,iBAAiB;IACrE,KAAK,EAAE,WAAW,CAAC;IACnB,aAAa,EAAE,wBAAwB,CAAC;IACxC,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,eAAO,MAAM,sBAAsB,0DAKhC,4BAA4B,oBA4B9B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { newRequestInfoTmpl } from './new-request-info.tmpl.js';
|
|
2
|
+
import { requestInfoJSDocTmpl } from './request-info-jsdoc.tmpl.js';
|
|
3
|
+
export const requestInfoPerFileTmpl = async ({ route, configuration, apiParams, formatTSContent, }) => {
|
|
4
|
+
const dataContractNames = configuration.modelTypes.map((it) => it.name);
|
|
5
|
+
const { utils } = configuration;
|
|
6
|
+
const { _ } = utils;
|
|
7
|
+
return await formatTSContent(`
|
|
8
|
+
/* eslint-disable */
|
|
9
|
+
/* tslint:disable */
|
|
10
|
+
import { RequestInfo, RequestParams } from "mobx-tanstack-query-api";
|
|
11
|
+
${dataContractNames.length > 0
|
|
12
|
+
? `
|
|
13
|
+
import { ${dataContractNames.join(', ')} } from "./data-contracts.ts";
|
|
14
|
+
`
|
|
15
|
+
: ''}
|
|
16
|
+
|
|
17
|
+
${requestInfoJSDocTmpl({
|
|
18
|
+
route,
|
|
19
|
+
configuration,
|
|
20
|
+
apiParams,
|
|
21
|
+
})}
|
|
22
|
+
export const ${_.camelCase(route.routeName.usage)} = ${newRequestInfoTmpl({
|
|
23
|
+
route,
|
|
24
|
+
configuration,
|
|
25
|
+
apiParams,
|
|
26
|
+
})}
|
|
27
|
+
`);
|
|
28
|
+
};
|
package/index.d.ts
ADDED
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './runtime/index.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mobx-tanstack-query-api",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"keywords": [],
|
|
5
|
+
"author": "js2me",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"description": "",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/js2me/mobx-tanstack-query-api/issues"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/js2me/mobx-tanstack-query-api",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git://github.com/js2me/mobx-tanstack-query-api"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@tanstack/query-core": "^5.68.0",
|
|
19
|
+
"mobx": "^6.13.6",
|
|
20
|
+
"mobx-tanstack-query": "^4.2.5"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"swagger-typescript-api": "^13.0.23",
|
|
24
|
+
"yummies": "^3.0.36"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.17.11",
|
|
28
|
+
"eslint": "^8.57.1",
|
|
29
|
+
"js2me-eslint-config": "^1.0.7",
|
|
30
|
+
"js2me-exports-post-build-script": "^2.0.17",
|
|
31
|
+
"jsdom": "^26.0.0",
|
|
32
|
+
"rimraf": "^6.0.1",
|
|
33
|
+
"typescript": "^5.7.2",
|
|
34
|
+
"unplugin-swc": "^1.5.1",
|
|
35
|
+
"vitest": "^3.0.5"
|
|
36
|
+
},
|
|
37
|
+
"exports": {
|
|
38
|
+
"./codegen": {
|
|
39
|
+
"import": "./codegen/index.js",
|
|
40
|
+
"default": "./codegen/index.js",
|
|
41
|
+
"types": "./codegen/index.d.ts"
|
|
42
|
+
},
|
|
43
|
+
"./codegen/templates/new-request-info.tmpl": {
|
|
44
|
+
"import": "./codegen/templates/new-request-info.tmpl.js",
|
|
45
|
+
"default": "./codegen/templates/new-request-info.tmpl.js",
|
|
46
|
+
"types": "./codegen/templates/new-request-info.tmpl.d.ts"
|
|
47
|
+
},
|
|
48
|
+
"./codegen/templates/request-info-jsdoc.tmpl": {
|
|
49
|
+
"import": "./codegen/templates/request-info-jsdoc.tmpl.js",
|
|
50
|
+
"default": "./codegen/templates/request-info-jsdoc.tmpl.js",
|
|
51
|
+
"types": "./codegen/templates/request-info-jsdoc.tmpl.d.ts"
|
|
52
|
+
},
|
|
53
|
+
"./codegen/templates/request-info-per-file.tmpl": {
|
|
54
|
+
"import": "./codegen/templates/request-info-per-file.tmpl.js",
|
|
55
|
+
"default": "./codegen/templates/request-info-per-file.tmpl.js",
|
|
56
|
+
"types": "./codegen/templates/request-info-per-file.tmpl.d.ts"
|
|
57
|
+
},
|
|
58
|
+
".": {
|
|
59
|
+
"import": "./index.js",
|
|
60
|
+
"default": "./index.js",
|
|
61
|
+
"types": "./index.d.ts"
|
|
62
|
+
},
|
|
63
|
+
"./runtime/http-client": {
|
|
64
|
+
"import": "./runtime/http-client.js",
|
|
65
|
+
"default": "./runtime/http-client.js",
|
|
66
|
+
"types": "./runtime/http-client.d.ts"
|
|
67
|
+
},
|
|
68
|
+
"./runtime": {
|
|
69
|
+
"import": "./runtime/index.js",
|
|
70
|
+
"default": "./runtime/index.js",
|
|
71
|
+
"types": "./runtime/index.d.ts"
|
|
72
|
+
},
|
|
73
|
+
"./runtime/request-info": {
|
|
74
|
+
"import": "./runtime/request-info.js",
|
|
75
|
+
"default": "./runtime/request-info.js",
|
|
76
|
+
"types": "./runtime/request-info.d.ts"
|
|
77
|
+
},
|
|
78
|
+
"./package.json": "./package.json"
|
|
79
|
+
},
|
|
80
|
+
"files": [
|
|
81
|
+
"*"
|
|
82
|
+
],
|
|
83
|
+
"main": "./index.js",
|
|
84
|
+
"typings": "./index.d.ts",
|
|
85
|
+
"scripts": {
|
|
86
|
+
"clean": "rimraf dist",
|
|
87
|
+
"lint:check": "eslint . --fix",
|
|
88
|
+
"ts:check": "tsc --noEmit",
|
|
89
|
+
"check": "npm run lint:check && npm run ts:check",
|
|
90
|
+
"prebuild": "npm run clean && npm run check",
|
|
91
|
+
"build": "tsc && node ./post-build.mjs",
|
|
92
|
+
"pub": "PUBLISH=true pnpm run build",
|
|
93
|
+
"pub:patch": "PUBLISH=true PUBLISH_VERSION=patch pnpm run build",
|
|
94
|
+
"pub:minor": "PUBLISH=true PUBLISH_VERSION=minor pnpm run build",
|
|
95
|
+
"pub:major": "PUBLISH=true PUBLISH_VERSION=major pnpm run build",
|
|
96
|
+
"test": "vitest run",
|
|
97
|
+
"test:watch": "vitest watch",
|
|
98
|
+
"test:coverage": "vitest run --coverage",
|
|
99
|
+
"dev": "pnpm test:watch",
|
|
100
|
+
"playground": "node ./playground/index.mjs"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type QueryParamsType = Record<string | number, any>;
|
|
2
|
+
export type ResponseFormat = keyof Omit<Body, 'body' | 'bodyUsed'>;
|
|
3
|
+
export interface FullRequestParams extends Omit<RequestInit, 'body'> {
|
|
4
|
+
/** set parameter to `true` for call `securityWorker` for this request */
|
|
5
|
+
secure?: boolean;
|
|
6
|
+
/** request path */
|
|
7
|
+
path: string;
|
|
8
|
+
/** content type of request body */
|
|
9
|
+
contentType?: string;
|
|
10
|
+
/** query params */
|
|
11
|
+
query?: QueryParamsType;
|
|
12
|
+
/** format of response (i.e. response.json() -> format: "json") */
|
|
13
|
+
format?: ResponseFormat;
|
|
14
|
+
/** request body */
|
|
15
|
+
body?: unknown;
|
|
16
|
+
/** base url */
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
/** meta data */
|
|
19
|
+
meta?: Record<string, any>;
|
|
20
|
+
}
|
|
21
|
+
export type RequestParams = Omit<FullRequestParams, 'body' | 'method' | 'query' | 'path' | 'serviceName'>;
|
|
22
|
+
export interface HttpClientConfig<TMeta = unknown> {
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
meta?: TMeta;
|
|
25
|
+
baseApiParams?: Omit<RequestParams, 'baseUrl' | 'cancelToken' | 'signal'>;
|
|
26
|
+
contentFormatters?: Record<string, (input: any) => any>;
|
|
27
|
+
toQueryString?: (query?: QueryParamsType) => string;
|
|
28
|
+
buildUrl?: (fullParams: FullRequestParams, formattedParts: {
|
|
29
|
+
baseUrl: string;
|
|
30
|
+
path: string;
|
|
31
|
+
query: string;
|
|
32
|
+
}) => string;
|
|
33
|
+
interceptor?: (requestParams: RequestParams, metadata: TMeta | null) => Promise<RequestParams | void> | RequestParams | void;
|
|
34
|
+
fetch?: typeof fetch;
|
|
35
|
+
}
|
|
36
|
+
export interface HttpResponse<D, E = unknown> extends Response {
|
|
37
|
+
data: D;
|
|
38
|
+
error: E;
|
|
39
|
+
}
|
|
40
|
+
export type AnyHttpResponse = HttpResponse<any, any>;
|
|
41
|
+
export declare const isHttpResponse: (response: unknown, status?: number) => response is AnyHttpResponse;
|
|
42
|
+
export declare class HttpClient<TMeta = unknown> {
|
|
43
|
+
baseUrl: string;
|
|
44
|
+
meta: TMeta | null;
|
|
45
|
+
private interceptor?;
|
|
46
|
+
private fetch;
|
|
47
|
+
private customBuildUrl;
|
|
48
|
+
private customToQueryString;
|
|
49
|
+
private baseApiParams;
|
|
50
|
+
badResponse: unknown;
|
|
51
|
+
constructor(config?: HttpClientConfig<TMeta>);
|
|
52
|
+
setMeta: (data: TMeta | null) => void;
|
|
53
|
+
setBadResponse: (response: unknown) => void;
|
|
54
|
+
protected encodeQueryParam(key: string, value: any): string;
|
|
55
|
+
protected addQueryParam(query: QueryParamsType, key: string): string;
|
|
56
|
+
protected addArrayQueryParam(query: QueryParamsType, key: string): any;
|
|
57
|
+
protected toQueryString(rawQuery?: QueryParamsType): string;
|
|
58
|
+
private contentFormatters;
|
|
59
|
+
protected mergeRequestParams(params1: RequestParams, params2?: RequestParams): RequestParams;
|
|
60
|
+
private formatResponse;
|
|
61
|
+
buildUrl: (params: FullRequestParams) => string;
|
|
62
|
+
request: <T = any, E = any>(fullParams: FullRequestParams) => Promise<HttpResponse<T, E>>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=http-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/runtime/http-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { action, makeObservable, observable } from 'mobx';
|
|
2
|
+
export const isHttpResponse = (response, status) => !!response &&
|
|
3
|
+
typeof response === 'object' &&
|
|
4
|
+
response instanceof Response &&
|
|
5
|
+
'data' in response &&
|
|
6
|
+
(!status || response.status === status);
|
|
7
|
+
export class HttpClient {
|
|
8
|
+
baseUrl = '';
|
|
9
|
+
meta = null;
|
|
10
|
+
interceptor;
|
|
11
|
+
fetch;
|
|
12
|
+
customBuildUrl;
|
|
13
|
+
customToQueryString;
|
|
14
|
+
baseApiParams = {
|
|
15
|
+
credentials: 'same-origin',
|
|
16
|
+
headers: {},
|
|
17
|
+
redirect: 'follow',
|
|
18
|
+
referrerPolicy: 'no-referrer',
|
|
19
|
+
};
|
|
20
|
+
badResponse = null;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.baseUrl = config?.baseUrl ?? '';
|
|
23
|
+
this.meta = config?.meta ?? null;
|
|
24
|
+
this.interceptor = config?.interceptor;
|
|
25
|
+
this.fetch = config?.fetch ?? fetch;
|
|
26
|
+
this.customBuildUrl = config?.buildUrl;
|
|
27
|
+
this.customToQueryString = config?.toQueryString;
|
|
28
|
+
Object.assign(this.contentFormatters, config?.contentFormatters ?? {});
|
|
29
|
+
observable.ref(this, 'badResponse');
|
|
30
|
+
observable.ref(this, 'meta');
|
|
31
|
+
action(this, 'setMeta');
|
|
32
|
+
action(this, 'setBadResponse');
|
|
33
|
+
makeObservable(this);
|
|
34
|
+
}
|
|
35
|
+
setMeta = (data) => {
|
|
36
|
+
this.meta = data;
|
|
37
|
+
};
|
|
38
|
+
setBadResponse = (response) => {
|
|
39
|
+
this.badResponse = response;
|
|
40
|
+
};
|
|
41
|
+
encodeQueryParam(key, value) {
|
|
42
|
+
const encodedKey = encodeURIComponent(key);
|
|
43
|
+
return `${encodedKey}=${encodeURIComponent(typeof value === 'number' ? value : `${value}`)}`;
|
|
44
|
+
}
|
|
45
|
+
addQueryParam(query, key) {
|
|
46
|
+
return this.encodeQueryParam(key, query[key]);
|
|
47
|
+
}
|
|
48
|
+
addArrayQueryParam(query, key) {
|
|
49
|
+
const value = query[key];
|
|
50
|
+
return value.map((v) => this.encodeQueryParam(key, v)).join('&');
|
|
51
|
+
}
|
|
52
|
+
toQueryString(rawQuery) {
|
|
53
|
+
if (this.customToQueryString) {
|
|
54
|
+
return this.customToQueryString(rawQuery);
|
|
55
|
+
}
|
|
56
|
+
const query = rawQuery || {};
|
|
57
|
+
const keys = Object.keys(query).filter((key) => 'undefined' !== typeof query[key]);
|
|
58
|
+
return keys
|
|
59
|
+
.map((key) => Array.isArray(query[key])
|
|
60
|
+
? this.addArrayQueryParam(query, key)
|
|
61
|
+
: this.addQueryParam(query, key))
|
|
62
|
+
.join('&');
|
|
63
|
+
}
|
|
64
|
+
contentFormatters = {
|
|
65
|
+
'application/json': (input) => input !== null && (typeof input === 'object' || typeof input === 'string')
|
|
66
|
+
? JSON.stringify(input)
|
|
67
|
+
: input,
|
|
68
|
+
'text/plain': (input) => input !== null && typeof input !== 'string'
|
|
69
|
+
? JSON.stringify(input)
|
|
70
|
+
: input,
|
|
71
|
+
'multipart/form-data': (input) => Object.keys(input || {}).reduce((formData, key) => {
|
|
72
|
+
const property = input[key];
|
|
73
|
+
if (property instanceof Blob) {
|
|
74
|
+
formData.append(key, property);
|
|
75
|
+
}
|
|
76
|
+
else if (typeof property === 'object' && property !== null) {
|
|
77
|
+
formData.append(key, JSON.stringify(property));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
formData.append(key, `${property}`);
|
|
81
|
+
}
|
|
82
|
+
return formData;
|
|
83
|
+
}, new FormData()),
|
|
84
|
+
'application/x-www-form-urlencoded': (input) => this.toQueryString(input),
|
|
85
|
+
'application/octet-stream': (input) => input,
|
|
86
|
+
};
|
|
87
|
+
mergeRequestParams(params1, params2) {
|
|
88
|
+
return {
|
|
89
|
+
...this.baseApiParams,
|
|
90
|
+
...params1,
|
|
91
|
+
...params2,
|
|
92
|
+
headers: {
|
|
93
|
+
...this.baseApiParams.headers,
|
|
94
|
+
...params1.headers,
|
|
95
|
+
...params2?.headers,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
async formatResponse(responseFormat, raw) {
|
|
100
|
+
const response = raw;
|
|
101
|
+
response.data = null;
|
|
102
|
+
response.error = null;
|
|
103
|
+
if (responseFormat) {
|
|
104
|
+
try {
|
|
105
|
+
const formatted = await response[responseFormat]();
|
|
106
|
+
if (response.ok) {
|
|
107
|
+
response.data = formatted;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
response.error = formatted;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
if (response.ok) {
|
|
115
|
+
response.error = error;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
response.error = null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (!response.ok) {
|
|
123
|
+
this.setBadResponse(response);
|
|
124
|
+
throw response;
|
|
125
|
+
}
|
|
126
|
+
return response;
|
|
127
|
+
}
|
|
128
|
+
buildUrl = (params) => {
|
|
129
|
+
const baseUrl = params.baseUrl ?? this.baseUrl ?? '';
|
|
130
|
+
const path = params.path;
|
|
131
|
+
const queryString = params.query && this.toQueryString(params.query);
|
|
132
|
+
const query = queryString ? `?${queryString}` : '';
|
|
133
|
+
if (this.customBuildUrl) {
|
|
134
|
+
return this.customBuildUrl(params, { baseUrl, path, query });
|
|
135
|
+
}
|
|
136
|
+
const url = baseUrl + path + query;
|
|
137
|
+
return url;
|
|
138
|
+
};
|
|
139
|
+
request = async (fullParams) => {
|
|
140
|
+
this.setBadResponse(null);
|
|
141
|
+
const { body, contentType = 'application/json', format = 'json', ...params } = fullParams;
|
|
142
|
+
let requestParams = this.mergeRequestParams(params);
|
|
143
|
+
if (this.interceptor) {
|
|
144
|
+
requestParams =
|
|
145
|
+
(await this.interceptor(requestParams, this.meta)) ?? requestParams;
|
|
146
|
+
}
|
|
147
|
+
const payloadFormatter = this.contentFormatters[contentType];
|
|
148
|
+
const responseFormat = format || requestParams.format;
|
|
149
|
+
const url = this.buildUrl(fullParams);
|
|
150
|
+
const responseFormatter = this.formatResponse.bind(this, responseFormat);
|
|
151
|
+
let headers;
|
|
152
|
+
if (requestParams.headers instanceof Headers) {
|
|
153
|
+
headers = requestParams.headers;
|
|
154
|
+
}
|
|
155
|
+
else if (Array.isArray(requestParams.headers)) {
|
|
156
|
+
headers = new Headers(requestParams.headers);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
headers = new Headers(requestParams.headers);
|
|
160
|
+
}
|
|
161
|
+
if (!headers.has('Content-Type')) {
|
|
162
|
+
headers.set('Content-Type', contentType);
|
|
163
|
+
}
|
|
164
|
+
return this.fetch(url, {
|
|
165
|
+
...requestParams,
|
|
166
|
+
headers,
|
|
167
|
+
body: body == null ? null : payloadFormatter(body),
|
|
168
|
+
})
|
|
169
|
+
.then(responseFormatter)
|
|
170
|
+
.catch(responseFormatter);
|
|
171
|
+
};
|
|
172
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
package/runtime/index.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { InvalidateOptions, InvalidateQueryFilters, QueryClient, QueryFunctionContext } from '@tanstack/query-core';
|
|
2
|
+
import { MobxQuery, MobxQueryConfig } from 'mobx-tanstack-query';
|
|
3
|
+
import { AnyObject, MaybeFalsy } from 'yummies/utils/types';
|
|
4
|
+
import type { FullRequestParams, HttpClient, HttpResponse } from './http-client.js';
|
|
5
|
+
export interface RequestInfo<TData, TError, TInput extends AnyObject, TParams extends any[] = any[]> {
|
|
6
|
+
(...params: TParams): ReturnType<RequestInfo<TData, TError, TInput, TParams>['request']>;
|
|
7
|
+
}
|
|
8
|
+
export declare class RequestInfo<TData, TError, TInput extends AnyObject, TParams extends any[] = any[], TMetaData extends AnyObject = AnyObject> {
|
|
9
|
+
protected cfg: {
|
|
10
|
+
operationId: string;
|
|
11
|
+
meta?: TMetaData;
|
|
12
|
+
params: (...params: TParams) => FullRequestParams;
|
|
13
|
+
keys: (string | {
|
|
14
|
+
name: string;
|
|
15
|
+
param: number;
|
|
16
|
+
} | {
|
|
17
|
+
name: string;
|
|
18
|
+
rest: true;
|
|
19
|
+
})[];
|
|
20
|
+
tags: string[];
|
|
21
|
+
};
|
|
22
|
+
protected queryClient: QueryClient;
|
|
23
|
+
protected http: HttpClient;
|
|
24
|
+
meta: TMetaData;
|
|
25
|
+
constructor(cfg: {
|
|
26
|
+
operationId: string;
|
|
27
|
+
meta?: TMetaData;
|
|
28
|
+
params: (...params: TParams) => FullRequestParams;
|
|
29
|
+
keys: (string | {
|
|
30
|
+
name: string;
|
|
31
|
+
param: number;
|
|
32
|
+
} | {
|
|
33
|
+
name: string;
|
|
34
|
+
rest: true;
|
|
35
|
+
})[];
|
|
36
|
+
tags: string[];
|
|
37
|
+
}, queryClient: QueryClient, http: HttpClient);
|
|
38
|
+
private get hasRestParam();
|
|
39
|
+
protected buildParamsFromContext(ctx: QueryFunctionContext<any, any>): TParams;
|
|
40
|
+
protected buildParamsFromInput(input: TInput): TParams;
|
|
41
|
+
protected buildQueryKeyFromInput(input: TInput): any[];
|
|
42
|
+
protected buildInputFromQueryKey(queryKey: any[]): TInput;
|
|
43
|
+
getFullUrl(input: TInput): string;
|
|
44
|
+
getPath(input: TInput): string;
|
|
45
|
+
getTags(): string[];
|
|
46
|
+
request(...params: TParams): Promise<HttpResponse<TData, TError>>;
|
|
47
|
+
toQueryKey(input: TInput): any[];
|
|
48
|
+
invalidateByOperationId(filters?: Omit<InvalidateQueryFilters<HttpResponse<TData, TError>>, 'queryKey' | 'predicate'>, options?: InvalidateOptions): Promise<void>;
|
|
49
|
+
invalidateByTags(filters?: Omit<InvalidateQueryFilters<HttpResponse<TData, TError>>, 'queryKey' | 'predicate'>, options?: InvalidateOptions): Promise<void>;
|
|
50
|
+
invalidate(input: TInput, filters?: Omit<InvalidateQueryFilters<HttpResponse<TData, TError>>, 'queryKey' | 'predicate'> & {
|
|
51
|
+
queryKeyIndex?: number;
|
|
52
|
+
}, options?: InvalidateOptions): Promise<void>;
|
|
53
|
+
toQuery({ input: getInput, ...options }: Omit<MobxQueryConfig<HttpResponse<TData, TError>, TError>, 'options' | 'queryFn' | 'queryClient'> & {
|
|
54
|
+
input: () => MaybeFalsy<TInput>;
|
|
55
|
+
}): MobxQuery<HttpResponse<TData, TError>, TError, any>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=request-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-info.d.ts","sourceRoot":"","sources":["../../src/runtime/request-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { MobxQuery } from 'mobx-tanstack-query';
|
|
2
|
+
export class RequestInfo {
|
|
3
|
+
cfg;
|
|
4
|
+
queryClient;
|
|
5
|
+
http;
|
|
6
|
+
meta;
|
|
7
|
+
constructor(cfg, queryClient, http) {
|
|
8
|
+
this.cfg = cfg;
|
|
9
|
+
this.queryClient = queryClient;
|
|
10
|
+
this.http = http;
|
|
11
|
+
this.meta = cfg.meta ?? {};
|
|
12
|
+
// Сохраняем оригинальный инстанс
|
|
13
|
+
const instance = this;
|
|
14
|
+
// Создаем функцию-обертку
|
|
15
|
+
const callable = function (...params) {
|
|
16
|
+
return instance.request.apply(instance, params);
|
|
17
|
+
};
|
|
18
|
+
// Копируем прототип
|
|
19
|
+
Object.setPrototypeOf(callable, new.target.prototype);
|
|
20
|
+
// Копируем методы из оригинального инстанса
|
|
21
|
+
Object.getOwnPropertyNames(instance)
|
|
22
|
+
.concat(Object.getOwnPropertyNames(new.target.prototype))
|
|
23
|
+
.forEach((key) => {
|
|
24
|
+
if (key === 'constructor')
|
|
25
|
+
return;
|
|
26
|
+
const desc = Object.getOwnPropertyDescriptor(instance, key) ||
|
|
27
|
+
Object.getOwnPropertyDescriptor(new.target.prototype, key);
|
|
28
|
+
if (desc)
|
|
29
|
+
Object.defineProperty(callable, key, desc);
|
|
30
|
+
});
|
|
31
|
+
return callable;
|
|
32
|
+
}
|
|
33
|
+
get hasRestParam() {
|
|
34
|
+
return this.cfg.keys.some((key) => {
|
|
35
|
+
if (typeof key !== 'string' && 'rest' in key) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
buildParamsFromContext(ctx) {
|
|
41
|
+
const input = this.buildInputFromQueryKey(ctx.queryKey);
|
|
42
|
+
return this.buildParamsFromInput(input);
|
|
43
|
+
}
|
|
44
|
+
buildParamsFromInput(input) {
|
|
45
|
+
const args = [];
|
|
46
|
+
const restParams = {};
|
|
47
|
+
if (this.hasRestParam) {
|
|
48
|
+
args[0] = restParams;
|
|
49
|
+
}
|
|
50
|
+
this.cfg.keys.forEach((key) => {
|
|
51
|
+
if (typeof key === 'object') {
|
|
52
|
+
if (key.name === 'request') {
|
|
53
|
+
args.push(input[key.name]);
|
|
54
|
+
}
|
|
55
|
+
else if (this.hasRestParam) {
|
|
56
|
+
if ('rest' in key) {
|
|
57
|
+
Object.assign(restParams, input);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if ('param' in key) {
|
|
61
|
+
args[key.param] = input[key.name];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return args;
|
|
66
|
+
}
|
|
67
|
+
buildQueryKeyFromInput(input) {
|
|
68
|
+
const restParams = this.hasRestParam ? { ...input } : {};
|
|
69
|
+
return this.cfg.keys.map((key) => {
|
|
70
|
+
if (typeof key === 'string') {
|
|
71
|
+
return key;
|
|
72
|
+
}
|
|
73
|
+
if (this.hasRestParam) {
|
|
74
|
+
if ('rest' in key) {
|
|
75
|
+
return restParams;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const param = restParams[key.name];
|
|
79
|
+
delete restParams[key.name];
|
|
80
|
+
return param;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return input[key.name];
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
buildInputFromQueryKey(queryKey) {
|
|
89
|
+
const input = {};
|
|
90
|
+
this.cfg.keys.forEach((key, index) => {
|
|
91
|
+
const keyPart = queryKey[index];
|
|
92
|
+
if (typeof key === 'string') {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (key.name === 'request') {
|
|
96
|
+
input[key.name] = keyPart;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if ('rest' in key) {
|
|
100
|
+
Object.assign(input, keyPart);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if ('param' in key) {
|
|
104
|
+
input[key.name] = keyPart;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return input;
|
|
108
|
+
}
|
|
109
|
+
getFullUrl(input) {
|
|
110
|
+
const params = this.cfg.params(...this.buildParamsFromInput(input));
|
|
111
|
+
return this.http.buildUrl(params);
|
|
112
|
+
}
|
|
113
|
+
getPath(input) {
|
|
114
|
+
return this.cfg.params(...this.buildParamsFromInput(input)).path;
|
|
115
|
+
}
|
|
116
|
+
getTags() {
|
|
117
|
+
return this.cfg.tags;
|
|
118
|
+
}
|
|
119
|
+
request(...params) {
|
|
120
|
+
return this.http.request(this.cfg.params(...params));
|
|
121
|
+
}
|
|
122
|
+
toQueryKey(input) {
|
|
123
|
+
return this.buildQueryKeyFromInput(input);
|
|
124
|
+
}
|
|
125
|
+
invalidateByOperationId(filters, options) {
|
|
126
|
+
return this.queryClient.invalidateQueries({
|
|
127
|
+
...filters,
|
|
128
|
+
predicate: (query) => {
|
|
129
|
+
if (query.meta?.operationId) {
|
|
130
|
+
return query.meta?.operationId === this.cfg.operationId;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
},
|
|
134
|
+
}, options);
|
|
135
|
+
}
|
|
136
|
+
invalidateByTags(filters, options) {
|
|
137
|
+
const tags = this.getTags();
|
|
138
|
+
return this.queryClient.invalidateQueries({
|
|
139
|
+
...filters,
|
|
140
|
+
predicate: (query) => {
|
|
141
|
+
if (Array.isArray(query.meta?.tags)) {
|
|
142
|
+
return query.meta.tags.some((tag) => tags.includes(tag));
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
},
|
|
146
|
+
}, options);
|
|
147
|
+
}
|
|
148
|
+
invalidate(input, filters, options) {
|
|
149
|
+
return this.queryClient.invalidateQueries({
|
|
150
|
+
...filters,
|
|
151
|
+
queryKey: this.toQueryKey(input).slice(0, filters?.queryKeyIndex),
|
|
152
|
+
exact: filters?.exact ?? false,
|
|
153
|
+
}, options);
|
|
154
|
+
}
|
|
155
|
+
toQuery({ input: getInput, ...options }) {
|
|
156
|
+
return new MobxQuery({
|
|
157
|
+
...options,
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
159
|
+
// @ts-expect-error
|
|
160
|
+
queryClient: this.queryClient,
|
|
161
|
+
options: () => {
|
|
162
|
+
const input = getInput();
|
|
163
|
+
return {
|
|
164
|
+
meta: {
|
|
165
|
+
tags: this.getTags(),
|
|
166
|
+
operationId: this.cfg.operationId,
|
|
167
|
+
...options.meta,
|
|
168
|
+
},
|
|
169
|
+
enabled: !!input,
|
|
170
|
+
queryKey: input ? this.toQueryKey(input) : '__SKIP__',
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
queryFn: async (ctx) => {
|
|
174
|
+
const args = this.buildParamsFromContext(ctx);
|
|
175
|
+
const requestParamsIndex = args.length - 1;
|
|
176
|
+
if (args[requestParamsIndex]) {
|
|
177
|
+
if (!args[requestParamsIndex].signal) {
|
|
178
|
+
args[requestParamsIndex].signal = ctx.signal;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
args[requestParamsIndex] = { signal: ctx.signal };
|
|
183
|
+
}
|
|
184
|
+
const response = await this.request(...args);
|
|
185
|
+
return response;
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|