milkio 0.1.2 → 0.2.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.
@@ -1,94 +1,90 @@
1
- /* eslint-disable no-console */
2
-
3
- import ejs from "ejs"
4
- import { join } from "node:path"
5
- import { existsSync, mkdirSync } from "node:fs"
6
- import { cwd, exit } from "node:process"
7
- import { unlink, writeFile } from "node:fs/promises"
8
- import { camel, hyphen } from "@poech/camel-hump-under"
9
- import { $, Glob } from "bun"
10
- import { MilkioConfig } from ".."
1
+ import ejs from "ejs";
2
+ import { join } from "node:path";
3
+ import { existsSync, mkdirSync } from "node:fs";
4
+ import { cwd, exit } from "node:process";
5
+ import { unlink, writeFile } from "node:fs/promises";
6
+ import { camel, hyphen } from "@poech/camel-hump-under";
7
+ import { $, Glob } from "bun";
8
+ import type { MilkioConfig } from "..";
11
9
 
12
10
  export default async () => {
13
- // Delete the files generated in the past and regenerate them
14
- try {
15
- await unlink(join(cwd(), "generated", "api-schema.ts"))
16
- } catch (error) { } // Maybe the file does not exist
17
-
18
- // Make sure that the existing directories are all present
19
- existsSync(join("generated")) || mkdirSync(join("generated"))
20
- existsSync(join("generated", "raw")) || mkdirSync(join("generated", "raw"))
21
- existsSync(join("generated", "raw", "apps")) || mkdirSync(join("generated", "raw", "apps"))
22
-
23
- if (!existsSync(join("generated", "README.md"))) {
24
- await writeFile(join("generated", "README.md"), "⚠️ All files in this directory are generated by milkio. Please do not modify the content, otherwise your modifications will be overwritten in the next generation.")
25
- }
26
-
27
- const utils = {
28
- camel: (str: string) => camel(str).replaceAll("-", "").replaceAll("_", ""),
29
- hyphen: (str: string) => hyphen(str).replaceAll("_", "")
30
- }
31
-
32
- // Write a basic framework to ensure that there are no errors when reading later
33
- const apiSchemaSkeleton = `
11
+ // Delete the files generated in the past and regenerate them
12
+ try {
13
+ await unlink(join(cwd(), "generated", "api-schema.ts"));
14
+ } catch (error) {} // Maybe the file does not exist
15
+
16
+ // Make sure that the existing directories are all present
17
+ existsSync(join("generated")) || mkdirSync(join("generated"));
18
+ existsSync(join("generated", "raw")) || mkdirSync(join("generated", "raw"));
19
+ existsSync(join("generated", "raw", "apps")) || mkdirSync(join("generated", "raw", "apps"));
20
+
21
+ if (!existsSync(join("generated", "README.md"))) {
22
+ await writeFile(join("generated", "README.md"), "⚠️ All files in this directory are generated by milkio. Please do not modify the content, otherwise your modifications will be overwritten in the next generation.");
23
+ }
24
+
25
+ const utils = {
26
+ camel: (str: string) => camel(str).replaceAll("-", "").replaceAll("_", ""),
27
+ hyphen: (str: string) => hyphen(str).replaceAll("_", ""),
28
+ };
29
+
30
+ // Write a basic framework to ensure that there are no errors when reading later
31
+ const apiSchemaSkeleton = `
34
32
  export default {
35
33
  apiValidator: {},
36
34
  apiMethodsSchema: {},
37
35
  apiMethodsTypeSchema: {},
38
36
  }
39
- `
40
- await writeFile(join(cwd(), "generated", "api-schema.ts"), ejs.render(apiSchemaSkeleton, { utils }))
41
-
42
- // Generate api-schema.ts file through templates
43
- const templateVars = {
44
- utils,
45
- apiPaths: [] as Array<string>,
46
- apiTestPaths: [] as Array<string>
47
- }
48
-
49
- const glob = new Glob("**/*.ts")
50
- const appFiles = await Array.fromAsync(glob.scan({ cwd: join(cwd(), "src", "apps") }))
51
-
52
-
53
- console.time(`File Stage`)
54
-
55
-
56
- for (const path of appFiles) {
57
- if (!path.endsWith(".ts")) continue
58
- const module = await import(/* @vite-ignore */ join(cwd(), "src", "apps", path))
59
-
60
- if (module?.api?.isApi === true) {
61
- // Exclude disallowed characters
62
- if (path.includes("_")) {
63
- console.error(`\n\nPath: ` + `"${path.slice(0, -3)}"`)
64
- console.error(`Do not use "_" in the path. If you want to add a separator between words, please use "-".\n`)
65
- exit(1)
66
- }
67
- if (!/^[a-z0-9/$/-]+$/.test(path.slice(0, -3))) {
68
- console.error(`\n\nPath: ` + `"${path.slice(0, -3)}"`)
69
- console.error(`The path can only contain lowercase letters, numbers, and "-".\n`)
70
- exit(1)
71
- }
72
-
73
- templateVars.apiPaths.push(path)
74
-
75
- if (module?.test?.isApiTest === true) {
76
- templateVars.apiTestPaths.push(path)
77
- }
78
-
79
- // typia
80
- const filePath = join(cwd(), "generated", "raw", "apps", path)
81
- const dirPath = join(cwd(), "generated", "raw", "apps", path).split("/").slice(0, -1).join("/")
82
- if (!existsSync(dirPath)) {
83
- mkdirSync(dirPath, { recursive: true })
84
- }
85
- let importPath = "../../../"
86
-
87
- for (let i = 0; i < path.split("/").length - 1; i++) {
88
- importPath = importPath + "../"
89
- }
90
- importPath = importPath + "src/apps"
91
- const template = `
37
+ `;
38
+ await writeFile(join(cwd(), "generated", "api-schema.ts"), ejs.render(apiSchemaSkeleton, { utils }));
39
+
40
+ // Generate api-schema.ts file through templates
41
+ const templateVars = {
42
+ utils,
43
+ apiPaths: [] as Array<string>,
44
+ apiTestPaths: [] as Array<string>,
45
+ };
46
+
47
+ const glob = new Glob("**/*.ts");
48
+ const appFiles = await Array.fromAsync(glob.scan({ cwd: join(cwd(), "src", "apps") }));
49
+
50
+ console.time(`File Stage`);
51
+
52
+ for (const path of appFiles) {
53
+ if (!path.endsWith(".ts")) continue;
54
+ const module = await import(/* @vite-ignore */ join(cwd(), "src", "apps", path));
55
+
56
+ if (module?.api?.isApi === true) {
57
+ // Exclude disallowed characters
58
+ if (path.includes("_")) {
59
+ console.error(`\n\nPath: "${path.slice(0, -3)}"`);
60
+ console.error(`Do not use "_" in the path. If you want to add a separator between words, please use "-".\n`);
61
+ exit(1);
62
+ }
63
+ if (!/^[a-z0-9/$/-]+$/.test(path.slice(0, -3))) {
64
+ console.error(`\n\nPath: "${path.slice(0, -3)}"`);
65
+ console.error(`The path can only contain lowercase letters, numbers, and "-".\n`);
66
+ exit(1);
67
+ }
68
+
69
+ templateVars.apiPaths.push(path);
70
+
71
+ if (module?.test?.isApiTest === true) {
72
+ templateVars.apiTestPaths.push(path);
73
+ }
74
+
75
+ // typia
76
+ const filePath = join(cwd(), "generated", "raw", "apps", path);
77
+ const dirPath = join(cwd(), "generated", "raw", "apps", path).split("/").slice(0, -1).join("/");
78
+ if (!existsSync(dirPath)) {
79
+ mkdirSync(dirPath, { recursive: true });
80
+ }
81
+ let importPath = "../../../";
82
+
83
+ for (let i = 0; i < path.split("/").length - 1; i++) {
84
+ importPath = `${importPath}../`;
85
+ }
86
+ importPath = `${importPath}src/apps`;
87
+ const template = `
92
88
  import typia from "typia";
93
89
  import { _validate, type ExecuteResultFail, type ExecuteResultSuccess } from "milkio";
94
90
  import { type TSONEncode } from "@southern-aurora/tson";
@@ -99,17 +95,17 @@ export const validateParams = async (params: any) => typia.misc.validatePrune<Pa
99
95
  type ResultsT = Awaited<ReturnType<typeof <%= utils.camel(path.replaceAll('/', '$').slice(0, -${3})) %>['api']['action']>>;
100
96
  export const validateResults = async (results: any) => { _validate(typia.validate<TSONEncode<ExecuteResultSuccess<ResultsT> | ExecuteResultFail>>(results)); return typia.json.stringify<TSONEncode<ExecuteResultSuccess<ResultsT> | ExecuteResultFail>>(results); };
101
97
  export const randParams = async () => typia.random<ParamsT>();
102
- `.trim()
103
- // export const paramsSchema = typia.json.application<[{ data: ParamsT }], "swagger">();
98
+ `.trim();
99
+ // export const paramsSchema = typia.json.application<[{ data: ParamsT }], "swagger">();
104
100
 
105
- await writeFile(filePath, ejs.render(template, { ...templateVars, path }))
106
- }
107
- }
101
+ await writeFile(filePath, ejs.render(template, { ...templateVars, path }));
102
+ }
103
+ }
108
104
 
