milkio 0.0.10 → 0.0.11

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 (45) hide show
  1. package/.co.toml +0 -0
  2. package/api-test/index.ts +64 -0
  3. package/c.ts +39 -57
  4. package/defines/define-api-test.ts +3 -3
  5. package/defines/define-api.ts +3 -3
  6. package/defines/define-http-handler.ts +60 -69
  7. package/defines/define-middleware.ts +2 -2
  8. package/defines/define-use.ts +6 -6
  9. package/index.ts +23 -22
  10. package/kernel/context.ts +1 -2
  11. package/kernel/fail.ts +6 -6
  12. package/kernel/logger.ts +38 -38
  13. package/kernel/meta.ts +5 -5
  14. package/kernel/middleware.ts +16 -16
  15. package/kernel/milkio.ts +70 -95
  16. package/kernel/runtime.ts +2 -7
  17. package/kernel/validate.ts +5 -5
  18. package/package.json +4 -1
  19. package/scripts/gen-insignificant.ts +261 -0
  20. package/scripts/gen-significant.ts +176 -0
  21. package/{scripts → scripts-del}/build-cookbook.ts +119 -119
  22. package/scripts-del/build-dto.ts +65 -0
  23. package/{scripts → scripts-del}/generate/generate-app-partial.ts +31 -31
  24. package/{scripts → scripts-del}/generate/generate-app.ts +41 -41
  25. package/scripts-del/generate/generate-database.ts +22 -0
  26. package/scripts-del/generate-partial.ts +15 -0
  27. package/scripts-del/generate.ts +23 -0
  28. package/templates/api.ts +4 -4
  29. package/types.ts +29 -19
  30. package/utils/create-template.ts +5 -5
  31. package/utils/create-ulid.ts +3 -3
  32. package/utils/env-to-boolean.ts +5 -5
  33. package/utils/env-to-number.ts +2 -2
  34. package/utils/env-to-string.ts +2 -2
  35. package/utils/exec.ts +12 -12
  36. package/utils/handle-catch-error.ts +10 -10
  37. package/utils/remove-dir.ts +11 -11
  38. package/utils/tson.ts +2 -2
  39. package/defines/define-api-test-handler.ts +0 -71
  40. package/kernel/config.ts +0 -14
  41. package/scripts/build-dto.ts +0 -65
  42. package/scripts/generate/generate-database.ts +0 -22
  43. package/scripts/generate-database.ts +0 -23
  44. package/scripts/generate-partial.ts +0 -15
  45. package/scripts/generate.ts +0 -23
@@ -1,116 +1,116 @@
1
1
  /* eslint-disable no-console, @typescript-eslint/no-dynamic-delete */
2
2
 
3
- import { TSON, type Cookbook } from "..";
4
- import { join } from "node:path";
5
- import { cwd } from "node:process";
6
- import { writeFile, readFile } from "node:fs/promises";
3
+ import { TSON, type Cookbook } from ".."
4
+ import { join } from "node:path"
5
+ import { cwd } from "node:process"
6
+ import { writeFile, readFile } from "node:fs/promises"
7
7
 
