anl 26.510.0 → 26.510.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/lib/package.cjs CHANGED
@@ -1 +1 @@
1
- var e=`26.510.0`;Object.defineProperty(exports,`version`,{enumerable:!0,get:function(){return e}});
1
+ var e=`26.510.1`;Object.defineProperty(exports,`version`,{enumerable:!0,get:function(){return e}});
@@ -33,16 +33,16 @@ export default defineConfig({
33
33
  comment: 'enum-descriptions',
34
34
  },
35
35
  });
36
- `}resolveSelectedServiceIndices(e,t){let n=new Map;e.forEach((e,t)=>{e.name&&n.set(e.name.toLowerCase(),t)}),e.forEach((e,t)=>{let i=r.computeSegment(e.apiListFileName).toLowerCase();i&&!n.has(i)&&n.set(i,t)});let i=new Set,a=[];for(let e of t){let t=e.toLowerCase(),r=n.get(t);r===void 0?a.push(e):i.add(r)}if(a.length){let t=e.map(e=>e.name||r.computeSegment(e.apiListFileName)).filter(Boolean).join(`, `);throw Error(`未找到匹配的 swagger 服务:${a.join(`, `)}。可用服务:${t||`<无>`}`)}return Array.from(i).sort((e,t)=>e-t)}async promptSelectServices(e){let t=e.map((e,t)=>{let n=e.name||r.computeSegment(e.apiListFileName)||`#${t}`;return{name:`${n} (${e.apiListFileName} ← ${e.url})`,value:t,short:n}}),{picked:n}=await s.default.prompt([{type:`checkbox`,name:`picked`,message:`请选择需要重新生成的 swagger 服务(空选 = 全部):`,choices:t,pageSize:Math.min(20,t.length)}]);return!n||n.length===0?e.map((e,t)=>t):n.sort((e,t)=>e-t)}async initialize(e,i,a,o){let s=process.cwd();try{let l=await this.getConfig(s),u={...h,...l},f=a??u.logLevel;f&&t.setLogLevel(f);let m=Object.prototype.hasOwnProperty.call(l,`swaggerConfig`),g=this.normalizeswaggerConfig(u,m);if(!p)return;let _=g.length>1,v=_?g.map(e=>r.computeSegment(e.apiListFileName)):g.map(()=>``);if(_){let e=new Map;v.forEach((t,n)=>{if(!t)throw Error(`swaggerConfig[${n}].apiListFileName="${g[n].apiListFileName}" 无法派生有效 segment(清洗后为空),请使用包含字母/数字的文件名。`);if(t.toLowerCase()===`index`)throw Error(`swaggerConfig[${n}].apiListFileName="${g[n].apiListFileName}" 派生 segment 为 "index",会与顶层 models/index.ts 形成自引用,请改为其他文件名(如 "main.ts" / "default.ts")。`);if(e.has(t))throw Error(`swaggerConfig 多个服务的 apiListFileName 在派生 segment 时冲突:"${g[e.get(t)].apiListFileName}" 与 "${g[n].apiListFileName}" 都解析为 "${t}",请改名以避免目录覆盖。`);e.set(t,n)})}let y=g.map(e=>(e.namespaceIsolation??u.namespaceIsolation??`segment`)===`none`?``:r.segmentToNamespacePrefix(r.computeSegment(e.apiListFileName)));if(_){let e=g.map((e,t)=>({s:e,idx:t})).filter(({s:e})=>(e.namespaceIsolation??u.namespaceIsolation??`segment`)===`none`).map(({s:e})=>e.apiListFileName);e.length>0&&t.log.warning(`检测到多服务场景下以下服务关闭了 namespace 前缀(namespaceIsolation: 'none'):${e.join(`, `)}。 不同服务若存在同名 path,将会因 declare namespace 全局合并而互相污染类型,请确认是否符合预期。`);let n=new Map;y.forEach((e,t)=>{if(e){if(n.has(e))throw Error(`swaggerConfig 多个服务派生的 namespace 前缀冲突:"${g[n.get(e)].apiListFileName}" 与 "${g[t].apiListFileName}" 都解析为前缀 "${e}",请改名以避免类型同名合并。`);n.set(e,t)}})}let b,x;o?.length?(b=this.resolveSelectedServiceIndices(g,o),x=b.length!==g.length):g.length>1&&process.stdin.isTTY&&process.stdout.isTTY?(t.log.print(d.default.cyan(`
36
+ `}resolveSelectedServiceIndices(e,t){let n=new Map;e.forEach((e,t)=>{e.name&&n.set(e.name.toLowerCase(),t)}),e.forEach((e,t)=>{let i=r.computeSegment(e.apiListFileName).toLowerCase();i&&!n.has(i)&&n.set(i,t)});let i=new Set,a=[];for(let e of t){let t=e.toLowerCase(),r=n.get(t);r===void 0?a.push(e):i.add(r)}if(a.length){let t=e.map(e=>e.name??r.computeSegment(e.apiListFileName)).filter(Boolean).join(`, `);throw Error(`未找到匹配的 swagger 服务:${a.join(`, `)}。可用服务:${t||`<无>`}`)}return Array.from(i).sort((e,t)=>e-t)}async promptSelectServices(e){let t=e.map((e,t)=>{let n=(e.name??r.computeSegment(e.apiListFileName))||`#${t}`;return{name:`${n} (${e.apiListFileName} ← ${e.url})`,value:t,short:n}}),{picked:n}=await s.default.prompt([{type:`checkbox`,name:`picked`,message:`请选择需要重新生成的 swagger 服务(空选 = 全部):`,choices:t,pageSize:Math.min(20,t.length)}]);return!n||n.length===0?e.map((e,t)=>t):n.sort((e,t)=>e-t)}async initialize(e,i,a,o){let s=process.cwd();try{let l=await this.getConfig(s),u={...h,...l},f=a??u.logLevel;f&&t.setLogLevel(f);let m=Object.prototype.hasOwnProperty.call(l,`swaggerConfig`),g=this.normalizeswaggerConfig(u,m);if(!p)return;let _=g.length>1,v=_?g.map(e=>r.computeSegment(e.apiListFileName)):g.map(()=>``);if(_){let e=new Map;v.forEach((t,n)=>{if(!t)throw Error(`swaggerConfig[${n}].apiListFileName="${g[n].apiListFileName}" 无法派生有效 segment(清洗后为空),请使用包含字母/数字的文件名。`);if(t.toLowerCase()===`index`)throw Error(`swaggerConfig[${n}].apiListFileName="${g[n].apiListFileName}" 派生 segment 为 "index",会与顶层 models/index.ts 形成自引用,请改为其他文件名(如 "main.ts" / "default.ts")。`);if(e.has(t))throw Error(`swaggerConfig 多个服务的 apiListFileName 在派生 segment 时冲突:"${g[e.get(t)].apiListFileName}" 与 "${g[n].apiListFileName}" 都解析为 "${t}",请改名以避免目录覆盖。`);e.set(t,n)})}let y=g.map(e=>(e.namespaceIsolation??u.namespaceIsolation??`segment`)===`none`?``:r.segmentToNamespacePrefix(r.computeSegment(e.apiListFileName)));if(_){let e=g.map((e,t)=>({s:e,idx:t})).filter(({s:e})=>(e.namespaceIsolation??u.namespaceIsolation??`segment`)===`none`).map(({s:e})=>e.apiListFileName);e.length>0&&t.log.warning(`检测到多服务场景下以下服务关闭了 namespace 前缀(namespaceIsolation: 'none'):${e.join(`, `)}。 不同服务若存在同名 path,将会因 declare namespace 全局合并而互相污染类型,请确认是否符合预期。`);let n=new Map;y.forEach((e,t)=>{if(e){if(n.has(e))throw Error(`swaggerConfig 多个服务派生的 namespace 前缀冲突:"${g[n.get(e)].apiListFileName}" 与 "${g[t].apiListFileName}" 都解析为前缀 "${e}",请改名以避免类型同名合并。`);n.set(e,t)}})}let b,x;o?.length?(b=this.resolveSelectedServiceIndices(g,o),x=b.length!==g.length):g.length>1&&process.stdin.isTTY&&process.stdout.isTTY?(t.log.print(d.default.cyan(`
37
37
  检测到多个 swagger 服务,请选择本次要重新生成的服务:`)),b=await this.promptSelectServices(g),x=b.length!==g.length):(b=g.map((e,t)=>t),x=!1),this.printExecutionPlan(g,b,x),await c.default.promises.mkdir(u.saveApiListFolderPath,{recursive:!0}),await this.copyAjaxConfigFiles(u.saveApiListFolderPath),x?await this.cleanSelectedTargets(u,g,b,v,_):(await n.clearDirExcept(u.saveApiListFolderPath,[`config`]),await n.clearDir(u.saveTypeFolderPath),await n.clearDir(u.saveEnumFolderPath));let S=[];for(let t=0;t<b.length;t++){let n=b[t],r=this.buildServerConfig(u,g[n],v[n],y[n]),i=x?!0:t>0,a=await this.handle(r,i,e);e&&a&&S.push({serverUrl:g[n].url,list:a})}if(_&&(await this.writeTopLevelModelsBarrel(u,v,b,x),b.filter(e=>(g[e].enumIsolation??`segment`)===`segment`).map(e=>v[e]).filter(Boolean).length>0&&await this.writeTopLevelEnumsBarrel(u,v,g,b,x),g.every(e=>(e.enumIsolation??`segment`)===`segment`)&&await this.warnLegacyTopLevelEnums(u)),i!==void 0&&i!==!1&&(x?await this.formatSelectedFiles(u,g,b,v,_,i):await this.formatGeneratedFiles(u,i)),t.log.banner(`All done — see you next time!`),e&&S.length>0){let n=e===`miss`?`excludeInterface`:`includeInterface`;for(let{serverUrl:e,list:r}of S)b.length>1?t.log.print(d.default.cyan(`\n[${n}] ${e}`)):t.log.print(d.default.cyan(`\n[${n}]`)),t.log.print(JSON.stringify(r,null,2));t.log.print(`
