swgto-ts 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,147 +1,147 @@
1
- # swgto
2
-
3
- `swgto` 是一个把 `OpenAPI 3.x` 文档转换成项目内请求函数的 Node.js 库和 CLI。
4
-
5
- 安装后会注册一个 `swgto` 命令。执行时它会在当前目录查找 `.swaggerts.config.ts` 或 `.swaggerts.config.js`,然后生成:
6
-
7
- - 按路径前缀分组的请求文件
8
- - 按文档模块输出请求文件。单文档默认输出到 `services/`,多文档时多个模块目录平级
9
- - `outputDir/index.ts` 或 `outputDir/index.js`
10
- - 类型文件 `outputDir/types.ts` 或带 JSDoc 的 `outputDir/types.js`
11
-
12
- ## 安装
13
-
14
- ```bash
15
- npm install swgto-ts
16
- ```
17
-
18
- ## 配置
19
-
20
- 在项目根目录创建 `.swaggerts.config.ts`:
21
-
22
- ```ts
23
- import type { SwaggerTsConfig } from 'swgto-ts'
24
-
25
- const config: SwaggerTsConfig = {
26
- docUrls: 'https://example.com/openapi.json',
27
- httpClientPath: '@/utils/request',
28
- outputDir: 'src/api',
29
- outputType: 'ts',
30
- typeName: 'types',
31
- cleanOutput: true,
32
- renameMethod: (apiPath, method) => `${method}_${apiPath.replace(/[\\/{}]/g, '_')}`,
33
- resolveRequestPath: (apiPath, method) => `/proxy${apiPath}`,
34
- }
35
-
36
- export default config
37
- ```
38
-
39
- 多文档模式下需要提供 `moduleName`:
40
-
41
- ```ts
42
- export default {
43
- docUrls: ['https://example.com/user-openapi.json', 'https://example.com/order-openapi.json'],
44
- httpClientPath: '@/utils/request',
45
- outputDir: 'src/api',
46
- moduleName: (docUrl) => (docUrl.includes('user') ? 'user' : 'order'),
47
- }
48
- ```
49
-
50
- ## 使用
51
-
52
- ```bash
53
- swgto
54
- ```
55
-
56
- ## 输出示例
57
-
58
- ```text
59
- src/api/
60
- index.ts
61
- types.ts
62
- services/
63
- get_user_list.ts
64
- post_user_create.ts
65
- ```
66
-
67
- ## 配置项
68
-
69
- ```ts
70
- export interface SwaggerTsConfig {
71
- docUrls: string | string[]
72
- httpClientPath: string
73
- renameMethod?: (path: string, method: string) => string
74
- resolveRequestPath?: (path: string, method: string, docUrl: string) => string
75
- ignoreUrl?: (path: string, method: string, docUrl: string) => boolean
76
- outputDir?: string
77
- moduleName?: (docUrl: string) => string
78
- outputType?: 'ts' | 'js'
79
- typeName?: string
80
- cleanOutput?: boolean
81
- fileNaming?: 'module' | 'path'
82
- flattenQueryParam?: boolean
83
- mergeParams?: boolean
84
- }
85
- ```
86
-
87
- ### 字段说明
88
-
89
- | 字段 | 类型 | 默认值 | 说明 |
90
- | -------------------- | ----------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
91
- | `docUrls` | `string \| string[]` | (必填) | OpenAPI 3.x 文档的 URL,支持单文档字符串或多文档数组 |
92
- | `httpClientPath` | `string` | (必填) | 项目内 HTTP 请求工具的引入路径,生成的文件会从中 `import request` |
93
- | `outputDir` | `string` | `'src/api'` | 代码输出目录,相对项目根目录 |
94
- | `outputType` | `'ts' \| 'js'` | `'ts'` | 输出文件类型,`'ts'` 生成 `.ts` 文件,`'js'` 生成 `.js` 文件(带 JSDoc 类型注释) |
95
- | `typeName` | `string` | `'types'` | 类型文件名(不含后缀),如 `'types'` 生成 `types.ts` 或 `types.js` |
96
- | `fileNaming` | `'module' \| 'path'` | `'path'` | 文件组织方式:`'path'` 按接口路径每个文件一个函数;`'module'` 按控制器合并到同一个文件 |
97
- | `moduleName` | `(docUrl) => string` | `'services'` | 多文档时,为每个文档指定模块目录名。多文档模式下**必填** |
98
- | `renameMethod` | `(path, method) => string` | 见说明 | 自定义函数名生成规则。默认根据路径和方法名自动生成(如 `get_user_list`) |
99
- | `resolveRequestPath` | `(path, method, docUrl) => string` | 原路径 | 自定义请求路径转换规则,可用于添加统一前缀等,如 `(path) => \`/proxy\${path}\`` |
100
- | `ignoreUrl` | `(path, method, docUrl) => boolean` | 不过滤 | 过滤不需要生成代码的接口,返回 `true` 跳过当前接口 |
101
- | `cleanOutput` | `boolean` | `false` | 生成前是否清空输出目录 |
102
- | `flattenQueryParam` | `boolean` | `false` | 当 query 参数只有一个且为 `$ref` 引用类型时,直接用引用类型代替 `{ query: RefType }` |
103
- | `mergeParams` | `boolean` | `false` | 合并参数层级:`true` 时展平 `path/query/body` 嵌套,直接使用 `params: { field1, field2 }` 代替 `params: { path: {...}, query: {...} }` |
104
-
105
- ### 函数名生成规则
106
-
107
- 默认函数名格式为 `{method}_{path_segments}`,如:
108
-
109
- - `GET /user/list` → `get_user_list`
110
- - `POST /user/create` → `post_user_create`
111
-
112
- 可通过 `renameMethod` 自定义:
113
-
114
- ```ts
115
- renameMethod: (path, method) => `${method}_${path.replace(/[\\/{}]/g, '_')}`,
116
- ```
117
-
118
- ### 文件组织方式
119
-
120
- **`fileNaming: 'path'`(默认)**— 每个接口生成独立文件:
121
-
122
- ```
123
- src/api/moduleA/
124
- get_user_list.ts
125
- post_user_create.ts
126
- get_user_detail.ts
127
- ```
128
-
129
- **`fileNaming: 'module'`**— 按控制器合并文件(自动识别 RESTful 资源路径分组):
130
-
131
- ```
132
- src/api/moduleA/
133
- user.ts // 包含 get_user_list, post_user_create, get_user_detail
134
- order.ts // 包含 get_order_list, post_order_create
135
- ```
136
-
137
- ### 参数合并模式
138
-
139
- `mergeParams: true` 时展平参数层级,适用于不想嵌套 `path/query/body` 的场景:
140
-
141
- ```ts
142
- // mergeParams: false(默认),参数按来源嵌套
143
- getUser({ path: { id: '1' }, query: { name: 'foo' } })
144
-
145
- // mergeParams: true,参数展平
146
- getUser({ id: '1', name: 'foo' })
147
- ```
1
+ # swgto
2
+
3
+ `swgto` 是一个把 `OpenAPI 3.x` 文档转换成项目内请求函数的 Node.js 库和 CLI。
4
+
5
+ 安装后会注册一个 `swgto` 命令。执行时它会在当前目录查找 `.swaggerts.config.ts` 或 `.swaggerts.config.js`,然后生成:
6
+
7
+ - 按路径前缀分组的请求文件
8
+ - 按文档模块输出请求文件。单文档默认输出到 `services/`,多文档时多个模块目录平级
9
+ - `outputDir/index.ts` 或 `outputDir/index.js`
10
+ - 类型文件 `outputDir/types.ts` 或带 JSDoc 的 `outputDir/types.js`
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ npm install swgto-ts
16
+ ```
17
+
18
+ ## 配置
19
+
20
+ 在项目根目录创建 `.swaggerts.config.ts`:
21
+
22
+ ```ts
23
+ import type { SwaggerTsConfig } from 'swgto-ts'
24
+
25
+ const config: SwaggerTsConfig = {
26
+ docUrls: 'https://example.com/openapi.json',
27
+ httpClientPath: '@/utils/request',
28
+ outputDir: 'src/api',
29
+ outputType: 'ts',
30
+ typeName: 'types',
31
+ cleanOutput: true,
32
+ renameMethod: (apiPath, method) => `${method}_${apiPath.replace(/[\\/{}]/g, '_')}`,
33
+ resolveRequestPath: (apiPath, method) => `/proxy${apiPath}`,
34
+ }
35
+
36
+ export default config
37
+ ```
38
+
39
+ 多文档模式下需要提供 `moduleName`:
40
+
41
+ ```ts
42
+ export default {
43
+ docUrls: ['https://example.com/user-openapi.json', 'https://example.com/order-openapi.json'],
44
+ httpClientPath: '@/utils/request',
45
+ outputDir: 'src/api',
46
+ moduleName: (docUrl) => (docUrl.includes('user') ? 'user' : 'order'),
47
+ }
48
+ ```
49
+
50
+ ## 使用
51
+
52
+ ```bash
53
+ swgto
54
+ ```
55
+
56
+ ## 输出示例
57
+
58
+ ```text
59
+ src/api/
60
+ index.ts
61
+ types.ts
62
+ services/
63
+ get_user_list.ts
64
+ post_user_create.ts
65
+ ```
66
+
67
+ ## 配置项
68
+
69
+ ```ts
70
+ export interface SwaggerTsConfig {
71
+ docUrls: string | string[]
72
+ httpClientPath: string
73
+ renameMethod?: (path: string, method: string) => string
74
+ resolveRequestPath?: (path: string, method: string, docUrl: string) => string
75
+ ignoreUrl?: (path: string, method: string, docUrl: string) => boolean
76
+ outputDir?: string
77
+ moduleName?: (docUrl: string) => string
78
+ outputType?: 'ts' | 'js'
79
+ typeName?: string
80
+ cleanOutput?: boolean
81
+ fileNaming?: 'module' | 'path'
82
+ flattenQueryParam?: boolean
83
+ mergeParams?: boolean
84
+ }
85
+ ```
86
+
87
+ ### 字段说明
88
+
89
+ | 字段 | 类型 | 默认值 | 说明 |
90
+ | -------------------- | ----------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
91
+ | `docUrls` | `string \| string[]` | (必填) | OpenAPI 3.x 文档的 URL,支持单文档字符串或多文档数组 |
92
+ | `httpClientPath` | `string` | (必填) | 项目内 HTTP 请求工具的引入路径,生成的文件会从中 `import request` |
93
+ | `outputDir` | `string` | `'src/api'` | 代码输出目录,相对项目根目录 |
94
+ | `outputType` | `'ts' \| 'js'` | `'ts'` | 输出文件类型,`'ts'` 生成 `.ts` 文件,`'js'` 生成 `.js` 文件(带 JSDoc 类型注释) |
95
+ | `typeName` | `string` | `'types'` | 类型文件名(不含后缀),如 `'types'` 生成 `types.ts` 或 `types.js` |
96
+ | `fileNaming` | `'module' \| 'path'` | `'path'` | 文件组织方式:`'path'` 按接口路径每个文件一个函数;`'module'` 按控制器合并到同一个文件 |
97
+ | `moduleName` | `(docUrl) => string` | `'services'` | 多文档时,为每个文档指定模块目录名。多文档模式下**必填** |
98
+ | `renameMethod` | `(path, method) => string` | 见说明 | 自定义函数名生成规则。默认根据路径和方法名自动生成(如 `get_user_list`) |
99
+ | `resolveRequestPath` | `(path, method, docUrl) => string` | 原路径 | 自定义请求路径转换规则,可用于添加统一前缀等,如 `(path) => \`/proxy\${path}\`` |
100
+ | `ignoreUrl` | `(path, method, docUrl) => boolean` | 不过滤 | 过滤不需要生成代码的接口,返回 `true` 跳过当前接口 |
101
+ | `cleanOutput` | `boolean` | `false` | 生成前是否清空输出目录 |
102
+ | `flattenQueryParam` | `boolean` | `false` | 当 query 参数只有一个且为 `$ref` 引用类型时,直接用引用类型代替 `{ query: RefType }` |
103
+ | `mergeParams` | `boolean` | `false` | 合并参数层级:`true` 时展平 `path/query/body` 嵌套,直接使用 `params: { field1, field2 }` 代替 `params: { path: {...}, query: {...} }` |
104
+
105
+ ### 函数名生成规则
106
+
107
+ 默认函数名格式为 `{method}_{path_segments}`,如:
108
+
109
+ - `GET /user/list` → `get_user_list`
110
+ - `POST /user/create` → `post_user_create`
111
+
112
+ 可通过 `renameMethod` 自定义:
113
+
114
+ ```ts
115
+ renameMethod: (path, method) => `${method}_${path.replace(/[\\/{}]/g, '_')}`,
116
+ ```
117
+
118
+ ### 文件组织方式
119
+
120
+ **`fileNaming: 'path'`(默认)**— 每个接口生成独立文件:
121
+
122
+ ```
123
+ src/api/moduleA/
124
+ get_user_list.ts
125
+ post_user_create.ts
126
+ get_user_detail.ts
127
+ ```
128
+
129
+ **`fileNaming: 'module'`**— 按控制器合并文件(自动识别 RESTful 资源路径分组):
130
+
131
+ ```
132
+ src/api/moduleA/
133
+ user.ts // 包含 get_user_list, post_user_create, get_user_detail
134
+ order.ts // 包含 get_order_list, post_order_create
135
+ ```
136
+
137
+ ### 参数合并模式
138
+
139
+ `mergeParams: true` 时展平参数层级,适用于不想嵌套 `path/query/body` 的场景:
140
+
141
+ ```ts
142
+ // mergeParams: false(默认),参数按来源嵌套
143
+ getUser({ path: { id: '1' }, query: { name: 'foo' } })
144
+
145
+ // mergeParams: true,参数展平
146
+ getUser({ id: '1', name: 'foo' })
147
+ ```
@@ -1,5 +1,5 @@
1
1
  // src/generate.ts