8
8
  export async function buildCookbook() {
9
- const schema = await import("../../../generate/api-schema");
10
- const paths = Object.keys(schema.default.apiMethodsSchema);
9
+ const schema = await import("../../../generated/api-schema")
10
+ const paths = Object.keys(schema.default.apiMethodsSchema)
11
11
 
12
- const cookbook: Cookbook = {};
12
+ const cookbook: Cookbook = {}
13
13
  for (const path of paths) {
14
14
  // const module = await import(/* @vite-ignore */ join(`../../../src/apps/${path}`));
15
- const code = (await readFile(join(cwd(), `./src/apps/${path}.ts`))).toString();
16
- const codeLines = code.split("\n");
17
- let title;
18
- let desc;
19
- const descRaw = /\n\/\*\*\n[\s\S]+?\*\//.exec(code)?.[0] ?? "";
15
+ const code = (await readFile(join(cwd(), `./src/apps/${path}.ts`))).toString()
16
+ const codeLines = code.split("\n")
17
+ let title
18
+ let desc
19
+ const descRaw = /\n\/\*\*\n[\s\S]+?\*\//.exec(code)?.[0] ?? ""
20
20
 
21
21
  if (descRaw) {
22
- const descRawLines = descRaw.split("\n");
23
- if (descRawLines.at(0)?.trim() === "") descRawLines.shift();
24
- if (descRawLines.at(-1)?.trim() === "") descRawLines.pop();
25
- let first = true;
22
+ const descRawLines = descRaw.split("\n")
23
+ if (descRawLines.at(0)?.trim() === "") descRawLines.shift()
24
+ if (descRawLines.at(-1)?.trim() === "") descRawLines.pop()
25
+ let first = true
26
26
  for (let index = 0; index < descRawLines.length; index++) {
27
- const descRawLine = descRawLines[index].replace(/^[/ ]+?[*]*/, "").replace(/[*]*\/$/, "");
27
+ const descRawLine = descRawLines[index].replace(/^[/ ]+?[*]*/, "").replace(/[*]*\/$/, "")
28
28
 
29
- if (!descRawLine) continue;
29
+ if (!descRawLine) continue
30
30
  if (first) {
31
- title = descRawLine.replace(/#/g, "").trim();
31
+ title = descRawLine.replace(/#/g, "").trim()
32
32
  // Originally the title was in the first line, desc is the rest of it, now desc contains complete markdown content.
33
33
  // continue;
34
34
  }
35
- first = false;
36
- desc = (desc ?? "") + "\n" + descRawLine.trim();
35
+ first = false
36
+ desc = (desc ?? "") + "\n" + descRawLine.trim()
37
37
  }
38
38
  }
39
39
 
40
- let apiParams = /action\([\s\S]+?\)/.exec(code)?.[0] ?? ""; // The intention of the following code is to extract the parameter part of the action.
41
- apiParams = /\([\s\S]*,/.exec(apiParams)?.[0] ?? "";
42
- apiParams = apiParams.slice(0, -1);
43
- apiParams = apiParams.slice(/[\s\S]+?:/.exec(apiParams)?.[0].length);
44
- const apiParamsLines = apiParams.split("\n"); // The intention of the following code is to remove extra spaces, which will make the code look more beautiful.
45
- if (apiParamsLines.at(-1)?.trim() === "") apiParamsLines.pop();
46
- if (apiParamsLines.at(-1)?.trim() === "") apiParamsLines.pop();
47
- let spaceNumber = 0;
40
+ let apiParams = /action\([\s\S]+?\)/.exec(code)?.[0] ?? "" // The intention of the following code is to extract the parameter part of the action.
41
+ apiParams = /\([\s\S]*,/.exec(apiParams)?.[0] ?? ""
42
+ apiParams = apiParams.slice(0, -1)
43
+ apiParams = apiParams.slice(/[\s\S]+?:/.exec(apiParams)?.[0].length)
44
+ const apiParamsLines = apiParams.split("\n") // The intention of the following code is to remove extra spaces, which will make the code look more beautiful.
45
+ if (apiParamsLines.at(-1)?.trim() === "") apiParamsLines.pop()
46
+ if (apiParamsLines.at(-1)?.trim() === "") apiParamsLines.pop()
47
+ let spaceNumber = 0
48
48
  for (const char of apiParamsLines.at(-1) ?? "") {
49
- if (char === " ") spaceNumber++;
50
- else break;
49
+ if (char === " ") spaceNumber++
50
+ else break
51
51
  }
52
52
  for (let index = 0; index < apiParamsLines.length; index++) {
53
- const line = apiParamsLines[index];
54
- let spaceNumberForThisLine = 0;
53
+ const line = apiParamsLines[index]
54
+ let spaceNumberForThisLine = 0
55
55
  for (const char of line) {
56
- if (char === " ") spaceNumberForThisLine++;
57
- else break;
56
+ if (char === " ") spaceNumberForThisLine++
57
+ else break
58
58
  }
59
59
  if (spaceNumberForThisLine >= spaceNumber) {
60
- apiParamsLines[index] = line.slice(spaceNumber);
60
+ apiParamsLines[index] = line.slice(spaceNumber)
61
61
  } else {
62
- apiParamsLines[index] = line.slice(spaceNumberForThisLine);
62
+ apiParamsLines[index] = line.slice(spaceNumberForThisLine)
63
63
  }
64
64
  }
65
- apiParams = apiParamsLines.join("\n");
65
+ apiParams = apiParamsLines.join("\n")
66
66
 
67
67
  // Find the code for the API testing section.
68
- const apiTestsCodeChars = [];
69
- let apiTestsStartIndex = undefined as undefined | number;
70
- let semicolonMatch = 0;
71
- let semicolonMax = 0;
68
+ const apiTestsCodeChars = []
69
+ let apiTestsStartIndex = undefined as undefined | number
70
+ let semicolonMatch = 0
71
+ let semicolonMax = 0
72
72
  for (let index = 0; index < codeLines.length; index++) {
73
- const codeLine = codeLines[index];
74
- if (apiTestsStartIndex === undefined && !codeLine.includes("defineApiTest(")) continue;
75
- if (apiTestsStartIndex === undefined) apiTestsStartIndex = index;
76
- const codeChars = codeLine.split("");
73
+ const codeLine = codeLines[index]
74
+ if (apiTestsStartIndex === undefined && !codeLine.includes("defineApiTest(")) continue
75
+ if (apiTestsStartIndex === undefined) apiTestsStartIndex = index
76
+ const codeChars = codeLine.split("")
77
77
  for (const codeChar of codeChars) {
78
78
  if (codeChar === "[") {
79
- semicolonMatch++;
80
- semicolonMax++;
79
+ semicolonMatch++
80
+ semicolonMax++
81
81
  }
82
- if (semicolonMatch !== 0) apiTestsCodeChars.push(codeChar);
83
- if (codeChar === "]") semicolonMatch--;
82
+ if (semicolonMatch !== 0) apiTestsCodeChars.push(codeChar)
83
+ if (codeChar === "]") semicolonMatch--
84
84
  }
85
85
  if (semicolonMatch === 0 && semicolonMax >= 1) {
86
- break;
86
+ break
87
87
  }
88
- apiTestsCodeChars.push("\n");
88
+ apiTestsCodeChars.push("\n")
89
89
  }
90
90
 
91
91
  // Find the code for each API test case.
92
- const apiCaseCodes: Array<string> = [];
93
- let currentApiCaseCode = undefined as undefined | Array<string>;
94
- let apiTestCaseStartIndex = undefined as undefined | number;
95
- let apiTestCaseMatch = 0;
92
+ const apiCaseCodes: Array<string> = []
93
+ let currentApiCaseCode = undefined as undefined | Array<string>
94
+ let apiTestCaseStartIndex = undefined as undefined | number
95
+ let apiTestCaseMatch = 0
96
96
  for (let index = 0; index < apiTestsCodeChars.length; index++) {
97
- const apiTestsCodeChar = apiTestsCodeChars[index];
97
+ const apiTestsCodeChar = apiTestsCodeChars[index]
98
98
  if (apiTestCaseStartIndex === undefined && apiTestsCodeChar === "{") {
99
- currentApiCaseCode = [];
100
- apiTestCaseStartIndex = index;
99
+ currentApiCaseCode = []
100
+ apiTestCaseStartIndex = index
101
101
  }
102
102
  if (apiTestsCodeChar === "{") {
103
- apiTestCaseMatch++;
103
+ apiTestCaseMatch++
104
104
  }
105
105
 
106
- if (apiTestCaseMatch !== 0) currentApiCaseCode!.push(apiTestsCodeChar);
106
+ if (apiTestCaseMatch !== 0) currentApiCaseCode!.push(apiTestsCodeChar)
107
107
 
108
108
  if (apiTestsCodeChar === "}") {
109
- apiTestCaseMatch--;
109
+ apiTestCaseMatch--
110
110
  if (apiTestCaseMatch === 0) {
111
- apiCaseCodes.push(currentApiCaseCode!.join(""));
112
- currentApiCaseCode = undefined;
113
- apiTestCaseStartIndex = undefined;
111
+ apiCaseCodes.push(currentApiCaseCode!.join(""))
112
+ currentApiCaseCode = undefined
113
+ apiTestCaseStartIndex = undefined
114
114
  }
115
115
  }
116
116
  }
@@ -118,60 +118,60 @@ export async function buildCookbook() {
118
118
  const apiCases: Array<{
119
119
  name: string;
120
120
  handler: string;
121
- }> = [];
121
+ }> = []
122
122
 
123
123
  for (let index = 0; index < apiCaseCodes.length; index++) {
124
- const code = apiCaseCodes[index];
125
- const name = /name:[\s\S]+?,/.exec(code)?.[0]?.slice(5, -1)?.trim().slice(1, -1) ?? "";
126
- const handlerChars = /handler:[\s\S]*/.exec(code)?.[0]?.split("") ?? [];
127
- let handler = ""; // Find the main code of the handler.
128
- let handlerStartIndex = undefined as undefined | number;
129
- let handlerMatch = 0;
124
+ const code = apiCaseCodes[index]
125
+ const name = /name:[\s\S]+?,/.exec(code)?.[0]?.slice(5, -1)?.trim().slice(1, -1) ?? ""
126
+ const handlerChars = /handler:[\s\S]*/.exec(code)?.[0]?.split("") ?? []
127
+ let handler = "" // Find the main code of the handler.
128
+ let handlerStartIndex = undefined as undefined | number
129
+ let handlerMatch = 0
130
130
  for (let index = 0; index < handlerChars.length; index++) {
131
- const handlerChar = handlerChars[index];
132
- if (handlerStartIndex !== undefined && handlerChar === "{") handlerStartIndex = index;
133
- if (handlerChar === "{") handlerMatch++;
134
- if (handlerMatch !== 0) handler = handler + handlerChar;
135
- if (handlerChar === "}") handlerMatch--;
136
- if (handlerStartIndex !== undefined && handlerMatch === 0) break;
131
+ const handlerChar = handlerChars[index]
132
+ if (handlerStartIndex !== undefined && handlerChar === "{") handlerStartIndex = index
133
+ if (handlerChar === "{") handlerMatch++
134
+ if (handlerMatch !== 0) handler = handler + handlerChar
135
+ if (handlerChar === "}") handlerMatch--
136
+ if (handlerStartIndex !== undefined && handlerMatch === 0) break
137
137
  }
138
- handler = handler.slice(1, -1);
139
-
140
- const handlerLines = handler.split("\n"); // The intention of the following code is to remove extra spaces, which will make the code look more beautiful.
141
- if (handlerLines.at(-1)?.trim() === "") handlerLines.pop();
142
- if (handlerLines.at(-1)?.trim() === "") handlerLines.pop();
143
- if (handlerLines.at(0)?.trim() === "") handlerLines.shift();
144
- if (handlerLines.at(0)?.trim() === "") handlerLines.shift();
145
- let spaceNumber = 0;
138
+ handler = handler.slice(1, -1)
139
+
140
+ const handlerLines = handler.split("\n") // The intention of the following code is to remove extra spaces, which will make the code look more beautiful.
141
+ if (handlerLines.at(-1)?.trim() === "") handlerLines.pop()
142
+ if (handlerLines.at(-1)?.trim() === "") handlerLines.pop()
143
+ if (handlerLines.at(0)?.trim() === "") handlerLines.shift()
144
+ if (handlerLines.at(0)?.trim() === "") handlerLines.shift()
145
+ let spaceNumber = 0
146
146
  for (const char of handlerLines.at(-1) ?? "") {
147
- if (char === " ") spaceNumber++;
148
- else break;
147
+ if (char === " ") spaceNumber++
148
+ else break
149
149
  }
150
150
  for (let index = 0; index < handlerLines.length; index++) {
151
- const line = handlerLines[index];
152
- let spaceNumberForThisLine = 0;
151
+ const line = handlerLines[index]
152
+ let spaceNumberForThisLine = 0
153
153
  for (const char of line) {
154
- if (char === " ") spaceNumberForThisLine++;
155
- else break;
154
+ if (char === " ") spaceNumberForThisLine++
155
+ else break
156
156
  }
157
157
  if (spaceNumberForThisLine >= spaceNumber) {
158
- handlerLines[index] = line.slice(spaceNumber);
158
+ handlerLines[index] = line.slice(spaceNumber)
159
159
  } else {
160
- handlerLines[index] = line.slice(spaceNumberForThisLine);
160
+ handlerLines[index] = line.slice(spaceNumberForThisLine)
161
161
  }
162
162
  }
163
- handler = handlerLines.join("\n");
163
+ handler = handlerLines.join("\n")
164
164
 
165
165
  apiCases.push({
166
166
  name,
167
167
  handler
168
- });
168
+ })
169
169
  }
170
170
 
171
171
  // This value has been deprecated because TypeScript types can already replace it well
172
172
  // let paramsSchema;
173
173
  // try {
174
- // const moduleGenerated = await import(/* @vite-ignore */ `../../../generate/products/apps/${path}`);
174
+ // const moduleGenerated = await import(/* @vite-ignore */ `../../../generated/products/apps/${path}`);
175
175
  // paramsSchema = moduleGenerated.paramsSchema.schemas[0]?.properties?.data;
176
176
  // } catch (error) {}
177
177
 
@@ -180,46 +180,46 @@ export async function buildCookbook() {
180
180
  desc,
181
181
  params: apiParams,
182
182
  cases: apiCases
183
- };
183
+ }
184
184
  }
185
185
 
186
186
  /**
187
187
  * -- indexes
188
188
  */
189
189
 
190
- const indexes: Record<string, Array<string>> = {};
191
- const folderIndexes: Record<string, Array<string>> = {};
192
- indexes["(root)"] = [];
193
- folderIndexes["(root)"] = [];
190
+ const indexes: Record<string, Array<string>> = {}
191
+ const folderIndexes: Record<string, Array<string>> = {}
192
+ indexes["(root)"] = []
193
+ folderIndexes["(root)"] = []
194
194
  for (const path in cookbook) {
195
- if (!path.includes("/")) indexes["(root)"].push(path);
195
+ if (!path.includes("/")) indexes["(root)"].push(path)
196
196
  }
197
197
  for (const path in cookbook) {
198
- const dirnames = path.split("/");
198
+ const dirnames = path.split("/")
199
199
  for (let index = 0; index < dirnames.length - 1; index++) {
200
- const dirpath = dirnames.slice(0, index + 1).join("/");
201
- if (!indexes[dirpath]) indexes[dirpath] = [];
202
- if (!folderIndexes[dirpath]) folderIndexes[dirpath] = [];
200
+ const dirpath = dirnames.slice(0, index + 1).join("/")
201
+ if (!indexes[dirpath]) indexes[dirpath] = []
202
+ if (!folderIndexes[dirpath]) folderIndexes[dirpath] = []
203
203
  if (index + 1 === dirnames.length - 1) {
204
- indexes[dirpath].push(path);
204
+ indexes[dirpath].push(path)
205
205
  } else {
206
- const childDirpath = dirnames.slice(0, index + 2).join("/");
207
- if (folderIndexes[dirpath].includes(childDirpath)) continue;
208
- folderIndexes[dirpath].push(childDirpath);
206
+ const childDirpath = dirnames.slice(0, index + 2).join("/")
207
+ if (folderIndexes[dirpath].includes(childDirpath)) continue
208
+ folderIndexes[dirpath].push(childDirpath)
209
209
  }
210
210
  }
211
211
  }
212
212
  for (const path in folderIndexes) {
213
- if (path.includes("/") || path === "(root)") continue;
214
- folderIndexes["(root)"].push(path);
213
+ if (path.includes("/") || path === "(root)") continue
214
+ folderIndexes["(root)"].push(path)
215
215
  }
216
216
 
217
- const readme = (await readFile(join(cwd(), "src", "apps", "README.md"))).toString();
218
- Object.keys(indexes).forEach((key) => indexes[key].length === 0 && delete indexes[key]);
219
- const generatedAt = new Date();
217
+ const readme = (await readFile(join(cwd(), "src", "apps", "README.md"))).toString()
218
+ Object.keys(indexes).forEach((key) => indexes[key].length === 0 && delete indexes[key])
219
+ const generatedAt = new Date()
220
220
 
221
221
  await writeFile(
222
- join(cwd(), `./generate/cookbook.json`),
222
+ join(cwd(), `./generated/cookbook.json`),
223
223
  TSON.stringify({
224
224
  cookbook,
225
225
  readme,
@@ -227,7 +227,7 @@ export async function buildCookbook() {
227
227
  folderIndexes,
228
228
  generatedAt
229
229
  })
230
- );
230
+ )
231
231
  }
232
232
 
233
- void buildCookbook();
233
+ void buildCookbook()
@@ -0,0 +1,65 @@
1
+ /* eslint-disable no-console */
2
+ import { cwd, platform } from "node:process"
3
+ import { exec as nodeExec } from "node:child_process"
4
+ import { removeDir } from "../utils/remove-dir"
5
+ import { join } from "node:path"
6
+ import { copyFile, mkdir } from "node:fs/promises"
7
+
8
+ export async function buildDTO() {
9
+ console.log("🥛 Milkio DTO Building..")
10
+
11
+ removeDir(join(cwd(), "packages", "dto", "dist"))
12
+ removeDir(join(cwd(), "packages", "dto", "generated"))
13
+ await mkdir(join(cwd(), "packages", "dto", "dist"))
14
+ await mkdir(join(cwd(), "packages", "dto", "generated"))
15
+
16
+ // Generate the corresponding types for the files in the project and output them to the /packages/dto/generate directory.
17
+ await new Promise((resolve) =>
18
+ nodeExec("bun ./node_modules/typescript/bin/tsc --project tsconfig.build-dto.json", (e, stdout) => {
19
+ resolve(e)
20
+ })
21
+ )
22
+ await copyFile(join(cwd(), "src", "fail-code.ts"), join(cwd(), "packages", "dto", "generated", "src", "fail-code.ts"))
23
+
24
+ // Packaging type for the dto
25
+ await new Promise((resolve) =>
26
+ nodeExec("cd ./packages/dto && bunx tsc", (e) => {
27
+ resolve(e)
28
+ })
29
+ )
30
+
31
+ // build /src/dto/index.ts to js
32
+ await Bun.build({
33
+ entrypoints: ["./packages/dto/index.ts"],
34
+ outdir: "./packages/dto"
35
+ })
36
+
37
+ const root = join(cwd(), "packages", "dto")
38
+
39
+ console.log("🥛 Milkio DTO Build Finished")
40
+ console.log("\x1B[2m")
41
+ console.log("Now, your latest code (including changes to your interface) is built to the latest version and waiting for your release!")
42
+ console.log("")
43
+ console.log("If you want to publish it to NPM, you can use a command similar to the following.")
44
+ console.log(`(But before that, you may need to modify the package name (${join(cwd(), "packages", "dto", "package.json")}) and login to your NPM account or private NPM repository)`)
45
+
46
+ if (platform !== "win32") {
47
+ console.log("You can publish it to npm by running this commands:\n")
48
+ console.log("\u001B[0m---")
49
+ console.log(`cd ${join(root)} \\`)
50
+ console.log(" && npm version major \\")
51
+ console.log(" && npm publish --access public \\")
52
+ console.log(` && cd ${join(cwd())}`)
53
+ } else {
54
+ console.log("You can publish it to npm by running this commands (use \x1B[42mPowerShell\x1B[0m):")
55
+ console.log("\u001B[0m---")
56
+ console.log('$ErrorActionPreference = "Stop";')
57
+ console.log(`Set-Location ${join(root)};`)
58
+ console.log("npm version major;")
59
+ console.log("npm publish --access public;")
60
+ console.log(`Set-Location ${join(cwd())};`)
61
+ }
62
+ console.log("---")
63
+ }
64
+
65
+ await buildDTO()
@@ -1,56 +1,56 @@
1
1
  /* eslint-disable no-console */
2
2
 
3
- import ejs from "ejs";
4
- import { join } from "node:path";
5
- import { existsSync, mkdirSync } from "node:fs";
6
- import { cwd, env, exit } from "node:process";
7
- import { writeFile, readFile } from "node:fs/promises";
8
- import { exec as nodeExec } from "node:child_process";
9
- import { camel, hump, hyphen } from "@poech/camel-hump-under";
3
+ import ejs from "ejs"
4
+ import { join } from "node:path"
5
+ import { existsSync, mkdirSync } from "node:fs"
6
+ import { cwd, env, exit } from "node:process"
7
+ import { writeFile, readFile } from "node:fs/promises"
8
+ import { exec as nodeExec } from "node:child_process"
9
+ import { camel, hump, hyphen } from "@poech/camel-hump-under"
10
10
 
11
11
  const utils = {
12
12
  camel: (str: string) => camel(str).replaceAll("-", "").replaceAll("_", ""),
13
13
  hump: (str: string) => hump(str).replaceAll("-", "").replaceAll("_", ""),
14
14
  hyphen: (str: string) => hyphen(str).replaceAll("_", "")
15
- };
15
+ }
16
16
 