38
38
  `)}}catch(e){let n=e instanceof Error?e.message:`Unknown error`;t.log.error(`Initialization failed: ${n}`),process.exitCode=1}}printExecutionPlan(e,n,i){let a=new Set(n);t.log.print(d.default.cyan(i?`
39
39
  [anl type] 选择型生成,仅处理以下服务:`:`
40
- [anl type] 全量生成,将处理所有服务:`)),e.forEach((e,n)=>{let i=e.name||r.computeSegment(e.apiListFileName)||`#${n}`;a.has(n)?t.log.print(` ${d.default.green(`●`)} ${i} (${e.apiListFileName}) ${d.default.gray(e.url)}`):t.log.print(` ${d.default.gray(`○ skip `)}${i} (${e.apiListFileName}) ${d.default.gray(e.url)}`)}),t.log.print(``)}async cleanSelectedTargets(e,t,r,i,a){for(let o of r)if(await n.clearDir(`${e.saveApiListFolderPath}/${t[o].apiListFileName}`),a){let r=i[o];r&&(await n.clearDir(`${e.saveTypeFolderPath}/connectors/${r}`),await n.clearDir(`${e.saveTypeFolderPath}/models/${r}`),(t[o].enumIsolation??`segment`)===`segment`&&await n.clearDir(`${e.saveEnumFolderPath}/${r}`))}else await n.clearDir(`${e.saveTypeFolderPath}/connectors`),await n.clearDir(`${e.saveTypeFolderPath}/models`)}async writeTopLevelModelsBarrel(e,i,a,o){let s=`${e.saveTypeFolderPath}/models/index.ts`,l=e=>{let t=r.segmentToNamespacePrefix(e);if(!t)throw Error(`无法为 segment "${e}" 生成 namespace 别名,请改用包含字母/数字的 apiListFileName。`);return`export * as ${t} from './${e}';`},u=o?a.map(e=>i[e]).filter(Boolean):i.filter(Boolean),d=u.map(e=>l(e)),f=e=>{let t=e.match(/from\s+['"]\.\/([^'\"]+)['"]/);return t?t[1]:null},p;if(o){let e=[];try{e=(await c.default.promises.readFile(s,`utf8`)).split(`
40
+ [anl type] 全量生成,将处理所有服务:`)),e.forEach((e,n)=>{let i=(e.name??r.computeSegment(e.apiListFileName))||`#${n}`;a.has(n)?t.log.print(` ${d.default.green(`●`)} ${i} (${e.apiListFileName}) ${d.default.gray(e.url)}`):t.log.print(` ${d.default.gray(`○ skip `)}${i} (${e.apiListFileName}) ${d.default.gray(e.url)}`)}),t.log.print(``)}async cleanSelectedTargets(e,t,r,i,a){for(let o of r)if(await n.clearDir(`${e.saveApiListFolderPath}/${t[o].apiListFileName}`),a){let r=i[o];r&&(await n.clearDir(`${e.saveTypeFolderPath}/connectors/${r}`),await n.clearDir(`${e.saveTypeFolderPath}/models/${r}`),(t[o].enumIsolation??`segment`)===`segment`&&await n.clearDir(`${e.saveEnumFolderPath}/${r}`))}else await n.clearDir(`${e.saveTypeFolderPath}/connectors`),await n.clearDir(`${e.saveTypeFolderPath}/models`)}async writeTopLevelModelsBarrel(e,i,a,o){let s=`${e.saveTypeFolderPath}/models/index.ts`,l=e=>{let t=r.segmentToNamespacePrefix(e);if(!t)throw Error(`无法为 segment "${e}" 生成 namespace 别名,请改用包含字母/数字的 apiListFileName。`);return`export * as ${t} from './${e}';`},u=o?a.map(e=>i[e]).filter(Boolean):i.filter(Boolean),d=u.map(e=>l(e)),f=e=>{let t=/from\s+['"]\.\/([^'"]+)['"]/.exec(e);return t?t[1]:null},p;if(o){let e=[];try{e=(await c.default.promises.readFile(s,`utf8`)).split(`
41
41
  `).filter(e=>e.trim()!==``)}catch{e=[]}let t=new Set(u);p=[...e.filter(e=>{let n=f(e);return!(n&&t.has(n))}).map(e=>{let t=f(e);if(!t||/export\s+\*\s+as\s+/.test(e))return e;try{return l(t)}catch{return e}}),...d]}else p=d;await n.writeFileRecursive(s,p.join(`
