@wx-sab/renkei 1.2.5 → 1.3.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.
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const utils_1 = require("./utils");
5
+ (0, vitest_1.describe)('utils', () => {
6
+ (0, vitest_1.describe)('generateConfig', () => {
7
+ (0, vitest_1.it)('should generate config with default values', () => {
8
+ const conf = {
9
+ serviceName: 'test-service'
10
+ };
11
+ const result = (0, utils_1.generateConfig)(conf);
12
+ (0, vitest_1.expect)(result.sourceType).toBe('apifox');
13
+ (0, vitest_1.expect)(result.output).toContain('src/services');
14
+ (0, vitest_1.expect)(result.name).toBe('model.d.ts');
15
+ (0, vitest_1.expect)(result.modular).toBe(false);
16
+ (0, vitest_1.expect)(result.modelNamespace).toBe('Model');
17
+ (0, vitest_1.expect)(result.requestTempalte).toBe(`import { request } from '@wx-sab/renkei'`);
18
+ });
19
+ (0, vitest_1.it)('should merge user config with default config', () => {
20
+ const conf = {
21
+ serviceName: 'test-service',
22
+ sourceType: 'swagger',
23
+ output: '/custom/output',
24
+ name: 'custom.d.ts',
25
+ modelNamespace: 'CustomModel'
26
+ };
27
+ const result = (0, utils_1.generateConfig)(conf);
28
+ (0, vitest_1.expect)(result.sourceType).toBe('swagger');
29
+ (0, vitest_1.expect)(result.output).toBe('/custom/output');
30
+ (0, vitest_1.expect)(result.name).toBe('custom.d.ts');
31
+ (0, vitest_1.expect)(result.modelNamespace).toBe('CustomModel');
32
+ });
33
+ (0, vitest_1.it)('should generate apifox source when sourceType is apifox', () => {
34
+ const conf = {
35
+ serviceName: 'test-service',
36
+ sourceType: 'apifox',
37
+ apifoxProjectId: '12345'
38
+ };
39
+ const result = (0, utils_1.generateConfig)(conf);
40
+ (0, vitest_1.expect)(result.source).toContain('projectId=12345');
41
+ (0, vitest_1.expect)(result.source).toContain('127.0.0.1:4523');
42
+ });
43
+ (0, vitest_1.it)('should generate swagger source when sourceType is swagger', () => {
44
+ const conf = {
45
+ serviceName: 'my-service',
46
+ sourceType: 'swagger'
47
+ };
48
+ const result = (0, utils_1.generateConfig)(conf);
49
+ (0, vitest_1.expect)(result.source).toContain('my-service');
50
+ (0, vitest_1.expect)(result.source).toContain('api-docs');
51
+ });
52
+ (0, vitest_1.it)('should use custom source if provided', () => {
53
+ const conf = {
54
+ serviceName: 'test-service',
55
+ source: 'https://custom.api.com/swagger'
56
+ };
57
+ const result = (0, utils_1.generateConfig)(conf);
58
+ (0, vitest_1.expect)(result.source).toBe('https://custom.api.com/swagger');
59
+ });
60
+ (0, vitest_1.it)('should apply customResponseType function', () => {
61
+ const conf = {
62
+ serviceName: 'test-service',
63
+ customResponseType: (type) => `CustomResponse<${type}>`
64
+ };
65
+ const result = (0, utils_1.generateConfig)(conf);
66
+ (0, vitest_1.expect)(result.customResponseType).toBeDefined();
67
+ (0, vitest_1.expect)(result.customResponseType('User')).toBe('CustomResponse<User>');
68
+ });
69
+ (0, vitest_1.it)('should apply customMockService function', () => {
70
+ const conf = {
71
+ serviceName: 'test-service',
72
+ apifoxProjectId: '12345',
73
+ customMockService: (config) => `https://mock.example.com/${config.apifoxProjectId}`
74
+ };
75
+ const result = (0, utils_1.generateConfig)(conf);
76
+ (0, vitest_1.expect)(result.customMockService).toBeDefined();
77
+ (0, vitest_1.expect)(result.customMockService(result)).toBe('https://mock.example.com/12345');
78
+ });
79
+ (0, vitest_1.it)('should use default customResponseType when not provided', () => {
80
+ const conf = {
81
+ serviceName: 'test-service'
82
+ };
83
+ const result = (0, utils_1.generateConfig)(conf);
84
+ (0, vitest_1.expect)(result.customResponseType).toBeDefined();
85
+ (0, vitest_1.expect)(result.customResponseType('User')).toBe('AxiosResponse<User>');
86
+ });
87
+ (0, vitest_1.it)('should use default customMockService when apifoxProjectId is provided', () => {
88
+ const conf = {
89
+ serviceName: 'test-service',
90
+ apifoxProjectId: '12345'
91
+ };
92
+ const result = (0, utils_1.generateConfig)(conf);
93
+ (0, vitest_1.expect)(result.customMockService).toBeDefined();
94
+ (0, vitest_1.expect)(result.customMockService(result)).toContain('mock.apifox.cn');
95
+ (0, vitest_1.expect)(result.customMockService(result)).toContain('12345');
96
+ });
97
+ (0, vitest_1.it)('should return empty string for default customMockService without apifoxProjectId', () => {
98
+ const conf = {
99
+ serviceName: 'test-service'
100
+ };
101
+ const result = (0, utils_1.generateConfig)(conf);
102
+ (0, vitest_1.expect)(result.customMockService).toBeDefined();
103
+ (0, vitest_1.expect)(result.customMockService(result)).toBe('');
104
+ });
105
+ });
106
+ (0, vitest_1.describe)('generateRouteName', () => {
107
+ (0, vitest_1.it)('should generate route name from method and route', () => {
108
+ const result = (0, utils_1.generateRouteName)('GET', '/api/users');
109
+ (0, vitest_1.expect)(result).toBe('get_api_users');
110
+ });
111
+ (0, vitest_1.it)('should handle route with path parameters', () => {
112
+ const result = (0, utils_1.generateRouteName)('POST', '/api/users/{id}');
113
+ (0, vitest_1.expect)(result).toBe('post_api_users_$p');
114
+ });
115
+ (0, vitest_1.it)('should convert to lowercase', () => {
116
+ const result = (0, utils_1.generateRouteName)('GET', '/API/Users');
117
+ (0, vitest_1.expect)(result).toBe('get_api_users');
118
+ });
119
+ (0, vitest_1.it)('should replace hyphens with underscores', () => {
120
+ const result = (0, utils_1.generateRouteName)('GET', '/api/user-profiles');
121
+ (0, vitest_1.expect)(result).toBe('get_api_user_profiles');
122
+ });
123
+ (0, vitest_1.it)('should replace dots with underscores', () => {
124
+ const result = (0, utils_1.generateRouteName)('GET', '/api/user.profiles');
125
+ (0, vitest_1.expect)(result).toBe('get_api_user_profiles');
126
+ });
127
+ (0, vitest_1.it)('should replace asterisks with underscores', () => {
128
+ const result = (0, utils_1.generateRouteName)('GET', '/api/user*profiles');
129
+ (0, vitest_1.expect)(result).toBe('get_api_user_profiles');
130
+ });
131
+ (0, vitest_1.it)('should handle complex route patterns', () => {
132
+ const result = (0, utils_1.generateRouteName)('DELETE', '/api/users/{userId}/posts/{postId}');
133
+ (0, vitest_1.expect)(result).toBe('delete_api_users_$p_posts_$p');
134
+ });
135
+ (0, vitest_1.it)('should handle empty route segments', () => {
136
+ const result = (0, utils_1.generateRouteName)('GET', '/api//users');
137
+ (0, vitest_1.expect)(result).toBe('get_api_users');
138
+ });
139
+ });
140
+ (0, vitest_1.describe)('getValidName', () => {
141
+ (0, vitest_1.it)('should return null for empty string', () => {
142
+ const result = (0, utils_1.getValidName)('');
143
+ (0, vitest_1.expect)(result).toBeNull();
144
+ });
145
+ (0, vitest_1.it)('should return null for null/undefined', () => {
146
+ // 测试边界情况:null 和 undefined 输入
147
+ (0, vitest_1.expect)((0, utils_1.getValidName)(null)).toBeNull();
148
+ (0, vitest_1.expect)((0, utils_1.getValidName)(undefined)).toBeNull();
149
+ });
150
+ (0, vitest_1.it)('should return the same string if no special characters', () => {
151
+ const result = (0, utils_1.getValidName)('UserVO');
152
+ (0, vitest_1.expect)(result).toBe('UserVO');
153
+ });
154
+ (0, vitest_1.it)('should handle nested generic types', () => {
155
+ const result = (0, utils_1.getValidName)('ResponseVO«AgentTraceVO»');
156
+ (0, vitest_1.expect)(result).toBe('ResponseVOAgentTraceVO');
157
+ });
158
+ (0, vitest_1.it)('should handle path with slashes', () => {
159
+ const result = (0, utils_1.getValidName)('path/to/Component');
160
+ (0, vitest_1.expect)(result).toBe('Component');
161
+ });
162
+ (0, vitest_1.it)('should remove all non-word characters', () => {
163
+ const result = (0, utils_1.getValidName)('User@VO#Test');
164
+ (0, vitest_1.expect)(result).toBe('UserVOTest');
165
+ });
166
+ (0, vitest_1.it)('should handle complex nested types', () => {
167
+ const result = (0, utils_1.getValidName)('List«Map«String,Object»»');
168
+ (0, vitest_1.expect)(result).toBe('ListMapStringObject');
169
+ });
170
+ });
171
+ (0, vitest_1.describe)('defineConfig', () => {
172
+ (0, vitest_1.it)('should return single config', () => {
173
+ const config = {
174
+ serviceName: 'test-service',
175
+ sourceType: 'apifox',
176
+ apifoxProjectId: '12345'
177
+ };
178
+ const result = (0, utils_1.defineConfig)(config);
179
+ (0, vitest_1.expect)(result).toEqual(config);
180
+ });
181
+ (0, vitest_1.it)('should return array of configs', () => {
182
+ const configs = [
183
+ { serviceName: 'service1', sourceType: 'apifox', apifoxProjectId: '123' },
184
+ { serviceName: 'service2', sourceType: 'swagger' }
185
+ ];
186
+ const result = (0, utils_1.defineConfig)(configs);
187
+ (0, vitest_1.expect)(result).toEqual(configs);
188
+ (0, vitest_1.expect)(Array.isArray(result)).toBe(true);
189
+ (0, vitest_1.expect)(result).toHaveLength(2);
190
+ });
191
+ });
192
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wx-sab/renkei",
3
- "version": "1.2.5",
3
+ "version": "1.3.1",
4
4
  "description": "解析swagger转为ts代码,日本动漫《游戏王》中的‘Renkei’,意为连携或协作。",
5
5
  "main": "./lib/index.js",
6
6
  "bin": {
@@ -11,7 +11,10 @@
11
11
  "clean": "rm -rf lib",
12
12
  "build": "npm run clean & tsc --outDir lib",
13
13
  "version:alpha": "npm version premajor --preid alpha",
14
- "api": "ts-node --transpile-only ./src/cli.ts api"
14
+ "api": "ts-node --transpile-only ./src/cli.ts api",
15
+ "test": "vitest",
16
+ "test:ui": "vitest --ui",
17
+ "test:coverage": "vitest --coverage"
15
18
  },
16
19
  "repository": {
17
20
  "type": "git",
@@ -21,9 +24,13 @@
21
24
  "license": "ISC",
22
25
  "devDependencies": {
23
26
  "@types/cli-progress": "^3.11.5",
27
+ "@types/inquirer": "9.0.7",
24
28
  "@types/lodash": "^4.14.196",
25
29
  "@types/node": "^20.4.7",
26
- "typescript": "^5.1.6"
30
+ "@vitest/coverage-v8": "^4.1.4",
31
+ "@vitest/ui": "^4.1.4",
32
+ "typescript": "^5.1.6",
33
+ "vitest": "^4.1.4"
27
34
  },
28
35
  "files": [
29
36
  "lib",
@@ -33,6 +40,7 @@
33
40
  "axios": "^1.4.0",
34
41
  "cli-progress": "^3.12.0",
35
42
  "commander": "^11.0.0",
43
+ "inquirer": "8.2.6",
36
44
  "lodash": "^4.17.21",
37
45
  "swagger-typescript-api": "13.0.3",
38
46
  "ts-node": "^10.9.1"
package/templates/api.ejs CHANGED
@@ -1,5 +1,5 @@
1
1
  <%
2
- const { apiConfig, routes, utils, config, requestTemplate, modelNamespace, serviceName, namespace, requestTempalte, modelTypes } = it;
2
+ const { apiConfig, routes, utils, config, requestTemplate, modelNamespace, serviceName, namespace, requestTempalte, modelTypes, SKIP_ROUTE_MARKER } = it;
3
3
  const { info, servers, externalDocs } = apiConfig;
4
4
  const { _, require, formatDescription } = utils;
5
5
 
@@ -92,9 +92,9 @@ export class <%~ serviceName %> {
92
92
 
93
93
  <% routes.combined && routes.combined.forEach(({ routes = [], moduleName }) => { %>
94
94
  <% routes.forEach((route) => { %>
95
-
95
+ <% if (route.routeName.usage !== SKIP_ROUTE_MARKER) { %>
96
96
  <%~ includeFile('./procedure-call.ejs', { ...it, route }) %>
97
-
97
+ <% } %>
98
98
  <% }) %>
99
99
  <% }) %>
100
100
  }