109
- await writeFile(
110
- join(cwd(), "generated", "api-schema.ts"),
111
- ejs.render(
112
- `
105
+ await writeFile(
106
+ join(cwd(), "generated", "api-schema.ts"),
107
+ ejs.render(
108
+ `
113
109
  /**
114
110
  * ⚠️ This file is generated and modifications will be overwritten
115
111
  */
@@ -135,12 +131,12 @@ export default {
135
131
  },
136
132
  }
137
133
  `.trim(),
138
- templateVars
139
- )
140
- )
141
-
142
- // api
143
- const apiValidatorTemplate = `/**
134
+ templateVars,
135
+ ),
136
+ );
137
+
138
+ // api
139
+ const apiValidatorTemplate = `/**
144
140
  * ⚠️This file is generated and modifications will be overwritten
145
141
  */
146
142
 
@@ -151,26 +147,26 @@ export default {
151
147
  <% } %>
152
148
  },
153
149
  }
154
- `.trim()
155
- await writeFile(join(cwd(), "generated", "raw", "api-validator.ts"), ejs.render(apiValidatorTemplate, templateVars))
156
-
157
- console.timeEnd(`File Stage`)
158
- console.log(``)
159
-
160
- // typia
161
- console.time(`Typia Stage`)
162
- await $`bun run ./node_modules/typia/lib/executable/typia.js generate --input generated/raw --output generated/products --project tsconfig.json`
163
- console.timeEnd(`Typia Stage`)
164
- console.log(``)
165
-
166
- if (!existsSync(join(cwd(), "milkio.toml"))) return
167
- const milkioConfig = (await import(join(cwd(), "milkio.toml"))).default as MilkioConfig
168
- if (!milkioConfig?.generate?.significant) return
169
- let i = 0
170
- for (const command of milkioConfig.generate.significant) {
171
- ++i
172
- console.time(`Significant Stage (LINE ${i})`)
173
- await $`${{ raw: command }}`
174
- console.timeEnd(`Significant Stage (LINE ${i})`)
175
- }
176
- }
150
+ `.trim();
151
+ await writeFile(join(cwd(), "generated", "raw", "api-validator.ts"), ejs.render(apiValidatorTemplate, templateVars));
152
+
153
+ console.timeEnd(`File Stage`);
154
+ console.log(``);
155
+
156
+ // typia
157
+ console.time(`Typia Stage`);
158
+ await $`bun run ./node_modules/typia/lib/executable/typia.js generate --input generated/raw --output generated/products --project tsconfig.json`;
159
+ console.timeEnd(`Typia Stage`);
160
+ console.log(``);
161
+
162
+ if (!existsSync(join(cwd(), "milkio.toml"))) return;
163
+ const milkioConfig = (await import(join(cwd(), "milkio.toml"))).default as MilkioConfig;
164
+ if (!milkioConfig?.generate?.significant) return;
165
+ let i = 0;
166
+ for (const command of milkioConfig.generate.significant) {
167
+ ++i;
168
+ console.time(`Significant Stage (LINE ${i})`);
169
+ await $`${{ raw: command }}`;
170
+ console.timeEnd(`Significant Stage (LINE ${i})`);
171
+ }
172
+ };
package/types.ts CHANGED
@@ -1,50 +1,48 @@
1
- /* eslint-disable @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any */
1
+ import type { createMilkioApp } from ".";
2
+ import type { failCode } from "../../src/fail-code";
2
3
 
