paas-build-package 0.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.
Files changed (106) hide show
  1. package/.editorconfig +13 -0
  2. package/.vscode/extensions.json +13 -0
  3. package/.vscode/settings.json +19 -0
  4. package/.vscode/tasks.json +158 -0
  5. package/LICENSE +21 -0
  6. package/README.md +1 -0
  7. package/lerna.json +8 -0
  8. package/package.json +37 -0
  9. package/packages/build/CHANGELOG.md +14 -0
  10. package/packages/build/LICENSE +21 -0
  11. package/packages/build/README.md +1 -0
  12. package/packages/build/build.config.ts +22 -0
  13. package/packages/build/eslint.config.js +8 -0
  14. package/packages/build/package.json +103 -0
  15. package/packages/build/prettier.config.js +3 -0
  16. package/packages/build/src/commitlint/commitlint-config/commitlint-config.ts +37 -0
  17. package/packages/build/src/commitlint/index.ts +1 -0
  18. package/packages/build/src/constants/index.ts +70 -0
  19. package/packages/build/src/eslint/eslint-config/eslint-config.ts +161 -0
  20. package/packages/build/src/eslint/index.ts +1 -0
  21. package/packages/build/src/index.ts +8 -0
  22. package/packages/build/src/prettier/index.ts +1 -0
  23. package/packages/build/src/prettier/prettier-config/prettier-config.ts +48 -0
  24. package/packages/build/src/stylelint/index.ts +1 -0
  25. package/packages/build/src/stylelint/stylelint-config/stylelint-config.ts +39 -0
  26. package/packages/build/src/types/index.d.ts +1 -0
  27. package/packages/build/src/unocss/index.ts +1 -0
  28. package/packages/build/src/unocss/unocss.config.ts +45 -0
  29. package/packages/build/src/util/env-state/env-state.ts +9 -0
  30. package/packages/build/src/util/index.ts +52 -0
  31. package/packages/build/src/util/reg-exp/reg-exp.ts +1 -0
  32. package/packages/build/src/util/watcher/watcher.ts +114 -0
  33. package/packages/build/src/vite/index.ts +13 -0
  34. package/packages/build/src/vite/vite-config/vite-base-config.ts +49 -0
  35. package/packages/build/src/vite/vite-config/vite-config.ts +74 -0
  36. package/packages/build/src/vite/vite-config/vite-dev-config.ts +26 -0
  37. package/packages/build/src/vite/vite-config/vite-pkg-dev-config.ts +123 -0
  38. package/packages/build/src/vite/vite-config/vite-plugin-config.ts +149 -0
  39. package/packages/build/src/vite/vite-config/vite-project-config.ts +82 -0
  40. package/packages/build/src/vite/vite-plugins/imnport-external-plugin.ts +21 -0
  41. package/packages/build/src/vite/vite-plugins/inject-importmap-plugin.ts +133 -0
  42. package/packages/build/tsconfig.json +32 -0
  43. package/packages/cli/CHANGELOG.md +20 -0
  44. package/packages/cli/LICENSE +21 -0
  45. package/packages/cli/README.md +1 -0
  46. package/packages/cli/build.config.ts +22 -0
  47. package/packages/cli/hbs-temp/api-config.ts.hbs +21 -0
  48. package/packages/cli/hbs-temp/apis/{{api}}.service.d.ts.hbs +39 -0
  49. package/packages/cli/hbs-temp/entities.d.ts.hbs +19 -0
  50. package/packages/cli/hbs-temp/index.d.ts.hbs +9 -0
  51. package/packages/cli/package.json +72 -0
  52. package/packages/cli/src/actions/gen-api/api-manage.ts +96 -0
  53. package/packages/cli/src/actions/gen-api/gen-api.ts +211 -0
  54. package/packages/cli/src/actions/gen-api/model-manage.ts +269 -0
  55. package/packages/cli/src/actions/gen-api/special-entities.config.ts +26 -0
  56. package/packages/cli/src/actions/gen-cdn-lib/gen-cdn-lib.ts +149 -0
  57. package/packages/cli/src/actions/index.ts +3 -0
  58. package/packages/cli/src/actions/init-git/init-git.ts +28 -0
  59. package/packages/cli/src/bin.ts +5 -0
  60. package/packages/cli/src/commands/gen-api/gen-api.ts +65 -0
  61. package/packages/cli/src/commands/gen-cdn-lib/gen-cdn-lib.ts +25 -0
  62. package/packages/cli/src/commands/index.ts +22 -0
  63. package/packages/cli/src/commands/init-git/init-git.ts +16 -0
  64. package/packages/cli/src/core/handlebars/constant/index.ts +4 -0
  65. package/packages/cli/src/core/handlebars/handlebars-engine.ts +143 -0
  66. package/packages/cli/src/core/handlebars/helpers/and/and.ts +24 -0
  67. package/packages/cli/src/core/handlebars/helpers/camel-case/camel-case.ts +23 -0
  68. package/packages/cli/src/core/handlebars/helpers/concat/concat.ts +20 -0
  69. package/packages/cli/src/core/handlebars/helpers/eq/eq.ts +27 -0
  70. package/packages/cli/src/core/handlebars/helpers/format-import/format-import.ts +46 -0
  71. package/packages/cli/src/core/handlebars/helpers/format-import-item/format-import-item.ts +67 -0
  72. package/packages/cli/src/core/handlebars/helpers/format-js-type/format-js-type.ts +50 -0
  73. package/packages/cli/src/core/handlebars/helpers/gt/gt.ts +27 -0
  74. package/packages/cli/src/core/handlebars/helpers/gte/gte.ts +27 -0
  75. package/packages/cli/src/core/handlebars/helpers/helper-base.ts +27 -0
  76. package/packages/cli/src/core/handlebars/helpers/includes/includes.ts +25 -0
  77. package/packages/cli/src/core/handlebars/helpers/index.ts +52 -0
  78. package/packages/cli/src/core/handlebars/helpers/json/json.ts +23 -0
  79. package/packages/cli/src/core/handlebars/helpers/lower-case/lower-case.ts +22 -0
  80. package/packages/cli/src/core/handlebars/helpers/lt/lt.ts +27 -0
  81. package/packages/cli/src/core/handlebars/helpers/lte/lte.ts +27 -0
  82. package/packages/cli/src/core/handlebars/helpers/neq/neq.ts +27 -0
  83. package/packages/cli/src/core/handlebars/helpers/not/not.ts +25 -0
  84. package/packages/cli/src/core/handlebars/helpers/not-includes/not-includes.ts +25 -0
  85. package/packages/cli/src/core/handlebars/helpers/or/or.ts +26 -0
  86. package/packages/cli/src/core/handlebars/helpers/pascal-case/pascal-case.ts +23 -0
  87. package/packages/cli/src/core/handlebars/helpers/snake-case/snake-case.ts +23 -0
  88. package/packages/cli/src/core/handlebars/helpers/spinal-case/spinal-case.ts +23 -0
  89. package/packages/cli/src/core/handlebars/helpers/upper-case/upper-case.ts +22 -0
  90. package/packages/cli/src/core/handlebars/index.ts +2 -0
  91. package/packages/cli/src/core/handlebars/utils/helper/helper.ts +67 -0
  92. package/packages/cli/src/core/handlebars/utils/index.ts +23 -0
  93. package/packages/cli/src/core/index.ts +2 -0
  94. package/packages/cli/src/core/interface/index.ts +4 -0
  95. package/packages/cli/src/index.ts +36 -0
  96. package/packages/cli/src/interface/i-command/i-command.ts +23 -0
  97. package/packages/cli/src/interface/i-gen-cdn-lib-options/i-gen-cdn-lib-options.ts +58 -0
  98. package/packages/cli/src/interface/index.ts +2 -0
  99. package/packages/cli/src/types/index.d.ts +1 -0
  100. package/packages/cli/src/utils/index.ts +4 -0
  101. package/packages/cli/src/utils/local-binaries/local-binaries.ts +16 -0
  102. package/packages/cli/tsconfig.json +32 -0
  103. package/pnpm-workspace.yaml +10 -0
  104. package/tsconfig.app.json +18 -0
  105. package/tsconfig.json +11 -0
  106. package/tsconfig.node.json +26 -0