42
42
  `)+`
43
- `),t.log.info(`${s} - Top-level models barrel ${o?`merged`:`written`}.`)}async writeTopLevelEnumsBarrel(e,i,a,o,s){let l=`${e.saveEnumFolderPath}/index.ts`,u=e=>{let t=r.segmentToNamespacePrefix(e);if(!t)throw Error(`无法为 segment "${e}" 生成 namespace 别名,请改用包含字母/数字的 apiListFileName。`);return`export * as ${t} from './${e}';`},d=e=>(a[e].enumIsolation??`segment`)===`segment`,f=s?o.filter(e=>d(e)).map(e=>i[e]).filter(Boolean):i.map((e,t)=>({seg:e,i:t})).filter(({seg:e,i:t})=>!!e&&d(t)).map(({seg:e})=>e),p=f.map(e=>u(e)),m=e=>{let t=e.match(/from\s+['"]\.\/([^'\"]+)['"]/);return t?t[1]:null},h;if(s){let e=[];try{e=(await c.default.promises.readFile(l,`utf8`)).split(`
44
- `).filter(e=>e.trim()!==``)}catch{e=[]}let t=new Set(f);h=[...e.filter(e=>{let n=m(e);return!(n&&t.has(n))}),...p]}else{let e=[];try{e=(await c.default.promises.readFile(l,`utf8`)).split(`
45
- `).filter(e=>e.trim()!==``)}catch{e=[]}let t=new Set(f);h=[...e.filter(e=>{let n=m(e);return!(n&&t.has(n))}),...p]}await n.writeFileRecursive(l,h.join(`
43
+ `),t.log.info(`${s} - Top-level models barrel ${o?`merged`:`written`}.`)}async writeTopLevelEnumsBarrel(e,i,a,o,s){let l=`${e.saveEnumFolderPath}/index.ts`,u=e=>{let t=r.segmentToNamespacePrefix(e);if(!t)throw Error(`无法为 segment "${e}" 生成 namespace 别名,请改用包含字母/数字的 apiListFileName。`);return`export * as ${t} from './${e}';`},d=e=>(a[e].enumIsolation??`segment`)===`segment`,f=s?o.filter(e=>d(e)).map(e=>i[e]).filter(Boolean):i.map((e,t)=>({seg:e,i:t})).filter(({seg:e,i:t})=>!!e&&d(t)).map(({seg:e})=>e),p=Array.from(new Set(f)),m=(await Promise.all(p.map(async t=>{let n=`${e.saveEnumFolderPath}/${t}`;try{return(await c.default.promises.readdir(n,{withFileTypes:!0})).some(e=>e.isFile()&&/\.(d\.)?ts$/.test(e.name)&&e.name!==`index.ts`)?t:``}catch{return``}}))).filter(Boolean).map(e=>u(e)),h=e=>{let t=/from\s+['"]\.\/([^'"]+)['"]/.exec(e);return t?t[1]:null},g;if(s){let e=[];try{e=(await c.default.promises.readFile(l,`utf8`)).split(`
44
+ `).filter(e=>e.trim()!==``)}catch{e=[]}let t=new Set(p);g=[...e.filter(e=>{let n=h(e);return!(n&&t.has(n))}),...m]}else{let e=[];try{e=(await c.default.promises.readFile(l,`utf8`)).split(`
45
+ `).filter(e=>e.trim()!==``)}catch{e=[]}let t=new Set(p);g=[...e.filter(e=>{let n=h(e);return!(n&&t.has(n))}),...m]}await n.writeFileRecursive(l,g.join(`
46
46
  `)+`