3
- import { type createMilkioApp } from "."
4
- import type { failCode } from "../../src/fail-code"
4
+ export type MilkioApp = Awaited<ReturnType<typeof createMilkioApp>>;
5
5
 
6
- export type MilkioApp = Awaited<ReturnType<typeof createMilkioApp>>
6
+ export type ExecuteId = string | "global";
7
7
 
8
- export type ExecuteId = string | "global"
8
+ export type FailEnumerates = typeof failCode;
9
9
 
10
- export type FailEnumerates = typeof failCode
10
+ export type HttpRequest = Request;
11
11
 
12
- export type HTTPRequest = Request
13
-
14
- export type HTTPResponse = Override<ResponseInit & { body: string | null | undefined }, { headers: NonNullable<ResponseInit["headers"]> }>
12
+ export type HttpResponse = Override<ResponseInit & { body: string | null | undefined }, { headers: NonNullable<ResponseInit["headers"]> }>;
15
13
 
16
14
  export type Fail<FailCode extends keyof FailEnumerates> = {
17
- code: FailCode
18
- message: string
19
- data: Parameters<FailEnumerates[FailCode]>[0]
20
- }
15
+ code: FailCode;
16
+ message: string;
17
+ data: Parameters<FailEnumerates[FailCode]>[0];
18
+ };
21
19
 