@@ -0,0 +1,149 @@
1
+ import pacote from 'pacote';
2
+ import path from 'path';
3
+ import fse from 'fs-extra';
4
+ import log from 'consola';
5
+ import { Listr } from 'listr2';
6
+ import { IGenCdnLibOptions } from '../../interface';
7
+
8
+ /**
9
+ * 使用 pacote 从 npm 上下载制定包,至本地 cdn 项目目录,然后修改 import-map.json 文件,适配新包的版本号
10
+ *
11
+ * @export
12
+ * @class GenCdnLibAction
13
+ */
14
+ export class GenCdnLibAction {
15
+ private packages: string[] = [
16
+ '@gct-paas/api',
17
+ '@gct-paas/core',
18
+ '@gct-paas/core-mobile',
19
+ '@gct-paas/core-pad',
20
+ '@gct-paas/core-web',
21
+ '@gct-paas/design',
22
+ '@gct-paas/design-mobile',
23
+ '@gct-paas/design-pad',
24
+ '@gct-paas/design-web',
25
+ '@gct-paas/native',
26
+ '@gct-paas/render',
27
+ '@gct-paas/render-mobile',
28
+ '@gct-paas/render-pad',
29
+ '@gct-paas/render-web',
30
+ '@gct-paas/schema',
31
+ '@gct-paas/v-ben',
32
+ ];
33
+
34
+ /**
35
+ * 下载指定包并复制到外部依赖目录,返回入口文件名;若找不到入口文件则返回空字符串
36
+ */
37
+ private async downloadPkg(
38
+ pkg: string,
39
+ pkgInfo: Awaited<ReturnType<typeof pacote.manifest>>,
40
+ opts: IGenCdnLibOptions,
41
+ extraDir: string,
42
+ extractCacheDir: string,
43
+ cacheDir: string,
44
+ ): Promise<string> {
45
+ const _dlCacheDir = path.join(extractCacheDir, pkgInfo.name, pkgInfo.version);
46
+ // 下载并解压包到指定目录
47
+ await pacote.extract(pkgInfo.dist.tarball, _dlCacheDir, {
48
+ registry: opts.registry,
49
+ cache: cacheDir,
50
+ });
51
+ // 从解压出的 package.json 读取完整字段(包含自定义 loader 字段)
52
+ const localPkgJson = fse.readJSONSync(path.join(_dlCacheDir, 'package.json'));
53
+ const loaderField = localPkgJson.loader as string | undefined;
54
+ if (!loaderField) return '';
55
+ // noFiles 模式:仅读取 loader 字段,不拷贝文件至目标目录
56
+ if (!opts.noFiles) {
57
+ const sourceDistPath = path.join(_dlCacheDir, 'dist');
58
+ if (opts.clean) {
59
+ const extractPkgPath = path.join(extraDir, pkgInfo.name);
60
+ if (fse.existsSync(extractPkgPath)) {
61
+ fse.removeSync(extractPkgPath);
62
+ }
63
+ }
64
+ const extractPath = path.join(extraDir, pkgInfo.name);
65
+ fse.copySync(sourceDistPath, extractPath, { overwrite: true });
66
+ }
67
+ return path.basename(loaderField);
68
+ }
69
+
70
+ async run(opts: IGenCdnLibOptions) {
71
+ const cwd = process.cwd();
72
+ // 外部依赖目录
73
+ const extraDir = opts.dir ? path.resolve(cwd, opts.dir) : cwd;
74
+ // 外部依赖目录名称
75
+ const extraDirName = path.basename(extraDir);
76
+ // 检查外部依赖目录是否存在,不存在则创建
77
+ if (!fse.existsSync(extraDir)) {
78
+ fse.mkdirSync(extraDir, { recursive: true });
79
+ }
80
+ // 缓存目录
81
+ const cacheDir = opts.cache
82
+ ? path.resolve(cwd, opts.cache)
83
+ : path.join(extraDir, '.cache');
84
+ // 下载包的缓存解压缓存目录
85
+ const extractCacheDir = path.join(cacheDir, 'tmp');
86
+ // import-map.json 文件路径
87
+ const importMapJsonPath = opts.jsonPath
88
+ ? path.resolve(cwd, opts.jsonPath)
89
+ : path.join(extraDir, 'import-map.json');
90
+ // 判断 importMapJsonPath 是否存在
91
+ if (!fse.existsSync(importMapJsonPath)) {
92
+ log.warn(
93
+ `import-map.json 文件不存在于 ${importMapJsonPath},请确保路径正确或使用 --jsonPath 参数指定正确路径`,
94
+ );
95
+ return;
96
+ }
97
+ // import-map.json 文件内容
98
+ log.info('正在读取 import-map.json...');
99
+ const importMap = fse.readJSONSync(importMapJsonPath);
100
+
101
+ const tasks = new Listr(
102
+ this.packages.map((pkg) => ({
103
+ title: `${pkg}@${opts.tag}`,
104
+ task: async (_, task) => {
105
+ // 获取包的指定版本的 manifest 信息
106
+ task.title = `${pkg}@${opts.tag} 获取包信息...`;
107
+ const pkgInfo = await pacote.manifest(`${pkg}@${opts.tag}`, {
108
+ registry: opts.registry,
109
+ cache: cacheDir,
110
+ });
111
+
112
+ task.title = `${pkg}@${pkgInfo.version} 下载中...`;
113
+ const entryName = await this.downloadPkg(pkg, pkgInfo, opts, extraDir, extractCacheDir, cacheDir);
114
+
115
+ if (!entryName) {
116
+ task.skip('package.json 中没有 loader 字段,已跳过');
117
+ return;
118
+ }
119
+
120
+ // 修改 import-map.json,输出时使用相对路径,根从 extra 目录开始
121
+ importMap.imports[pkg] = `/${extraDirName}/${pkgInfo.name}/${entryName}`;
122
+ task.title = `${pkg}@${pkgInfo.version}`;
123
+ },
124
+ })),
125
+ { concurrent: true },
126
+ );
127
+
128
+ await tasks.run();
129
+
130
+ // 遍历所有 importMap.imports 给路径添加时间戳,每次编译后强制浏览器重新加载
131
+ const timestamp = Date.now();
132
+ for (const key in importMap.imports) {
133
+ // 如果有 t 参数,则替换为新的时间戳,否则添加 t 参数
134
+ if (importMap.imports[key].includes('?t=')) {
135
+ importMap.imports[key] = importMap.imports[key].replace(/\?t=\d+/, `?t=${timestamp}`);
136
+ } else {
137
+ importMap.imports[key] = `${importMap.imports[key]}?t=${timestamp}`;
138
+ }
139
+ }
140
+ // 写回 import-map.json 文件
141
+ fse.writeJSONSync(importMapJsonPath, importMap, { spaces: 2 });
142
+ // 删除缓存目录
143
+ if (opts.cleanCache && fse.existsSync(cacheDir)) {
144
+ log.info(`正在删除缓存目录: ${cacheDir}`);
145
+ fse.removeSync(cacheDir);
146
+ }
147
+ log.success('CDN 库文件生成成功!');
148
+ }
149
+ }
@@ -0,0 +1,3 @@
1
+ export { GenApiAction } from './gen-api/gen-api';
2
+ export { GenCdnLibAction } from './gen-cdn-lib/gen-cdn-lib';
3
+ export { InitGitAction } from './init-git/init-git';
@@ -0,0 +1,28 @@
1
+ import { execSync } from 'child_process';
2
+ import { consola } from 'consola';
3
+ import simpleGit from 'simple-git';
4
+
5
+ const GIT_CONFIGS: Record<string, string> = {
6
+ 'merge.ours.driver': 'true',
7
+ 'pull.ff': 'only',
8
+ 'core.autocrlf': 'false',
9
+ 'core.safecrlf': 'true',
10
+ 'core.eol': 'lf',
11
+ };
12
+
13
+ export class InitGitAction {
14
+ async run(): Promise<void> {
15
+ consola.start('初始化 Husky...');
16
+ execSync('npx husky', { stdio: 'inherit' });
17
+
18
+ const git = simpleGit(process.cwd());
19
+ consola.start('配置 Git 本地设置...');
20
+
21
+ for (const [key, value] of Object.entries(GIT_CONFIGS)) {
22
+ await git.addConfig(key, value, false, 'local');
23
+ consola.info(` git config --local ${key} "${value}"`);
24
+ }
25
+
26
+ consola.success('Git 配置初始化完成');
27
+ }
28
+ }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { bootstrap } from './index';
4
+
5
+ bootstrap();
@@ -0,0 +1,65 @@
1
+ import { Command } from 'commander';
2
+ import { ICommand } from '../../interface';
3
+ import { GenApiAction } from '../../actions';
4
+
5
+ export interface GenApiOptions {
6
+ /**
7
+ * 模板目录
8
+ *
9
+ * @author chitanda
10
+ * @date 2021-12-19 20:12:32
11
+ * @type {string}
12
+ */
13
+ template: string;
14
+ /**
15
+ * 模板输出目录
16
+ *
17
+ * @author chitanda
18
+ * @date 2021-12-19 20:12:37
19
+ * @type {string}
20
+ */
21
+ output: string;
22
+ /**
23
+ * 清理输出目录
24
+ *
25
+ * @author chitanda
26
+ * @date 2021-12-21 10:12:47
27
+ * @type {boolean}
28
+ */
29
+ clean: boolean;
30
+ /**
31
+ * swagger 地址
32
+ *
33
+ * @type {string}
34
+ */
35
+ url: string;
36
+ /**
37
+ * api标识
38
+ *
39
+ * @type {string}
40
+ */
41
+ tag: string;
42
+ }
43
+
44
+ export class GenApiCommand implements ICommand {
45
+ load(program: Command): void {
46
+ program
47
+ .command('gen-api')
48
+ .description('生成 api 文件')
49
+ .option('--url <base-url>', '指定api获取的swagger地址')
50
+ .option('-t --template <template>', '指定模板目录')
51
+ .option('-o --output <output>', '指定输出目录')
52
+ .option('--tag <tag>', '指定当前发布的分支')
53
+ .option('--clean', '清理输出目录')
54
+ .action(this.action.bind(this));
55
+ }
56
+ async action(args: GenApiOptions): Promise<void> {
57
+ await new GenApiAction().run(
58
+ args.url,
59
+ args.tag,
60
+ args.template,
61
+ args.output,
62
+ args.clean,
63
+ );
64
+ }
65
+ }
@@ -0,0 +1,25 @@
1
+ import { Command } from 'commander';
2
+ import { ICommand, IGenCdnLibOptions } from '../../interface';
3
+ import { GenCdnLibAction } from '../../actions';
4
+
5
+ export class GenCdnLibCommand implements ICommand {
6
+ load(program: Command): void {
7
+ program
8
+ .command('gen-cdn-lib')
9
+ .description('生成 cdn 库文件')
10
+ .option('--tag <tag>', '指定下载的版本标签(latest | dev | beta | alpha),默认为 latest', 'latest')
11
+ .option('--dir <dir>', '指定输出目录,未指定时默认为当前执行目录')
12
+ .option('--jsonPath <jsonPath>', '指定 import-map.json 文件路径,未制定默认使用指定的 dir 目录下的 import-map.json 文件')
13
+ .option('--clean', '是否清理输出目录后再生成')
14
+ .option('--registry <registry>', '指定 npm registry 地址,未指定时使用默认 registry')
15
+ .option('--cache <cache>', '指定 pacote 缓存目录,未指定时使用默认缓存目录')
16
+ .option('--cleanCache', '清理缓存目录,默认为 false', false)
17
+ .option('--noFiles', '是否只生成 import-map.json 文件而不下载包文件,默认为 false', false)
18
+ .action(this.action.bind(this));
19
+ }
20
+ async action(args: IGenCdnLibOptions): Promise<void> {
21
+ await new GenCdnLibAction().run(
22
+ args,
23
+ );
24
+ }
25
+ }
@@ -0,0 +1,22 @@
1
+ import { consola } from 'consola';
2
+ import { Command } from 'commander';
3
+ import { GenApiCommand } from './gen-api/gen-api';
4
+ import { GenCdnLibCommand } from './gen-cdn-lib/gen-cdn-lib';
5
+ import { InitGitCommand } from './init-git/init-git';
6
+
7
+ export class CommandLoader {
8
+ public static load(program: Command): void {
9
+ new GenApiCommand().load(program);
10
+ new GenCdnLibCommand().load(program);
11
+ new InitGitCommand().load(program);
12
+ this.handleInvalidCommand(program);
13
+ }
14
+
15
+ private static handleInvalidCommand(program: Command) {
16
+ program.on('command:*', () => {
17
+ consola.error(`未支持的命令: `, program.args.join(' '));
18
+ consola.log(`请使用 --help 查看已支持的命令.\n`);
19
+ process.exit(1);
20
+ });
21
+ }
22
+ }
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander';
2
+ import { ICommand } from '../../interface';
3
+ import { InitGitAction } from '../../actions';
4
+
5
+ export class InitGitCommand implements ICommand {
6
+ load(program: Command): void {
7
+ program
8
+ .command('init-git')
9
+ .description('初始化项目通用 Git 配置')
10
+ .action(this.action.bind(this));
11
+ }
12
+
13
+ async action(): Promise<void> {
14
+ await new InitGitAction().run();
15
+ }
16
+ }
@@ -0,0 +1,4 @@
1
+ // 模板文件后缀
2
+ export const TEMP_EXTENSION = '.hbs';
3
+ // 宏模板文件夹
4
+ export const MACRO_FOLDER = '@macro';
@@ -0,0 +1,143 @@
1
+ import Handlebars from 'handlebars';
2
+ import { installHelpers } from './helpers';
3
+ import { HelperUtil, winToUnixPath } from './utils';
4
+ import { IObject } from '../interface';
5
+ import { TEMP_EXTENSION } from './constant';
6
+
7
+ /**
8
+ * 生成器
9
+ *
10
+ * @export
11
+ * @class HandlebarsEngine
12
+ */
13
+ export class HandlebarsEngine {
14
+ /**
15
+ * 编译参数
16
+ *
17
+ * @protected
18
+ * @type {CompileOptions}
19
+ */
20
+ protected compileOpt: CompileOptions = { compat: true, noEscape: true };
21
+
22
+ /**
23
+ * Handlebars 运行时参数
24
+ *
25
+ * @protected
26
+ * @type {Handlebars.RuntimeOptions}
27
+ */
28
+ protected runtimeOpt: Handlebars.RuntimeOptions = {
29
+ allowProtoPropertiesByDefault: true,
30
+ };
31
+
32
+ /**
33
+ * 忽略编译的上下文标签规则
34
+ *
35
+ * @protected
36
+ */
37
+ protected tagReg = /^[a-zA-Z0-9:_-]+$/;
38
+
39
+ /**
40
+ * 模板映射内容
41
+ *
42
+ * @type {Map<string, string>} Map<模板路径, 模板内容>
43
+ */
44
+ readonly temps: Map<string, string> = new Map<string, string>();
45
+
46
+ constructor() {
47
+ installHelpers();
48
+ }
49
+
50
+ /**
51
+ * 注册宏
52
+ *
53
+ * @param {string} key 宏标识
54
+ * @param {string} template 宏模板内容
55
+ */
56
+ registerMacro(key: string, template: string): void {
57
+ key = winToUnixPath(key);
58
+ if (key.endsWith(TEMP_EXTENSION)) {
59
+ key = key.replace(TEMP_EXTENSION, '');
60
+ Handlebars.registerPartial(key, template);
61
+ } else {
62
+ Handlebars.registerPartial(key, template);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * 注册模板
68
+ *
69
+ * @param {string} key
70
+ * @param {string} template
71
+ */
72
+ registerTemp(key: string, template: string): void {
73
+ key = winToUnixPath(key);
74
+ if (key.endsWith(TEMP_EXTENSION)) {
75
+ key = key.replace(TEMP_EXTENSION, '');
76
+ this.temps.set(key, template);
77
+ } else {
78
+ this.temps.set(key, template);
79
+ }
80
+ }
81
+
82
+ /**
83
+ * 编译模板获取所有使用到的上下文级参数标识
84
+ *
85
+ * @param {string} template
86
+ * @return {*} {string[]}
87
+ */
88
+ parseContextTags(template: string): string[] {
89
+ const program = Handlebars.parse(template);
90
+ const set = new Set<string>();
91
+ this.calcTemplateTags(set, program.body);
92
+ return Array.from(set);
93
+ }
94
+
95
+ /**
96
+ * 计算编译模板中的参数标签
97
+ *
98
+ * @protected
99
+ * @param {Set<string>} set
100
+ * @param {Record<string, any>[]} tags
101
+ */
102
+ protected calcTemplateTags(
103
+ set: Set<string>,
104
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
+ tags: Record<string, any>[],
106
+ ): void {
107
+ tags.forEach(item => {
108
+ switch (item.type) {
109
+ case 'SubExpression':
110
+ if (item.params?.length > 0) {
111
+ this.calcTemplateTags(set, item.params);
112
+ }
113
+ return;
114
+ case 'MustacheStatement':
115
+ case 'PathExpression': {
116
+ const tag = item.path ? item.path.original : item.original;
117
+ if (HelperUtil.isHelperName(tag)) {
118
+ if (item.params?.length > 0) {
119
+ this.calcTemplateTags(set, item.params);
120
+ }
121
+ return;
122
+ }
123
+ if (this.tagReg.test(tag)) {
124
+ set.add(tag);
125
+ }
126
+ break;
127
+ }
128
+ default:
129
+ }
130
+ });
131
+ }
132
+
133
+ /**
134
+ * 直接工具模板和数据编译
135
+ *
136
+ * @param {string} template
137
+ * @param {IObject} data
138
+ * @return {*} {string}
139
+ */
140
+ render(template: string, data: IObject): string {
141
+ return Handlebars.compile(template, this.compileOpt)(data, this.runtimeOpt);
142
+ }
143
+ }
@@ -0,0 +1,24 @@
1
+ import { HelperUtil } from '../../utils';
2
+ import { HelperBase } from '../helper-base';
3
+
4
+ /**
5
+ * 并且条件模式
6
+ *
7
+ * @description 判断: word wor2 word3 必须在判断中必须全部为 true, 用法: {{#and word word2 word3}}xxx{{else}}yyy{{/and}}、{{and word word2 word3}} 返回值为 boolean 类型
8
+ * @export
9
+ * @class HelperAnd
10
+ * @extends {HelperBase}
11
+ */
12
+ export class HelperAnd extends HelperBase {
13
+ constructor() {
14
+ super('and');
15
+ }
16
+
17
+ onExecute(...args: unknown[] | Handlebars.HelperOptions[]): string | boolean {
18
+ const options = args[args.length - 1] as Handlebars.HelperOptions;
19
+ args.pop();
20
+ const arr = (args as unknown[]).filter(item => !!item);
21
+ const bol = arr.length === args.length;
22
+ return HelperUtil.handleJudgmentExecute(this, bol, options);
23
+ }
24
+ }
@@ -0,0 +1,23 @@
1
+ import { camelCase } from 'lodash-es';
2
+ import { HelperBase } from '../helper-base';
3
+
4
+ /**
5
+ * 转驼峰
6
+ *
7
+ * @description 用法 {{camelCase xxx}},效果: this-is-my-name => thisIsMyName
8
+ * @export
9
+ * @class HelperCamelCase
10
+ * @extends {HelperBase}
11
+ */
12
+ export class HelperCamelCase extends HelperBase {
13
+ constructor() {
14
+ super('camelCase');
15
+ }
16
+
17
+ onExecute(param: string): string {
18
+ if (!param) {
19
+ return '';
20
+ }
21
+ return camelCase(param);
22
+ }
23
+ }
@@ -0,0 +1,20 @@
1
+ import { HelperBase } from '../helper-base';
2
+
3
+ /**
4
+ * 字符串拼接
5
+ *
6
+ * @description 用法:{{concat string1 string2 string3}} 返回值为 string 类型
7
+ * @export
8
+ * @class HelperConcat
9
+ * @extends {HelperBase}
10
+ */
11
+ export class HelperConcat extends HelperBase {
12
+ constructor() {
13
+ super('concat');
14
+ }
15
+
16
+ onExecute(...args: string[]): string {
17
+ args.pop();
18
+ return args.join('');
19
+ }
20
+ }
@@ -0,0 +1,27 @@
1
+ import * as Handlebars from 'handlebars';
2
+ import { eq } from 'lodash-es';
3
+ import { HelperUtil } from '../../utils';
4
+ import { HelperBase } from '../helper-base';
5
+
6
+ /**
7
+ * 等于
8
+ *
9
+ * @description 判断: word === word2, 用法: {{#eq word word2}}xxx{{else}}yyy{{/eq}}、{{eq word 'xxx'}} 返回值为 boolean 类型
10
+ * @export
11
+ * @class HelperEq
12
+ * @extends {HelperBase}
13
+ */
14
+ export class HelperEq extends HelperBase {
15
+ constructor() {
16
+ super('eq');
17
+ }
18
+
19
+ onExecute(
20
+ param: unknown,
21
+ param2: unknown,
22
+ options: Handlebars.HelperOptions,
23
+ ): string | boolean {
24
+ const bol = eq(param, param2);
25
+ return HelperUtil.handleJudgmentExecute(this, bol, options);
26
+ }
27
+ }
@@ -0,0 +1,46 @@
1
+ import { HelperBase } from '../helper-base';
2
+
3
+ /**
4
+ * 格式化导入
5
+ *
6
+ * @description 专门格式化导入的 response 对象,效果: ResponseEntity«List«TraceSettingResponse»» => TraceSettingResponse
7
+ * @export
8
+ * @class HelperFormatImport
9
+ * @extends {HelperBase}
10
+ */
11
+ export class HelperFormatImport extends HelperBase {
12
+ constructor() {
13
+ super('formatImport');
14
+ }
15
+
16
+ onExecute(param: string[]): string {
17
+ if (!param || param.length === 0) {
18
+ return '';
19
+ }
20
+ const items = param
21
+ .map(item => {
22
+ if (item.indexOf('«') > -1) {
23
+ const arr = item.split('«');
24
+ return arr[arr.length - 1].split('»')[0];
25
+ }
26
+ return item;
27
+ })
28
+ .filter(item => {
29
+ const keys = item.split(',');
30
+ const tag = keys[0];
31
+ switch (tag) {
32
+ case 'string':
33
+ case 'object':
34
+ case 'void':
35
+ case 'integer':
36
+ case 'int':
37
+ case 'long':
38
+ case 'Map':
39
+ return false;
40
+ default:
41
+ return true;
42
+ }
43
+ });
44
+ return Array.from(new Set(items)).join(',');
45
+ }
46
+ }
@@ -0,0 +1,67 @@
1
+ import { HelperBase } from '../helper-base';
2
+
3
+ /**
4
+ * 格式化导入
5
+ *
6
+ * @description 专门格式化导入的 response 对象,效果: ResponseEntity«List«TraceSettingResponse»» => TraceSettingResponse
7
+ * @export
8
+ * @class HelperFormatImportItem
9
+ * @extends {HelperBase}
10
+ */
11
+ export class HelperFormatImportItem extends HelperBase {
12
+ constructor() {
13
+ super('formatImportItem');
14
+ }
15
+
16
+ onExecute(param: string): string {
17
+ if (!param) {
18
+ return '';
19
+ }
20
+ if (param.indexOf('«') > -1) {
21
+ // 先截出泛型区
22
+ const start = param.indexOf('«');
23
+ const end = param.indexOf('»');
24
+ param = param.substring(start + 1, end);
25
+ // 再根据泛型区
26
+ param = param.replace(/«/g, '___');
27
+ param = param.replace(/»/g, '___');
28
+ const arr = param.split('___');
29
+ const isType = arr.length > 1;
30
+ const type = isType ? arr[0] : '';
31
+ const text = isType ? arr[1] : arr[0];
32
+ let keys = text.split(',');
33
+ if (keys.length > 1) {
34
+ return 'IObject';
35
+ }
36
+ keys = keys.map(key => {
37
+ if (key === 'Void') {
38
+ return 'void';
39
+ }
40
+ if (key === 'int' || key === 'long') {
41
+ return 'number';
42
+ }
43
+ if (key === 'Map') {
44
+ return 'IObject';
45
+ }
46
+ return key;
47
+ });
48
+ const val = keys.join(',');
49
+ if (isType) {
50
+ if (type === 'List') {
51
+ if (val === 'Tree') {
52
+ return 'IObject[]';
53
+ }
54
+ return val + '[]';
55
+ }
56
+ if (type === 'PageBase') {
57
+ return `IPage<${val}>`;
58
+ }
59
+ if (type === 'Tree') {
60
+ return 'IObject';
61
+ }
62
+ }
63
+ return val;
64
+ }
65
+ return param;
66
+ }
67
+ }