2
- import path3 from "path";
2
+ import path4 from "path";
3
3
 
4
4
  // src/config/loadConfig.ts
5
5
  import { existsSync } from "fs";
@@ -74,8 +74,8 @@ function getPathMethods(operations) {
74
74
  }
75
75
  return map;
76
76
  }
77
- function deriveControllerName(path4, allPaths, pathMethods) {
78
- const segments = path4.split("/").filter(Boolean);
77
+ function deriveControllerName(path5, allPaths, pathMethods) {
78
+ const segments = path5.split("/").filter(Boolean);
79
79
  if (segments.length === 0) return "index";
80
80
  if (segments.length === 1) return segments[0];
81
81
  let effectiveLen = segments.length;
@@ -98,14 +98,14 @@ function deriveControllerName(path4, allPaths, pathMethods) {
98
98
  return segments[depth - 1];
99
99
  }
100
100
  const hasDirectSibling = [...allPaths].some((p) => {
101
- if (p === path4) return false;
101
+ if (p === path5) return false;
102
102
  if (!p.startsWith(ancestorPath + "/")) return false;
103
103
  const remaining = p.slice(ancestorPath.length + 1);
104
104
  return !remaining.includes("/");
105
105
  });
106
106
  if (hasDirectSibling) {
107
107
  const siblingIsRest = [...allPaths].some((p) => {
108
- if (p === path4) return false;
108
+ if (p === path5) return false;
109
109
  if (!p.startsWith(ancestorPath + "/")) return false;
110
110
  const remaining = p.slice(ancestorPath.length + 1);
111
111
  if (remaining.includes("/")) return false;
@@ -120,7 +120,7 @@ function deriveControllerName(path4, allPaths, pathMethods) {
120
120
  }
121
121
  const currentPath = "/" + segments.slice(0, depth + 1).join("/");
122
122
  const hasChildren = [...allPaths].some(
123
- (p) => p !== path4 && p.startsWith(currentPath + "/")
123
+ (p) => p !== path5 && p.startsWith(currentPath + "/")
124
124
  );
125
125
  if (hasChildren) {
126
126
  return resultName(segments, depth);
@@ -676,6 +676,64 @@ async function removeDir(dirPath) {
676
676
  }
677
677
  }
678
678
 
679
+ // src/utils/snapshot.ts
680
+ import path3 from "path";
681
+ import { readFile, writeFile as writeFile2 } from "fs/promises";
682
+ function buildKey(op) {
683
+ return `${op.docUrl}|${op.method}|${op.path}`;
684
+ }
685
+ function toEntry(op) {
686
+ return {
687
+ key: buildKey(op),
688
+ method: op.method,
689
+ path: op.path,
690
+ functionName: op.functionName,
691
+ summary: op.summary,
692
+ moduleName: op.moduleName
693
+ };
694
+ }
695
+ async function loadSnapshot(snapshotPath) {
696
+ const map = /* @__PURE__ */ new Map();
697
+ try {
698
+ const raw = await readFile(snapshotPath, "utf8");
699
+ const data = JSON.parse(raw);
700
+ if (data.version === 1) {
701
+ for (const entry of data.operations) {
702
+ map.set(entry.key, entry);
703
+ }
704
+ }
705
+ } catch {
706
+ }
707
+ return map;
708
+ }
709
+ async function saveSnapshot(snapshotPath, operations) {
710
+ const snapshot = {
711
+ version: 1,
712
+ operations: operations.map(toEntry)
713
+ };
714
+ await ensureDir(path3.dirname(snapshotPath));
715
+ await writeFile2(snapshotPath, JSON.stringify(snapshot, null, 2), "utf8");
716
+ }
717
+ function compareSnapshot(previous, current) {
718
+ const currentKeys = /* @__PURE__ */ new Set();
719
+ const newOperations = [];
720
+ for (const op of current) {
721
+ const key = buildKey(op);
722
+ currentKeys.add(key);
723
+ if (!previous.has(key)) {
724
+ newOperations.push(toEntry(op));
725
+ }
726
+ }
727
+ const removedOperations = [];
728
+ for (const [key, entry] of previous) {
729
+ if (!currentKeys.has(key)) {
730
+ removedOperations.push(entry);
731
+ }
732
+ }
733
+ return { newOperations, removedOperations };
734
+ }
735
+ var SNAPSHOT_FILE = ".swaggerts.cache.json";
736
+
679
737
  // src/generate.ts
680
738
  function getRootImportPath(typeName) {
681
739
  return `../${typeName}`;
@@ -684,8 +742,10 @@ async function generateFromConfig(cwd = process.cwd()) {
684
742
  const { configPath, config } = await loadConfig(cwd);
685
743
  const documentMap = /* @__PURE__ */ new Map();
686
744
  const operations = [];
745
+ const snapshotPath = path4.join(cwd, config.outputDir, SNAPSHOT_FILE);
746
+ const previousSnapshot = await loadSnapshot(snapshotPath);
687
747
  if (config.cleanOutput) {
688
- await removeDir(path3.join(cwd, config.outputDir));
748
+ await removeDir(path4.join(cwd, config.outputDir));
689
749
  console.log(`Cleaned output directory: ${config.outputDir}`);
690
750
  }
691
751
  for (const docUrl of config.docUrls) {
@@ -694,13 +754,14 @@ async function generateFromConfig(cwd = process.cwd()) {
694
754
  operations.push(...parsePaths(document, docUrl, config));
695
755
  }
696
756
  const grouped = groupByPrefix(operations);
757
+ const { newOperations, removedOperations } = compareSnapshot(previousSnapshot, operations);
697
758
  const files = [];
698
759
  for (const [moduleName, moduleOperations] of Object.entries(grouped)) {
699
760
  if (config.fileNaming === "module") {
700
761
  const controllerMap = groupByController(moduleOperations);
701
762
  for (const [controllerName, controllerOperations] of Object.entries(controllerMap)) {
702
- const relativeFile = path3.join(config.outputDir, moduleName, `${controllerName}.${config.outputType}`);
703
- const absoluteFile = path3.join(cwd, relativeFile);
763
+ const relativeFile = path4.join(config.outputDir, moduleName, `${controllerName}.${config.outputType}`);
764
+ const absoluteFile = path4.join(cwd, relativeFile);
704
765
  const content = config.outputType === "ts" ? generateTsModuleFile(controllerOperations, config.httpClientPath, getRootImportPath(config.typeName), config.mergeParams) : generateJsModuleFile(controllerOperations, config.httpClientPath, getRootImportPath(config.typeName), config.mergeParams);
705
766
  for (const op of controllerOperations) {
706
767
  op.fileBaseName = controllerName;
@@ -710,8 +771,8 @@ async function generateFromConfig(cwd = process.cwd()) {
710
771
  }
711
772
  } else {
712
773
  for (const operation of moduleOperations) {
713
- const relativeFile = path3.join(config.outputDir, moduleName, `${operation.fileBaseName}.${config.outputType}`);
714
- const absoluteFile = path3.join(cwd, relativeFile);
774
+ const relativeFile = path4.join(config.outputDir, moduleName, `${operation.fileBaseName}.${config.outputType}`);
775
+ const absoluteFile = path4.join(cwd, relativeFile);
715
776
  const content = config.outputType === "ts" ? generateTsRequestFile(operation, config.httpClientPath, getRootImportPath(config.typeName), config.mergeParams) : generateJsRequestFile(operation, config.httpClientPath, getRootImportPath(config.typeName), config.mergeParams);
716
777
  await writeTextFile(absoluteFile, content);
717
778
  files.push(relativeFile);
@@ -720,21 +781,24 @@ async function generateFromConfig(cwd = process.cwd()) {
720
781
  }
721
782
  const typesContent = generateTypesFile(documentMap, operations, config);
722
783
  const indexContent = generateIndexFile(operations, config);
723
- const typesFile = path3.join(cwd, config.outputDir, `${config.typeName}.${config.outputType === "ts" ? "ts" : "js"}`);
724
- const indexFile = path3.join(cwd, config.outputDir, `index.${config.outputType}`);
784
+ const typesFile = path4.join(cwd, config.outputDir, `${config.typeName}.${config.outputType === "ts" ? "ts" : "js"}`);
785
+ const indexFile = path4.join(cwd, config.outputDir, `index.${config.outputType}`);
725
786
  await writeTextFile(typesFile, typesContent);
726
787
  await writeTextFile(indexFile, indexContent);
727
788
  files.push(
728
- path3.relative(cwd, typesFile),
729
- path3.relative(cwd, indexFile)
789
+ path4.relative(cwd, typesFile),
790
+ path4.relative(cwd, indexFile)
730
791
  );
792
+ await saveSnapshot(snapshotPath, operations);
731
793
  return {
732
794
  configPath,
733
795
  files,
734
796
  operationCount: operations.length,
735
797
  moduleCount: Object.keys(grouped).length,
736
- apiFileCount: files.length - 2
798
+ apiFileCount: files.length - 2,
737
799
  // exclude types + index
800
+ newOperations,
801
+ removedOperations
738
802
  };
739
803
  }
740
804
 
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  generateFromConfig
4
- } from "./chunk-4OK6R2K5.js";
4
+ } from "./chunk-ZURWUVPF.js";
5
5
 
6
6
  // src/cli.ts
7
7
  async function main() {
@@ -13,6 +13,23 @@ async function main() {
13
13
  console.log(`Generated ${result.apiFileCount} api file(s), ${result.operationCount} operation(s) in ${result.moduleCount} module(s).`);
14
14
  console.log(`Wrote ${result.files.length} file(s) total (including types, index).`);
15
15
  console.log(`Done in ${elapsedMs}ms.`);
16
+ if (result.newOperations.length > 0) {
17
+ console.log(`
18
+ \u65B0\u589E ${result.newOperations.length} \u4E2A API:`);
19
+ const maxWidth = Math.max(...result.newOperations.map((op) => `${op.method.toUpperCase()} ${op.path}`.length));
20
+ for (const op of result.newOperations) {
21
+ const label = `${op.method.toUpperCase()} ${op.path}`.padEnd(maxWidth);
22
+ const desc = op.summary ? ` ${op.summary}` : "";
23
+ console.log(` ${label} -> ${op.functionName}${desc}`);
24
+ }
25
+ }
26
+ if (result.removedOperations.length > 0) {
27
+ console.log(`
28
+ \u79FB\u9664 ${result.removedOperations.length} \u4E2A API:`);
29
+ for (const op of result.removedOperations) {
30
+ console.log(` ${op.method.toUpperCase()} ${op.path} (${op.functionName})`);
31
+ }
32
+ }
16
33
  } catch (error) {
17
34
  const message = error instanceof Error ? error.message : String(error);
18
35
  console.error(`swgto failed: ${message}`);
package/dist/index.d.ts CHANGED
@@ -1,12 +1,3 @@
1
- interface GenerateResult {
2
- configPath: string;
3
- files: string[];
4
- operationCount: number;
5
- moduleCount: number;
6
- apiFileCount: number;
7
- }
8
- declare function generateFromConfig(cwd?: string): Promise<GenerateResult>;
9
-
10
1
  type OutputType = 'ts' | 'js';
11
2
  type RequestConfig = Record<string, unknown>;
12
3
  interface SwaggerTsConfig {
@@ -25,4 +16,25 @@ interface SwaggerTsConfig {
25
16
  mergeParams?: boolean;
26
17
  }
27
18
 
19
+ interface SnapshotEntry {
20
+ /** Unique key: docUrl | method | path */
21
+ key: string;
22
+ method: string;
23
+ path: string;
24
+ functionName: string;
25
+ summary?: string;
26
+ moduleName: string;
27
+ }
28
+
29
+ interface GenerateResult {
30
+ configPath: string;
31
+ files: string[];
32
+ operationCount: number;
33
+ moduleCount: number;
34
+ apiFileCount: number;
35
+ newOperations: SnapshotEntry[];
36
+ removedOperations: SnapshotEntry[];
37
+ }
38
+ declare function generateFromConfig(cwd?: string): Promise<GenerateResult>;
39
+
28
40
  export { type GenerateResult, type RequestConfig, type SwaggerTsConfig, generateFromConfig };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  generateFromConfig
3
- } from "./chunk-4OK6R2K5.js";
3
+ } from "./chunk-ZURWUVPF.js";
4
4
  export {
5
5
  generateFromConfig
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swgto-ts",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Generate API request files from OpenAPI 3.x documents.",
5
5
  "license": "MIT",
6
6
  "type": "module",