17
17
  export async function generateAppPartial(path?: string) {
18
- const partialPath = path ?? env.GENERATE_PARTIAL_PATH!;
19
- const partialDir = partialPath.split("/").slice(0, -1).join("/");
18
+ const partialPath = path ?? env.GENERATE_PARTIAL_PATH!
19
+ const partialDir = partialPath.split("/").slice(0, -1).join("/")
20
20
  // Generate api-schema.ts file through templates
21
21
  const templateVars = {
22
22
  utils
23
- };
23
+ }
24
24
 
25
- if (!partialPath.endsWith(".ts")) return;
26
- const module = await import(/* @vite-ignore */ `../../../../src/apps/${partialPath}`);
25
+ if (!partialPath.endsWith(".ts")) return
26
+ const module = await import(/* @vite-ignore */ `../../../../src/apps/${partialPath}`)
27
27
  if (module?.api?.isApi === true) {
28
28
  // Exclude disallowed characters
29
29
  if (partialPath.includes("_")) {
30
- console.error(`\n\nPath: ` + partialPath);
31
- console.error(`Do not use "_" in the path. If you want to add a separator between words, please use "-".\n`);
32
- exit(1);
30
+ console.error(`\n\nPath: ` + partialPath)
31
+ console.error(`Do not use "_" in the path. If you want to add a separator between words, please use "-".\n`)
32
+ exit(1)
33
33
  }
34
34
  if (/^[a-z0-9/-]+$/.test(partialPath)) {
35
- console.error(`\n\nPath: ` + partialPath);
36
- console.error(`The path can only contain lowercase letters, numbers, and "-".\n`);
37
- exit(1);
35
+ console.error(`\n\nPath: ` + partialPath)
36
+ console.error(`The path can only contain lowercase letters, numbers, and "-".\n`)
37
+ exit(1)
38
38
  }
39
39
  }
