create-aomex 0.0.75 → 0.0.77
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/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/package.json +19 -19
- package/templates/prisma/migrations/20251130164417_create_table_user/migration.sql +11 -0
- package/templates/prisma/migrations/migration_lock.toml +3 -0
- package/templates/prisma/schema.prisma +10 -4
- package/templates/prisma.config.ts +12 -0
- package/templates/src/configs/production.ts +1 -0
- package/templates/src/routers/user.router.ts +37 -0
- package/templates/src/services/index.ts +2 -0
- package/templates/src/services/prisma.ts +14 -3
- package/templates/src/services/user.service.ts +30 -0
- package/templates/tsconfig.json +4 -3
- package/templates/typings/prisma-json.d.ts +7 -0
package/dist/index.js
CHANGED
|
@@ -119,6 +119,7 @@ var pnpmVersion = execSync(`npm view pnpm version`, {
|
|
|
119
119
|
encoding: "utf8"
|
|
120
120
|
}).replaceAll("\n", "") || "0.0.0";
|
|
121
121
|
var nodeVersion = await selectNodeVersion(argv);
|
|
122
|
+
var nodeMajorVersion = nodeVersion.split(".")[0];
|
|
122
123
|
var targetDir = path2.resolve(projectName);
|
|
123
124
|
var { error } = await terminal3.runTasks([
|
|
124
125
|
{
|
|
@@ -140,7 +141,8 @@ var { error } = await terminal3.runTasks([
|
|
|
140
141
|
projectName,
|
|
141
142
|
nodeVersion,
|
|
142
143
|
pnpmVersion,
|
|
143
|
-
cronPort
|
|
144
|
+
cronPort,
|
|
145
|
+
nodeMajorVersion
|
|
144
146
|
};
|
|
145
147
|
await cp(templateDir, targetDir, { recursive: true });
|
|
146
148
|
const files = await readdir(targetDir, { recursive: true });
|
|
@@ -208,8 +210,10 @@ var { error } = await terminal3.runTasks([
|
|
|
208
210
|
"@aomex/prisma",
|
|
209
211
|
"@aomex/logger",
|
|
210
212
|
"ioredis",
|
|
211
|
-
"prisma"
|
|
213
|
+
"prisma",
|
|
212
214
|
// docker prisma migrate 要用,放dev会导致二进制不存在
|
|
215
|
+
"@prisma/adapter-mariadb",
|
|
216
|
+
"dotenv"
|
|
213
217
|
]
|
|
214
218
|
},
|
|
215
219
|
{
|
|
@@ -222,7 +226,8 @@ var { error } = await terminal3.runTasks([
|
|
|
222
226
|
"husky",
|
|
223
227
|
"prettier",
|
|
224
228
|
"@commitlint/cli",
|
|
225
|
-
"@commitlint/config-conventional"
|
|
229
|
+
"@commitlint/config-conventional",
|
|
230
|
+
"prisma-json-types-generator"
|
|
226
231
|
],
|
|
227
232
|
dev: true
|
|
228
233
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/input-project.ts","../src/select-node-version.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport path from 'node:path/posix';\nimport yargsParser from 'yargs-parser';\nimport {\n cp,\n mkdir,\n readdir,\n readFile,\n rename,\n stat,\n writeFile,\n} from 'node:fs/promises';\nimport { terminal } from '@aomex/console';\nimport { execSync, spawn } from 'node:child_process';\nimport { setTimeout } from 'node:timers/promises';\nimport { inputProject } from './input-project';\nimport { selectNodeVersion } from './select-node-version';\n\nconst runShell = async (command: string) => {\n await new Promise((resolve, reject) => {\n const stream = spawn(command, {\n cwd: process.cwd(),\n env: process.env,\n shell: true,\n });\n stream.on('close', resolve);\n stream.on('error', reject);\n });\n};\n\nconst argv = yargsParser(process.argv.slice(2));\nconst templateDir = path.join(import.meta.dirname, '..', 'templates');\nconst projectName = await inputProject(argv);\nconst pnpmVersion =\n execSync(`npm view pnpm version`, {\n encoding: 'utf8',\n }).replaceAll('\\n', '') || '0.0.0';\n\nconst nodeVersion = await selectNodeVersion(argv);\nconst targetDir = path.resolve(projectName);\n\nconst { error } = await terminal.runTasks([\n {\n title: '创建目录',\n task: async () => {\n await mkdir(targetDir, { recursive: true });\n process.chdir(targetDir);\n await setTimeout(500);\n },\n },\n {\n title: '复制模板文件',\n task: async () => {\n let cronPort = '' + Math.max(1, Math.floor(3 * Math.random()));\n for (let i = 0; i < 4; ++i) {\n cronPort += Math.floor(10 * Math.random());\n }\n\n const variables = {\n projectName,\n nodeVersion,\n pnpmVersion,\n cronPort,\n };\n await cp(templateDir, targetDir, { recursive: true });\n const files = await readdir(targetDir, { recursive: true });\n for (const file of files) {\n const isFile = (await stat(path.join(targetDir, file))).isFile();\n if (!isFile) continue;\n const fileAbsolutePath = path.resolve(file);\n let fileContent = await readFile(fileAbsolutePath, 'utf8');\n Object.entries(variables).forEach(([key, value]) => {\n fileContent = fileContent.replaceAll(`{{${key}}}`, value);\n });\n await writeFile(fileAbsolutePath, fileContent);\n }\n // .gitignore这个文件在安装的时候总是被忽略\n await rename(\n path.join(targetDir, 'gitignore'),\n path.join(targetDir, '.gitignore'),\n );\n await setTimeout(500);\n },\n },\n {\n title: 'git初始化',\n skip: async () => {\n return !/\\d\\.\\d/.test(execSync('git -v', { encoding: 'utf8' }));\n },\n task: async () => {\n await runShell('git init');\n await setTimeout(500);\n },\n },\n {\n title: '增加volta配置',\n skip: async () => {\n return !/\\d\\.\\d/.test(execSync('volta -v', { encoding: 'utf8' }));\n },\n task: async () => {\n await runShell(`volta pin node@${nodeVersion}`);\n await runShell(`volta pin pnpm@${pnpmVersion}`);\n },\n },\n {\n title: '安装插件',\n task: async (_, task) => {\n const packages: { label: string; pkgs: string[]; dev?: boolean }[] = [\n {\n label: 'dependencies',\n pkgs: [\n '@aomex/common',\n '@aomex/web',\n '@aomex/cors',\n '@aomex/etag',\n '@aomex/compress',\n '@aomex/http-logger',\n '@aomex/response-time',\n '@aomex/console',\n '@aomex/cron',\n '@aomex/helmet',\n '@aomex/openapi',\n '@aomex/swagger-ui',\n '@aomex/async-trace',\n '@prisma/client',\n '@aomex/cache',\n '@aomex/cache-redis-adapter',\n '@aomex/auth',\n '@aomex/prisma',\n '@aomex/logger',\n 'ioredis',\n 'prisma', // docker prisma migrate 要用,放dev会导致二进制不存在\n ],\n },\n {\n label: 'dev dependencies',\n pkgs: [\n 'typescript',\n 'tsx',\n 'tsc-alias',\n '@types/node',\n 'husky',\n 'prettier',\n '@commitlint/cli',\n '@commitlint/config-conventional',\n ],\n dev: true,\n },\n ];\n\n for (let i = 0; i < packages.length; ++i) {\n const { pkgs, dev, label } = packages[i]!;\n task.suffix = terminal.style('gray', label);\n await runShell(`pnpm add ${pkgs.join(' ')} ${dev ? '-D' : ''}`);\n }\n task.suffix = '';\n },\n },\n {\n title: '生成prisma客户端',\n task: async () => {\n await runShell('npx prisma generate');\n },\n },\n]);\n\nif (error) process.exit(1);\n\nconsole.log(\n '\\n项目创建成功:' +\n terminal.style(['blue', 'underline'], process.cwd()) +\n '\\n' +\n '启动项目可执行如下指令:' +\n '\\n\\n' +\n terminal.style('green', `cd ${projectName} && pnpm start`) +\n '\\n',\n);\n","import { terminal } from '@aomex/console';\nimport { input } from '@inquirer/prompts';\nimport { existsSync, readdirSync } from 'node:fs';\nimport sanitize from 'sanitize-filename';\nimport path from 'path';\n\nconst kebabCase = (value: string) => {\n value = sanitize(value);\n if (!value.length) return '';\n value = value[0]!.toLowerCase() + value.slice(1);\n return value\n .replace(/[A-Z]/g, (i) => '-' + i.toLowerCase())\n .replace(/_/g, '-')\n .replace(/-+/g, '-');\n};\n\nexport const inputProject = async (argv: Record<string, any>) => {\n let projectName: string = argv['project'];\n if (projectName) {\n projectName = kebabCase(projectName);\n const available = isProjectDirAvailable(projectName);\n if (typeof available === 'string') {\n terminal.printError(available);\n process.exit(1);\n }\n } else {\n projectName = await input({\n message: '请输入项目',\n validate(value) {\n return isProjectDirAvailable(value);\n },\n transformer(value) {\n return kebabCase(value);\n },\n });\n projectName = kebabCase(projectName);\n }\n\n return projectName;\n};\n\nconst isProjectDirAvailable = (projectName: string): string | true => {\n projectName = projectName.trim();\n if (!projectName.trim()) return '项目名不能为空';\n const targetDir = path.resolve(projectName);\n if (!existsSync(targetDir)) return true;\n if (!readdirSync(targetDir).length) return true;\n return `目录 \"${targetDir}\" 包含其它文件,请手动删除或选择新的项目名`;\n};\n","import { terminal } from '@aomex/console';\nimport { select } from '@inquirer/prompts';\n\nexport const selectNodeVersion = async (argv: Record<string, any>) => {\n let nodeVersion: string = argv['node'];\n if (!nodeVersion) {\n const nodes = await promise;\n nodeVersion = await select({\n message: '请选择node.js稳定版本',\n choices: nodes.map((item) => {\n return {\n name: `${item.version} ${terminal.style(['gray', 'dim'], item.date)}`,\n value: item.version,\n short: item.version,\n };\n }),\n loop: false,\n });\n }\n\n return nodeVersion.replace(/^v/, '');\n};\n\nconst fetchNodes = async () => {\n const response = await fetch(\n 'https://nodejs.org/download/release/index.json',\n );\n const nodes = (await response.json()) as {\n version: string;\n lts: boolean;\n date: string;\n }[];\n\n return nodes\n .map((item) => {\n return {\n ...item,\n versions: item.version.slice(1).split('.').map(Number) as [\n number,\n number,\n number,\n ],\n };\n })\n .filter((item) => {\n if (!item.lts) return false;\n if (item.versions[0] === 22 && item.versions[1] >= 15) return true;\n if (item.versions[0] >= 24) return true;\n return false;\n });\n};\n\nconst promise = fetchNodes();\n"],"mappings":"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","names":["path","terminal","argv","projectName","targetDir","terminal","argv","nodeVersion","path","terminal"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/input-project.ts","../src/select-node-version.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport path from 'node:path/posix';\nimport yargsParser from 'yargs-parser';\nimport {\n cp,\n mkdir,\n readdir,\n readFile,\n rename,\n stat,\n writeFile,\n} from 'node:fs/promises';\nimport { terminal } from '@aomex/console';\nimport { execSync, spawn } from 'node:child_process';\nimport { setTimeout } from 'node:timers/promises';\nimport { inputProject } from './input-project';\nimport { selectNodeVersion } from './select-node-version';\n\nconst runShell = async (command: string) => {\n await new Promise((resolve, reject) => {\n const stream = spawn(command, {\n cwd: process.cwd(),\n env: process.env,\n shell: true,\n });\n stream.on('close', resolve);\n stream.on('error', reject);\n });\n};\n\nconst argv = yargsParser(process.argv.slice(2));\nconst templateDir = path.join(import.meta.dirname, '..', 'templates');\nconst projectName = await inputProject(argv);\nconst pnpmVersion =\n execSync(`npm view pnpm version`, {\n encoding: 'utf8',\n }).replaceAll('\\n', '') || '0.0.0';\n\nconst nodeVersion = await selectNodeVersion(argv);\nconst nodeMajorVersion = nodeVersion.split('.')[0]!;\nconst targetDir = path.resolve(projectName);\n\nconst { error } = await terminal.runTasks([\n {\n title: '创建目录',\n task: async () => {\n await mkdir(targetDir, { recursive: true });\n process.chdir(targetDir);\n await setTimeout(500);\n },\n },\n {\n title: '复制模板文件',\n task: async () => {\n let cronPort = '' + Math.max(1, Math.floor(3 * Math.random()));\n for (let i = 0; i < 4; ++i) {\n cronPort += Math.floor(10 * Math.random());\n }\n\n const variables = {\n projectName,\n nodeVersion,\n pnpmVersion,\n cronPort,\n nodeMajorVersion,\n };\n await cp(templateDir, targetDir, { recursive: true });\n const files = await readdir(targetDir, { recursive: true });\n for (const file of files) {\n const isFile = (await stat(path.join(targetDir, file))).isFile();\n if (!isFile) continue;\n const fileAbsolutePath = path.resolve(file);\n let fileContent = await readFile(fileAbsolutePath, 'utf8');\n Object.entries(variables).forEach(([key, value]) => {\n fileContent = fileContent.replaceAll(`{{${key}}}`, value);\n });\n await writeFile(fileAbsolutePath, fileContent);\n }\n // .gitignore这个文件在安装的时候总是被忽略\n await rename(\n path.join(targetDir, 'gitignore'),\n path.join(targetDir, '.gitignore'),\n );\n await setTimeout(500);\n },\n },\n {\n title: 'git初始化',\n skip: async () => {\n return !/\\d\\.\\d/.test(execSync('git -v', { encoding: 'utf8' }));\n },\n task: async () => {\n await runShell('git init');\n await setTimeout(500);\n },\n },\n {\n title: '增加volta配置',\n skip: async () => {\n return !/\\d\\.\\d/.test(execSync('volta -v', { encoding: 'utf8' }));\n },\n task: async () => {\n await runShell(`volta pin node@${nodeVersion}`);\n await runShell(`volta pin pnpm@${pnpmVersion}`);\n },\n },\n {\n title: '安装插件',\n task: async (_, task) => {\n const packages: { label: string; pkgs: string[]; dev?: boolean }[] = [\n {\n label: 'dependencies',\n pkgs: [\n '@aomex/common',\n '@aomex/web',\n '@aomex/cors',\n '@aomex/etag',\n '@aomex/compress',\n '@aomex/http-logger',\n '@aomex/response-time',\n '@aomex/console',\n '@aomex/cron',\n '@aomex/helmet',\n '@aomex/openapi',\n '@aomex/swagger-ui',\n '@aomex/async-trace',\n '@prisma/client',\n '@aomex/cache',\n '@aomex/cache-redis-adapter',\n '@aomex/auth',\n '@aomex/prisma',\n '@aomex/logger',\n 'ioredis',\n 'prisma', // docker prisma migrate 要用,放dev会导致二进制不存在\n '@prisma/adapter-mariadb',\n 'dotenv',\n ],\n },\n {\n label: 'dev dependencies',\n pkgs: [\n 'typescript',\n 'tsx',\n 'tsc-alias',\n '@types/node',\n 'husky',\n 'prettier',\n '@commitlint/cli',\n '@commitlint/config-conventional',\n 'prisma-json-types-generator',\n ],\n dev: true,\n },\n ];\n\n for (let i = 0; i < packages.length; ++i) {\n const { pkgs, dev, label } = packages[i]!;\n task.suffix = terminal.style('gray', label);\n await runShell(`pnpm add ${pkgs.join(' ')} ${dev ? '-D' : ''}`);\n }\n task.suffix = '';\n },\n },\n {\n title: '生成prisma客户端',\n task: async () => {\n await runShell('npx prisma generate');\n },\n },\n]);\n\nif (error) process.exit(1);\n\nconsole.log(\n '\\n项目创建成功:' +\n terminal.style(['blue', 'underline'], process.cwd()) +\n '\\n' +\n '启动项目可执行如下指令:' +\n '\\n\\n' +\n terminal.style('green', `cd ${projectName} && pnpm start`) +\n '\\n',\n);\n","import { terminal } from '@aomex/console';\nimport { input } from '@inquirer/prompts';\nimport { existsSync, readdirSync } from 'node:fs';\nimport sanitize from 'sanitize-filename';\nimport path from 'path';\n\nconst kebabCase = (value: string) => {\n value = sanitize(value);\n if (!value.length) return '';\n value = value[0]!.toLowerCase() + value.slice(1);\n return value\n .replace(/[A-Z]/g, (i) => '-' + i.toLowerCase())\n .replace(/_/g, '-')\n .replace(/-+/g, '-');\n};\n\nexport const inputProject = async (argv: Record<string, any>) => {\n let projectName: string = argv['project'];\n if (projectName) {\n projectName = kebabCase(projectName);\n const available = isProjectDirAvailable(projectName);\n if (typeof available === 'string') {\n terminal.printError(available);\n process.exit(1);\n }\n } else {\n projectName = await input({\n message: '请输入项目',\n validate(value) {\n return isProjectDirAvailable(value);\n },\n transformer(value) {\n return kebabCase(value);\n },\n });\n projectName = kebabCase(projectName);\n }\n\n return projectName;\n};\n\nconst isProjectDirAvailable = (projectName: string): string | true => {\n projectName = projectName.trim();\n if (!projectName.trim()) return '项目名不能为空';\n const targetDir = path.resolve(projectName);\n if (!existsSync(targetDir)) return true;\n if (!readdirSync(targetDir).length) return true;\n return `目录 \"${targetDir}\" 包含其它文件,请手动删除或选择新的项目名`;\n};\n","import { terminal } from '@aomex/console';\nimport { select } from '@inquirer/prompts';\n\nexport const selectNodeVersion = async (argv: Record<string, any>) => {\n let nodeVersion: string = argv['node'];\n if (!nodeVersion) {\n const nodes = await promise;\n nodeVersion = await select({\n message: '请选择node.js稳定版本',\n choices: nodes.map((item) => {\n return {\n name: `${item.version} ${terminal.style(['gray', 'dim'], item.date)}`,\n value: item.version,\n short: item.version,\n };\n }),\n loop: false,\n });\n }\n\n return nodeVersion.replace(/^v/, '');\n};\n\nconst fetchNodes = async () => {\n const response = await fetch(\n 'https://nodejs.org/download/release/index.json',\n );\n const nodes = (await response.json()) as {\n version: string;\n lts: boolean;\n date: string;\n }[];\n\n return nodes\n .map((item) => {\n return {\n ...item,\n versions: item.version.slice(1).split('.').map(Number) as [\n number,\n number,\n number,\n ],\n };\n })\n .filter((item) => {\n if (!item.lts) return false;\n if (item.versions[0] === 22 && item.versions[1] >= 15) return true;\n if (item.versions[0] >= 24) return true;\n return false;\n });\n};\n\nconst promise = fetchNodes();\n"],"mappings":";;;AAEA,OAAOA,WAAU;AACjB,OAAO,iBAAiB;AACxB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAAC,iBAAgB;AACzB,SAAS,UAAU,aAAa;AAChC,SAAS,kBAAkB;;;ACf3B,SAAS,gBAAgB;AACzB,SAAS,aAAa;AACtB,SAAS,YAAY,mBAAmB;AACxC,OAAO,cAAc;AACrB,OAAO,UAAU;AAEjB,IAAM,YAAY,CAAC,UAAkB;AACnC,UAAQ,SAAS,KAAK;AACtB,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,UAAQ,MAAM,CAAC,EAAG,YAAY,IAAI,MAAM,MAAM,CAAC;AAC/C,SAAO,MACJ,QAAQ,UAAU,CAAC,MAAM,MAAM,EAAE,YAAY,CAAC,EAC9C,QAAQ,MAAM,GAAG,EACjB,QAAQ,OAAO,GAAG;AACvB;AAEO,IAAM,eAAe,OAAOC,UAA8B;AAC/D,MAAIC,eAAsBD,MAAK,SAAS;AACxC,MAAIC,cAAa;AACf,IAAAA,eAAc,UAAUA,YAAW;AACnC,UAAM,YAAY,sBAAsBA,YAAW;AACnD,QAAI,OAAO,cAAc,UAAU;AACjC,eAAS,WAAW,SAAS;AAC7B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,OAAO;AACL,IAAAA,eAAc,MAAM,MAAM;AAAA,MACxB,SAAS;AAAA,MACT,SAAS,OAAO;AACd,eAAO,sBAAsB,KAAK;AAAA,MACpC;AAAA,MACA,YAAY,OAAO;AACjB,eAAO,UAAU,KAAK;AAAA,MACxB;AAAA,IACF,CAAC;AACD,IAAAA,eAAc,UAAUA,YAAW;AAAA,EACrC;AAEA,SAAOA;AACT;AAEA,IAAM,wBAAwB,CAACA,iBAAuC;AACpE,EAAAA,eAAcA,aAAY,KAAK;AAC/B,MAAI,CAACA,aAAY,KAAK,EAAG,QAAO;AAChC,QAAMC,aAAY,KAAK,QAAQD,YAAW;AAC1C,MAAI,CAAC,WAAWC,UAAS,EAAG,QAAO;AACnC,MAAI,CAAC,YAAYA,UAAS,EAAE,OAAQ,QAAO;AAC3C,SAAO,iBAAOA,UAAS;AACzB;;;AChDA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,cAAc;AAEhB,IAAM,oBAAoB,OAAOC,UAA8B;AACpE,MAAIC,eAAsBD,MAAK,MAAM;AACrC,MAAI,CAACC,cAAa;AAChB,UAAM,QAAQ,MAAM;AACpB,IAAAA,eAAc,MAAM,OAAO;AAAA,MACzB,SAAS;AAAA,MACT,SAAS,MAAM,IAAI,CAAC,SAAS;AAC3B,eAAO;AAAA,UACL,MAAM,GAAG,KAAK,OAAO,IAAIF,UAAS,MAAM,CAAC,QAAQ,KAAK,GAAG,KAAK,IAAI,CAAC;AAAA,UACnE,OAAO,KAAK;AAAA,UACZ,OAAO,KAAK;AAAA,QACd;AAAA,MACF,CAAC;AAAA,MACD,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAOE,aAAY,QAAQ,MAAM,EAAE;AACrC;AAEA,IAAM,aAAa,YAAY;AAC7B,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,EACF;AACA,QAAM,QAAS,MAAM,SAAS,KAAK;AAMnC,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,KAAK,QAAQ,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAAA,IAKvD;AAAA,EACF,CAAC,EACA,OAAO,CAAC,SAAS;AAChB,QAAI,CAAC,KAAK,IAAK,QAAO;AACtB,QAAI,KAAK,SAAS,CAAC,MAAM,MAAM,KAAK,SAAS,CAAC,KAAK,GAAI,QAAO;AAC9D,QAAI,KAAK,SAAS,CAAC,KAAK,GAAI,QAAO;AACnC,WAAO;AAAA,EACT,CAAC;AACL;AAEA,IAAM,UAAU,WAAW;;;AFjC3B,IAAM,WAAW,OAAO,YAAoB;AAC1C,QAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACrC,UAAM,SAAS,MAAM,SAAS;AAAA,MAC5B,KAAK,QAAQ,IAAI;AAAA,MACjB,KAAK,QAAQ;AAAA,MACb,OAAO;AAAA,IACT,CAAC;AACD,WAAO,GAAG,SAAS,OAAO;AAC1B,WAAO,GAAG,SAAS,MAAM;AAAA,EAC3B,CAAC;AACH;AAEA,IAAM,OAAO,YAAY,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC9C,IAAM,cAAcC,MAAK,KAAK,YAAY,SAAS,MAAM,WAAW;AACpE,IAAM,cAAc,MAAM,aAAa,IAAI;AAC3C,IAAM,cACJ,SAAS,yBAAyB;AAAA,EAChC,UAAU;AACZ,CAAC,EAAE,WAAW,MAAM,EAAE,KAAK;AAE7B,IAAM,cAAc,MAAM,kBAAkB,IAAI;AAChD,IAAM,mBAAmB,YAAY,MAAM,GAAG,EAAE,CAAC;AACjD,IAAM,YAAYA,MAAK,QAAQ,WAAW;AAE1C,IAAM,EAAE,MAAM,IAAI,MAAMC,UAAS,SAAS;AAAA,EACxC;AAAA,IACE,OAAO;AAAA,IACP,MAAM,YAAY;AAChB,YAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAC1C,cAAQ,MAAM,SAAS;AACvB,YAAM,WAAW,GAAG;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM,YAAY;AAChB,UAAI,WAAW,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,KAAK,OAAO,CAAC,CAAC;AAC7D,eAAS,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG;AAC1B,oBAAY,KAAK,MAAM,KAAK,KAAK,OAAO,CAAC;AAAA,MAC3C;AAEA,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,GAAG,aAAa,WAAW,EAAE,WAAW,KAAK,CAAC;AACpD,YAAM,QAAQ,MAAM,QAAQ,WAAW,EAAE,WAAW,KAAK,CAAC;AAC1D,iBAAW,QAAQ,OAAO;AACxB,cAAM,UAAU,MAAM,KAAKD,MAAK,KAAK,WAAW,IAAI,CAAC,GAAG,OAAO;AAC/D,YAAI,CAAC,OAAQ;AACb,cAAM,mBAAmBA,MAAK,QAAQ,IAAI;AAC1C,YAAI,cAAc,MAAM,SAAS,kBAAkB,MAAM;AACzD,eAAO,QAAQ,SAAS,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAClD,wBAAc,YAAY,WAAW,KAAK,GAAG,MAAM,KAAK;AAAA,QAC1D,CAAC;AACD,cAAM,UAAU,kBAAkB,WAAW;AAAA,MAC/C;AAEA,YAAM;AAAA,QACJA,MAAK,KAAK,WAAW,WAAW;AAAA,QAChCA,MAAK,KAAK,WAAW,YAAY;AAAA,MACnC;AACA,YAAM,WAAW,GAAG;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM,YAAY;AAChB,aAAO,CAAC,SAAS,KAAK,SAAS,UAAU,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,IAChE;AAAA,IACA,MAAM,YAAY;AAChB,YAAM,SAAS,UAAU;AACzB,YAAM,WAAW,GAAG;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM,YAAY;AAChB,aAAO,CAAC,SAAS,KAAK,SAAS,YAAY,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,IAClE;AAAA,IACA,MAAM,YAAY;AAChB,YAAM,SAAS,kBAAkB,WAAW,EAAE;AAC9C,YAAM,SAAS,kBAAkB,WAAW,EAAE;AAAA,IAChD;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM,OAAO,GAAG,SAAS;AACvB,YAAM,WAA+D;AAAA,QACnE;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,KAAK;AAAA,QACP;AAAA,MACF;AAEA,eAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,EAAE,GAAG;AACxC,cAAM,EAAE,MAAM,KAAK,MAAM,IAAI,SAAS,CAAC;AACvC,aAAK,SAASC,UAAS,MAAM,QAAQ,KAAK;AAC1C,cAAM,SAAS,YAAY,KAAK,KAAK,GAAG,CAAC,IAAI,MAAM,OAAO,EAAE,EAAE;AAAA,MAChE;AACA,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,MAAM,YAAY;AAChB,YAAM,SAAS,qBAAqB;AAAA,IACtC;AAAA,EACF;AACF,CAAC;AAED,IAAI,MAAO,SAAQ,KAAK,CAAC;AAEzB,QAAQ;AAAA,EACN,iDACEA,UAAS,MAAM,CAAC,QAAQ,WAAW,GAAG,QAAQ,IAAI,CAAC,IACnD,mFAGAA,UAAS,MAAM,SAAS,MAAM,WAAW,gBAAgB,IACzD;AACJ;","names":["path","terminal","argv","projectName","targetDir","terminal","argv","nodeVersion","path","terminal"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-aomex",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.77",
|
|
4
4
|
"repository": "git@github.com:aomex/create-aomex.git",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,29 +30,29 @@
|
|
|
30
30
|
],
|
|
31
31
|
"bin": "dist/index.js",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@aomex/common": "^3.
|
|
34
|
-
"@aomex/console": "^3.
|
|
33
|
+
"@aomex/common": "^3.30.2",
|
|
34
|
+
"@aomex/console": "^3.30.2",
|
|
35
35
|
"@inquirer/prompts": "^7.4.1",
|
|
36
36
|
"sanitize-filename": "^1.6.3",
|
|
37
37
|
"yargs-parser": "^21.1.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@aomex/async-trace": "^3.
|
|
41
|
-
"@aomex/auth": "^3.
|
|
42
|
-
"@aomex/cache": "^3.
|
|
43
|
-
"@aomex/cache-redis-adapter": "^3.
|
|
44
|
-
"@aomex/compress": "^3.
|
|
45
|
-
"@aomex/cors": "^3.
|
|
46
|
-
"@aomex/cron": "^3.
|
|
47
|
-
"@aomex/etag": "^3.
|
|
48
|
-
"@aomex/helmet": "^3.
|
|
49
|
-
"@aomex/http-logger": "^3.
|
|
50
|
-
"@aomex/logger": "^3.
|
|
51
|
-
"@aomex/openapi": "^3.
|
|
52
|
-
"@aomex/prisma": "^3.
|
|
53
|
-
"@aomex/response-time": "^3.
|
|
54
|
-
"@aomex/swagger-ui": "^3.
|
|
55
|
-
"@aomex/web": "^3.
|
|
40
|
+
"@aomex/async-trace": "^3.30.2",
|
|
41
|
+
"@aomex/auth": "^3.30.2",
|
|
42
|
+
"@aomex/cache": "^3.30.2",
|
|
43
|
+
"@aomex/cache-redis-adapter": "^3.30.2",
|
|
44
|
+
"@aomex/compress": "^3.30.2",
|
|
45
|
+
"@aomex/cors": "^3.30.2",
|
|
46
|
+
"@aomex/cron": "^3.30.2",
|
|
47
|
+
"@aomex/etag": "^3.30.2",
|
|
48
|
+
"@aomex/helmet": "^3.30.2",
|
|
49
|
+
"@aomex/http-logger": "^3.30.2",
|
|
50
|
+
"@aomex/logger": "^3.30.2",
|
|
51
|
+
"@aomex/openapi": "^3.30.2",
|
|
52
|
+
"@aomex/prisma": "^3.30.2",
|
|
53
|
+
"@aomex/response-time": "^3.30.2",
|
|
54
|
+
"@aomex/swagger-ui": "^3.30.2",
|
|
55
|
+
"@aomex/web": "^3.30.2",
|
|
56
56
|
"@prisma/client": "^6.6.0",
|
|
57
57
|
"@types/lodash.kebabcase": "^4.1.9",
|
|
58
58
|
"@types/node": "^22.14.1",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE `user` (
|
|
3
|
+
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
|
4
|
+
`name` VARCHAR(191) NOT NULL,
|
|
5
|
+
`age` INTEGER NOT NULL DEFAULT 17,
|
|
6
|
+
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
7
|
+
`updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
8
|
+
|
|
9
|
+
UNIQUE INDEX `user_name_key`(`name`),
|
|
10
|
+
PRIMARY KEY (`id`)
|
|
11
|
+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
datasource db {
|
|
2
2
|
provider = "mysql"
|
|
3
|
-
url = env("DATABASE_URL")
|
|
4
3
|
relationMode = "prisma"
|
|
5
4
|
}
|
|
6
5
|
|
|
7
6
|
generator client {
|
|
8
|
-
provider = "prisma-client
|
|
7
|
+
provider = "prisma-client"
|
|
8
|
+
output = "../src/generated/prisma"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
generator json {
|
|
12
|
+
provider = "prisma-json-types-generator"
|
|
13
|
+
namespace = "PrismaJson"
|
|
9
14
|
}
|
|
10
15
|
|
|
11
16
|
generator aomex {
|
|
12
17
|
provider = "aomex-prisma"
|
|
18
|
+
output = "../src/generated/aomex/prisma"
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
model user {
|
|
16
22
|
id Int @id @default(autoincrement())
|
|
17
23
|
name String @unique
|
|
18
24
|
age Int @default(17)
|
|
19
|
-
created_at DateTime @default(now())
|
|
20
|
-
updated_at DateTime @default(now()) @updatedAt()
|
|
25
|
+
created_at DateTime @default(now())
|
|
26
|
+
updated_at DateTime @default(now()) @updatedAt()
|
|
21
27
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { rule } from '@aomex/common';
|
|
2
|
+
import { body, response, Router } from '@aomex/web';
|
|
3
|
+
import { services } from '@services';
|
|
4
|
+
import { prismaInput, prismaOutput } from '../generated/aomex/prisma';
|
|
5
|
+
|
|
6
|
+
export const router = new Router({
|
|
7
|
+
prefix: '/users',
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
router.get('/', {
|
|
11
|
+
mount: [
|
|
12
|
+
response({
|
|
13
|
+
statusCode: 200,
|
|
14
|
+
content: rule.array(prismaOutput.user.columns),
|
|
15
|
+
}),
|
|
16
|
+
],
|
|
17
|
+
action: async (ctx) => {
|
|
18
|
+
const users = await services.user.findUsers();
|
|
19
|
+
ctx.send(users);
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
router.post('/', {
|
|
24
|
+
mount: [
|
|
25
|
+
body({
|
|
26
|
+
...prismaInput.user.pick('name', 'age'),
|
|
27
|
+
}),
|
|
28
|
+
response({
|
|
29
|
+
statusCode: 201,
|
|
30
|
+
content: prismaOutput.user.columns,
|
|
31
|
+
}),
|
|
32
|
+
],
|
|
33
|
+
action: async (ctx) => {
|
|
34
|
+
const user = await services.user.createUser(ctx.body);
|
|
35
|
+
ctx.send(201, user);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { combineServices } from '@aomex/common';
|
|
2
2
|
import { CacheService } from './cache.service';
|
|
3
|
+
import { UserService } from './user.service';
|
|
3
4
|
|
|
4
5
|
export const services = await combineServices({
|
|
5
6
|
cache: CacheService,
|
|
7
|
+
user: UserService,
|
|
6
8
|
});
|
|
7
9
|
|
|
8
10
|
declare module '@aomex/common' {
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import { PrismaClient } from '
|
|
2
|
-
import * as runtime from '@prisma/client/runtime/
|
|
1
|
+
import { PrismaClient } from '../generated/prisma/client';
|
|
2
|
+
import * as runtime from '@prisma/client/runtime/client';
|
|
3
|
+
|
|
4
|
+
import { PrismaMariaDb } from '@prisma/adapter-mariadb';
|
|
5
|
+
|
|
6
|
+
const config = new URL(process.env['DATABASE_URL']!);
|
|
7
|
+
const adapter = new PrismaMariaDb({
|
|
8
|
+
host: config.hostname,
|
|
9
|
+
port: parseInt(config.port),
|
|
10
|
+
user: config.username,
|
|
11
|
+
password: config.password,
|
|
12
|
+
database: config.pathname.slice(1),
|
|
13
|
+
});
|
|
3
14
|
|
|
4
15
|
export const prisma = new PrismaClient({
|
|
5
|
-
|
|
16
|
+
adapter,
|
|
6
17
|
});
|
|
7
18
|
|
|
8
19
|
export type PrismaTX = Omit<PrismaClient, runtime.ITXClientDenyList>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Service } from '@aomex/common';
|
|
2
|
+
import { prisma } from './prisma';
|
|
3
|
+
import type { Prisma } from '../generated/prisma/client';
|
|
4
|
+
|
|
5
|
+
export class UserService extends Service {
|
|
6
|
+
async findUsers() {
|
|
7
|
+
return await prisma.user.findMany();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async findUserById(id: number) {
|
|
11
|
+
return await prisma.user.findUnique({
|
|
12
|
+
where: {
|
|
13
|
+
id,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async createUser(data: Prisma.userCreateInput) {
|
|
19
|
+
return prisma.user.create({
|
|
20
|
+
data,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async updateUser(id: number, data: Prisma.userUpdateInput) {
|
|
25
|
+
return await prisma.user.update({
|
|
26
|
+
where: { id },
|
|
27
|
+
data,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
package/templates/tsconfig.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"target": "
|
|
4
|
-
"module": "
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "es2022",
|
|
5
5
|
"strict": true,
|
|
6
6
|
"esModuleInterop": true,
|
|
7
7
|
"skipLibCheck": true,
|
|
8
|
+
"moduleResolution": "node",
|
|
8
9
|
"forceConsistentCasingInFileNames": true,
|
|
9
|
-
"moduleResolution": "node10",
|
|
10
10
|
"allowUnusedLabels": false,
|
|
11
11
|
"allowUnreachableCode": false,
|
|
12
12
|
"exactOptionalPropertyTypes": false,
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"noImplicitThis": true,
|
|
33
33
|
"allowSyntheticDefaultImports": true,
|
|
34
34
|
"resolveJsonModule": true,
|
|
35
|
+
"typeRoots": ["./typings", "node_modules/@types"],
|
|
35
36
|
"paths": {
|
|
36
37
|
"@configs": ["./src/configs/index.ts"],
|
|
37
38
|
"@configs/*": ["./src/configs/*"],
|