22
20
  export type MilkioMeta = {
23
- //
24
- }
21
+ //
22
+ };
25
23
 
26
- export type Cookbook = Record<string, CookbookItem>
24
+ export type Cookbook = Record<string, CookbookItem>;
27
25
 
28
26
  export type CookbookItem = {
29
- title?: string;
30
- desc?: string;
31
- params: string;
32
- cases: Array<{
33
- name: string;
34
- handler: string;
35
- }>
36
- }
27
+ title?: string;
28
+ desc?: string;
29
+ params: string;
30
+ cases: Array<{
31
+ name: string;
32
+ handler: string;
33
+ }>;
34
+ };
37
35
 
38
- export type Override<P, S> = Omit<P, keyof S> & S
36
+ export type Override<P, S> = Omit<P, keyof S> & S;
39
37
 
40
- export type Mixin<T, U> = U & Omit<T, keyof U>
38
+ export type Mixin<T, U> = U & Omit<T, keyof U>;
41
39
 
42
40
  export type MilkioConfig = {
43
- generate?: {
44
- significant?: Array<string>;
45
- insignificant?: Array<string>;
46
- },
47
- menubar?: {
48
- commands?: Array<{ name?: string, script?: string, icon?: string }>;
49
- }
50
- };
41
+ generate?: {
42
+ significant?: Array<string>;
43
+ insignificant?: Array<string>;
44
+ };
45
+ menubar?: {
46
+ commands?: Array<{ name?: string; script?: string; icon?: string }>;
47
+ };
48
+ };
@@ -1,5 +1,5 @@
1
- import { monotonicFactory } from "ulidx"
1
+ import { monotonicFactory } from "ulidx";
2
2
 
3
- const ulid = monotonicFactory()
3
+ const ulid = monotonicFactory();
4
4
 
5
- export const createUlid = () => ulid()
5
+ export const createUlid = () => ulid();
@@ -1,11 +1,11 @@
1
1
  export function envToBoolean(value: string | number | undefined, defaultValue: boolean) {
2
- if (value === "true") return true
2
+ if (value === "true") return true;
3
3
 
4
- if (value === "false") return false
4
+ if (value === "false") return false;
5
5
 
6
- if (value === "") return false
6
+ if (value === "") return false;
7
7
 
8
- if (undefined === value) return defaultValue
8
+ if (undefined === value) return defaultValue;
9
9
 
10
- return Boolean(value)
10
+ return Boolean(value);
11
11
  }