40
40
 
41
41
  // typia
42
- const filePathTmp = join(cwd(), "generate", "raw-tmp", "apps", partialPath);
43
- const dirPathTmp = join(cwd(), "generate", "raw-tmp", "apps", partialPath).split("/").slice(0, -1).join("/");
44
- const filePath = join(cwd(), "generate", "raw", "apps", partialPath);
42
+ const filePathTmp = join(cwd(), "generated", "raw-tmp", "apps", partialPath)
43
+ const dirPathTmp = join(cwd(), "generated", "raw-tmp", "apps", partialPath).split("/").slice(0, -1).join("/")
44
+ const filePath = join(cwd(), "generated", "raw", "apps", partialPath)
45
45
  if (!existsSync(dirPathTmp)) {
46
- mkdirSync(dirPathTmp, { recursive: true });
46
+ mkdirSync(dirPathTmp, { recursive: true })
47
47
  }
48
- let importPath = "../../../";
48
+ let importPath = "../../../"
49
49
 
50
50
  for (let i = 0; i < partialPath.split("/").length - 1; i++) {
51
- importPath = importPath + "../";
51
+ importPath = importPath + "../"
52
52
  }
53
- importPath = importPath + "src/apps";
53
+ importPath = importPath + "src/apps"
54
54
  const template = `
55
55
  import typia from "typia";
56
56
  import { _validate, type ExecuteResultSuccess } from "milkio";
@@ -61,14 +61,14 @@ type ParamsT = Parameters<typeof <%= utils.camel(path.replaceAll('/', '$').slice
61
61
  export const params = async (params: any) => typia.misc.validatePrune<ParamsT>(params);
62
62
  type ResultsT = Awaited<ReturnType<typeof <%= utils.camel(path.replaceAll('/', '$').slice(0, -${3})) %>['api']['action']>>;
63
63
  export const results = async (results: any) => { _validate(typia.validate<TSONEncode<ExecuteResultSuccess<ResultsT>>>(results)); return typia.json.stringify<TSONEncode<ExecuteResultSuccess<ResultsT>>>(results); };
64
- `.trim();
64
+ `.trim()
65
65
 
66
- await writeFile(filePathTmp, ejs.render(template, { ...templateVars, path: partialPath }));
66
+ await writeFile(filePathTmp, ejs.render(template, { ...templateVars, path: partialPath }))
67
67
 
68
68
  await new Promise((resolve) =>
69
69
  nodeExec(`bun run ./node_modules/typia/lib/executable/typia.js generate --input generate/raw-tmp/apps/${partialDir} --output generate/products-tmp/apps/${partialDir} --project tsconfig.json`, (e) => {
70
- resolve(e);
70
+ resolve(e)
71
71
  })
72
- );
73
- await Promise.all([writeFile(filePath, ejs.render(template, { ...templateVars, path: partialPath })), writeFile(join(cwd(), "generate", "products", "apps", partialPath), (await readFile(join(cwd(), "generate", "products-tmp", "apps", partialPath))).toString())]);
72
+ )
73
+ await Promise.all([writeFile(filePath, ejs.render(template, { ...templateVars, path: partialPath })), writeFile(join(cwd(), "generated", "products", "apps", partialPath), (await readFile(join(cwd(), "generated", "products-tmp", "apps", partialPath))).toString())])
74
74
  }