anl 25.1202.0 → 25.1203.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/README.ar.md +27 -21
- package/README.es.md +27 -21
- package/README.fr.md +27 -21
- package/README.jp.md +27 -21
- package/README.md +12 -6
- package/README.ru.md +27 -21
- package/README.zh.md +27 -21
- package/lib/package.json.js +1 -1
- package/lib/src/build-type/core/components.js +1 -1
- package/lib/src/build-type/core/path.js +1 -1
- package/lib/src/build-type/index.js +1 -1
- package/package.json +1 -1
package/README.ar.md
CHANGED
|
@@ -123,29 +123,35 @@ $ anl type
|
|
|
123
123
|
}
|
|
124
124
|
],
|
|
125
125
|
"publicPrefix": "api",
|
|
126
|
-
"
|
|
127
|
-
"
|
|
126
|
+
"parameterSeparator": "_",
|
|
127
|
+
"enmuConfig": {
|
|
128
|
+
"erasableSyntaxOnly": false,
|
|
129
|
+
"varnames": "enum-varnames",
|
|
130
|
+
"comment": "enum-descriptions"
|
|
131
|
+
}
|
|
128
132
|
}
|
|
129
133
|
```
|
|
130
134
|
|
|
131
135
|
#### شرح عناصر التكوين
|
|
132
136
|
|
|
133
|
-
| عنصر التكوين
|
|
134
|
-
|
|
|
135
|
-
| saveTypeFolderPath
|
|
136
|
-
| saveApiListFolderPath
|
|
137
|
-
| saveEnumFolderPath
|
|
138
|
-
| importEnumPath
|
|
139
|
-
| swaggerJsonUrl
|
|
140
|
-
| requestMethodsImportPath
|
|
141
|
-
| dataLevel
|
|
142
|
-
| formatting
|
|
143
|
-
| headers
|
|
144
|
-
| includeInterface
|
|
145
|
-
| excludeInterface
|
|
146
|
-
| publicPrefix
|
|
147
|
-
| erasableSyntaxOnly
|
|
148
|
-
| parameterSeparator
|
|
137
|
+
| عنصر التكوين | النوع | مطلوب | الوصف |
|
|
138
|
+
| ------------------------------- | ------------------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
139
|
+
| saveTypeFolderPath | string | نعم | مسار حفظ ملفات تعريف الأنواع |
|
|
140
|
+
| saveApiListFolderPath | string | نعم | مسار حفظ ملفات دوال طلبات API |
|
|
141
|
+
| saveEnumFolderPath | string | نعم | مسار حفظ ملفات بيانات التعداد |
|
|
142
|
+
| importEnumPath | string | نعم | مسار استيراد التعداد (مسار ملف enum المُشار إليه في apps/types/models/\*.ts) |
|
|
143
|
+
| swaggerJsonUrl | string | نعم | عنوان مستند Swagger JSON |
|
|
144
|
+
| requestMethodsImportPath | string | نعم | مسار استيراد طرق الطلب |
|
|
145
|
+
| dataLevel | 'data' \| 'serve' \| 'axios' | نعم | مستوى بيانات استجابة الواجهة |
|
|
146
|
+
| formatting | object | لا | تكوين تنسيق الكود |
|
|
147
|
+
| headers | object | لا | تكوين رأس الطلب |
|
|
148
|
+
| includeInterface | Array<{path: string, method: string}> | لا | الواجهات المضمنة: ملف قائمة الواجهات المحدد بـ `saveApiListFolderPath` سيتضمن فقط الواجهات في القائمة، متعارض مع حقل `excludeInterface` |
|
|
149
|
+
| excludeInterface | Array<{path: string, method: string}> | لا | الواجهات المستبعدة: نص قائمة الواجهات المحدد بـ `saveApiListFolderPath` لن يتضمن الواجهات في هذه القائمة، متعارض مع `includeInterface` |
|
|
150
|
+
| publicPrefix | string | لا | البادئة العامة على مسار url، على سبيل المثال: api/users، api/users/{id}، api هي البادئة العامة |
|
|
151
|
+
| enmuConfig.erasableSyntaxOnly | boolean | نعم | يتوافق مع خيار `compilerOptions.erasableSyntaxOnly` في tsconfig.json. عندما يكون `true`، يتم إنشاء كائن const بدلاً من enum (صيغة النوع فقط). القيمة الافتراضية: `false` |
|
|
152
|
+
| parameterSeparator | string | لا | الفاصل المستخدم بين أجزاء المسار والمعاملات عند إنشاء أسماء API وأسماء الأنواع. على سبيل المثال، `/users/{userId}/posts` مع الفاصل `'_'` ينشئ `users_userId_posts_GET`. القيمة الافتراضية: `'_'` |
|
|
153
|
+
| enmuConfig.varnames | string | لا | اسم الحقل في مخطط Swagger الذي يحتوي على أسماء عناصر التعداد المخصصة. القيمة الافتراضية: `enum-varnames`. |
|
|
154
|
+
| enmuConfig.comment | string | لا | اسم الحقل في مخطط Swagger الذي يحتوي على أوصاف عناصر التعداد (يُستخدم لإنشاء التعليقات). القيمة الافتراضية: `enum-descriptions`. |
|
|
149
155
|
|
|
150
156
|
#### العلاقة بين عناصر التكوين والملفات المولدة
|
|
151
157
|
|
|
@@ -207,9 +213,9 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
207
213
|
|
|
208
214
|
#### توليد التعداد
|
|
209
215
|
|
|
210
|
-
تدعم الأداة وضعين لتوليد التعداد، يتم التحكم فيهما من خلال تكوين `erasableSyntaxOnly`:
|
|
216
|
+
تدعم الأداة وضعين لتوليد التعداد، يتم التحكم فيهما من خلال تكوين `enmuConfig.erasableSyntaxOnly`:
|
|
211
217
|
|
|
212
|
-
**وضع التعداد التقليدي** (`erasableSyntaxOnly: false`، القيمة الافتراضية):
|
|
218
|
+
**وضع التعداد التقليدي** (`enmuConfig.erasableSyntaxOnly: false`، القيمة الافتراضية):
|
|
213
219
|
|
|
214
220
|
```typescript
|
|
215
221
|
export enum Status {
|
|
@@ -219,7 +225,7 @@ export enum Status {
|
|
|
219
225
|
}
|
|
220
226
|
```
|
|
221
227
|
|
|
222
|
-
**وضع الكائن الثابت** (`erasableSyntaxOnly: true`):
|
|
228
|
+
**وضع الكائن الثابت** (`enmuConfig.erasableSyntaxOnly: true`):
|
|
223
229
|
|
|
224
230
|
```typescript
|
|
225
231
|
export const Status = {
|
package/README.es.md
CHANGED
|
@@ -121,29 +121,35 @@ $ anl type
|
|
|
121
121
|
}
|
|
122
122
|
],
|
|
123
123
|
"publicPrefix": "api",
|
|
124
|
-
"
|
|
125
|
-
"
|
|
124
|
+
"parameterSeparator": "_",
|
|
125
|
+
"enmuConfig": {
|
|
126
|
+
"erasableSyntaxOnly": false,
|
|
127
|
+
"varnames": "enum-varnames",
|
|
128
|
+
"comment": "enum-descriptions"
|
|
129
|
+
}
|
|
126
130
|
}
|
|
127
131
|
```
|
|
128
132
|
|
|
129
133
|
#### Descripción de Elementos de Configuración
|
|
130
134
|
|
|
131
|
-
| Elemento de Configuración
|
|
132
|
-
|
|
|
133
|
-
| saveTypeFolderPath
|
|
134
|
-
| saveApiListFolderPath
|
|
135
|
-
| saveEnumFolderPath
|
|
136
|
-
| importEnumPath
|
|
137
|
-
| swaggerJsonUrl
|
|
138
|
-
| requestMethodsImportPath
|
|
139
|
-
| dataLevel
|
|
140
|
-
| formatting
|
|
141
|
-
| headers
|
|
142
|
-
| includeInterface
|
|
143
|
-
| excludeInterface
|
|
144
|
-
| publicPrefix
|
|
145
|
-
| erasableSyntaxOnly
|
|
146
|
-
| parameterSeparator
|
|
135
|
+
| Elemento de Configuración | Tipo | Requerido | Descripción |
|
|
136
|
+
| ------------------------------ | ------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
137
|
+
| saveTypeFolderPath | string | Sí | Ruta de guardado de archivos de definición de tipos |
|
|
138
|
+
| saveApiListFolderPath | string | Sí | Ruta de guardado de archivos de funciones de solicitud API |
|
|
139
|
+
| saveEnumFolderPath | string | Sí | Ruta de guardado de archivos de datos enum |
|
|
140
|
+
| importEnumPath | string | Sí | Ruta de importación de enum (ruta de referencia de archivos enum en apps/types/models/\*.ts) |
|
|
141
|
+
| swaggerJsonUrl | string | Sí | Dirección del documento Swagger JSON |
|
|
142
|
+
| requestMethodsImportPath | string | Sí | Ruta de importación de métodos de solicitud |
|
|
143
|
+
| dataLevel | 'data' \| 'serve' \| 'axios' | Sí | Nivel de datos de retorno de interfaz |
|
|
144
|
+
| formatting | object | No | Configuración de formateo de código |
|
|
145
|
+
| headers | object | No | Configuración de encabezados de solicitud |
|
|
146
|
+
| includeInterface | Array<{path: string, method: string}> | No | Interfaces incluidas: el archivo de lista de interfaces especificado por `saveApiListFolderPath` solo incluirá las interfaces en la lista, es mutuamente excluyente con el campo `excludeInterface` |
|
|
147
|
+
| excludeInterface | Array<{path: string, method: string}> | No | Interfaces excluidas: el texto de lista de interfaces especificado por `saveApiListFolderPath` no incluirá las interfaces en esta lista, es mutuamente excluyente con `includeInterface` |
|
|
148
|
+
| publicPrefix | string | No | Prefijo público en la ruta URL, por ejemplo: api/users, api/users/{id}, api es el prefijo público |
|
|
149
|
+
| enmuConfig.erasableSyntaxOnly | boolean | Sí | Alineado con la opción `compilerOptions.erasableSyntaxOnly` de tsconfig.json. Cuando es `true`, genera objetos const en lugar de enum (solo sintaxis de tipo). Valor predeterminado: `false` |
|
|
150
|
+
| parameterSeparator | string | No | Separador utilizado entre segmentos de ruta y parámetros al generar nombres de API y nombres de tipo. Por ejemplo, `/users/{userId}/posts` con el separador `'_'` genera `users_userId_posts_GET`. Valor predeterminado: `'_'` |
|
|
151
|
+
| enmuConfig.varnames | string | No | Nombre del campo en el esquema Swagger que contiene los nombres personalizados de los miembros del enum. Valor predeterminado: `enum-varnames`. |
|
|
152
|
+
| enmuConfig.comment | string | No | Nombre del campo en el esquema Swagger que contiene las descripciones de los miembros del enum (se usa para generar comentarios). Valor predeterminado: `enum-descriptions`. |
|
|
147
153
|
|
|
148
154
|
#### Relación entre Elementos de Configuración y Archivos Generados
|
|
149
155
|
|
|
@@ -205,9 +211,9 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
205
211
|
|
|
206
212
|
#### Generación de Enumeraciones
|
|
207
213
|
|
|
208
|
-
La herramienta admite dos modos de generación de enumeraciones, controlados mediante la configuración `erasableSyntaxOnly`:
|
|
214
|
+
La herramienta admite dos modos de generación de enumeraciones, controlados mediante la configuración `enmuConfig.erasableSyntaxOnly`:
|
|
209
215
|
|
|
210
|
-
**Modo de enumeración tradicional** (`erasableSyntaxOnly: false`, valor predeterminado):
|
|
216
|
+
**Modo de enumeración tradicional** (`enmuConfig.erasableSyntaxOnly: false`, valor predeterminado):
|
|
211
217
|
|
|
212
218
|
```typescript
|
|
213
219
|
export enum Status {
|
|
@@ -217,7 +223,7 @@ export enum Status {
|
|
|
217
223
|
}
|
|
218
224
|
```
|
|
219
225
|
|
|
220
|
-
**Modo de objeto constante** (`erasableSyntaxOnly: true`):
|
|
226
|
+
**Modo de objeto constante** (`enmuConfig.erasableSyntaxOnly: true`):
|
|
221
227
|
|
|
222
228
|
```typescript
|
|
223
229
|
export const Status = {
|
package/README.fr.md
CHANGED
|
@@ -123,29 +123,35 @@ $ anl type
|
|
|
123
123
|
}
|
|
124
124
|
],
|
|
125
125
|
"publicPrefix": "api",
|
|
126
|
-
"
|
|
127
|
-
"
|
|
126
|
+
"parameterSeparator": "_",
|
|
127
|
+
"enmuConfig": {
|
|
128
|
+
"erasableSyntaxOnly": false,
|
|
129
|
+
"varnames": "enum-varnames",
|
|
130
|
+
"comment": "enum-descriptions"
|
|
131
|
+
}
|
|
128
132
|
}
|
|
129
133
|
```
|
|
130
134
|
|
|
131
135
|
#### Explication des éléments de configuration
|
|
132
136
|
|
|
133
|
-
| Élément de configuration
|
|
134
|
-
|
|
|
135
|
-
| saveTypeFolderPath
|
|
136
|
-
| saveApiListFolderPath
|
|
137
|
-
| saveEnumFolderPath
|
|
138
|
-
| importEnumPath
|
|
139
|
-
| swaggerJsonUrl
|
|
140
|
-
| requestMethodsImportPath
|
|
141
|
-
| dataLevel
|
|
142
|
-
| formatting
|
|
143
|
-
| headers
|
|
144
|
-
| includeInterface
|
|
145
|
-
| excludeInterface
|
|
146
|
-
| publicPrefix
|
|
147
|
-
| erasableSyntaxOnly
|
|
148
|
-
| parameterSeparator
|
|
137
|
+
| Élément de configuration | Type | Obligatoire | Description |
|
|
138
|
+
| ------------------------------ | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
139
|
+
| saveTypeFolderPath | string | Oui | Chemin de sauvegarde des fichiers de définition de types |
|
|
140
|
+
| saveApiListFolderPath | string | Oui | Chemin de sauvegarde des fichiers de fonctions de requête API |
|
|
141
|
+
| saveEnumFolderPath | string | Oui | Chemin de sauvegarde des fichiers de données enum |
|
|
142
|
+
| importEnumPath | string | Oui | Chemin d'import enum (chemin des fichiers enum référencés dans apps/types/models/\*.ts) |
|
|
143
|
+
| swaggerJsonUrl | string | Oui | Adresse du document Swagger JSON |
|
|
144
|
+
| requestMethodsImportPath | string | Oui | Chemin d'import des méthodes de requête |
|
|
145
|
+
| dataLevel | 'data' \| 'serve' \| 'axios' | Oui | Niveau de données retournées par l'interface |
|
|
146
|
+
| formatting | object | Non | Configuration du formatage du code |
|
|
147
|
+
| headers | object | Non | Configuration des en-têtes de requête |
|
|
148
|
+
| includeInterface | Array<{path: string, method: string}> | Non | Interfaces à inclure : Le fichier de liste d'interfaces spécifié par `saveApiListFolderPath` ne contiendra que les interfaces de la liste, mutuellement exclusif avec `excludeInterface` |
|
|
149
|
+
| excludeInterface | Array<{path: string, method: string}> | Non | Interfaces à exclure : Le fichier de liste d'interfaces spécifié par `saveApiListFolderPath` ne contiendra pas les interfaces de cette liste, mutuellement exclusif avec `includeInterface` |
|
|
150
|
+
| publicPrefix | string | Non | Préfixe commun sur le chemin URL, par exemple : api/users, api/users/{id}, api est le préfixe commun |
|
|
151
|
+
| enmuConfig.erasableSyntaxOnly | boolean | Oui | Doit être cohérent avec l'option `compilerOptions.erasableSyntaxOnly` de tsconfig.json. Si `true`, génère un objet const au lieu d'un enum (syntaxe de type uniquement). Valeur par défaut : `false` |
|
|
152
|
+
| parameterSeparator | string | Non | Séparateur utilisé entre les segments de chemin et les paramètres lors de la génération des noms d'API et des noms de type. Par exemple, `/users/{userId}/posts` avec le séparateur `'_'` génère `users_userId_posts_GET`. Valeur par défaut : `'_'` |
|
|
153
|
+
| enmuConfig.varnames | string | Non | Nom du champ dans le schéma Swagger contenant les noms personnalisés des membres d'enum. Valeur par défaut : `enum-varnames`. |
|
|
154
|
+
| enmuConfig.comment | string | Non | Nom du champ dans le schéma Swagger contenant les descriptions des membres d'enum (utilisé pour générer des commentaires). Valeur par défaut : `enum-descriptions`. |
|
|
149
155
|
|
|
150
156
|
#### Relation entre les éléments de configuration et les fichiers générés
|
|
151
157
|
|
|
@@ -207,9 +213,9 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
207
213
|
|
|
208
214
|
#### Génération d'enum
|
|
209
215
|
|
|
210
|
-
L'outil prend en charge deux modes de génération d'enum, contrôlés par la configuration `erasableSyntaxOnly` :
|
|
216
|
+
L'outil prend en charge deux modes de génération d'enum, contrôlés par la configuration `enmuConfig.erasableSyntaxOnly` :
|
|
211
217
|
|
|
212
|
-
**Mode enum traditionnel** (`erasableSyntaxOnly: false`, valeur par défaut) :
|
|
218
|
+
**Mode enum traditionnel** (`enmuConfig.erasableSyntaxOnly: false`, valeur par défaut) :
|
|
213
219
|
|
|
214
220
|
```typescript
|
|
215
221
|
export enum Status {
|
|
@@ -219,7 +225,7 @@ export enum Status {
|
|
|
219
225
|
}
|
|
220
226
|
```
|
|
221
227
|
|
|
222
|
-
**Mode objet constant** (`erasableSyntaxOnly: true`) :
|
|
228
|
+
**Mode objet constant** (`enmuConfig.erasableSyntaxOnly: true`) :
|
|
223
229
|
|
|
224
230
|
```typescript
|
|
225
231
|
export const Status = {
|
package/README.jp.md
CHANGED
|
@@ -123,29 +123,35 @@ $ anl type
|
|
|
123
123
|
}
|
|
124
124
|
],
|
|
125
125
|
"publicPrefix": "api",
|
|
126
|
-
"
|
|
127
|
-
"
|
|
126
|
+
"parameterSeparator": "_",
|
|
127
|
+
"enmuConfig": {
|
|
128
|
+
"erasableSyntaxOnly": false,
|
|
129
|
+
"varnames": "enum-varnames",
|
|
130
|
+
"comment": "enum-descriptions"
|
|
131
|
+
}
|
|
128
132
|
}
|
|
129
133
|
```
|
|
130
134
|
|
|
131
135
|
#### 設定項目の説明
|
|
132
136
|
|
|
133
|
-
| 設定項目
|
|
134
|
-
|
|
|
135
|
-
| saveTypeFolderPath
|
|
136
|
-
| saveApiListFolderPath
|
|
137
|
-
| saveEnumFolderPath
|
|
138
|
-
| importEnumPath
|
|
139
|
-
| swaggerJsonUrl
|
|
140
|
-
| requestMethodsImportPath
|
|
141
|
-
| dataLevel
|
|
142
|
-
| formatting
|
|
143
|
-
| headers
|
|
144
|
-
| includeInterface
|
|
145
|
-
| excludeInterface
|
|
146
|
-
| publicPrefix
|
|
147
|
-
| erasableSyntaxOnly
|
|
148
|
-
| parameterSeparator
|
|
137
|
+
| 設定項目 | 型 | 必須 | 説明 |
|
|
138
|
+
| ------------------------------- | ------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
139
|
+
| saveTypeFolderPath | string | はい | 型定義ファイルの保存パス |
|
|
140
|
+
| saveApiListFolderPath | string | はい | API リクエスト関数ファイルの保存パス |
|
|
141
|
+
| saveEnumFolderPath | string | はい | 列挙データファイルの保存パス |
|
|
142
|
+
| importEnumPath | string | はい | 列挙型インポートパス(apps/types/models/\*.ts で enum ファイルを参照するパス) |
|
|
143
|
+
| swaggerJsonUrl | string | はい | Swagger JSON ドキュメントのアドレス |
|
|
144
|
+
| requestMethodsImportPath | string | はい | リクエストメソッドのインポートパス |
|
|
145
|
+
| dataLevel | 'data' \| 'serve' \| 'axios' | はい | インターフェースレスポンスデータのレベル |
|
|
146
|
+
| formatting | object | いいえ | コードフォーマット設定 |
|
|
147
|
+
| headers | object | いいえ | リクエストヘッダー設定 |
|
|
148
|
+
| includeInterface | Array<{path: string, method: string}> | いいえ | 含めるインターフェース:`saveApiListFolderPath` で指定されたインターフェースリストファイルには、このリストに含まれるインターフェースのみが含まれます。`excludeInterface` フィールドと相互排他的です |
|
|
149
|
+
| excludeInterface | Array<{path: string, method: string}> | いいえ | 除外するインターフェース:`saveApiListFolderPath` で指定されたインターフェースリストテキストには、このリストに含まれないインターフェースが含まれます。`includeInterface` と相互排他的です |
|
|
150
|
+
| publicPrefix | string | いいえ | URL パス上の共通プレフィックス、例:api/users、api/users/{id}、api が共通プレフィックスです |
|
|
151
|
+
| enmuConfig.erasableSyntaxOnly | boolean | はい | tsconfig.json の `compilerOptions.erasableSyntaxOnly` オプションと一致させます。`true` の場合、enum ではなく const オブジェクトを生成します(型のみの構文)。デフォルト値:`false` |
|
|
152
|
+
| parameterSeparator | string | いいえ | API 名と型名を生成する際に、パスセグメントとパラメータの間に使用される区切り文字。例えば、`/users/{userId}/posts` に区切り文字 `'_'` を使用すると `users_userId_posts_GET` が生成されます。デフォルト値:`'_'` |
|
|
153
|
+
| enmuConfig.varnames | string | いいえ | Swagger schema 内でカスタム列挙メンバー名が格納されているフィールド名。デフォルト値:`enum-varnames`。 |
|
|
154
|
+
| enmuConfig.comment | string | いいえ | Swagger schema 内で列挙メンバーの説明が格納されているフィールド名(コメント生成に使用)。デフォルト値:`enum-descriptions`。 |
|
|
149
155
|
|
|
150
156
|
#### 設定項目と生成ファイルの対応関係
|
|
151
157
|
|
|
@@ -207,9 +213,9 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
207
213
|
|
|
208
214
|
#### 列挙型生成
|
|
209
215
|
|
|
210
|
-
ツールは 2 つの列挙型生成モードをサポートしており、`erasableSyntaxOnly` 設定で制御します:
|
|
216
|
+
ツールは 2 つの列挙型生成モードをサポートしており、`enmuConfig.erasableSyntaxOnly` 設定で制御します:
|
|
211
217
|
|
|
212
|
-
**従来の列挙型モード** (`erasableSyntaxOnly: false`、デフォルト値):
|
|
218
|
+
**従来の列挙型モード** (`enmuConfig.erasableSyntaxOnly: false`、デフォルト値):
|
|
213
219
|
|
|
214
220
|
```typescript
|
|
215
221
|
export enum Status {
|
|
@@ -219,7 +225,7 @@ export enum Status {
|
|
|
219
225
|
}
|
|
220
226
|
```
|
|
221
227
|
|
|
222
|
-
**定数オブジェクトモード** (`erasableSyntaxOnly: true`):
|
|
228
|
+
**定数オブジェクトモード** (`enmuConfig.erasableSyntaxOnly: true`):
|
|
223
229
|
|
|
224
230
|
```typescript
|
|
225
231
|
export const Status = {
|
package/README.md
CHANGED
|
@@ -121,8 +121,12 @@ $ anl type
|
|
|
121
121
|
}
|
|
122
122
|
],
|
|
123
123
|
"publicPrefix": "api",
|
|
124
|
-
"
|
|
125
|
-
"
|
|
124
|
+
"parameterSeparator": "_",
|
|
125
|
+
"enmuConfig": {
|
|
126
|
+
"erasableSyntaxOnly": false,
|
|
127
|
+
"varnames": "enum-varnames",
|
|
128
|
+
"comment": "enum-descriptions"
|
|
129
|
+
}
|
|
126
130
|
}
|
|
127
131
|
```
|
|
128
132
|
|
|
@@ -142,8 +146,10 @@ $ anl type
|
|
|
142
146
|
| includeInterface | Array<{path: string, method: string}> | No | Included interfaces: The interface list file specified by `saveApiListFolderPath` will only include interfaces in the list, mutually exclusive with `excludeInterface` field |
|
|
143
147
|
| excludeInterface | Array<{path: string, method: string}> | No | Excluded interfaces: The interface list file specified by `saveApiListFolderPath` will not include interfaces in this list, mutually exclusive with `includeInterface` |
|
|
144
148
|
| publicPrefix | string | No | Common prefix on url path, e.g.: api/users, api/users/{id}, api is the common prefix |
|
|
145
|
-
| erasableSyntaxOnly
|
|
149
|
+
| enmuConfig.erasableSyntaxOnly | boolean | Yes | Align with tsconfig.json `compilerOptions.erasableSyntaxOnly`. When `true`, generates const objects instead of enums (type-only syntax). Default: `false` |
|
|
146
150
|
| parameterSeparator | string | No | Separator used between path segments and parameters when generating API names and type names. For example, `/users/{userId}/posts` with separator `'_'` generates `users_userId_posts_GET`. Default: `'_'` |
|
|
151
|
+
| enmuConfig.varnames | string | No | Schema field name that stores custom enum member identifiers. Default: `enum-varnames`. |
|
|
152
|
+
| enmuConfig.comment | string | No | Schema field name that stores enum member descriptions (used for inline comments). Default: `enum-descriptions`. |
|
|
147
153
|
|
|
148
154
|
#### Configuration Items and Generated Files Correspondence
|
|
149
155
|
|
|
@@ -205,9 +211,9 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
205
211
|
|
|
206
212
|
#### Enum Generation
|
|
207
213
|
|
|
208
|
-
The tool supports two enum generation modes, controlled by the `erasableSyntaxOnly` configuration:
|
|
214
|
+
The tool supports two enum generation modes, controlled by the `enmuConfig.erasableSyntaxOnly` configuration:
|
|
209
215
|
|
|
210
|
-
**Traditional Enum Mode** (`erasableSyntaxOnly: false`, default):
|
|
216
|
+
**Traditional Enum Mode** (`enmuConfig.erasableSyntaxOnly: false`, default):
|
|
211
217
|
|
|
212
218
|
```typescript
|
|
213
219
|
export enum Status {
|
|
@@ -217,7 +223,7 @@ export enum Status {
|
|
|
217
223
|
}
|
|
218
224
|
```
|
|
219
225
|
|
|
220
|
-
**Const Object Mode** (`erasableSyntaxOnly: true`):
|
|
226
|
+
**Const Object Mode** (`enmuConfig.erasableSyntaxOnly: true`):
|
|
221
227
|
|
|
222
228
|
```typescript
|
|
223
229
|
export const Status = {
|
package/README.ru.md
CHANGED
|
@@ -123,29 +123,35 @@ $ anl type
|
|
|
123
123
|
}
|
|
124
124
|
],
|
|
125
125
|
"publicPrefix": "api",
|
|
126
|
-
"
|
|
127
|
-
"
|
|
126
|
+
"parameterSeparator": "_",
|
|
127
|
+
"enmuConfig": {
|
|
128
|
+
"erasableSyntaxOnly": false,
|
|
129
|
+
"varnames": "enum-varnames",
|
|
130
|
+
"comment": "enum-descriptions"
|
|
131
|
+
}
|
|
128
132
|
}
|
|
129
133
|
```
|
|
130
134
|
|
|
131
135
|
#### Описание элементов конфигурации
|
|
132
136
|
|
|
133
|
-
| Элемент конфигурации
|
|
134
|
-
|
|
|
135
|
-
| saveTypeFolderPath
|
|
136
|
-
| saveApiListFolderPath
|
|
137
|
-
| saveEnumFolderPath
|
|
138
|
-
| importEnumPath
|
|
139
|
-
| swaggerJsonUrl
|
|
140
|
-
| requestMethodsImportPath
|
|
141
|
-
| dataLevel
|
|
142
|
-
| formatting
|
|
143
|
-
| headers
|
|
144
|
-
| includeInterface
|
|
145
|
-
| excludeInterface
|
|
146
|
-
| publicPrefix
|
|
147
|
-
| erasableSyntaxOnly
|
|
148
|
-
| parameterSeparator
|
|
137
|
+
| Элемент конфигурации | Тип | Обязательный | Описание |
|
|
138
|
+
| ------------------------------ | ------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
139
|
+
| saveTypeFolderPath | string | Да | Путь сохранения файлов определений типов |
|
|
140
|
+
| saveApiListFolderPath | string | Да | Путь сохранения файлов функций API-запросов |
|
|
141
|
+
| saveEnumFolderPath | string | Да | Путь сохранения файлов данных enum |
|
|
142
|
+
| importEnumPath | string | Да | Путь импорта enum (путь ссылки на файлы enum в apps/types/models/\*.ts) |
|
|
143
|
+
| swaggerJsonUrl | string | Да | Адрес документа Swagger JSON |
|
|
144
|
+
| requestMethodsImportPath | string | Да | Путь импорта методов запросов |
|
|
145
|
+
| dataLevel | 'data' \| 'serve' \| 'axios' | Да | Уровень данных возврата интерфейса |
|
|
146
|
+
| formatting | object | Нет | Конфигурация форматирования кода |
|
|
147
|
+
| headers | object | Нет | Конфигурация заголовков запроса |
|
|
148
|
+
| includeInterface | Array<{path: string, method: string}> | Нет | Включаемые интерфейсы: файл списка интерфейсов, указанный `saveApiListFolderPath`, будет включать только интерфейсы из списка, взаимоисключающий с полем `excludeInterface` |
|
|
149
|
+
| excludeInterface | Array<{path: string, method: string}> | Нет | Исключаемые интерфейсы: файл списка интерфейсов, указанный `saveApiListFolderPath`, не будет содержать интерфейсы из этого списка, взаимоисключающий с `includeInterface` |
|
|
150
|
+
| publicPrefix | string | Нет | Общий префикс на url path, например: api/users、api/users/{id} ,api является общим префиксом |
|
|
151
|
+
| enmuConfig.erasableSyntaxOnly | boolean | Да | Соответствует опции `compilerOptions.erasableSyntaxOnly` в tsconfig.json. При значении `true` генерируется const объект вместо enum (только типовый синтаксис). Значение по умолчанию: `false` |
|
|
152
|
+
| parameterSeparator | string | Нет | Разделитель между сегментами пути и параметрами при генерации имен API и имен типов. Например, `/users/{userId}/posts` с разделителем `'_'` генерирует `users_userId_posts_GET`. Значение по умолчанию: `'_'` |
|
|
153
|
+
| enmuConfig.varnames | string | Нет | Имя поля в схеме Swagger, в котором находятся пользовательские имена элементов enum. Значение по умолчанию: `enum-varnames`. |
|
|
154
|
+
| enmuConfig.comment | string | Нет | Имя поля в схеме Swagger, содержащее описания элементов enum (используется для генерации комментариев). Значение по умолчанию: `enum-descriptions`. |
|
|
149
155
|
|
|
150
156
|
#### Соответствие элементов конфигурации и генерируемых файлов
|
|
151
157
|
|
|
@@ -207,9 +213,9 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
207
213
|
|
|
208
214
|
#### Генерация enum
|
|
209
215
|
|
|
210
|
-
Инструмент поддерживает два режима генерации enum, контролируемые через конфигурацию `erasableSyntaxOnly`:
|
|
216
|
+
Инструмент поддерживает два режима генерации enum, контролируемые через конфигурацию `enmuConfig.erasableSyntaxOnly`:
|
|
211
217
|
|
|
212
|
-
**Традиционный режим enum** (`erasableSyntaxOnly: false`, значение по умолчанию):
|
|
218
|
+
**Традиционный режим enum** (`enmuConfig.erasableSyntaxOnly: false`, значение по умолчанию):
|
|
213
219
|
|
|
214
220
|
```typescript
|
|
215
221
|
export enum Status {
|
|
@@ -219,7 +225,7 @@ export enum Status {
|
|
|
219
225
|
}
|
|
220
226
|
```
|
|
221
227
|
|
|
222
|
-
**Режим константного объекта** (`erasableSyntaxOnly: true`):
|
|
228
|
+
**Режим константного объекта** (`enmuConfig.erasableSyntaxOnly: true`):
|
|
223
229
|
|
|
224
230
|
```typescript
|
|
225
231
|
export const Status = {
|
package/README.zh.md
CHANGED
|
@@ -123,29 +123,35 @@ $ anl type
|
|
|
123
123
|
}
|
|
124
124
|
],
|
|
125
125
|
"publicPrefix": "api",
|
|
126
|
-
"
|
|
127
|
-
"
|
|
126
|
+
"parameterSeparator": "_",
|
|
127
|
+
"enmuConfig": {
|
|
128
|
+
"erasableSyntaxOnly": false,
|
|
129
|
+
"varnames": "enum-varnames",
|
|
130
|
+
"comment": "enum-descriptions"
|
|
131
|
+
}
|
|
128
132
|
}
|
|
129
133
|
```
|
|
130
134
|
|
|
131
135
|
#### 配置项说明
|
|
132
136
|
|
|
133
|
-
| 配置项
|
|
134
|
-
|
|
|
135
|
-
| saveTypeFolderPath
|
|
136
|
-
| saveApiListFolderPath
|
|
137
|
-
| saveEnumFolderPath
|
|
138
|
-
| importEnumPath
|
|
139
|
-
| swaggerJsonUrl
|
|
140
|
-
| requestMethodsImportPath
|
|
141
|
-
| dataLevel
|
|
142
|
-
| formatting
|
|
143
|
-
| headers
|
|
144
|
-
| includeInterface
|
|
145
|
-
| excludeInterface
|
|
146
|
-
| publicPrefix
|
|
147
|
-
| erasableSyntaxOnly
|
|
148
|
-
| parameterSeparator
|
|
137
|
+
| 配置项 | 类型 | 必填 | 说明 |
|
|
138
|
+
| ----------------------------- | ------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
139
|
+
| saveTypeFolderPath | string | 是 | 类型定义文件保存路径 |
|
|
140
|
+
| saveApiListFolderPath | string | 是 | API 请求函数文件保存路径 |
|
|
141
|
+
| saveEnumFolderPath | string | 是 | 枚举数据文件保存路径 |
|
|
142
|
+
| importEnumPath | string | 是 | 枚举导入路径(apps/types/models/\*.ts 中 enum 文件的引用的路径) |
|
|
143
|
+
| swaggerJsonUrl | string | 是 | Swagger JSON 文档地址 |
|
|
144
|
+
| requestMethodsImportPath | string | 是 | 请求方法导入路径 |
|
|
145
|
+
| dataLevel | 'data' \| 'serve' \| 'axios' | 是 | 接口返回数据层级 |
|
|
146
|
+
| formatting | object | 否 | 代码格式化配置 |
|
|
147
|
+
| headers | object | 否 | 请求头配置 |
|
|
148
|
+
| includeInterface | Array<{path: string, method: string}> | 否 | 包含的接口:`saveApiListFolderPath`指定的接口列表文件,只会包含列表中的接口,与 `excludeInterface` 字段互斥 |
|
|
149
|
+
| excludeInterface | Array<{path: string, method: string}> | 否 | 排除的接口: `saveApiListFolderPath` 指定的接口列表文本,不存在该列表中的接口,与 `includeInterface` 互斥 |
|
|
150
|
+
| publicPrefix | string | 否 | url path 上的公共前缀,例如:api/users、api/users/{id} ,api 就是公共前缀 |
|
|
151
|
+
| enmuConfig.erasableSyntaxOnly | boolean | 是 | 与 tsconfig.json 的 `compilerOptions.erasableSyntaxOnly` 选项保持一致。为 `true` 时,生成 const 对象而非 enum(仅类型语法)。默认值:`false` |
|
|
152
|
+
| parameterSeparator | string | 否 | 生成 API 名称和类型名称时,路径段和参数之间使用的分隔符。例如,`/users/{userId}/posts` 使用分隔符 `'_'` 会生成 `users_userId_posts_GET`。默认值:`'_'` |
|
|
153
|
+
| enmuConfig.varnames | string | 否 | Swagger schema 中自定义枚举成员名所在的字段名。默认值:`enum-varnames`。 |
|
|
154
|
+
| enmuConfig.comment | string | 否 | Swagger schema 中自定义枚举描述所在的字段名(用于生成注释)。默认值:`enum-descriptions`。 |
|
|
149
155
|
|
|
150
156
|
#### 配置项与生成的文件对应关系
|
|
151
157
|
|
|
@@ -207,9 +213,9 @@ export const userDetailGet = (params: UserDetail_GET.Query) => GET<UserDetail_GE
|
|
|
207
213
|
|
|
208
214
|
#### 枚举生成
|
|
209
215
|
|
|
210
|
-
工具支持两种枚举生成模式,通过 `erasableSyntaxOnly` 配置控制:
|
|
216
|
+
工具支持两种枚举生成模式,通过 `enmuConfig.erasableSyntaxOnly` 配置控制:
|
|
211
217
|
|
|
212
|
-
**传统枚举模式** (`erasableSyntaxOnly: false`,默认值):
|
|
218
|
+
**传统枚举模式** (`enmuConfig.erasableSyntaxOnly: false`,默认值):
|
|
213
219
|
|
|
214
220
|
```typescript
|
|
215
221
|
export enum Status {
|
|
@@ -219,7 +225,7 @@ export enum Status {
|
|
|
219
225
|
}
|
|
220
226
|
```
|
|
221
227
|
|
|
222
|
-
**常量对象模式** (`erasableSyntaxOnly: true`):
|
|
228
|
+
**常量对象模式** (`enmuConfig.erasableSyntaxOnly: true`):
|
|
223
229
|
|
|
224
230
|
```typescript
|
|
225
231
|
export const Status = {
|
package/lib/package.json.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="25.
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="25.1203.1",i="FE command line tool",t="bin/an-cli.js",s={registry:"https://registry.npmjs.org"},o={dev:"rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript -w",build:"rimraf lib && rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",pub:"bash publish.sh",ts:"tsc ./src/int.ts --noEmit --watch",blink:"npm run build && npm link","sync-docs":"node scripts/sync-docs.js"},r={anl:"bin/an-cli.js"},n="Gleason <bianliuzhu@gmail.com>",l={"@commitlint/cli":"^17.4.3","@commitlint/config-conventional":"^17.4.3","@rollup/plugin-commonjs":"^21.0.1","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^13.1.3","@rollup/plugin-typescript":"^8.3.0","@types/inquirer":"^9.0.7","@types/shelljs":"^0.8.11","@typescript-eslint/eslint-plugin":"^5.52.0","@typescript-eslint/parser":"^5.52.0","cross-env":"^7.0.3",eslint:"^8.7.0",husky:"^8.0.3","openapi-types":"^12.1.3",prettier:"^3.3.2",rimraf:"^5.0.7",rollup:"^2.64.0","rollup-plugin-cleandir":"^2.0.0","rollup-plugin-copy":"^3.5.0","rollup-plugin-terser":"^7.0.2",typescript:"^4.5.4"},p={"app-root-path":"^3.1.0",cac:"^6.7.12",chalk:"4.*","clear-console":"^1.1.0",commander:"14.0.1",figures:"^6.1.0",inquirer:"^10.1.8","log-symbols":"^5.1.0",ora:"5.*","progress-estimator":"^0.3.0",shelljs:"^0.8.5"},c=["cli","command-line","frontend","typescript","type-generation","code-generator","swagger","openapi","api","rest-api","eslint","stylelint","prettier","commitlint","linter","formatter","react","vue","git","gitflow","developer-tools","automation","scaffolding"],a=["package.json","README.md","lib","template"],u={type:"git",url:"https://github.com/bianliuzhu/an-cli.git"},g="commonjs",m={name:"anl",version:e,description:i,main:t,publishConfig:s,scripts:o,bin:r,author:n,license:"ISC",devDependencies:l,dependencies:p,keywords:c,files:a,repository:u,type:g};exports.author=n,exports.bin=r,exports.default=m,exports.dependencies=p,exports.description=i,exports.devDependencies=l,exports.files=a,exports.keywords=c,exports.license="ISC",exports.main=t,exports.name="anl",exports.publishConfig=s,exports.repository=u,exports.scripts=o,exports.type=g,exports.version=e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../utils/index.js");const t="\t";exports.default=class{config;schemas={};enumsMap=new Map;schemasMap=new Map;defaultReturn={headerRef:"",renderStr:"",comment:"",typeName:""};requiredFieldS=[];constructor(e,t){this.schemas=e,this.config=t}nullable(e){return""+(e?" | null":"")}getEnumTypeName(e){return this.config.erasableSyntaxOnly?`${e}Type`:e}fieldComment(e){const{description:t}=e;if(t){return["\t","/**","\n",`\t * ${t}`,"\n","\t */"].join("")}return""}typeNameToFileName(e){return e.replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase().replace(/-+/g,"-")}nameTheHumpCenterStroke(e){const t=e.replace("#/components/schemas/",""),n={typeName:t,fileName:this.typeNameToFileName(t),dataType:""};if(this.schemas){const e=this.schemas[t];e.enum?n.dataType="enum":n.dataType=e.type}return n}parseRef(e){if(!e?.trim())return{headerRefStr:"",typeName:"",dataType:""};const{fileName:t,typeName:n,dataType:r=""}=this.nameTheHumpCenterStroke(e);let s;if("enum"===r){s=`import type { ${this.getEnumTypeName(n)} } from '${this.config.importEnumPath}';`}else s=`import type { ${n} } from './${t}';`;return{headerRefStr:s,typeName:n,dataType:r}}parseObject(e,n){let r="",s="";if("object"===e.type){const i=e;if("object"==typeof i.additionalProperties){const e=this.parseArray(i.additionalProperties,n)??this.defaultReturn;r=e?.headerRef??"",s=e?.renderStr??""}s="boolean"==typeof i.additionalProperties?`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: Record<string, unknown>${this.nullable(i.nullable)};`:`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: ${e.type}${this.nullable(e.nullable)};`}return{headerRef:r,renderStr:s}}parseArray(n,r){const s=n,{items:i={},nullable:a,example:o}=s,u=i?.$ref;if(u){const{headerRefStr:n,typeName:s,dataType:i}=this.parseRef(u);if("enum"===i&&e.isValidJSON(o)){const e=this.typeNameToFileName(s),t=this.convertJsonToEnumString(o,s);this.enumsMap.set(e,{fileName:e,content:t})}const l="enum"===i?this.getEnumTypeName(s):s;return{headerRef:n,renderStr:`${t}${r}${this.requiredFieldS.includes(r)?"":"?"}: Array<${l}>${this.nullable(a)};`,typeName:l}}const l=i?.type;let p="integer"===l?"number":l;return"object"===l&&(p="Record<string, unknown>"),{headerRef:"",renderStr:`${t}${r}${this.requiredFieldS.includes(r)?"":"?"}: Array<${p}>${this.nullable(a)};`,typeName:p}}parseBoolean(e,n){return"boolean"===e.type?`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: boolean${this.nullable(e.nullable)};`:""}parseEnum(e,n){if(!Array.isArray(e.enum))return null;if(this.config.erasableSyntaxOnly){if("integer"===e.type){return{headerRef:"",renderStr:[`export const ${n} = {`,...e.enum.map(e=>`${t}NUMBER_${e}: ${e},`),"} as const;","",`export type ${this.getEnumTypeName(n)} = typeof ${n}[keyof typeof ${n}];`].join("\n")}}if("string"===e.type){const r=e.enum.every(e=>!isNaN(Number(e)));return{headerRef:"",renderStr:[`export const ${n} = {`,...e.enum.map(e=>r?`${t}NUMBER_${e}: '${e}',`:`${t}${e.toUpperCase()}: '${e}',`),"} as const;","",`export type ${this.getEnumTypeName(n)} = typeof ${n}[keyof typeof ${n}];`].join("\n")}}}else{if("integer"===e.type){return{headerRef:"",renderStr:[`export enum ${n} {`,...e.enum.map(e=>`${t}NUMBER_${e} = ${e},`),"}"].join("\n")}}if("string"===e.type){const r=e.enum.every(e=>!isNaN(Number(e)));return{headerRef:"",renderStr:[`export enum ${n} {`,...e.enum.map(e=>r?`${t}NUMBER_${e} = '${e}',`:`${t}${e.toUpperCase()} = '${e}',`),"}"].join("\n")}}}return null}parseInteger(e,n){if(Array.isArray(e.enum)){const t=n.charAt(0).toUpperCase()+n.slice(1);return this.parseEnum(e,t)?.renderStr??""}return`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: number${this.nullable(e.nullable)};`}parseNumber(e,n){return"number"===e.type?`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: number${this.nullable(e.nullable)};`:""}convertJsonToEnumString(e,n){try{const r=JSON.parse(e);if(this.config.erasableSyntaxOnly){return`export const ${n} = {\n${Object.entries(r).map(([e,n])=>`${t}${e}: '${n}'`).join(",\n")}\n} as const;\n\nexport type ${this.getEnumTypeName(n)} = typeof ${n}[keyof typeof ${n}];`}return`export enum ${n} {\n${Object.entries(r).map(([e,n])=>`${t}${e} = '${n}'`).join(",\n")}\n}`}catch(e){return console.error("JSON 解析失败:",e),""}}parseString(n,r){if("string"===n.type){if(n.enum){const s=r.charAt(0).toUpperCase()+r.slice(1);if(e.isValidJSON(n.example)){const e=this.convertJsonToEnumString(n.example,s),i=this.getEnumTypeName(s);return{headerRef:"",renderStr:`${t}${r}${this.requiredFieldS.includes(r)?"":"?"}: ${i}${this.nullable(n.nullable)};`,comment:e}}{const e=this.typeNameToFileName(s),t=this.parseEnum(n,s);if(t&&!this.enumsMap.has(e))return this.enumsMap.set(e,{fileName:e,content:t.renderStr}),{headerRef:"",renderStr:""}}}return{headerRef:"",renderStr:`${t}${r}${this.requiredFieldS.includes(r)?"":"?"}: string${this.nullable(n.nullable)};`}}return null}parseProperties(n,r){const s=[],i=[];for(const a in n){const o=n[a];if(o?.$ref){const{headerRefStr:n,typeName:r,dataType:u}=this.parseRef(o.$ref);i.includes(n)||i.push(n);const l=o,p=this.fieldComment(l);""!==p&&s.push(p);const c="enum"===u?this.getEnumTypeName(r):r;s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: ${c};`);const h=o.example;if("enum"===u&&h&&e.isValidJSON(h)){const e=this.typeNameToFileName(r),t=this.convertJsonToEnumString(h,r);this.enumsMap.set(e,{fileName:e,content:t})}continue}if("allOf"in o){const e=o.allOf?.[0];if(e?.$ref){const{headerRefStr:n,typeName:r,dataType:u}=this.parseRef(e.$ref),l="enum"===u?this.getEnumTypeName(r):r;i.includes(n)||i.push(n);const p=o,c=this.fieldComment(p);""!==c&&s.push(c),s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: ${l}${this.nullable(o.nullable)};`);continue}}const u=o,l=this.fieldComment(u);switch(""!==l&&s.push(l),u.type){case"array":{const e=this.parseArray(u,a)??this.defaultReturn;s.push(e?.renderStr??""),i.includes(e.headerRef)||r===e.typeName||i.push(e.headerRef)}break;case"boolean":s.push(this.parseBoolean(u,a));break;case"integer":s.push(this.parseInteger(u,a));break;case"number":s.push(this.parseNumber(u,a));break;case"string":if(u.enum){const n=a.charAt(0).toUpperCase()+a.slice(1);if(u.example&&e.isValidJSON(u.example)){const e=this.getEnumTypeName(n),r=`import type { ${e} } from '${this.config.importEnumPath}';`;i.includes(r)||i.push(r);const o=this.typeNameToFileName(n);if(!this.enumsMap.has(o)){const e=this.convertJsonToEnumString(u.example,n);this.enumsMap.set(o,{fileName:o,content:e})}s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: ${e}${this.nullable(u.nullable)};`)}else{const e=this.parseEnum(u,n);if(e?.renderStr){const r=this.getEnumTypeName(n),o=`import type { ${r} } from '${this.config.importEnumPath}';`;i.includes(o)||i.push(o);const l=this.typeNameToFileName(n);this.enumsMap.has(l)||this.enumsMap.set(l,{fileName:l,content:e.renderStr}),s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: ${r}${this.nullable(u.nullable)};`)}}}else u.format&&"binary"===u.format?s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: File${this.nullable(u.nullable)};`):s.push(this.parseString(u,a)?.renderStr??"");break;case"object":{const{headerRef:e,renderStr:t}=this.parseObject(u,a)??this.defaultReturn;s.push(t),i.includes(e)||i.push(e)}}}const a=[`export interface ${r} {`,...s,"}"];if(i.length>0){const e=i.filter(e=>""!==e);e.length>0&&e.push(""),a.unshift(...e)}const o=a.join("\n");return{headerRef:i.join("\n"),renderStr:o}}async generateContent(e,t){if("items"in e)return console.warn(`数组类型未处理: ${t}`,e.items),"";switch(e.type){case"boolean":return this.parseBoolean(e,t);case"integer":return this.parseInteger(e,t);case"number":return this.parseNumber(e,t);case"object":{const n=this.parseProperties(e.properties,t);return n?.renderStr??""}case"string":{const n=this.parseString(e,t);return n?.renderStr??""}default:return""}}async parseData(){try{if(!this.schemas)return void console.warn("schemas 为空");for(const[e,t]of Object.entries(this.schemas)){if("$ref"in t){console.warn(`跳过 ReferenceObject: ${e}`);continue}const n="type"in t?t:null;if(!n?.type){console.warn(`无效的 schema 对象: ${e}`);continue}this.requiredFieldS=t.required??[];const r=this.typeNameToFileName(e),s=await this.generateContent(n,e);if(s){(s.includes("export enum ")||s.includes("export const ")&&s.includes("as const"))&&!this.enumsMap.has(r)?this.enumsMap.set(r,{fileName:r,content:s}):this.schemasMap.set(e,{fileName:r,content:s})}}}catch(e){throw console.error("解析过程出错:",e),e}}async writeEnums(){const t=[],n=[];for(const[,r]of this.enumsMap){const s=async({fileName:t,content:r})=>{n.push(`export * from './${t}';`);const s=`${this.config.saveEnumFolderPath}/${t}.ts`;await e.writeFileRecursive(s,r),e.log.info(`${s.padEnd(80)} - Write done!`)};t.push(s(r))}await Promise.all(t),await e.writeFileRecursive(`${this.config.saveEnumFolderPath}/index.ts`,n.join("\n")),e.log.success("Enums write done!")}async writeFile(){const t=[],n=[],r=`${this.config.saveTypeFolderPath}/models/`;for(const[,s]of this.schemasMap){const i=async({fileName:t,content:s})=>{n.push(`export * from './${t}';`);const i=`${r}${t}.ts`;await e.writeFileRecursive(i,s),e.log.info(`${i.padEnd(80)} - Write done!`)};t.push(i(s))}await Promise.all(t),await e.writeFileRecursive(`${r}index.ts`,n.join("\n")),e.log.success("Component parse & write done!")}async handle(){await this.parseData(),await this.writeFile(),await this.writeEnums()}};
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../utils/index.js");const t="\t";exports.default=class{config;schemas={};enumsMap=new Map;schemasMap=new Map;defaultReturn={headerRef:"",renderStr:"",comment:"",typeName:""};requiredFieldS=[];constructor(e,t){this.schemas=e,this.config=t}handleEnum(n,r){const s=r.charAt(0).toUpperCase()+r.slice(1);if(e.isValidJSON(n.example)){const e=this.convertJsonToEnumString(n.example,s),i=this.getEnumTypeName(s);return{headerRef:"",renderStr:`${t}${r}${this.requiredFieldS.includes(r)?"":"?"}: ${i}${this.nullable(n.nullable)};`,comment:e}}const i=this.typeNameToFileName(s),a=this.parseEnum(n,s);return a&&!this.enumsMap.has(i)?(this.enumsMap.set(i,{fileName:i,content:a.renderStr}),{headerRef:"",renderStr:""}):null}nullable(e){return""+(e?" | null":"")}getEnumTypeName(e){return this.config.enmuConfig.erasableSyntaxOnly?`${e}Type`:e}fieldComment(e){const{description:t}=e;if(t){return["\t","/**","\n",`\t * ${t}`,"\n","\t */"].join("")}return""}typeNameToFileName(e){return e.replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase().replace(/-+/g,"-")}nameTheHumpCenterStroke(e){const t=e.replace("#/components/schemas/",""),n={typeName:t,fileName:this.typeNameToFileName(t),dataType:""};if(this.schemas){const e=this.schemas[t];e.enum?n.dataType="enum":n.dataType=e.type}return n}parseRef(e){if(!e?.trim())return{headerRefStr:"",typeName:"",dataType:""};const{fileName:t,typeName:n,dataType:r=""}=this.nameTheHumpCenterStroke(e);let s;if("enum"===r){s=`import type { ${this.getEnumTypeName(n)} } from '${this.config.importEnumPath}';`}else s=`import type { ${n} } from './${t}';`;return{headerRefStr:s,typeName:n,dataType:r}}parseObject(e,n){let r="",s="";if("object"===e.type){const i=e;if("object"==typeof i.additionalProperties){const e=this.parseArray(i.additionalProperties,n)??this.defaultReturn;r=e?.headerRef??"",s=e?.renderStr??""}s="boolean"==typeof i.additionalProperties?`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: Record<string, unknown>${this.nullable(i.nullable)};`:`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: ${e.type}${this.nullable(e.nullable)};`}return{headerRef:r,renderStr:s}}parseArray(n,r){const s=n,{items:i={},nullable:a,example:o}=s,u=i?.$ref;if(u){const{headerRefStr:n,typeName:s,dataType:i}=this.parseRef(u);if("enum"===i&&e.isValidJSON(o)){const e=this.typeNameToFileName(s),t=this.convertJsonToEnumString(o,s);this.enumsMap.set(e,{fileName:e,content:t})}const l="enum"===i?this.getEnumTypeName(s):s;return{headerRef:n,renderStr:`${t}${r}${this.requiredFieldS.includes(r)?"":"?"}: Array<${l}>${this.nullable(a)};`,typeName:l}}const l=i?.type;let c="integer"===l?"number":l;return"object"===l&&(c="Record<string, unknown>"),{headerRef:"",renderStr:`${t}${r}${this.requiredFieldS.includes(r)?"":"?"}: Array<${c}>${this.nullable(a)};`,typeName:c}}parseBoolean(e,n){return"boolean"===e.type?`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: boolean${this.nullable(e.nullable)};`:""}extractEnumMetadata(e){const t={},{enmuConfig:n}=this.config,r=e;if(n?.varnames){const e=r[n.varnames];Array.isArray(e)&&(t.customNames=e.map(e=>`${e}`))}if(n?.comment){const e=r[n.comment];if(e&&"object"==typeof e&&!Array.isArray(e)){const n={};Object.entries(e).forEach(([e,t])=>{"string"==typeof t&&(n[e]=t)}),Object.keys(n).length&&(t.descriptionMap=n)}}return t}resolveEnumMemberName(e,t,n){const{customNames:r,isNumericEnum:s,treatStringAsNumeric:i}=n,a=r?.[t];return"string"==typeof a&&a.trim()?a:s||"string"==typeof e&&i?`NUMBER_${e}`:"string"==typeof e&&e?e.toUpperCase():`ENUM_${t}`}parseEnum(e,n){if(!Array.isArray(e.enum))return null;const r=Boolean(e.type&&["integer","number"].includes(e.type)),s=e.enum,i="string"===e.type&&s.every(e=>"string"==typeof e&&!isNaN(Number(e))),{customNames:a,descriptionMap:o}=this.extractEnumMetadata(e),u=this.config.enmuConfig.erasableSyntaxOnly,l=s.map((e,n)=>{const s=this.resolveEnumMemberName(e,n,{customNames:a,isNumericEnum:r,treatStringAsNumeric:i}),l=r?`${e}`:`'${String(e)}'`,c=u?`${s}: ${l},`:`${s} = ${l},`,m=o?.[String(e)];return m?[`${t}/** ${m} */`,`${t}${c}`].join("\n"):`${t}${c}`});return l.length?u?{headerRef:"",renderStr:[`export const ${n} = {`,...l,"} as const;","",`export type ${this.getEnumTypeName(n)} = typeof ${n}[keyof typeof ${n}];`].join("\n")}:{headerRef:"",renderStr:[`export enum ${n} {`,...l,"}"].join("\n")}:null}parseInteger(e,n){if(Array.isArray(e.enum)){const t=n.charAt(0).toUpperCase()+n.slice(1);return this.parseEnum(e,t)?.renderStr??""}return`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: number${this.nullable(e.nullable)};`}parseNumber(e,n){if("number"!==e.type)return null;if(e.enum){const t=this.handleEnum(e,n);if(t)return t}return{headerRef:"",renderStr:`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: number${this.nullable(e.nullable)};`}}convertJsonToEnumString(e,n){try{const r=JSON.parse(e);if(this.config.enmuConfig.erasableSyntaxOnly){return`export const ${n} = {\n${Object.entries(r).map(([e,n])=>`${t}${e}: '${n}'`).join(",\n")}\n} as const;\n\nexport type ${this.getEnumTypeName(n)} = typeof ${n}[keyof typeof ${n}];`}return`export enum ${n} {\n${Object.entries(r).map(([e,n])=>`${t}${e} = '${n}'`).join(",\n")}\n}`}catch(e){return console.error("JSON 解析失败:",e),""}}parseString(e,n){if("string"!==e.type)return null;if(e.enum){const t=this.handleEnum(e,n);if(t)return t}return{headerRef:"",renderStr:`${t}${n}${this.requiredFieldS.includes(n)?"":"?"}: string${this.nullable(e.nullable)};`}}parseProperties(n,r){const s=[],i=[];for(const a in n){const o=n[a];if(o?.$ref){const{headerRefStr:n,typeName:r,dataType:u}=this.parseRef(o.$ref);i.includes(n)||i.push(n);const l=o,c=this.fieldComment(l);""!==c&&s.push(c);const m="enum"===u?this.getEnumTypeName(r):r;s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: ${m};`);const p=o.example;if("enum"===u&&p&&e.isValidJSON(p)){const e=this.typeNameToFileName(r),t=this.convertJsonToEnumString(p,r);this.enumsMap.set(e,{fileName:e,content:t})}continue}if("allOf"in o){const e=o.allOf?.[0];if(e?.$ref){const{headerRefStr:n,typeName:r,dataType:u}=this.parseRef(e.$ref),l="enum"===u?this.getEnumTypeName(r):r;i.includes(n)||i.push(n);const c=o,m=this.fieldComment(c);""!==m&&s.push(m),s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: ${l}${this.nullable(o.nullable)};`);continue}}const u=o,l=this.fieldComment(u);switch(""!==l&&s.push(l),u.type){case"array":{const e=this.parseArray(u,a)??this.defaultReturn;s.push(e?.renderStr??""),i.includes(e.headerRef)||r===e.typeName||i.push(e.headerRef)}break;case"boolean":s.push(this.parseBoolean(u,a));break;case"integer":s.push(this.parseInteger(u,a));break;case"number":{const e=this.parseNumber(u,a);e&&(e.headerRef&&!i.includes(e.headerRef)&&i.push(e.headerRef),s.push(e.renderStr))}break;case"string":if(u.enum){const n=a.charAt(0).toUpperCase()+a.slice(1);if(u.example&&e.isValidJSON(u.example)){const e=this.getEnumTypeName(n),r=`import type { ${e} } from '${this.config.importEnumPath}';`;i.includes(r)||i.push(r);const o=this.typeNameToFileName(n);if(!this.enumsMap.has(o)){const e=this.convertJsonToEnumString(u.example,n);this.enumsMap.set(o,{fileName:o,content:e})}s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: ${e}${this.nullable(u.nullable)};`)}else{const e=this.parseEnum(u,n);if(e?.renderStr){const r=this.getEnumTypeName(n),o=`import type { ${r} } from '${this.config.importEnumPath}';`;i.includes(o)||i.push(o);const l=this.typeNameToFileName(n);this.enumsMap.has(l)||this.enumsMap.set(l,{fileName:l,content:e.renderStr}),s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: ${r}${this.nullable(u.nullable)};`)}}}else u.format&&"binary"===u.format?s.push(`${t}${a}${this.requiredFieldS.includes(a)?"":"?"}: File${this.nullable(u.nullable)};`):s.push(this.parseString(u,a)?.renderStr??"");break;case"object":{const{headerRef:e,renderStr:t}=this.parseObject(u,a)??this.defaultReturn;s.push(t),i.includes(e)||i.push(e)}}}const a=[`export interface ${r} {`,...s,"}"];if(i.length>0){const e=i.filter(e=>""!==e);e.length>0&&e.push(""),a.unshift(...e)}const o=a.join("\n");return{headerRef:i.join("\n"),renderStr:o}}async generateContent(e,t){if("items"in e)return console.warn(`数组类型未处理: ${t}`,e.items),"";switch(e.type){case"boolean":return this.parseBoolean(e,t);case"integer":return this.parseInteger(e,t);case"number":{const n=this.parseNumber(e,t);return n?.renderStr??""}case"object":{const n=this.parseProperties(e.properties,t);return n?.renderStr??""}case"string":{const n=this.parseString(e,t);return n?.renderStr??""}default:return""}}async parseData(){try{if(!this.schemas)return void console.warn("schemas 为空");for(const[e,t]of Object.entries(this.schemas)){if("$ref"in t){console.warn(`跳过 ReferenceObject: ${e}`);continue}const n="type"in t?t:null;if(!n?.type){console.warn(`无效的 schema 对象: ${e}`);continue}this.requiredFieldS=t.required??[];const r=this.typeNameToFileName(e),s=await this.generateContent(n,e);if(s){(s.includes("export enum ")||s.includes("export const ")&&s.includes("as const"))&&!this.enumsMap.has(r)?this.enumsMap.set(r,{fileName:r,content:s}):this.schemasMap.set(e,{fileName:r,content:s})}}}catch(e){throw console.error("解析过程出错:",e),e}}async writeEnums(){const t=[],n=[];for(const[,r]of this.enumsMap){const s=async({fileName:t,content:r})=>{n.push(`export * from './${t}';`);const s=`${this.config.saveEnumFolderPath}/${t}.ts`;await e.writeFileRecursive(s,r),e.log.info(`${s.padEnd(80)} - Write done!`)};t.push(s(r))}await Promise.all(t),await e.writeFileRecursive(`${this.config.saveEnumFolderPath}/index.ts`,n.join("\n")),e.log.success("Enums write done!")}async writeFile(){const t=[],n=[],r=`${this.config.saveTypeFolderPath}/models/`;for(const[,s]of this.schemasMap){const i=async({fileName:t,content:s})=>{n.push(`export * from './${t}';`);const i=`${r}${t}.ts`;await e.writeFileRecursive(i,s),e.log.info(`${i.padEnd(80)} - Write done!`)};t.push(i(s))}await Promise.all(t),await e.writeFileRecursive(`${r}index.ts`,n.join("\n")),e.log.success("Component parse & write done!")}async handle(){await this.parseData(),await this.writeFile(),await this.writeEnums()}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../utils/index.js");const t="\t";var n;!function(e){e.GET="get",e.PUT="put",e.POST="post",e.DELETE="delete",e.OPTIONS="options",e.HEAD="head",e.PATCH="patch",e.TRACE="trace"}(n||(n={}));const r={typeMapping:new Map([["integer","number"],["string","string"],["boolean","boolean"],["binary","File"],["number","number"],["null","null"],["undefined","undefined"],["date","Date"],["time","Date"],["datetime","Date"],["timestamp","Date"]]),errorHandling:{throwOnError:!1,logErrors:!0}},s="#/components/schemas/",a="#/components/parameters/",i="#/definitions/",o=["application/json","text/json","text/plain","application/x-www-form-urlencoded","application/xml","text/xml","*/*","application/octet-stream","multipart/form-data"],c=["application/octet-stream","multipart/form-data"];class p{pathsObject={};nonArrayType=["boolean","object","number","string","integer"];pathKey="";contentBody={payload:{path:[],query:[],body:[]},response:"",_response:"",fileName:"",method:"",requestPath:"",summary:"",apiName:"",typeName:"",deprecated:!1,contentType:"application/json"};Map=new Map;config;errors=[];referenceCache=new Map;parameters={};schemas={};templates={exportConst:e=>`export const ${e}`,typeDefinition:(e,t)=>`type ${e} = ${t}`,interfaceDefinition:e=>`interface ${e}`};constructor(e,t,n,s){this.pathsObject=e,this.parameters=t??{},this.schemas=n??{},this.config={...r,...s,typeMapping:new Map([...r.typeMapping||[],...s.typeMapping||[]])}}handleError(t){if(this.errors.push(t),this.config.errorHandling?.logErrors&&e.log.error(`${t.type}: ${t.message}${t.path?` at ${t.path}`:""}`),this.config.errorHandling?.throwOnError)throw new Error(`${t.type}: ${t.message}`)}getIndentation(){return this.config.formatting?.indentation||t}getEnumTypeName(e){return this.config.erasableSyntaxOnly?`${e}Type`:e}typeNameToFileName(e){return e=(e=(e=e.replace(/_/g,"-")).replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()).replace(/-+/g,"-")}stringifySchemaResult(e){if(Array.isArray(e)){const t=this.config.formatting?.lineEnding??"\n",n=this.getIndentation();return`{${t}${e.join(t)}${t}${n}}`}return e}handleComplexType(e){try{return e.oneOf?e.oneOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" | "):e.allOf?e.allOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" & "):e.anyOf?e.anyOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" | "):e.enum?"number"===e.type||"integer"===e.type?e.enum.join(" | "):e.enum.map(e=>`'${e}'`).join(" | "):"unknown"}catch(e){return this.handleError({type:"SCHEMA",message:"Failed to handle complex type",details:e}),"unknown"}}propertiesParse(e){if(!e)return[];const n=[];for(const r in e){const s=e[r],a=this.schemaParse(s);let i="";i=Array.isArray(a)?`${t}${t}${r}: {${a.join("\n")}};`:`${t}${t}${r}: ${a};`,n.push(i)}return n}nonArraySchemaObjectParse(e){if(!e)return"unknown";if("binary"===e.format||"string"===e.type&&"binary"===e.format)return"File";switch(e.type){case"boolean":return"boolean";case"integer":case"number":return"number";case"object":return this.propertiesParse(e.properties);case"string":return"binary"===e.format?"File":"string";default:return"unknown"}}arraySchemaObjectParse(e){if("array"!==e.type)return"";const{items:t}=e,n="$ref"in t?t:null,r=t;if(n){return`Array<${this.referenceObjectParse(n)}>`}if(r){const e=this.schemaParse(t);return Array.isArray(e)?`Array<{${e.join("\n")}}>`:`Array<${e}>`}return""}referenceObjectParse(e){try{const t=e.$ref,n=this.referenceCache.get(t);if(n)return n;let r=t;t.startsWith(s)&&(r=t.replace(s,"")),t.startsWith(a)&&(r=t.replace(a,"")),t.startsWith(i)&&(r=t.replace(i,""));const o=this.typeNameToFileName(r),c=/enum/gi.test(r),p=this.schemas?.[r],l=p&&"enum"in p&&Array.isArray(p.enum),h=c||l,y=h?this.getEnumTypeName(r):r,m=h?`import('${this.config.importEnumPath}/${o}').${y}`:`import('../models/${o}').${r}`;return this.referenceCache.set(t,m),m}catch(e){return this.handleError({type:"REFERENCE",message:"Failed to parse reference object",details:e}),"unknown"}}schemaParse(e){try{if(!e)return"unknown";if("oneOf"in e||"allOf"in e||"anyOf"in e||"enum"in e)return this.handleComplexType(e);if("$ref"in e)return this.referenceObjectParse(e);const t=e,n=t.type,r=!0===t.nullable?" | null":"";if(e.format&&this.config.typeMapping?.has(e.format))return this.config.typeMapping.get(e.format)+r;if(n&&this.config.typeMapping?.has(n))return this.config.typeMapping.get(n)+r;if("array"===n&&t.items){const e=this.schemaParse(t.items);if(Array.isArray(e)){const t=this.config.formatting?.lineEnding,n=this.config.formatting?.indentation;return`Array<{${t}${e.join("\n")}${t}${n}${n}}>`}return`Array<${e}>`}if("object"===n||"object"==typeof t){if(t.properties){const e=this.propertiesParse(t.properties);return e.length?e:["unknown"]}if(!0===t.additionalProperties)return"Record<string, unknown>"+r;if("object"==typeof t.additionalProperties){return`Record<string, ${this.schemaParse(t.additionalProperties)}>`+r}}return"unknown"}catch(e){return this.handleError({type:"SCHEMA",message:"Failed to parse schema",details:e}),"unknown"}}responseObjectParse(e){try{const t=e.content;if(!t)return"";let n;for(const e of o)if(t[e]?.schema){n=t[e].schema;break}return n?this.schemaParse(n):""}catch(e){return this.handleError({type:"RESPONSE",message:"Failed to parse response object",details:e}),""}}responseHandle(e){const t=e[200];if(!t)return;const n="content"in t?t:null,r="$ref"in t?t:null;if(null===n&&null===r&&(this.contentBody.response="type Response = unknown",this.contentBody._response="unknown"),r){const e=this.referenceObjectParse(r);this.contentBody.response=`type Response = ${e}`,this.contentBody._response=e}if(n){const e=this.responseObjectParse(n);if(Array.isArray(e)){if(1===e.length&&"unknown"===e[0])this.contentBody.response=`type Response = ${e.join("\n")};`;else{const t=this.config.formatting?.lineEnding,n=this.config.formatting?.indentation;this.contentBody.response=`interface Response {${t}${e.join("\n")}${t}${n}};`}this.contentBody._response=`${e.join("\n")}`}else this.contentBody.response=`type Response = ${e}`,this.contentBody._response=`${e}`}}requestBodyObjectParse(e){const n=Object.values(e.content),{schema:r}=n[0]||{schema:null};if(r){const e=r?.type,n="$ref"in r?r:null,s="array"===e?r:null,a=e&&this.nonArrayType.includes(e)?r:null;if(n){const e=this.referenceObjectParse(n);return`${t}type Body = ${e}`}if(s){const e=this.arraySchemaObjectParse(s);return`${t}type Body = ${e}`}if(a){const e=this.nonArraySchemaObjectParse(a);return Array.isArray(e)?0===e.length?[`${t}type Body = ${a.type};`]:[`${t}interface Body {`,...e.map(e=>e.replace(/: string;/,": File;")),"}"]:[`${t}type Body = ${e}`]}}}requestBodyParse(e){if(!e)return"{}";const n="$ref"in e?e:null,r="content"in e?e:null;if(n){const e=this.referenceObjectParse(n);return`${t}type Body = ${e}`}return r&&"[object Object]"===String(e)&&0!==Reflect.ownKeys(e).length?this.requestBodyObjectParse(r):"{}"}parametersItemHandle(e,n,r){const s="$ref"in e?e:null,i="name"in e?e:null;if(s&&s.$ref&&s.$ref.startsWith(a)&&this.parameters){const e=s.$ref.replace(a,""),t=this.parameters[e];this.parametersItemHandle(t,n,r)}if(i){if("path"===i.in){const e=this.schemaParse(i.schema);n.push(`${t}${t}type ${i.name} = ${e};`),this.contentBody.payload._path?"string"==typeof e?this.contentBody.payload._path[i.name]=e:console.log("Unexpected v2value type:",e):"string"==typeof e?this.contentBody.payload._path={[i.name]:e}:console.log("Unexpected v2value type:",e)}if("query"===i.in){const e=this.schemaParse(i.schema);r.push(`${t}${t}${i.name}: ${e};`),this.contentBody.payload._query?"string"==typeof e?this.contentBody.payload._query[i.name]=e:console.log("Unexpected v2value type:",e):"string"==typeof e?this.contentBody.payload._query={[i.name]:e}:console.log("Unexpected v2value type:",e)}}}requestParametersParse(e){const n=[],r=[];e?.map(e=>this.parametersItemHandle(e,n,r)),0!==n.length&&(n.unshift(`${t}namespace Path {`),n.push(`${t}}`)),0!==r.length&&(r.unshift(`${t}interface Query {`),r.push(`${t}}`)),this.contentBody.payload.path=n,this.contentBody.payload.query=r}requestHandle(e){if(e.parameters&&this.requestParametersParse(e.parameters),e.requestBody){const t=this.requestBodyParse(e.requestBody);if(Array.isArray(t))this.contentBody.payload.body=t;else if(t){const e=t?.split("\n")||[];this.contentBody.payload.body=e}}}apiRequestItemHandle(e){const{payload:t,requestPath:n,_response:r,method:s,typeName:a,apiName:i,contentType:o}=e,{_path:p,_query:l,body:h}=t,y=(()=>{const e=[];for(const t in p)e.push(`${t}: ${a}.Path.${t}`);const t=e.join(e.length>1?",":"");return""===t?t:t+","})(),m=(()=>{const e=l?`query: ${a}.Query,`:"";return""===e?"":`${e}`})(),u=(()=>{const e=h.length>0?`body: ${a}.Body,`:"";return""===e?"":`${e}`})(),d=(y+m+u).replace(/,$/,"");return[`export const ${i} = `,"(",d,""===d?"params?: IRequestFnParams":", params?: IRequestFnParams",")"," => ",s,""+(r?`<${a}.Response>`:""),"(","`"+n+"`,",(()=>{const e=c.includes(o)?`headers: { 'Content-Type': '${o}' }`:void 0;return["{",e?`${e},`:"","...params, ",""===m?"":"query,",""===u?"":"body,","},"].join("")})(),`'${this.config.dataLevel}'`,");"].join("")}parsePathItemObject(e,t){if(e)for(const n in e){const r=e[n];if(r){if(this.config.includeInterface&&this.config.includeInterface.length>0){const e=this.config.includeInterface?.find(e=>t.includes(e.path)&&e.method===n);if(!e)return}else if(this.config.excludeInterface&&this.config.excludeInterface.length>0){const e=this.config.excludeInterface?.find(e=>t.includes(e.path)&&e.method===n);if(e)return}const e=n.toUpperCase(),s=t+"|"+e,{apiName:a,typeName:i,fileName:c,path:p}=this.convertEndpointString(s),l=r.requestBody&&"content"in r.requestBody&&r.requestBody.content,h="object"==typeof l?Object.keys(l)[0]:"application/json";this.contentBody={payload:{path:[],query:[],body:[]},response:"",_response:"",fileName:c,method:e,typeName:i,requestPath:p,apiName:a,summary:r.summary,deprecated:r.deprecated??!1,contentType:o.includes(h)?h:"application/json"},this.requestHandle(r),this.responseHandle(r.responses),this.Map.has(s)||this.Map.set(s,JSON.parse(JSON.stringify(this.contentBody)))}}}cleanSegment(e){let t=e.replace(/^[0-9]+/,"");return t?(t=t.replace(/[^a-zA-Z0-9_.-]/g,""),t):"num"+e}toCamelCase(e,t=!1){const n=this.cleanSegment(e).split(/[-_.]+/).filter(e=>e.length>0);return 0===n.length?"":n.map((e,n)=>0===n&&t?e.toLowerCase():e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}toPascalCase(e){const t=this.cleanSegment(e).split(/[-_.]+/).filter(e=>e.length>0);return 0===t.length?"":t.map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}convertEndpointString(e){let t=e;e.startsWith("/")||(t="/"+e);const[n,r]=t.split("|");let s="";this.config.publicPrefix&&(s=this.config.publicPrefix.replace(/^\/+|\/+$/g,""));let a=n.replace(/^\/+/,"");if(s&&a.startsWith(s+"/"))a=a.slice(s.length+1);else if(s&&a===s)a="";else if(s&&a.startsWith(s)){const e=a.slice(s.length);(e.startsWith("/")||""===e)&&(a=e.replace(/^\/+/,""))}const i=a?a.split("/").filter(e=>e):[],o=i.map(e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1);return{type:"param",original:e,normalized:t}}return{type:"normal",original:e,normalized:e}}),c=[];for(let e=0;e<o.length;e++){const t=o[e],n=o[e+1];if("normal"===t.type&&n&&"param"===n.type){if(this.cleanSegment(t.normalized).toLowerCase().replace(/[-_.]/g,"")===this.cleanSegment(n.normalized).toLowerCase().replace(/[-_.]/g,""))continue}c.push(t)}const p=this.config.parameterSeparator||"_";let l="",h=[];const y=e=>{if(h.length>0){const t=h.map((t,n)=>this.toCamelCase(t,e&&0===n)).join("");l+=(l&&h.length>0?p:"")+t,h=[]}};for(let e=0;e<c.length;e++){const t=c[e];if("normal"===t.type)h.push(t.normalized);else{y(""===l);const e=this.cleanSegment(t.normalized);l+=(l?p:"")+e}}y(""===l);let m="";h=[];const u=()=>{if(h.length>0){const e=h.map(e=>this.toPascalCase(e)).join("");m+=(m&&h.length>0?p:"")+e,h=[]}};for(let e=0;e<c.length;e++){const t=c[e];if("normal"===t.type)h.push(t.normalized);else{u();const e=this.toPascalCase(t.normalized);m+=(m?p:"")+e}}u();let d="";i.length>0?(d=i.map(e=>e.replace(/[{}]/g,"")).join("-"),d=`${d}-${r}`.toLowerCase()):d=`${r}`.toLowerCase();let f="/"+a;a||(f="/"),f=f.replace(/\{(\w+)\}/g,(e,t)=>`\${${t}}`);return{apiName:l?`${l}_${r}`:r,fileName:d,typeName:m?`${m}_${r}`:r,path:f}}parseData(){return new Promise((e,t)=>{try{for(const e in this.pathsObject){const t=this.pathsObject[e];t&&this.parsePathItemObject(t,e)}e(this.Map)}catch(e){this.handleError({type:"SCHEMA",message:"Failed to parse schema",details:e}),t(e)}})}async writeFile(){const n=[],r=[],s=this.config.saveTypeFolderPath,a=[],i=(n,i)=>new Promise((o,c)=>{try{const{payload:p,response:l,fileName:h,summary:y,typeName:m,deprecated:u}=i,[,d]=n.split("|");!a.includes(d)&&a.push(d);const f=[`declare namespace ${m} {`,...p.path,...p.query,...p.body,`${t}${l}`,"}"];y&&r.push(["/**","\n",u?` * @deprecated ${y}`:` * ${y}`,"\n"," */"].join(""));const g=this.apiRequestItemHandle(i);r.push(g,"");const $=`${s}/connectors/${h}.d.ts`;e.writeFileRecursive($,f.join("\n")).then(()=>{e.log.info(`${$.padEnd(80)} - Write done!`),o(1)}).catch(e=>{this.handleError({type:"FILE_WRITE",message:"Failed to write type definition file",path:h,details:e}),c(e)})}catch(e){this.handleError({type:"PATH",message:"Failed to process path item",path:n,details:e}),c(e)}});for(const[e,t]of this.Map)n.push(i(e,t));try{await Promise.all(n),e.log.success("Path parse & write done!"),r.unshift(`import { ${a.join(", ")} } from '${this.config.requestMethodsImportPath||"./api"}';`,"\n"),await e.clearDir(this.config.saveApiListFolderPath+"/index.ts"),await e.writeFileRecursive(this.config.saveApiListFolderPath+"/index.ts",r.join("\n")),this.Map=new Map,this.errors.length>0&&e.log.warning(`Completed with ${this.errors.length} errors`)}catch(e){throw this.handleError({type:"FILE_WRITE",message:"Failed to write API list file",details:e}),e}}async handle(){try{await this.parseData(),await this.writeFile()}catch(e){if(this.handleError({type:"SCHEMA",message:"Failed to handle schema",details:e}),this.config.errorHandling?.throwOnError)throw e}}}exports.PathParse=p,exports.default=p;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../utils/index.js");const t="\t";var n;!function(e){e.GET="get",e.PUT="put",e.POST="post",e.DELETE="delete",e.OPTIONS="options",e.HEAD="head",e.PATCH="patch",e.TRACE="trace"}(n||(n={}));const r={typeMapping:new Map([["integer","number"],["string","string"],["boolean","boolean"],["binary","File"],["number","number"],["null","null"],["undefined","undefined"],["date","Date"],["time","Date"],["datetime","Date"],["timestamp","Date"]]),errorHandling:{throwOnError:!1,logErrors:!0}},s="#/components/schemas/",a="#/components/parameters/",i="#/definitions/",o=["application/json","text/json","text/plain","application/x-www-form-urlencoded","application/xml","text/xml","*/*","application/octet-stream","multipart/form-data"],c=["application/octet-stream","multipart/form-data"];class p{pathsObject={};nonArrayType=["boolean","object","number","string","integer"];pathKey="";contentBody={payload:{path:[],query:[],body:[]},response:"",_response:"",fileName:"",method:"",requestPath:"",summary:"",apiName:"",typeName:"",deprecated:!1,contentType:"application/json"};Map=new Map;config;errors=[];referenceCache=new Map;parameters={};schemas={};templates={exportConst:e=>`export const ${e}`,typeDefinition:(e,t)=>`type ${e} = ${t}`,interfaceDefinition:e=>`interface ${e}`};constructor(e,t,n,s){this.pathsObject=e,this.parameters=t??{},this.schemas=n??{},this.config={...r,...s,typeMapping:new Map([...r.typeMapping||[],...s.typeMapping||[]])}}handleError(t){if(this.errors.push(t),this.config.errorHandling?.logErrors&&e.log.error(`${t.type}: ${t.message}${t.path?` at ${t.path}`:""}`),this.config.errorHandling?.throwOnError)throw new Error(`${t.type}: ${t.message}`)}getIndentation(){return this.config.formatting?.indentation||t}getEnumTypeName(e){return this.config.enmuConfig.erasableSyntaxOnly?`${e}Type`:e}typeNameToFileName(e){return e=(e=(e=e.replace(/_/g,"-")).replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()).replace(/-+/g,"-")}stringifySchemaResult(e){if(Array.isArray(e)){const t=this.config.formatting?.lineEnding??"\n",n=this.getIndentation();return`{${t}${e.join(t)}${t}${n}}`}return e}handleComplexType(e){try{return e.oneOf?e.oneOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" | "):e.allOf?e.allOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" & "):e.anyOf?e.anyOf.map(e=>this.stringifySchemaResult(this.schemaParse(e))).join(" | "):e.enum?"number"===e.type||"integer"===e.type?e.enum.join(" | "):e.enum.map(e=>`'${e}'`).join(" | "):"unknown"}catch(e){return this.handleError({type:"SCHEMA",message:"Failed to handle complex type",details:e}),"unknown"}}propertiesParse(e){if(!e)return[];const n=[];for(const r in e){const s=e[r],a=this.schemaParse(s);let i="";i=Array.isArray(a)?`${t}${t}${r}: {${a.join("\n")}};`:`${t}${t}${r}: ${a};`,n.push(i)}return n}nonArraySchemaObjectParse(e){if(!e)return"unknown";if("binary"===e.format||"string"===e.type&&"binary"===e.format)return"File";switch(e.type){case"boolean":return"boolean";case"integer":case"number":return"number";case"object":return this.propertiesParse(e.properties);case"string":return"binary"===e.format?"File":"string";default:return"unknown"}}arraySchemaObjectParse(e){if("array"!==e.type)return"";const{items:t}=e,n="$ref"in t?t:null,r=t;if(n){return`Array<${this.referenceObjectParse(n)}>`}if(r){const e=this.schemaParse(t);return Array.isArray(e)?`Array<{${e.join("\n")}}>`:`Array<${e}>`}return""}referenceObjectParse(e){try{const t=e.$ref,n=this.referenceCache.get(t);if(n)return n;let r=t;t.startsWith(s)&&(r=t.replace(s,"")),t.startsWith(a)&&(r=t.replace(a,"")),t.startsWith(i)&&(r=t.replace(i,""));const o=this.typeNameToFileName(r),c=/enum/gi.test(r),p=this.schemas?.[r],l=p&&"enum"in p&&Array.isArray(p.enum),h=c||l,y=h?this.getEnumTypeName(r):r,m=h?`import('${this.config.importEnumPath}/${o}').${y}`:`import('../models/${o}').${r}`;return this.referenceCache.set(t,m),m}catch(e){return this.handleError({type:"REFERENCE",message:"Failed to parse reference object",details:e}),"unknown"}}schemaParse(e){try{if(!e)return"unknown";if("oneOf"in e||"allOf"in e||"anyOf"in e||"enum"in e)return this.handleComplexType(e);if("$ref"in e)return this.referenceObjectParse(e);const t=e,n=t.type,r=!0===t.nullable?" | null":"";if(e.format&&this.config.typeMapping?.has(e.format))return this.config.typeMapping.get(e.format)+r;if(n&&this.config.typeMapping?.has(n))return this.config.typeMapping.get(n)+r;if("array"===n&&t.items){const e=this.schemaParse(t.items);if(Array.isArray(e)){const t=this.config.formatting?.lineEnding,n=this.config.formatting?.indentation;return`Array<{${t}${e.join("\n")}${t}${n}${n}}>`}return`Array<${e}>`}if("object"===n||"object"==typeof t){if(t.properties){const e=this.propertiesParse(t.properties);return e.length?e:["unknown"]}if(!0===t.additionalProperties)return"Record<string, unknown>"+r;if("object"==typeof t.additionalProperties){return`Record<string, ${this.schemaParse(t.additionalProperties)}>`+r}}return"unknown"}catch(e){return this.handleError({type:"SCHEMA",message:"Failed to parse schema",details:e}),"unknown"}}responseObjectParse(e){try{const t=e.content;if(!t)return"";let n;for(const e of o)if(t[e]?.schema){n=t[e].schema;break}return n?this.schemaParse(n):""}catch(e){return this.handleError({type:"RESPONSE",message:"Failed to parse response object",details:e}),""}}responseHandle(e){const t=e[200];if(!t)return;const n="content"in t?t:null,r="$ref"in t?t:null;if(null===n&&null===r&&(this.contentBody.response="type Response = unknown",this.contentBody._response="unknown"),r){const e=this.referenceObjectParse(r);this.contentBody.response=`type Response = ${e}`,this.contentBody._response=e}if(n){const e=this.responseObjectParse(n);if(Array.isArray(e)){if(1===e.length&&"unknown"===e[0])this.contentBody.response=`type Response = ${e.join("\n")};`;else{const t=this.config.formatting?.lineEnding,n=this.config.formatting?.indentation;this.contentBody.response=`interface Response {${t}${e.join("\n")}${t}${n}};`}this.contentBody._response=`${e.join("\n")}`}else this.contentBody.response=`type Response = ${e}`,this.contentBody._response=`${e}`}}requestBodyObjectParse(e){const n=Object.values(e.content),{schema:r}=n[0]||{schema:null};if(r){const e=r?.type,n="$ref"in r?r:null,s="array"===e?r:null,a=e&&this.nonArrayType.includes(e)?r:null;if(n){const e=this.referenceObjectParse(n);return`${t}type Body = ${e}`}if(s){const e=this.arraySchemaObjectParse(s);return`${t}type Body = ${e}`}if(a){const e=this.nonArraySchemaObjectParse(a);return Array.isArray(e)?0===e.length?[`${t}type Body = ${a.type};`]:[`${t}interface Body {`,...e.map(e=>e.replace(/: string;/,": File;")),"}"]:[`${t}type Body = ${e}`]}}}requestBodyParse(e){if(!e)return"{}";const n="$ref"in e?e:null,r="content"in e?e:null;if(n){const e=this.referenceObjectParse(n);return`${t}type Body = ${e}`}return r&&"[object Object]"===String(e)&&0!==Reflect.ownKeys(e).length?this.requestBodyObjectParse(r):"{}"}parametersItemHandle(e,n,r){const s="$ref"in e?e:null,i="name"in e?e:null;if(s&&s.$ref&&s.$ref.startsWith(a)&&this.parameters){const e=s.$ref.replace(a,""),t=this.parameters[e];this.parametersItemHandle(t,n,r)}if(i){if("path"===i.in){const e=this.schemaParse(i.schema);n.push(`${t}${t}type ${i.name} = ${e};`),this.contentBody.payload._path?"string"==typeof e?this.contentBody.payload._path[i.name]=e:console.log("Unexpected v2value type:",e):"string"==typeof e?this.contentBody.payload._path={[i.name]:e}:console.log("Unexpected v2value type:",e)}if("query"===i.in){const e=this.schemaParse(i.schema);r.push(`${t}${t}${i.name}: ${e};`),this.contentBody.payload._query?"string"==typeof e?this.contentBody.payload._query[i.name]=e:console.log("Unexpected v2value type:",e):"string"==typeof e?this.contentBody.payload._query={[i.name]:e}:console.log("Unexpected v2value type:",e)}}}requestParametersParse(e){const n=[],r=[];e?.map(e=>this.parametersItemHandle(e,n,r)),0!==n.length&&(n.unshift(`${t}namespace Path {`),n.push(`${t}}`)),0!==r.length&&(r.unshift(`${t}interface Query {`),r.push(`${t}}`)),this.contentBody.payload.path=n,this.contentBody.payload.query=r}requestHandle(e){if(e.parameters&&this.requestParametersParse(e.parameters),e.requestBody){const t=this.requestBodyParse(e.requestBody);if(Array.isArray(t))this.contentBody.payload.body=t;else if(t){const e=t?.split("\n")||[];this.contentBody.payload.body=e}}}apiRequestItemHandle(e){const{payload:t,requestPath:n,_response:r,method:s,typeName:a,apiName:i,contentType:o}=e,{_path:p,_query:l,body:h}=t,y=(()=>{const e=[];for(const t in p)e.push(`${t}: ${a}.Path.${t}`);const t=e.join(e.length>1?",":"");return""===t?t:t+","})(),m=(()=>{const e=l?`query: ${a}.Query,`:"";return""===e?"":`${e}`})(),u=(()=>{const e=h.length>0?`body: ${a}.Body,`:"";return""===e?"":`${e}`})(),d=(y+m+u).replace(/,$/,"");return[`export const ${i} = `,"(",d,""===d?"params?: IRequestFnParams":", params?: IRequestFnParams",")"," => ",s,""+(r?`<${a}.Response>`:""),"(","`"+n+"`,",(()=>{const e=c.includes(o)?`headers: { 'Content-Type': '${o}' }`:void 0;return["{",e?`${e},`:"","...params, ",""===m?"":"query,",""===u?"":"body,","},"].join("")})(),`'${this.config.dataLevel}'`,");"].join("")}parsePathItemObject(e,t){if(e)for(const n in e){const r=e[n];if(r){if(this.config.includeInterface&&this.config.includeInterface.length>0){const e=this.config.includeInterface?.find(e=>t.includes(e.path)&&e.method===n);if(!e)return}else if(this.config.excludeInterface&&this.config.excludeInterface.length>0){const e=this.config.excludeInterface?.find(e=>t.includes(e.path)&&e.method===n);if(e)return}const e=n.toUpperCase(),s=t+"|"+e,{apiName:a,typeName:i,fileName:c,path:p}=this.convertEndpointString(s),l=r.requestBody&&"content"in r.requestBody&&r.requestBody.content,h="object"==typeof l?Object.keys(l)[0]:"application/json";this.contentBody={payload:{path:[],query:[],body:[]},response:"",_response:"",fileName:c,method:e,typeName:i,requestPath:p,apiName:a,summary:r.summary,deprecated:r.deprecated??!1,contentType:o.includes(h)?h:"application/json"},this.requestHandle(r),this.responseHandle(r.responses),this.Map.has(s)||this.Map.set(s,JSON.parse(JSON.stringify(this.contentBody)))}}}cleanSegment(e){let t=e.replace(/^[0-9]+/,"");return t?(t=t.replace(/[^a-zA-Z0-9_.-]/g,""),t):"num"+e}toCamelCase(e,t=!1){const n=this.cleanSegment(e).split(/[-_.]+/).filter(e=>e.length>0);return 0===n.length?"":n.map((e,n)=>0===n&&t?e.toLowerCase():e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}toPascalCase(e){const t=this.cleanSegment(e).split(/[-_.]+/).filter(e=>e.length>0);return 0===t.length?"":t.map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join("")}convertEndpointString(e){let t=e;e.startsWith("/")||(t="/"+e);const[n,r]=t.split("|");let s="";this.config.publicPrefix&&(s=this.config.publicPrefix.replace(/^\/+|\/+$/g,""));let a=n.replace(/^\/+/,"");if(s&&a.startsWith(s+"/"))a=a.slice(s.length+1);else if(s&&a===s)a="";else if(s&&a.startsWith(s)){const e=a.slice(s.length);(e.startsWith("/")||""===e)&&(a=e.replace(/^\/+/,""))}const i=a?a.split("/").filter(e=>e):[],o=i.map(e=>{if(e.startsWith("{")&&e.endsWith("}")){const t=e.slice(1,-1);return{type:"param",original:e,normalized:t}}return{type:"normal",original:e,normalized:e}}),c=[];for(let e=0;e<o.length;e++){const t=o[e],n=o[e+1];if("normal"===t.type&&n&&"param"===n.type){if(this.cleanSegment(t.normalized).toLowerCase().replace(/[-_.]/g,"")===this.cleanSegment(n.normalized).toLowerCase().replace(/[-_.]/g,""))continue}c.push(t)}const p=this.config.parameterSeparator||"_";let l="",h=[];const y=e=>{if(h.length>0){const t=h.map((t,n)=>this.toCamelCase(t,e&&0===n)).join("");l+=(l&&h.length>0?p:"")+t,h=[]}};for(let e=0;e<c.length;e++){const t=c[e];if("normal"===t.type)h.push(t.normalized);else{y(""===l);const e=this.cleanSegment(t.normalized);l+=(l?p:"")+e}}y(""===l);let m="";h=[];const u=()=>{if(h.length>0){const e=h.map(e=>this.toPascalCase(e)).join("");m+=(m&&h.length>0?p:"")+e,h=[]}};for(let e=0;e<c.length;e++){const t=c[e];if("normal"===t.type)h.push(t.normalized);else{u();const e=this.toPascalCase(t.normalized);m+=(m?p:"")+e}}u();let d="";i.length>0?(d=i.map(e=>e.replace(/[{}]/g,"")).join("-"),d=`${d}-${r}`.toLowerCase()):d=`${r}`.toLowerCase();let f="/"+a;a||(f="/"),f=f.replace(/\{(\w+)\}/g,(e,t)=>`\${${t}}`);return{apiName:l?`${l}_${r}`:r,fileName:d,typeName:m?`${m}_${r}`:r,path:f}}parseData(){return new Promise((e,t)=>{try{for(const e in this.pathsObject){const t=this.pathsObject[e];t&&this.parsePathItemObject(t,e)}e(this.Map)}catch(e){this.handleError({type:"SCHEMA",message:"Failed to parse schema",details:e}),t(e)}})}async writeFile(){const n=[],r=[],s=this.config.saveTypeFolderPath,a=[],i=(n,i)=>new Promise((o,c)=>{try{const{payload:p,response:l,fileName:h,summary:y,typeName:m,deprecated:u}=i,[,d]=n.split("|");!a.includes(d)&&a.push(d);const f=[`declare namespace ${m} {`,...p.path,...p.query,...p.body,`${t}${l}`,"}"];y&&r.push(["/**","\n",u?` * @deprecated ${y}`:` * ${y}`,"\n"," */"].join(""));const g=this.apiRequestItemHandle(i);r.push(g,"");const $=`${s}/connectors/${h}.d.ts`;e.writeFileRecursive($,f.join("\n")).then(()=>{e.log.info(`${$.padEnd(80)} - Write done!`),o(1)}).catch(e=>{this.handleError({type:"FILE_WRITE",message:"Failed to write type definition file",path:h,details:e}),c(e)})}catch(e){this.handleError({type:"PATH",message:"Failed to process path item",path:n,details:e}),c(e)}});for(const[e,t]of this.Map)n.push(i(e,t));try{await Promise.all(n),e.log.success("Path parse & write done!"),r.unshift(`import { ${a.join(", ")} } from '${this.config.requestMethodsImportPath||"./api"}';`,"\n"),await e.clearDir(this.config.saveApiListFolderPath+"/index.ts"),await e.writeFileRecursive(this.config.saveApiListFolderPath+"/index.ts",r.join("\n")),this.Map=new Map,this.errors.length>0&&e.log.warning(`Completed with ${this.errors.length} errors`)}catch(e){throw this.handleError({type:"FILE_WRITE",message:"Failed to write API list file",details:e}),e}}async handle(){try{await this.parseData(),await this.writeFile()}catch(e){if(this.handleError({type:"SCHEMA",message:"Failed to handle schema",details:e}),this.config.errorHandling?.throwOnError)throw e}}}exports.PathParse=p,exports.default=p;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("fs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("fs"),a=require("../utils/index.js"),t=require("./core/components.js"),s=require("./core/get-data.js"),r=require("./core/path.js"),o=require("shelljs"),n=require("chalk"),i=require("path");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var c=l(e),d=l(n),u=l(i);let p;const f="development"===process.env.NODE_ENV,g={saveTypeFolderPath:f?"apps/types":"src/api/types",saveApiListFolderPath:f?"apps/types":"src/api",saveEnumFolderPath:f?"apps/types/enums":"src/enums",importEnumPath:"../../../enums",requestMethodsImportPath:"./fetch",publicPrefix:"/api",dataLevel:"serve",swaggerJsonUrl:"https://generator3.swagger.io/openapi.json",headers:{},formatting:{indentation:"\t",lineEnding:"\n"},includeInterface:[],excludeInterface:[],parameterSeparator:"_",enmuConfig:{erasableSyntaxOnly:!1,varnames:"enum-varnames",comment:"enum-descriptions"}};class h{schemas={};paths={};async handle(e){try{let a;if(a=f?(await Promise.resolve().then(function(){return require("../../data/openapi.json.js")})).default:await s.getSwaggerJson(e),!a)throw new Error("无法获取 Swagger 数据");this.schemas=a.components?.schemas||{},this.paths=a.paths||{};const o=new t.default(this.schemas,e),n=new r.PathParse(this.paths,a.components?.parameters,this.schemas,e);return await o.handle(),await n.handle(),!0}catch(e){if(e instanceof Error)throw new Error(`Handle Swagger data failed: ${e.message}`);throw new Error("Handle Swagger data failed: unknown error")}}async formatGeneratedFiles(e){const t=`npx prettier --write "${e.saveTypeFolderPath}/**/*.{ts,d.ts}"`;try{await c.default.promises.access(e.saveTypeFolderPath);const{stderr:s}=await new Promise((e,a)=>{o.exec(t,(t,s,r)=>{t?a(t):e({stdout:s,stderr:r})})});s&&(console.log("\n"),console.log("$",d.default.yellow(t)),console.log("\n")),a.log.success("File formatting successful"),console.log("\n")}catch(e){console.log(""),console.log(e),a.log.error("Format failed, please manually execute the following command:"),console.log("$",d.default.yellow(t)),console.log("")}}async copyAjaxConfigFiles(e){try{const t=["config.ts","error-message.ts","fetch.ts","api-type.d.ts"],s=f?u.default.join(__dirname,"..","..","postbuild-assets","ajax-config"):u.default.join(__dirname,"..","..","ajax-config"),r=e;for(const e of t){const t=u.default.join(s,e),o=u.default.join(r,e);try{await c.default.promises.access(t);try{await c.default.promises.access(o),a.log.info(`${e} already exists, skipping generation.`)}catch{await c.default.promises.copyFile(t,o),a.log.success(`${e} create done.`)}}catch(e){a.log.error(`Source file ${t} does not exist`);continue}}}catch(e){return e}}async getConfig(e){try{const a=await c.default.promises.readFile(e,"utf8");return p=!0,JSON.parse(a)}catch(t){return p=!1,a.log.warning("Config file does not exist, will automatically create config file."),await a.writeFileRecursive(e,JSON.stringify(g,null,2)),a.log.success("Please check the an.config.json file in the project root directory"),g}}async initialize(){const e=process.cwd()+"/an.config.json";try{const t=await this.getConfig(e);if(!p)return;await c.default.promises.mkdir(t.saveApiListFolderPath,{recursive:!0}),await this.copyAjaxConfigFiles(t.saveApiListFolderPath),await a.clearDir(t.saveTypeFolderPath),await a.clearDir(t.saveEnumFolderPath),await this.handle(t),await this.formatGeneratedFiles(t),a.log.success("Successfully, all done, see you next time!"),console.log("\n")}catch(e){const t=e instanceof Error?e.message:"Unknown error";a.log.error(`Initialization failed: ${t}`)}}}if("development"===process.env.NODE_ENV){(new h).initialize()}exports.Main=h;
|