@@ -1,5 +1,5 @@
1
1
  export function envToNumber(value: string | undefined, defaultValue: number) {
2
- if (value === undefined) return defaultValue
2
+ if (value === undefined) return defaultValue;
3
3
 
4
- return Number.parseInt(value, 10)
4
+ return Number.parseInt(value, 10);
5
5
  }
@@ -1,5 +1,5 @@
1
1
  export function envToString(value: string | number | undefined, defaultValue: string) {
2
- if (value === undefined) return defaultValue
2
+ if (value === undefined) return defaultValue;
3
3
 
4
- return `${value}`
4
+ return `${value}`;
5
5
  }
package/utils/exec.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { env, type SpawnOptions } from "bun"
1
+ import { env, type SpawnOptions } from "bun";
2
2
 
3
3
  /**
4
4
  * This is a legacy wrapper that was written before $ Shell was created.
@@ -6,22 +6,22 @@ import { env, type SpawnOptions } from "bun"
6
6
  */
7
7
 
8
8
  export const exec = async (cwd: string, command: Array<string>, options: Partial<SpawnOptions.OptionsObject> = {}) => {
9
- return new Promise((resolve, reject) => {
10
- if (!("cwd" in options)) options.cwd = cwd
11
- if (!("stdin" in options)) options.stdin = "inherit"
12
- if (!("stdout" in options)) options.stdout = "inherit"
13
- if (!("env" in options)) options.env = { ...env }
9
+ return new Promise((resolve, reject) => {
10
+ if (!("cwd" in options)) options.cwd = cwd;
11
+ if (!("stdin" in options)) options.stdin = "inherit";
12
+ if (!("stdout" in options)) options.stdout = "inherit";
13
+ if (!("env" in options)) options.env = { ...env };
14
14
 
15
- options.onExit = (proc, exitCode, signalCode, error) => {
16
- // eslint-disable-next-line prefer-promise-reject-errors
17
- if (exitCode !== 0) reject({ proc, exitCode, signalCode, error })
18
- else resolve({ proc, exitCode, signalCode, error })
19
- }
15
+ options.onExit = (proc, exitCode, signalCode, error) => {
16
+ // eslint-disable-next-line prefer-promise-reject-errors
17
+ if (exitCode !== 0) reject({ proc, exitCode, signalCode, error });
18
+ else resolve({ proc, exitCode, signalCode, error });
19
+ };
20
20
 
21
- try {
22
- Bun.spawn(command, options)
23
- } catch (error) {
24
- reject(error)
25
- }
26
- })
27
- }
21
+ try {
22
+ Bun.spawn(command, options);
23
+ } catch (error) {
24
+ reject(error);
25
+ }
26
+ });
27
+ };
@@ -1,45 +1,45 @@
1
- import { failCode } from "../../../src/fail-code"
2
- import { useLogger, type ExecuteId, type ExecuteResult } from ".."
3
- import { configMilkio } from "../../../src/config/milkio"
1
+ import { failCode } from "../../../src/fail-code";
2
+ import { useLogger, type ExecuteId, type ExecuteResult } from "..";
3
+ import { configMilkio } from "../../../src/config/milkio";
4
4
 
