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 CHANGED
@@ -123,29 +123,35 @@ $ anl type
123
123
  }
124
124
  ],
125
125
  "publicPrefix": "api",
126
- "erasableSyntaxOnly": false,
127
- "parameterSeparator": "_"
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 | string | نعم | مسار حفظ ملفات تعريف الأنواع |
136
- | saveApiListFolderPath | string | نعم | مسار حفظ ملفات دوال طلبات API |
137
- | saveEnumFolderPath | string | نعم | مسار حفظ ملفات بيانات التعداد |
138
- | importEnumPath | string | نعم | مسار استيراد التعداد (مسار ملف enum المُشار إليه في apps/types/models/\*.ts) |
139
- | swaggerJsonUrl | string | نعم | عنوان مستند Swagger JSON |
140
- | requestMethodsImportPath | string | نعم | مسار استيراد طرق الطلب |
141
- | dataLevel | 'data' \| 'serve' \| 'axios' | نعم | مستوى بيانات استجابة الواجهة |
142
- | formatting | object | لا | تكوين تنسيق الكود |
143
- | headers | object | لا | تكوين رأس الطلب |
144
- | includeInterface | Array<{path: string, method: string}> | لا | الواجهات المضمنة: ملف قائمة الواجهات المحدد بـ `saveApiListFolderPath` سيتضمن فقط الواجهات في القائمة، متعارض مع حقل `excludeInterface` |
145
- | excludeInterface | Array<{path: string, method: string}> | لا | الواجهات المستبعدة: نص قائمة الواجهات المحدد بـ `saveApiListFolderPath` لن يتضمن الواجهات في هذه القائمة، متعارض مع `includeInterface` |
146
- | publicPrefix | string | لا | البادئة العامة على مسار url، على سبيل المثال: api/users، api/users/{id}، api هي البادئة العامة |
147
- | erasableSyntaxOnly | boolean | نعم | يتوافق مع خيار `compilerOptions.erasableSyntaxOnly` في tsconfig.json. عندما يكون `true`، يتم إنشاء كائن const بدلاً من enum (صيغة النوع فقط). القيمة الافتراضية: `false` |
148
- | parameterSeparator | string | لا | الفاصل المستخدم بين أجزاء المسار والمعاملات عند إنشاء أسماء API وأسماء الأنواع. على سبيل المثال، `/users/{userId}/posts` مع الفاصل `'_'` ينشئ `users_userId_posts_GET`. القيمة الافتراضية: `'_'` |
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
- "erasableSyntaxOnly": false,
125
- "parameterSeparator": "_"
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 | Tipo | Requerido | Descripción |
132
- | ------------------------- | ------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
133
- | saveTypeFolderPath | string | Sí | Ruta de guardado de archivos de definición de tipos |
134
- | saveApiListFolderPath | string | Sí | Ruta de guardado de archivos de funciones de solicitud API |
135
- | saveEnumFolderPath | string | Sí | Ruta de guardado de archivos de datos enum |
136
- | importEnumPath | string | Sí | Ruta de importación de enum (ruta de referencia de archivos enum en apps/types/models/\*.ts) |
137
- | swaggerJsonUrl | string | Sí | Dirección del documento Swagger JSON |
138
- | requestMethodsImportPath | string | Sí | Ruta de importación de métodos de solicitud |
139
- | dataLevel | 'data' \| 'serve' \| 'axios' | Sí | Nivel de datos de retorno de interfaz |
140
- | formatting | object | No | Configuración de formateo de código |
141
- | headers | object | No | Configuración de encabezados de solicitud |
142
- | 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` |
143
- | 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` |
144
- | publicPrefix | string | No | Prefijo público en la ruta URL, por ejemplo: api/users, api/users/{id}, api es el prefijo público |
145
- | 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` |
146
- | 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: `'_'` |
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
- "erasableSyntaxOnly": false,
127
- "parameterSeparator": "_"
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 | Type | Obligatoire | Description |
134
- | ------------------------ | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
135
- | saveTypeFolderPath | string | Oui | Chemin de sauvegarde des fichiers de définition de types |
136
- | saveApiListFolderPath | string | Oui | Chemin de sauvegarde des fichiers de fonctions de requête API |
137
- | saveEnumFolderPath | string | Oui | Chemin de sauvegarde des fichiers de données enum |
138
- | importEnumPath | string | Oui | Chemin d'import enum (chemin des fichiers enum référencés dans apps/types/models/\*.ts) |
139
- | swaggerJsonUrl | string | Oui | Adresse du document Swagger JSON |
140
- | requestMethodsImportPath | string | Oui | Chemin d'import des méthodes de requête |
141
- | dataLevel | 'data' \| 'serve' \| 'axios' | Oui | Niveau de données retournées par l'interface |
142
- | formatting | object | Non | Configuration du formatage du code |
143
- | headers | object | Non | Configuration des en-têtes de requête |
144
- | 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` |
145
- | 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` |
146
- | publicPrefix | string | Non | Préfixe commun sur le chemin URL, par exemple : api/users, api/users/{id}, api est le préfixe commun |
147
- | 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` |
148
- | 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 : `'_'` |
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
- "erasableSyntaxOnly": false,
127
- "parameterSeparator": "_"
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 | string | はい | 型定義ファイルの保存パス |
136
- | saveApiListFolderPath | string | はい | API リクエスト関数ファイルの保存パス |
137
- | saveEnumFolderPath | string | はい | 列挙データファイルの保存パス |
138
- | importEnumPath | string | はい | 列挙型インポートパス(apps/types/models/\*.ts で enum ファイルを参照するパス) |
139
- | swaggerJsonUrl | string | はい | Swagger JSON ドキュメントのアドレス |
140
- | requestMethodsImportPath | string | はい | リクエストメソッドのインポートパス |
141
- | dataLevel | 'data' \| 'serve' \| 'axios' | はい | インターフェースレスポンスデータのレベル |
142
- | formatting | object | いいえ | コードフォーマット設定 |
143
- | headers | object | いいえ | リクエストヘッダー設定 |
144
- | includeInterface | Array<{path: string, method: string}> | いいえ | 含めるインターフェース:`saveApiListFolderPath` で指定されたインターフェースリストファイルには、このリストに含まれるインターフェースのみが含まれます。`excludeInterface` フィールドと相互排他的です |
145
- | excludeInterface | Array<{path: string, method: string}> | いいえ | 除外するインターフェース:`saveApiListFolderPath` で指定されたインターフェースリストテキストには、このリストに含まれないインターフェースが含まれます。`includeInterface` と相互排他的です |
146
- | publicPrefix | string | いいえ | URL パス上の共通プレフィックス、例:api/users、api/users/{id}、api が共通プレフィックスです |
147
- | erasableSyntaxOnly | boolean | はい | tsconfig.json の `compilerOptions.erasableSyntaxOnly` オプションと一致させます。`true` の場合、enum ではなく const オブジェクトを生成します(型のみの構文)。デフォルト値:`false` |
148
- | parameterSeparator | string | いいえ | API 名と型名を生成する際に、パスセグメントとパラメータの間に使用される区切り文字。例えば、`/users/{userId}/posts` に区切り文字 `'_'` を使用すると `users_userId_posts_GET` が生成されます。デフォルト値:`'_'` |
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
- "erasableSyntaxOnly": false,
125
- "parameterSeparator": "_"
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 | boolean | Yes | Align with tsconfig.json `compilerOptions.erasableSyntaxOnly`. When `true`, generates const objects instead of enums (type-only syntax). Default: `false` |
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
- "erasableSyntaxOnly": false,
127
- "parameterSeparator": "_"
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 | string | Да | Путь сохранения файлов определений типов |
136
- | saveApiListFolderPath | string | Да | Путь сохранения файлов функций API-запросов |
137
- | saveEnumFolderPath | string | Да | Путь сохранения файлов данных enum |
138
- | importEnumPath | string | Да | Путь импорта enum (путь ссылки на файлы enum в apps/types/models/\*.ts) |
139
- | swaggerJsonUrl | string | Да | Адрес документа Swagger JSON |
140
- | requestMethodsImportPath | string | Да | Путь импорта методов запросов |
141
- | dataLevel | 'data' \| 'serve' \| 'axios' | Да | Уровень данных возврата интерфейса |
142
- | formatting | object | Нет | Конфигурация форматирования кода |
143
- | headers | object | Нет | Конфигурация заголовков запроса |
144
- | includeInterface | Array<{path: string, method: string}> | Нет | Включаемые интерфейсы: файл списка интерфейсов, указанный `saveApiListFolderPath`, будет включать только интерфейсы из списка, взаимоисключающий с полем `excludeInterface` |
145
- | excludeInterface | Array<{path: string, method: string}> | Нет | Исключаемые интерфейсы: файл списка интерфейсов, указанный `saveApiListFolderPath`, не будет содержать интерфейсы из этого списка, взаимоисключающий с `includeInterface` |
146
- | publicPrefix | string | Нет | Общий префикс на url path, например: api/users、api/users/{id} ,api является общим префиксом |
147
- | erasableSyntaxOnly | boolean | Да | Соответствует опции `compilerOptions.erasableSyntaxOnly` в tsconfig.json. При значении `true` генерируется const объект вместо enum (только типовый синтаксис). Значение по умолчанию: `false` |
148
- | parameterSeparator | string | Нет | Разделитель между сегментами пути и параметрами при генерации имен API и имен типов. Например, `/users/{userId}/posts` с разделителем `'_'` генерирует `users_userId_posts_GET`. Значение по умолчанию: `'_'` |
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
- "erasableSyntaxOnly": false,
127
- "parameterSeparator": "_"
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 | string | 是 | 类型定义文件保存路径 |
136
- | saveApiListFolderPath | string | 是 | API 请求函数文件保存路径 |
137
- | saveEnumFolderPath | string | 是 | 枚举数据文件保存路径 |
138
- | importEnumPath | string | 是 | 枚举导入路径(apps/types/models/\*.ts 中 enum 文件的引用的路径) |
139
- | swaggerJsonUrl | string | 是 | Swagger JSON 文档地址 |
140
- | requestMethodsImportPath | string | 是 | 请求方法导入路径 |
141
- | dataLevel | 'data' \| 'serve' \| 'axios' | 是 | 接口返回数据层级 |
142
- | formatting | object | 否 | 代码格式化配置 |
143
- | headers | object | 否 | 请求头配置 |
144
- | includeInterface | Array<{path: string, method: string}> | 否 | 包含的接口:`saveApiListFolderPath`指定的接口列表文件,只会包含列表中的接口,与 `excludeInterface` 字段互斥 |
145
- | excludeInterface | Array<{path: string, method: string}> | 否 | 排除的接口: `saveApiListFolderPath` 指定的接口列表文本,不存在该列表中的接口,与 `includeInterface` 互斥 |
146
- | publicPrefix | string | 否 | url path 上的公共前缀,例如:api/users、api/users/{id} ,api 就是公共前缀 |
147
- | erasableSyntaxOnly | boolean | 是 | 与 tsconfig.json 的 `compilerOptions.erasableSyntaxOnly` 选项保持一致。为 `true` 时,生成 const 对象而非 enum(仅类型语法)。默认值:`false` |
148
- | parameterSeparator | string | 否 | 生成 API 名称和类型名称时,路径段和参数之间使用的分隔符。例如,`/users/{userId}/posts` 使用分隔符 `'_'` 会生成 `users_userId_posts_GET`。默认值:`'_'` |
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 = {
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e="25.1202.0",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
+ "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"),t=require("../utils/index.js"),a=require("./core/components.js"),s=require("./core/get-data.js"),r=require("./core/path.js"),o=require("shelljs"),i=require("chalk"),n=require("path");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var c=l(e),d=l(i),u=l(n);let p;const f="development"===process.env.NODE_ENV,h={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:[],erasableSyntaxOnly:!1,parameterSeparator:"_"};class g{schemas={};paths={};async handle(e){try{let t;if(t=f?(await Promise.resolve().then(function(){return require("../../data/openapi.json.js")})).default:await s.getSwaggerJson(e),!t)throw new Error("无法获取 Swagger 数据");this.schemas=t.components?.schemas||{},this.paths=t.paths||{};const o=new a.default(this.schemas,e),i=new r.PathParse(this.paths,t.components?.parameters,this.schemas,e);return await o.handle(),await i.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 a=`npx prettier --write "${e.saveTypeFolderPath}/**/*.{ts,d.ts}"`;try{await c.default.promises.access(e.saveTypeFolderPath);const{stderr:s}=await new Promise((e,t)=>{o.exec(a,(a,s,r)=>{a?t(a):e({stdout:s,stderr:r})})});s&&(console.log("\n"),console.log("$",d.default.yellow(a)),console.log("\n")),t.log.success("File formatting successful"),console.log("\n")}catch(e){console.log(""),console.log(e),t.log.error("Format failed, please manually execute the following command:"),console.log("$",d.default.yellow(a)),console.log("")}}async copyAjaxConfigFiles(e){try{const a=["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 a){const a=u.default.join(s,e),o=u.default.join(r,e);try{await c.default.promises.access(a);try{await c.default.promises.access(o),t.log.info(`${e} already exists, skipping generation.`)}catch{await c.default.promises.copyFile(a,o),t.log.success(`${e} create done.`)}}catch(e){t.log.error(`Source file ${a} does not exist`);continue}}}catch(e){return e}}async getConfig(e){try{const t=await c.default.promises.readFile(e,"utf8");return p=!0,JSON.parse(t)}catch(a){return p=!1,t.log.warning("Config file does not exist, will automatically create config file."),await t.writeFileRecursive(e,JSON.stringify(h,null,2)),t.log.success("Please check the an.config.json file in the project root directory"),h}}async initialize(){const e=process.cwd()+"/an.config.json";try{const a=await this.getConfig(e);if(!p)return;await c.default.promises.mkdir(a.saveApiListFolderPath,{recursive:!0}),await this.copyAjaxConfigFiles(a.saveApiListFolderPath),await t.clearDir(a.saveTypeFolderPath),await t.clearDir(a.saveEnumFolderPath),await this.handle(a),await this.formatGeneratedFiles(a),t.log.success("Successfully, all done, see you next time!"),console.log("\n")}catch(e){const a=e instanceof Error?e.message:"Unknown error";t.log.error(`Initialization failed: ${a}`)}}}if("development"===process.env.NODE_ENV){(new g).initialize()}exports.Main=g;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anl",
3
- "version": "25.1202.0",
3
+ "version": "25.1203.1",
4
4
  "description": "FE command line tool",
5
5
  "main": "bin/an-cli.js",
6
6
  "publishConfig": {