47
47
  `),t.log.info(`${l} - Top-level enums barrel ${s?`merged`:`written`}.`)}async warnLegacyTopLevelEnums(e){let n=e.saveEnumFolderPath;try{let e=(await c.default.promises.readdir(n,{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.endsWith(`.ts`)&&e.name!==`index.ts`).map(e=>e.name);e.length>0&&t.log.warning(`检测到 ${n} 顶层仍存在历史枚举文件(${e.slice(0,5).join(`, `)}${e.length>5?` ...`:``}),共 ${e.length} 个。\n若已切换到 enumIsolation: 'segment'(默认),建议执行 \`anl type\` 全量重生成或手动清理这些文件,避免与 ${n}/<segment>/ 下的隔离枚举混用。`)}catch{}}async formatSelectedFiles(e,n,r,i,a,o){let s=[];for(let t of r){let r=`${e.saveApiListFolderPath}/${n[t].apiListFileName}`;try{await c.default.promises.access(r),s.push(`"${r}"`)}catch{}let o=a&&i[t]?[`${e.saveTypeFolderPath}/connectors/${i[t]}`,`${e.saveTypeFolderPath}/models/${i[t]}`]:[`${e.saveTypeFolderPath}/connectors`,`${e.saveTypeFolderPath}/models`];for(let e of o)try{await c.default.promises.access(e),s.push(`"${e}/**/*.{ts,d.ts}"`)}catch{}if(a&&i[t]&&(n[t].enumIsolation??`segment`)===`segment`){let n=`${e.saveEnumFolderPath}/${i[t]}`;try{await c.default.promises.access(n),s.push(`"${n}/**/*.{ts,d.ts}"`)}catch{}}else{let t=e.saveEnumFolderPath;try{await c.default.promises.access(t),s.push(`"${t}/*.ts"`)}catch{}}}if(s.length===0){t.log.warning(`No files to format for the selected services.`);return}let f=await this.resolvePrettierExecutable(),p=``;if(typeof o==`string`&&o.trim()){let e=l.default.resolve(process.cwd(),o.trim());try{await c.default.promises.access(e),p=` --config "${e}"`}catch{let e=await this.detectPrettierConfig();e&&(p=` --config "${e}"`)}}else{let e=await this.detectPrettierConfig();e&&(p=` --config "${e}"`)}let m=`${f} --write ${s.join(` `)}${p}`;try{t.spinner.start(`Formatting selected files...`),await new Promise((e,t)=>{(0,u.exec)(m,n=>{n?t(Error(String(n))):e()})}),t.spinner.success(`File formatting successful`),t.log.print(`
48
48
  `)}catch(e){t.spinner.error(`Format failed`),t.log.print(e),t.log.error(`Format failed, please manually execute the following command:`),t.log.print(`$`,d.default.yellow(m))}}};m&&new g().initialize().catch(e=>{console.error(e)}),exports.Main=g;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anl",
3
- "version": "26.510.0",
3
+ "version": "26.510.1",
4
4
  "description": "FE command line tool",
5
5
  "main": "bin/an-cli.js",
6
6
  "exports": {
@@ -28,10 +28,10 @@
28
28
  "ts": "tsc ./src/int.ts --noEmit --watch",
29
29
  "blink": "pnpm run build && pnpm link",
30
30
  "docs": "docsify serve ./docs",
31
- "test:type": "node bin/an-cli.js type",
32
- "test:type:one": "node bin/an-cli.js type -S op",
33
- "test:type:multi": "node bin/an-cli.js type -S op,notice",
34
- "test:type:miss": "node bin/an-cli.js type -S notExist"
31
+ "type": "node bin/an-cli.js type",
32
+ "type:one": "node bin/an-cli.js type -S op",
33
+ "type:multi": "node bin/an-cli.js type -S op,notice",
34
+ "type:miss": "node bin/an-cli.js type -S notExist"
35
35
  },
36
36
  "bin": {
37
37
  "anl": "bin/an-cli.js"