5
5
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
6
  export function hanldeCatchError(error: any, executeId: ExecuteId): ExecuteResult<any> {
7
- const logger = useLogger(executeId)
7
+ const logger = useLogger(executeId);
8
8
 
9
- if (configMilkio.debug === true) {
10
- logger.error("\nError Data: " + JSON.stringify(error))
11
- if (error.stack) logger.error("\nError Stack: ", error.stack)
12
- else logger.error("\nError Stack: ", error)
13
- }
9
+ if (configMilkio.debug === true) {
10
+ logger.error(`\nError Data: ${JSON.stringify(error)}`);
11
+ if (error.stack) logger.error("\nError Stack: ", error.stack);
12
+ else logger.error("\nError Stack: ", error);
13
+ }
14
14
 
15
- if (error.name !== "MilkioReject") {
16
- if (configMilkio.debug === true) {
17
- // If it is not MilkioReject, it is considered an internal server error that should not be exposed
18
- logger.error(`FailCode: INTERNAL_SERVER_ERROR`)
19
- }
15
+ if (error.name !== "MilkioReject") {
16
+ if (configMilkio.debug === true) {
17
+ // If it is not MilkioReject, it is considered an internal server error that should not be exposed
18
+ logger.error(`FailCode: INTERNAL_SERVER_ERROR`);
19
+ }
20
20
 
21
- return {
22
- executeId,
23
- success: false,
24
- fail: {
25
- code: "INTERNAL_SERVER_ERROR",
26
- message: failCode.INTERNAL_SERVER_ERROR(),
27
- data: undefined
28
- }
29
- }
30
- } else {
31
- if (configMilkio.debug === true) {
32
- logger.error(`FailCode: ${error.code}`)
33
- }
21
+ return {
22
+ executeId,
23
+ success: false,
24
+ fail: {
25
+ code: "INTERNAL_SERVER_ERROR",
26
+ message: failCode.INTERNAL_SERVER_ERROR(),
27
+ data: undefined,
28
+ },
29
+ };
30
+ }
34
31
 
35
- return {
36
- executeId,
37
- success: false,
38
- fail: {
39
- code: error.code,
40
- message: error.message,
41
- data: error.data
42
- }
43
- }
44
- }
32
+ if (configMilkio.debug === true) {
33
+ logger.error(`FailCode: ${error.code}`);
34
+ }
35
+
36
+ return {
37
+ executeId,
38
+ success: false,
39
+ fail: {
40
+ code: error.code,
41
+ message: error.message,
42
+ data: error.data,
43
+ },
44
+ };
45
45
  }
@@ -1,8 +1,8 @@
1
1
  export const headerToPlainObject = (headers: Headers) => {
2
- if (headers.toJSON) return headers.toJSON()
3
- const plainHeaders: Record<string, string> = {}
4
- headers.forEach((value, key) => {
5
- plainHeaders[key] = value
6
- })
7
- return headers
8
- }
2
+ if (headers.toJSON) return headers.toJSON();
3
+ const plainHeaders: Record<string, string> = {};
4
+ headers.forEach((value, key) => {
5
+ plainHeaders[key] = value;
6
+ });
7
+ return headers;
8
+ };
@@ -1,22 +1,22 @@
1
- import { existsSync, lstatSync, readdirSync, rmdirSync, unlinkSync } from "node:fs"
2
- import path from "node:path"
1
+ import { existsSync, lstatSync, readdirSync, rmdirSync, unlinkSync } from "node:fs";
2
+ import path from "node:path";
3
3
 
4
4
  export function removeDir(pathstr: string, skips: Array<string> = []) {
5
- if (!existsSync(pathstr)) return
6
- const files = readdirSync(pathstr)
7
- files.forEach((file) => {
8
- const dirname = path.resolve(pathstr, file)
9
- const stats = lstatSync(dirname)
10
- for (const skip of skips) {
11
- if (dirname.startsWith(skip)) return
12
- }
13
- if (stats.isDirectory()) {
14
- removeDir(dirname)
15
- } else {
16
- unlinkSync(dirname)
17
- }
18
- })
19
- try {
20
- rmdirSync(pathstr)
21
- } catch (error) {}
5
+ if (!existsSync(pathstr)) return;
6
+ const files = readdirSync(pathstr);
7
+ files.forEach((file) => {
8
+ const dirname = path.resolve(pathstr, file);
9
+ const stats = lstatSync(dirname);
10
+ for (const skip of skips) {
11
+ if (dirname.startsWith(skip)) return;
12
+ }
13
+ if (stats.isDirectory()) {
14
+ removeDir(dirname);
15
+ } else {
16
+ unlinkSync(dirname);
17
+ }
18
+ });
19
+ try {
20
+ rmdirSync(pathstr);
21
+ } catch (error) {}
22
22
  }
package/utils/tson.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { TSON as _TSON } from "@southern-aurora/tson"
1
+ import { TSON as _TSON } from "@southern-aurora/tson";
2
2
 
3
- export const TSON = _TSON
3
+ export const TSON = _TSON;
package/.co.toml DELETED
@@ -1,2 +0,0 @@
1
- ["general"]
2
- includes = ["co:bun"]