wormajs 0.3.1 → 1.0.0-beta.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/dist/bin/actions.js +162 -5
- package/dist/bin/cli.js +7 -1
- package/dist/bin/renderer.js +2 -8
- package/dist/checkUpdates.js +98 -0
- package/dist/config.js +7 -0
- package/dist/constant.js +1 -2
- package/dist/core/WorkerPool.js +14 -0
- package/dist/core/loader/callingCodeLoader/helper.js +2 -3
- package/dist/core/loader/callingCodeLoader/index.js +1 -1
- package/dist/core/parser/openApiParser/helper.js +32 -19
- package/dist/core/parser/templateParser/index.js +25 -12
- package/dist/core/workerPool/index.js +2 -1
- package/dist/functions/changeReport.js +230 -0
- package/dist/functions/diffApis.js +82 -0
- package/dist/functions/diffDocument.js +542 -0
- package/dist/functions/sourceSnapshot.js +107 -0
- package/dist/functions/wormaJson.js +306 -66
- package/dist/generate.js +24 -2
- package/dist/helper/config/ConfigHelper.js +1 -2
- package/dist/helper/config/ConfigManager.js +7 -0
- package/dist/helper/config/GeneratorHelper.js +74 -21
- package/dist/helper/config/zType.js +24 -1
- package/dist/helper/template/index.js +60 -4
- package/dist/index.js +17 -1
- package/dist/plugins/index.js +2 -2
- package/dist/plugins/presets/aiDoc.js +4 -0
- package/dist/plugins/presets/payloadModifier/dsl.js +147 -0
- package/dist/plugins/presets/payloadModifier/index.js +122 -135
- package/dist/plugins/presets/payloadModifier/patch.js +171 -0
- package/dist/plugins/presets/payloadModifier/scope.js +109 -0
- package/dist/plugins/presets/platform/index.js +1 -3
- package/dist/plugins/presets/postman.js +105 -0
- package/dist/template/presets/ai-doc/SKILL.md.handlebars +1 -1
- package/dist/template/presets/alova/common/services/{tag}.d.cts.handlebars +1 -1
- package/dist/template/presets/alova/module/services/{tag}.d.ts.handlebars +1 -1
- package/dist/template/presets/alova/partials/dts-fn-declare.handlebars +1 -1
- package/dist/template/presets/alova/partials/dts-types.handlebars +12 -0
- package/dist/template/presets/alova/typescript/services/{tag}.ts.handlebars +11 -6
- package/dist/template/presets/axios/partials/dts-types.handlebars +9 -5
- package/dist/template/presets/axios/typescript/services/{tag}.ts.handlebars +9 -5
- package/dist/template/presets/fetch/partials/dts-types.handlebars +8 -5
- package/dist/template/presets/fetch/typescript/services/{tag}.ts.handlebars +9 -5
- package/dist/template/presets/ky/partials/dts-types.handlebars +8 -5
- package/dist/template/presets/ky/typescript/services/{tag}.ts.handlebars +9 -5
- package/dist/utils/format.js +62 -15
- package/dist/utils/template.js +1 -1
- package/package.json +3 -2
- package/typings/index.d.ts +266 -13
- package/typings/plugins.d.ts +171 -80
- package/dist/plugins/presets/payloadModifier/hepler.js +0 -289
- package/dist/plugins/presets/platform/fastapi.js +0 -22
- package/dist/template/presets/alova/partials/dts-extra-config.handlebars +0 -8
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unwrapTransformationOutput = unwrapTransformationOutput;
|
|
4
|
+
exports.postman = postman;
|
|
5
|
+
const constant_1 = require("../../constant");
|
|
6
|
+
/** Base address of the Postman API */
|
|
7
|
+
const POSTMAN_API_BASE = 'https://api.getpostman.com';
|
|
8
|
+
/**
|
|
9
|
+
* Unwraps the OpenAPI definition returned by the Postman collection
|
|
10
|
+
* transformation endpoint, which responds with `{ output: "<stringified spec>" }`
|
|
11
|
+
* instead of the specification itself.
|
|
12
|
+
*
|
|
13
|
+
* The response is parsed exactly once. Anything that is not a transformation
|
|
14
|
+
* envelope (an error payload, an HTML page, a malformed body, …) throws instead
|
|
15
|
+
* of being silently passed through, so the real problem surfaces immediately.
|
|
16
|
+
* The unwrapped spec is then validated by the generator's parser, like any other
|
|
17
|
+
* input — this function does not re-parse or validate it.
|
|
18
|
+
*/
|
|
19
|
+
function unwrapTransformationOutput(spec) {
|
|
20
|
+
let parsed;
|
|
21
|
+
try {
|
|
22
|
+
parsed = JSON.parse(spec);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw new Error('[postman] The transformation response is not valid JSON: '
|
|
26
|
+
+ `${error instanceof Error ? error.message : String(error)}. `
|
|
27
|
+
+ `Received: ${spec.slice(0, 200)}`);
|
|
28
|
+
}
|
|
29
|
+
const output = parsed?.output;
|
|
30
|
+
if (typeof output !== 'string') {
|
|
31
|
+
throw new TypeError('[postman] The transformation response must be a JSON object with a string `output` field. '
|
|
32
|
+
+ 'Check that the collection uid is correct and that you have access to it. '
|
|
33
|
+
+ `Received: ${spec.slice(0, 200)}`);
|
|
34
|
+
}
|
|
35
|
+
return output;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Postman platform plugin.
|
|
39
|
+
*
|
|
40
|
+
* Postman collections are not OpenAPI documents, so the plugin points `input` to
|
|
41
|
+
* the collection transformation endpoint, which converts the collection into an
|
|
42
|
+
* OpenAPI definition:
|
|
43
|
+
*
|
|
44
|
+
* ```
|
|
45
|
+
* https://api.getpostman.com/collections/<collectionId>/transformations
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* The `x-api-key` header is injected through `fetchOptions`. The endpoint responds
|
|
49
|
+
* with `{ output: "<spec>" }`, so the plugin unwraps that envelope in its
|
|
50
|
+
* `beforeSpecParse` hook.
|
|
51
|
+
*
|
|
52
|
+
* `apiKey` and `collectionId` are both required — the plugin throws a clear error
|
|
53
|
+
* when either is missing.
|
|
54
|
+
*
|
|
55
|
+
* @param options - `{ apiKey, collectionId }`
|
|
56
|
+
* @param options.apiKey - Postman API key used to read the collection
|
|
57
|
+
* @param options.collectionId - The uid of the Postman collection
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { postman, alovaGlobals } from 'wormajs/plugin';
|
|
62
|
+
*
|
|
63
|
+
* defineConfig({
|
|
64
|
+
* generator: [{
|
|
65
|
+
* plugins: [
|
|
66
|
+
* postman({
|
|
67
|
+
* apiKey: 'PMAK-xxx',
|
|
68
|
+
* collectionId: '12345678-a1b2-c3d4-e5f6-7890abcdef12',
|
|
69
|
+
* }),
|
|
70
|
+
* alovaGlobals(),
|
|
71
|
+
* ],
|
|
72
|
+
* output: './src/api',
|
|
73
|
+
* }]
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
function postman({ apiKey, collectionId }) {
|
|
78
|
+
return {
|
|
79
|
+
name: constant_1.PluginName.POSTMAN,
|
|
80
|
+
async config({ config }) {
|
|
81
|
+
if (!apiKey) {
|
|
82
|
+
throw new Error('[postman] `apiKey` is required — the Postman API key used to read the collection '
|
|
83
|
+
+ '(e.g. postman({ apiKey: "PMAK-xxx", collectionId: "12345678-..." })).');
|
|
84
|
+
}
|
|
85
|
+
if (!collectionId) {
|
|
86
|
+
throw new Error('[postman] `collectionId` is required — the uid of the Postman collection '
|
|
87
|
+
+ '(e.g. postman({ apiKey: "PMAK-xxx", collectionId: "12345678-..." })).');
|
|
88
|
+
}
|
|
89
|
+
config.input = `${POSTMAN_API_BASE}/collections/${encodeURIComponent(collectionId.trim())}/transformations`;
|
|
90
|
+
config.fetchOptions = {
|
|
91
|
+
...config.fetchOptions,
|
|
92
|
+
method: 'GET',
|
|
93
|
+
headers: {
|
|
94
|
+
...config.fetchOptions?.headers,
|
|
95
|
+
'x-api-key': apiKey,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
return config;
|
|
99
|
+
},
|
|
100
|
+
beforeSpecParse({ spec }) {
|
|
101
|
+
return unwrapTransformationOutput(spec);
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
exports.default = postman;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function {{{name}}}<Config extends Alova2MethodConfig<{{
|
|
1
|
+
export declare function {{{name}}}<Config extends Alova2MethodConfig<{{{name}}}Response> & {{{name}}}ExtraConfig>(config{{#or pathParameters queryParameters requestBody }}{{else}}?{{/or}}: Config): Alova2Method<ExtractResponded<Config, '{{{name}}}', {{{name}}}Response>>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{{#if pathParameters}}export type {{{name}}}PathParams = {{addNamespace pathParameters @root.componentNames}};
|
|
2
|
+
{{/if}}{{#if queryParameters}}export type {{{name}}}Params = {{addNamespace queryParameters @root.componentNames}};
|
|
3
|
+
{{/if}}{{#if requestBody}}export type {{{name}}}Data = {{addNamespace requestBody @root.componentNames}};
|
|
4
|
+
{{/if}}export type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
5
|
+
{{#or pathParameters queryParameters requestBody}}
|
|
6
|
+
export interface {{{name}}}ExtraConfig {
|
|
7
|
+
{{#if pathParameters}}pathParams: {{{name}}}PathParams;
|
|
8
|
+
{{/if}}{{#if queryParameters}}params: {{{name}}}Params;
|
|
9
|
+
{{/if}}{{#if requestBody}}data: {{{name}}}Data;
|
|
10
|
+
{{/if}}
|
|
11
|
+
}
|
|
12
|
+
{{/or}}
|
|
@@ -10,16 +10,21 @@ const {{{currentTag.tag}}}DefaultConfig = resolveTagDefaultConfig(defaultConfig,
|
|
|
10
10
|
{{> extract-responded}}
|
|
11
11
|
{{#each currentTag.apis}}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
export type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
14
|
+
{{#if pathParameters}}export type {{{name}}}PathParams = {{addNamespace pathParameters @root.componentNames}};
|
|
15
|
+
{{/if}}{{#if queryParameters}}export type {{{name}}}Params = {{addNamespace queryParameters @root.componentNames}};
|
|
16
|
+
{{/if}}{{#if requestBody}}export type {{{name}}}Data = {{addNamespace requestBody @root.componentNames}};
|
|
17
|
+
{{/if}}
|
|
18
|
+
export interface {{{name}}}ExtraConfig {
|
|
19
|
+
{{#if pathParameters}}pathParams: {{{name}}}PathParams;
|
|
20
|
+
{{/if}}{{#if queryParameters}}params: {{{name}}}Params;
|
|
21
|
+
{{/if}}{{#if requestBody}}data: {{{name}}}Data;
|
|
17
22
|
{{/if}}
|
|
18
23
|
}
|
|
19
24
|
{{> api-jsdoc}}
|
|
20
|
-
export function {{{name}}}<Config extends Alova2MethodConfig<{{
|
|
25
|
+
export function {{{name}}}<Config extends Alova2MethodConfig<{{{name}}}Response> & {{{name}}}ExtraConfig>(config{{#or pathParameters queryParameters requestBody }}{{else}}?{{/or}}: Config): Alova2Method<ExtractResponded<Config, '{{{name}}}', {{{name}}}Response>> {
|
|
21
26
|
const { url, data, mergedConfig } = buildPayload('{{{path}}}', {{../currentTag.tag}}DefaultConfig, {{{name}}}.name, config);
|
|
22
|
-
return alovaInstance.Request<ExtractResponded<Config, '{{{name}}}', {{
|
|
27
|
+
return alovaInstance.Request<ExtractResponded<Config, '{{{name}}}', {{{name}}}Response>>({
|
|
23
28
|
...mergedConfig,
|
|
24
29
|
url,
|
|
25
30
|
data,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
2
|
-
type {{{name}}}
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
export type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
2
|
+
{{#if pathParameters}}export type {{{name}}}PathParams = {{addNamespace pathParameters @root.componentNames}};
|
|
3
|
+
{{/if}}{{#if queryParameters}}export type {{{name}}}Params = {{addNamespace queryParameters @root.componentNames}};
|
|
4
|
+
{{/if}}{{#if requestBody}}export type {{{name}}}Data = {{addNamespace requestBody @root.componentNames}};
|
|
5
|
+
{{/if}}
|
|
6
|
+
export type {{{name}}}ExtraConfig = Omit<AxiosRequestConfig, 'data' | 'params'> & {
|
|
7
|
+
{{#if pathParameters}}pathParams: {{{name}}}PathParams;
|
|
8
|
+
{{/if}}{{#if queryParameters}}params: {{{name}}}Params;
|
|
9
|
+
{{/if}}{{#if requestBody}}data: {{{name}}}Data;
|
|
6
10
|
{{/if}}
|
|
7
11
|
};
|
|
@@ -8,11 +8,15 @@ import type * as ComponentTypes from '../components';
|
|
|
8
8
|
const {{{currentTag.tag}}}DefaultConfig = resolveTagDefaultConfig(defaultConfig, '{{{currentTag.tag}}}DefaultConfig');
|
|
9
9
|
|
|
10
10
|
{{#each currentTag.apis}}
|
|
11
|
-
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
12
|
-
type {{{name}}}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
12
|
+
{{#if pathParameters}}export type {{{name}}}PathParams = {{addNamespace pathParameters @root.componentNames}};
|
|
13
|
+
{{/if}}{{#if queryParameters}}export type {{{name}}}Params = {{addNamespace queryParameters @root.componentNames}};
|
|
14
|
+
{{/if}}{{#if requestBody}}export type {{{name}}}Data = {{addNamespace requestBody @root.componentNames}};
|
|
15
|
+
{{/if}}
|
|
16
|
+
export type {{{name}}}ExtraConfig = Omit<AxiosRequestConfig, 'data' | 'params'> & {
|
|
17
|
+
{{#if pathParameters}}pathParams: {{{name}}}PathParams;
|
|
18
|
+
{{/if}}{{#if queryParameters}}params: {{{name}}}Params;
|
|
19
|
+
{{/if}}{{#if requestBody}}data: {{{name}}}Data;
|
|
16
20
|
{{/if}}
|
|
17
21
|
};
|
|
18
22
|
{{> api-jsdoc}}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
type {{{name}}}
|
|
2
|
-
type {{{name}}}
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
{{#if pathParameters}}export type {{{name}}}PathParams = {{addNamespace pathParameters @root.componentNames}};
|
|
2
|
+
{{/if}}{{#if queryParameters}}export type {{{name}}}Params = {{addNamespace queryParameters @root.componentNames}};
|
|
3
|
+
{{/if}}{{#if requestBody}}export type {{{name}}}Data = {{addNamespace requestBody @root.componentNames}};
|
|
4
|
+
{{/if}}export type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
5
|
+
export type {{{name}}}ExtraConfig = Omit<RequestInit, 'body'> & {
|
|
6
|
+
{{#if pathParameters}}pathParams: {{{name}}}PathParams;
|
|
7
|
+
{{/if}}{{#if queryParameters}}params?: {{{name}}}Params;
|
|
8
|
+
{{/if}}{{#if requestBody}}body?: {{{name}}}Data | BodyInit;
|
|
6
9
|
{{/if}}
|
|
7
10
|
};
|
|
@@ -7,11 +7,15 @@ import type * as ComponentTypes from '../components';
|
|
|
7
7
|
const {{{currentTag.tag}}}DefaultConfig = resolveTagDefaultConfig(defaultConfig, '{{{currentTag.tag}}}DefaultConfig');
|
|
8
8
|
|
|
9
9
|
{{#each currentTag.apis}}
|
|
10
|
-
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
11
|
-
type {{{name}}}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
export type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
11
|
+
{{#if pathParameters}}export type {{{name}}}PathParams = {{addNamespace pathParameters @root.componentNames}};
|
|
12
|
+
{{/if}}{{#if queryParameters}}export type {{{name}}}Params = {{addNamespace queryParameters @root.componentNames}};
|
|
13
|
+
{{/if}}{{#if requestBody}}export type {{{name}}}Data = {{addNamespace requestBody @root.componentNames}};
|
|
14
|
+
{{/if}}
|
|
15
|
+
export type {{{name}}}ExtraConfig = Omit<RequestInit, 'body'> & {
|
|
16
|
+
{{#if pathParameters}}pathParams: {{{name}}}PathParams;
|
|
17
|
+
{{/if}}{{#if queryParameters}}params?: {{{name}}}Params;
|
|
18
|
+
{{/if}}{{#if requestBody}}body?: {{{name}}}Data;
|
|
15
19
|
{{/if}}
|
|
16
20
|
};
|
|
17
21
|
{{> api-jsdoc}}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
type {{{name}}}
|
|
1
|
+
{{#if pathParameters}}export type {{{name}}}PathParams = {{addNamespace pathParameters @root.componentNames}};
|
|
2
|
+
{{/if}}{{#if queryParameters}}export type {{{name}}}Params = {{addNamespace queryParameters @root.componentNames}};
|
|
3
|
+
{{/if}}{{#if requestBody}}export type {{{name}}}Data = {{addNamespace requestBody @root.componentNames}};
|
|
4
|
+
{{/if}}export type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
2
5
|
{{#or pathParameters queryParameters requestBody}}
|
|
3
|
-
type {{{name}}}ExtraConfig = Options & {
|
|
4
|
-
{{#if pathParameters}}pathParams: {{
|
|
5
|
-
{{/if}}{{#if queryParameters}}searchParams: {{
|
|
6
|
-
{{/if}}{{#if requestBody}}json: {{
|
|
6
|
+
export type {{{name}}}ExtraConfig = Options & {
|
|
7
|
+
{{#if pathParameters}}pathParams: {{{name}}}PathParams;
|
|
8
|
+
{{/if}}{{#if queryParameters}}searchParams: {{{name}}}Params;
|
|
9
|
+
{{/if}}{{#if requestBody}}json: {{{name}}}Data;
|
|
7
10
|
{{/if}}
|
|
8
11
|
};
|
|
9
12
|
{{/or}}
|
|
@@ -8,11 +8,15 @@ import type * as ComponentTypes from '../components';
|
|
|
8
8
|
const {{{currentTag.tag}}}DefaultConfig = resolveTagDefaultConfig(defaultConfig, '{{{currentTag.tag}}}DefaultConfig');
|
|
9
9
|
|
|
10
10
|
{{#each currentTag.apis}}
|
|
11
|
-
type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
12
|
-
type {{{name}}}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export type {{{name}}}Response = {{addNamespace response @root.componentNames}};
|
|
12
|
+
{{#if pathParameters}}export type {{{name}}}PathParams = {{addNamespace pathParameters @root.componentNames}};
|
|
13
|
+
{{/if}}{{#if queryParameters}}export type {{{name}}}Params = {{addNamespace queryParameters @root.componentNames}};
|
|
14
|
+
{{/if}}{{#if requestBody}}export type {{{name}}}Data = {{addNamespace requestBody @root.componentNames}};
|
|
15
|
+
{{/if}}
|
|
16
|
+
export type {{{name}}}ExtraConfig = Options & {
|
|
17
|
+
{{#if pathParameters}}pathParams: {{{name}}}PathParams;
|
|
18
|
+
{{/if}}{{#if queryParameters}}searchParams: {{{name}}}Params;
|
|
19
|
+
{{/if}}{{#if requestBody}}json: {{{name}}}Data;
|
|
16
20
|
{{/if}}
|
|
17
21
|
};
|
|
18
22
|
{{> api-jsdoc}}
|
package/dist/utils/format.js
CHANGED
|
@@ -33,13 +33,37 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
36
|
+
exports.defaultFormatOptions = void 0;
|
|
37
|
+
exports.isFormatEnabled = isFormatEnabled;
|
|
37
38
|
exports.format = format;
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const config_1 = require("../config");
|
|
40
|
+
/**
|
|
41
|
+
* 回退用的真实动态 import。
|
|
42
|
+
* `new Function` 内的 `import()` 不会被 TypeScript 降级为 `require()`,用于 CJS 产物中加载纯 ESM 包。
|
|
43
|
+
*/
|
|
44
|
+
// eslint-disable-next-line no-new-func -- CJS 产物必须保留 new Function 包裹的真实动态 import,才能加载纯 ESM 的 oxfmt
|
|
45
|
+
const fallbackImport = new Function('specifier', 'return import(specifier)');
|
|
46
|
+
/** oxfmt 只加载一次,后续复用 */
|
|
47
|
+
let oxfmtPromise;
|
|
48
|
+
/**
|
|
49
|
+
* oxfmt 是 ESM-only(`"type": "module"`,无 require 条件),而 worma 的编译产物是 CommonJS。
|
|
50
|
+
*
|
|
51
|
+
* 优先使用字面量 `import()`:vite/vitest 的 SSR 转换器只会识别源码中直接出现的 `import(...)`
|
|
52
|
+
* 并替换为它的 dynamic import 回调,因此测试环境必须走这条路径。
|
|
53
|
+
* 而在 `module: CommonJS` 编译产物中,TypeScript 会把 `import()` 降级为 `require()`,
|
|
54
|
+
* 对纯 ESM 包会抛 `ERR_REQUIRE_ESM`(或 oxfmt 含顶层 await 时抛 `ERR_REQUIRE_ASYNC_MODULE`),
|
|
55
|
+
* 此时回退到 `new Function` 包裹的真实动态 import。
|
|
56
|
+
*/
|
|
57
|
+
function loadOxfmt() {
|
|
58
|
+
oxfmtPromise ??= Promise.resolve().then(() => __importStar(require('oxfmt'))).catch(() => fallbackImport('oxfmt'));
|
|
59
|
+
return oxfmtPromise;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 与历史 prettier 配置等价的默认格式化参数。
|
|
63
|
+
* prettier 的 `insertPragma` 在 oxfmt 中不存在(原本即为 false,直接去掉);
|
|
64
|
+
* `endOfLine: 'auto'` 不为 oxfmt 支持,语义最接近的是 `lf`。
|
|
65
|
+
*/
|
|
66
|
+
exports.defaultFormatOptions = {
|
|
43
67
|
printWidth: 120,
|
|
44
68
|
tabWidth: 2,
|
|
45
69
|
useTabs: false,
|
|
@@ -47,18 +71,41 @@ exports.prettierConfig = {
|
|
|
47
71
|
singleQuote: true,
|
|
48
72
|
trailingComma: 'none',
|
|
49
73
|
bracketSpacing: true,
|
|
50
|
-
insertPragma: false,
|
|
51
|
-
endOfLine: 'auto',
|
|
52
74
|
bracketSameLine: true,
|
|
53
75
|
arrowParens: 'avoid',
|
|
54
|
-
vueIndentScriptAndStyle: false,
|
|
55
76
|
singleAttributePerLine: true,
|
|
77
|
+
vueIndentScriptAndStyle: false,
|
|
78
|
+
endOfLine: 'lf',
|
|
56
79
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
80
|
+
/** 合并 默认 < 用户全局配置 < 本次调用覆盖,并剥掉 worma 自有的 `enabled` 字段 */
|
|
81
|
+
function resolveOptions(config) {
|
|
82
|
+
const { enabled, ...oxfmtOptions } = {
|
|
83
|
+
...exports.defaultFormatOptions,
|
|
84
|
+
...((0, config_1.getGlobalConfig)().format ?? {}),
|
|
61
85
|
...(config ?? {}),
|
|
62
|
-
|
|
63
|
-
|
|
86
|
+
};
|
|
87
|
+
void enabled;
|
|
88
|
+
return oxfmtOptions;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 是否对生成产物执行格式化。由 `format.enabled` 控制,默认 true。
|
|
92
|
+
*/
|
|
93
|
+
function isFormatEnabled() {
|
|
94
|
+
return (0, config_1.getGlobalConfig)().format?.enabled ?? true;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 格式化一段代码。
|
|
98
|
+
* @param fileName 文件名,oxfmt 依据扩展名推断语言(无 prettier 的 `parser` 选项)
|
|
99
|
+
* @param text 源码文本
|
|
100
|
+
* @param config 单次调用的覆盖配置,优先级最高
|
|
101
|
+
* @returns 格式化后的代码;解析失败时抛错,由调用方回退原文
|
|
102
|
+
*/
|
|
103
|
+
async function format(fileName, text, config) {
|
|
104
|
+
const { format: oxfmtFormat } = await loadOxfmt();
|
|
105
|
+
const result = await oxfmtFormat(fileName, text, resolveOptions(config));
|
|
106
|
+
const fatal = result.errors?.find(error => error.severity === 'Error');
|
|
107
|
+
if (fatal) {
|
|
108
|
+
throw new Error(`oxfmt failed to format ${fileName}: ${fatal.message}`);
|
|
109
|
+
}
|
|
110
|
+
return result.code;
|
|
64
111
|
}
|
package/dist/utils/template.js
CHANGED
|
@@ -111,6 +111,6 @@ async function generateFile(distDir, fileName, content) {
|
|
|
111
111
|
await promises_1.default.mkdir(distDir, { recursive: true });
|
|
112
112
|
}
|
|
113
113
|
const filePath = node_path_1.default.join(distDir, fileName);
|
|
114
|
-
const formattedText = await (0, format_1.format)(content);
|
|
114
|
+
const formattedText = await (0, format_1.format)(fileName, content);
|
|
115
115
|
await promises_1.default.writeFile(filePath, formattedText);
|
|
116
116
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wormajs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
4
|
"description": "A modern OpenAPI code generator - Generate type-safe API clients from OpenAPI specs",
|
|
5
5
|
"author": "worma",
|
|
6
6
|
"license": "MIT",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"alova": "^3.3.4",
|
|
52
52
|
"chalk": "4.1.2",
|
|
53
|
+
"cli-table3": "^0.6.5",
|
|
53
54
|
"cli-truncate": "^4.0.0",
|
|
54
55
|
"commander": "^14.0.0",
|
|
55
56
|
"esbuild": "^0.25.6",
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
"log-update": "^6.1.0",
|
|
61
62
|
"openapi-types": "^12.1.3",
|
|
62
63
|
"ora": "5.4.1",
|
|
63
|
-
"
|
|
64
|
+
"oxfmt": "^0.67.0",
|
|
64
65
|
"skills": "^1.5.13",
|
|
65
66
|
"string-width": "^7.2.0",
|
|
66
67
|
"swagger2openapi": "^7.0.8",
|