@wener/common 1.0.4 → 1.0.5

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.
@@ -0,0 +1,18 @@
1
+ import { formatLogObject } from "./formatLogObject.js";
2
+ export function createStandardConsolaReporter({ format = formatLogObject } = {}) {
3
+ return {
4
+ log: (o, ctx) => {
5
+ let out = format(o, ctx);
6
+ let fn = console.log;
7
+ const { level } = o;
8
+ if (level < 1) {
9
+ fn = console.error;
10
+ }
11
+ else if (level === 1) {
12
+ fn = console.warn;
13
+ }
14
+ fn(out);
15
+ }
16
+ };
17
+ }
18
+ //# sourceMappingURL=createStandardConsolaReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/consola/createStandardConsolaReporter.ts"],"sourcesContent":["import type { ConsolaOptions, ConsolaReporter, LogObject } from 'consola/core';\nimport { formatLogObject } from './formatLogObject';\n\ntype Formatter = (\n\to: LogObject,\n\tctx: {\n\t\toptions: ConsolaOptions;\n\t},\n) => string;\n\nexport function createStandardConsolaReporter({\n\tformat = formatLogObject,\n}: {\n\tformat?: Formatter;\n} = {}): ConsolaReporter {\n\treturn {\n\t\tlog: (o, ctx) => {\n\t\t\tlet out = format(o, ctx);\n\t\t\tlet fn = console.log;\n\n\t\t\tconst { level } = o;\n\t\t\tif (level < 1) {\n\t\t\t\tfn = console.error;\n\t\t\t} else if (level === 1) {\n\t\t\t\tfn = console.warn;\n\t\t\t}\n\n\t\t\tfn(out);\n\t\t},\n\t};\n}\n"],"names":["formatLogObject","createStandardConsolaReporter","format","log","o","ctx","out","fn","console","level","error","warn"],"mappings":"AACA,SAASA,eAAe,QAAQ,oBAAoB;AASpD,OAAO,SAASC,8BAA8B,EAC7CC,SAASF,eAAe,EAGxB,GAAG,CAAC,CAAC;IACL,OAAO;QACNG,KAAK,CAACC,GAAGC;YACR,IAAIC,MAAMJ,OAAOE,GAAGC;YACpB,IAAIE,KAAKC,QAAQL,GAAG;YAEpB,MAAM,EAAEM,KAAK,EAAE,GAAGL;YAClB,IAAIK,QAAQ,GAAG;gBACdF,KAAKC,QAAQE,KAAK;YACnB,OAAO,IAAID,UAAU,GAAG;gBACvBF,KAAKC,QAAQG,IAAI;YAClB;YAEAJ,GAAGD;QACJ;IACD;AACD"}
@@ -0,0 +1,125 @@
1
+ import colors from "chalk";
2
+ import dayjs from "dayjs";
3
+ import { isDevelopment } from "std-env";
4
+ const levelColors = {
5
+ trace: colors.gray,
6
+ debug: colors.cyan,
7
+ info: colors.blueBright,
8
+ warn: colors.yellow,
9
+ error: colors.red,
10
+ fatal: colors.bgRed.white,
11
+ silent: colors.white,
12
+ log: colors.white,
13
+ success: colors.green,
14
+ fail: colors.red,
15
+ ready: colors.green,
16
+ start: colors.cyan,
17
+ box: colors.white,
18
+ verbose: colors.green
19
+ };
20
+ const levelShort = {
21
+ trace: 'TRAC',
22
+ debug: 'DEBG',
23
+ info: 'INFO',
24
+ warn: 'WARN',
25
+ error: 'ERRO',
26
+ fatal: 'FATL',
27
+ silent: 'SLNT',
28
+ log: 'LOG ',
29
+ success: 'SUCC',
30
+ fail: 'FAIL',
31
+ ready: 'READ',
32
+ start: 'STRT',
33
+ box: 'BOX ',
34
+ verbose: 'VERB'
35
+ };
36
+ const start = Date.now();
37
+ export function formatLogObject(o, ctx) {
38
+ let { date, type, tag } = o;
39
+ type = type === 'log' ? 'info' : type;
40
+ const color = levelColors[type] || colors.white;
41
+ const levelText = levelShort[type] || type.toUpperCase().slice(0, 4); // Get first 4 chars, consistent uppercase
42
+ let line = '';
43
+ let out = [];
44
+ // Timestamp
45
+ if (isDevelopment) {
46
+ // process.hrtime.bigint()
47
+ let diff = (date.getTime() - start) / 1000;
48
+ out.push(colors.gray(diff.toFixed(3).padStart(7, ' ')));
49
+ } else {
50
+ out.push(colors.gray(dayjs(date).format('YYYY-MM-DD HH:mm:ss.SSS')));
51
+ }
52
+ // Log Level (colored)
53
+ // Pad to 4 characters
54
+ out.push(color(levelText.padEnd(4, ' ')));
55
+ if (tag) {
56
+ out.push(colors.yellow(`[${tag}]`)); // Added color for tag
57
+ }
58
+ {
59
+ const [message, ...additional] = formatArgs(o.args, ctx).split('\n');
60
+ out.push(characterFormat(message));
61
+ line = out.join(' ');
62
+ if (additional.length > 0) {
63
+ line += characterFormat(additional.join('\n'));
64
+ }
65
+ if (type === 'trace') {
66
+ const _err = new Error('Trace: ' + o.message);
67
+ line += formatStack(_err.stack || '', _err.message);
68
+ }
69
+ }
70
+ // if (!message && typeof args[0] === 'string') {
71
+ // message = args.shift();
72
+ // }
73
+ // if (message) {
74
+ // out.push(message);
75
+ // }
76
+ // if (args.length) {
77
+ // out.push(...args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a)))); // Handle non-string args
78
+ // }
79
+ // todo format error
80
+ // https://github.com/unjs/consola/blob/main/src/reporters/fancy.ts
81
+ // return out.join(' '); // Increased spacing for better readability
82
+ return line;
83
+ }
84
+ function characterFormat(str) {
85
+ return str// highlight backticks
86
+ .replace(/`([^`]+)`/gm, (_, m)=>colors.cyan(m))// underline underscores
87
+ .replace(/\s+_([^_]+)_\s+/gm, (_, m)=>` ${colors.underline(m)} `);
88
+ }
89
+ function parseStack(stack, message) {
90
+ // const cwd = process.cwd() + sep;
91
+ const lines = stack.split('\n').splice(message.split('\n').length).map((l)=>l.trim().replace('file://', ''));
92
+ return lines;
93
+ }
94
+ function formatStack(stack, message, opts) {
95
+ const indent = ' '.repeat((opts?.errorLevel || 0) + 1);
96
+ return `\n${indent}` + parseStack(stack, message).map((line)=>' ' + line.replace(/^at +/, (m)=>colors.gray(m)).replace(/\((.+)\)/, (_, m)=>`(${colors.cyan(m)})`)).join(`\n${indent}`);
97
+ }
98
+ function formatArgs(args, opts) {
99
+ const _args = args.map((arg)=>{
100
+ if (arg && typeof arg.stack === 'string') {
101
+ return formatError(arg, opts);
102
+ }
103
+ return arg;
104
+ });
105
+ // Only supported with Node >= 10
106
+ // https://nodejs.org/api/util.html#util_util_inspect_object_options
107
+ return formatWithOptions(opts, ..._args);
108
+ }
109
+ function formatWithOptions(o, ...params) {
110
+ // import { formatWithOptions } from 'node:util';
111
+ return params.join(' ');
112
+ }
113
+ function formatError(err, opts) {
114
+ const message = err.message ?? formatWithOptions(opts, err);
115
+ const stack = err.stack ? formatStack(err.stack, message, opts) : '';
116
+ const level = opts?.errorLevel || 0;
117
+ const causedPrefix = level > 0 ? `${' '.repeat(level)}[cause]: ` : '';
118
+ const causedError = err.cause ? '\n\n' + formatError(err.cause, {
119
+ ...opts,
120
+ errorLevel: level + 1
121
+ }) : '';
122
+ return causedPrefix + message + '\n' + stack + causedError;
123
+ }
124
+
125
+ //# sourceMappingURL=formatLogObject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/consola/formatLogObject.ts"],"sourcesContent":["import colors from 'chalk';\nimport type { ConsolaOptions, FormatOptions, LogObject, LogType } from 'consola/core';\nimport dayjs from 'dayjs';\nimport { isDevelopment } from 'std-env';\n\nconst levelColors: Record<LogType, (str: string) => string> = {\n\ttrace: colors.gray,\n\tdebug: colors.cyan,\n\tinfo: colors.blueBright,\n\twarn: colors.yellow,\n\terror: colors.red,\n\tfatal: colors.bgRed.white,\n\tsilent: colors.white,\n\tlog: colors.white,\n\tsuccess: colors.green,\n\tfail: colors.red,\n\tready: colors.green,\n\tstart: colors.cyan,\n\tbox: colors.white,\n\tverbose: colors.green,\n};\n\nconst levelShort: Record<LogType, string> = {\n\ttrace: 'TRAC',\n\tdebug: 'DEBG',\n\tinfo: 'INFO',\n\twarn: 'WARN',\n\terror: 'ERRO',\n\tfatal: 'FATL',\n\tsilent: 'SLNT',\n\tlog: 'LOG ', // Added space to make it 4 characters\n\tsuccess: 'SUCC',\n\tfail: 'FAIL',\n\tready: 'READ',\n\tstart: 'STRT',\n\tbox: 'BOX ', // Added space to make it 4 characters\n\tverbose: 'VERB',\n};\nconst start = Date.now();\n\nexport function formatLogObject(\n\to: LogObject,\n\tctx: {\n\t\toptions: ConsolaOptions;\n\t},\n) {\n\tlet { date, type, tag } = o;\n\ttype = type === 'log' ? 'info' : type;\n\n\tconst color = levelColors[type] || colors.white;\n\tconst levelText = levelShort[type] || type.toUpperCase().slice(0, 4); // Get first 4 chars, consistent uppercase\n\n\tlet line = '';\n\tlet out: string[] = [];\n\n\t// Timestamp\n\tif (isDevelopment) {\n\t\t// process.hrtime.bigint()\n\t\tlet diff = (date.getTime() - start) / 1000;\n\n\t\tout.push(colors.gray(diff.toFixed(3).padStart(7, ' ')));\n\t} else {\n\t\tout.push(colors.gray(dayjs(date).format('YYYY-MM-DD HH:mm:ss.SSS')));\n\t}\n\n\t// Log Level (colored)\n\t// Pad to 4 characters\n\tout.push(color(levelText.padEnd(4, ' ')));\n\n\tif (tag) {\n\t\tout.push(colors.yellow(`[${tag}]`)); // Added color for tag\n\t}\n\n\t{\n\t\tconst [message, ...additional] = formatArgs(o.args, ctx).split('\\n');\n\n\t\tout.push(characterFormat(message));\n\n\t\tline = out.join(' ');\n\t\tif (additional.length > 0) {\n\t\t\tline += characterFormat(additional.join('\\n'));\n\t\t}\n\n\t\tif (type === 'trace') {\n\t\t\tconst _err = new Error('Trace: ' + o.message);\n\t\t\tline += formatStack(_err.stack || '', _err.message);\n\t\t}\n\t}\n\n\t// if (!message && typeof args[0] === 'string') {\n\t// message = args.shift();\n\t// }\n\t// if (message) {\n\t// out.push(message);\n\t// }\n\t// if (args.length) {\n\t// out.push(...args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a)))); // Handle non-string args\n\t// }\n\n\t// todo format error\n\t// https://github.com/unjs/consola/blob/main/src/reporters/fancy.ts\n\n\t// return out.join(' '); // Increased spacing for better readability\n\treturn line;\n}\n\nfunction characterFormat(str: string) {\n\treturn (\n\t\tstr\n\t\t\t// highlight backticks\n\t\t\t.replace(/`([^`]+)`/gm, (_, m) => colors.cyan(m))\n\t\t\t// underline underscores\n\t\t\t.replace(/\\s+_([^_]+)_\\s+/gm, (_, m) => ` ${colors.underline(m)} `)\n\t);\n}\n\nfunction parseStack(stack: string, message: string) {\n\t// const cwd = process.cwd() + sep;\n\n\tconst lines = stack\n\t\t.split('\\n')\n\t\t.splice(message.split('\\n').length)\n\t\t.map(\n\t\t\t(l) => l.trim().replace('file://', ''),\n\t\t\t// .replace(cwd, '')\n\t\t);\n\n\treturn lines;\n}\n\nfunction formatStack(stack: string, message: string, opts?: FormatOptions) {\n\tconst indent = ' '.repeat((opts?.errorLevel || 0) + 1);\n\treturn (\n\t\t`\\n${indent}`\n\t\t+ parseStack(stack, message)\n\t\t\t.map(\n\t\t\t\t(line) =>\n\t\t\t\t\t' ' + line.replace(/^at +/, (m) => colors.gray(m)).replace(/\\((.+)\\)/, (_, m) => `(${colors.cyan(m)})`),\n\t\t\t)\n\t\t\t.join(`\\n${indent}`)\n\t);\n}\n\nfunction formatArgs(args: any[], opts: FormatOptions) {\n\tconst _args = args.map((arg) => {\n\t\tif (arg && typeof arg.stack === 'string') {\n\t\t\treturn formatError(arg, opts);\n\t\t}\n\t\treturn arg;\n\t});\n\n\t// Only supported with Node >= 10\n\t// https://nodejs.org/api/util.html#util_util_inspect_object_options\n\treturn formatWithOptions(opts, ..._args);\n}\n\nfunction formatWithOptions(o: any, ...params: any[]) {\n\t// import { formatWithOptions } from 'node:util';\n\treturn params.join(' ');\n}\n\nfunction formatError(err: any, opts: FormatOptions): string {\n\tconst message = err.message ?? formatWithOptions(opts, err);\n\tconst stack = err.stack ? formatStack(err.stack, message, opts) : '';\n\n\tconst level = opts?.errorLevel || 0;\n\tconst causedPrefix = level > 0 ? `${' '.repeat(level)}[cause]: ` : '';\n\tconst causedError = err.cause ? '\\n\\n' + formatError(err.cause, { ...opts, errorLevel: level + 1 }) : '';\n\n\treturn causedPrefix + message + '\\n' + stack + causedError;\n}\n"],"names":["colors","dayjs","isDevelopment","levelColors","trace","gray","debug","cyan","info","blueBright","warn","yellow","error","red","fatal","bgRed","white","silent","log","success","green","fail","ready","start","box","verbose","levelShort","Date","now","formatLogObject","o","ctx","date","type","tag","color","levelText","toUpperCase","slice","line","out","diff","getTime","push","toFixed","padStart","format","padEnd","message","additional","formatArgs","args","split","characterFormat","join","length","_err","Error","formatStack","stack","str","replace","_","m","underline","parseStack","lines","splice","map","l","trim","opts","indent","repeat","errorLevel","_args","arg","formatError","formatWithOptions","params","err","level","causedPrefix","causedError","cause"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { formatLogObject } from "./formatLogObject.js";
2
+ export { createStandardConsolaReporter } from "./createStandardConsolaReporter.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/consola/index.ts"],"sourcesContent":["export { formatLogObject } from './formatLogObject';\nexport { createStandardConsolaReporter } from './createStandardConsolaReporter';\n"],"names":["formatLogObject","createStandardConsolaReporter"],"mappings":"AAAA,SAASA,eAAe,QAAQ,oBAAoB;AACpD,SAASC,6BAA6B,QAAQ,kCAAkC"}
@@ -16,7 +16,7 @@ export function resolvePagination(page, options = {}) {
16
16
  pageSize = maybeFunction(options.pageSize, pageSize);
17
17
  }
18
18
  pageSize ??= 20;
19
- pageSize = clamp(pageSize, 1, options.maxPageSize ?? 100);
19
+ pageSize = clamp(pageSize, 1, options.maxPageSize ?? 1000);
20
20
  let { pageNumber = 1, pageIndex, limit, offset } = out;
21
21
  // page index over page number
22
22
  pageNumber = Math.max(pageNumber, 1);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data/resolvePagination.ts"],"sourcesContent":["import { maybeFunction, type MaybeFunction } from '@wener/utils';\nimport { clamp, mapValues, omitBy, pick } from 'es-toolkit';\nimport { maybeNumber, type MaybeNumber } from './maybeNumber';\n\nexport type PaginationInput = {\n\tlimit?: MaybeNumber;\n\toffset?: MaybeNumber;\n\tpageSize?: MaybeNumber;\n\tpageNumber?: MaybeNumber;\n\tpageIndex?: MaybeNumber;\n};\n\nexport type ResolvedPagination = {\n\tlimit: number;\n\toffset: number;\n\tpageSize: number;\n\tpageNumber: number;\n\tpageIndex: number;\n};\n\nexport function resolvePagination(\n\tpage: PaginationInput,\n\toptions: {\n\t\tpageSize?: MaybeFunction<number, [number | undefined]>;\n\t\tmaxPageSize?: number;\n\t} = {},\n): ResolvedPagination {\n\tlet out = omitBy(\n\t\tmapValues(\n\t\t\t//\n\t\t\tpick(page, ['limit', 'offset', 'pageSize', 'pageNumber', 'pageIndex']),\n\t\t\t// to Number\n\t\t\t(v) => maybeNumber(v),\n\t\t),\n\t\t(v) => v === undefined || v === null,\n\t);\n\tlet { pageSize } = out;\n\tif (options.pageSize) {\n\t\tpageSize = maybeFunction(options.pageSize, pageSize);\n\t}\n\tpageSize ??= 20;\n\tpageSize = clamp(pageSize, 1, options.maxPageSize ?? 100);\n\n\tlet { pageNumber = 1, pageIndex, limit, offset } = out;\n\t// page index over page number\n\tpageNumber = Math.max(pageNumber, 1);\n\tpageIndex = Math.max(pageIndex ?? pageNumber - 1, 0);\n\tlimit = Math.max(1, limit ?? pageSize);\n\toffset = Math.max(0, offset ?? pageSize * pageIndex);\n\n\tpageSize = limit;\n\tpageIndex = Math.floor(offset / pageSize);\n\treturn {\n\t\tlimit,\n\t\toffset,\n\t\tpageSize,\n\t\tpageNumber: pageIndex + 1,\n\t\tpageIndex,\n\t};\n}\n"],"names":["maybeFunction","clamp","mapValues","omitBy","pick","maybeNumber","resolvePagination","page","options","out","v","undefined","pageSize","maxPageSize","pageNumber","pageIndex","limit","offset","Math","max","floor"],"mappings":"AAAA,SAASA,aAAa,QAA4B,eAAe;AACjE,SAASC,KAAK,EAAEC,SAAS,EAAEC,MAAM,EAAEC,IAAI,QAAQ,aAAa;AAC5D,SAASC,WAAW,QAA0B,gBAAgB;AAkB9D,OAAO,SAASC,kBACfC,IAAqB,EACrBC,UAGI,CAAC,CAAC;IAEN,IAAIC,MAAMN,OACTD,UACC,EAAE;IACFE,KAAKG,MAAM;QAAC;QAAS;QAAU;QAAY;QAAc;KAAY,GACrE,YAAY;IACZ,CAACG,IAAML,YAAYK,KAEpB,CAACA,IAAMA,MAAMC,aAAaD,MAAM;IAEjC,IAAI,EAAEE,QAAQ,EAAE,GAAGH;IACnB,IAAID,QAAQI,QAAQ,EAAE;QACrBA,WAAWZ,cAAcQ,QAAQI,QAAQ,EAAEA;IAC5C;IACAA,aAAa;IACbA,WAAWX,MAAMW,UAAU,GAAGJ,QAAQK,WAAW,IAAI;IAErD,IAAI,EAAEC,aAAa,CAAC,EAAEC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAE,GAAGR;IACnD,8BAA8B;IAC9BK,aAAaI,KAAKC,GAAG,CAACL,YAAY;IAClCC,YAAYG,KAAKC,GAAG,CAACJ,aAAaD,aAAa,GAAG;IAClDE,QAAQE,KAAKC,GAAG,CAAC,GAAGH,SAASJ;IAC7BK,SAASC,KAAKC,GAAG,CAAC,GAAGF,UAAUL,WAAWG;IAE1CH,WAAWI;IACXD,YAAYG,KAAKE,KAAK,CAACH,SAASL;IAChC,OAAO;QACNI;QACAC;QACAL;QACAE,YAAYC,YAAY;QACxBA;IACD;AACD"}
1
+ {"version":3,"sources":["../../src/data/resolvePagination.ts"],"sourcesContent":["import { maybeFunction, type MaybeFunction } from '@wener/utils';\nimport { clamp, mapValues, omitBy, pick } from 'es-toolkit';\nimport { maybeNumber, type MaybeNumber } from './maybeNumber';\n\nexport type PaginationInput = {\n\tlimit?: MaybeNumber;\n\toffset?: MaybeNumber;\n\tpageSize?: MaybeNumber;\n\tpageNumber?: MaybeNumber;\n\tpageIndex?: MaybeNumber;\n};\n\nexport type ResolvedPagination = {\n\tlimit: number;\n\toffset: number;\n\tpageSize: number;\n\tpageNumber: number;\n\tpageIndex: number;\n};\n\nexport function resolvePagination(\n\tpage: PaginationInput,\n\toptions: {\n\t\tpageSize?: MaybeFunction<number, [number | undefined]>;\n\t\tmaxPageSize?: number;\n\t} = {},\n): ResolvedPagination {\n\tlet out = omitBy(\n\t\tmapValues(\n\t\t\t//\n\t\t\tpick(page, ['limit', 'offset', 'pageSize', 'pageNumber', 'pageIndex']),\n\t\t\t// to Number\n\t\t\t(v) => maybeNumber(v),\n\t\t),\n\t\t(v) => v === undefined || v === null,\n\t);\n\tlet { pageSize } = out;\n\tif (options.pageSize) {\n\t\tpageSize = maybeFunction(options.pageSize, pageSize);\n\t}\n\tpageSize ??= 20;\n\tpageSize = clamp(pageSize, 1, options.maxPageSize ?? 1000);\n\n\tlet { pageNumber = 1, pageIndex, limit, offset } = out;\n\t// page index over page number\n\tpageNumber = Math.max(pageNumber, 1);\n\tpageIndex = Math.max(pageIndex ?? pageNumber - 1, 0);\n\tlimit = Math.max(1, limit ?? pageSize);\n\toffset = Math.max(0, offset ?? pageSize * pageIndex);\n\n\tpageSize = limit;\n\tpageIndex = Math.floor(offset / pageSize);\n\treturn {\n\t\tlimit,\n\t\toffset,\n\t\tpageSize,\n\t\tpageNumber: pageIndex + 1,\n\t\tpageIndex,\n\t};\n}\n"],"names":["maybeFunction","clamp","mapValues","omitBy","pick","maybeNumber","resolvePagination","page","options","out","v","undefined","pageSize","maxPageSize","pageNumber","pageIndex","limit","offset","Math","max","floor"],"mappings":"AAAA,SAASA,aAAa,QAA4B,eAAe;AACjE,SAASC,KAAK,EAAEC,SAAS,EAAEC,MAAM,EAAEC,IAAI,QAAQ,aAAa;AAC5D,SAASC,WAAW,QAA0B,gBAAgB;AAkB9D,OAAO,SAASC,kBACfC,IAAqB,EACrBC,UAGI,CAAC,CAAC;IAEN,IAAIC,MAAMN,OACTD,UACC,EAAE;IACFE,KAAKG,MAAM;QAAC;QAAS;QAAU;QAAY;QAAc;KAAY,GACrE,YAAY;IACZ,CAACG,IAAML,YAAYK,KAEpB,CAACA,IAAMA,MAAMC,aAAaD,MAAM;IAEjC,IAAI,EAAEE,QAAQ,EAAE,GAAGH;IACnB,IAAID,QAAQI,QAAQ,EAAE;QACrBA,WAAWZ,cAAcQ,QAAQI,QAAQ,EAAEA;IAC5C;IACAA,aAAa;IACbA,WAAWX,MAAMW,UAAU,GAAGJ,QAAQK,WAAW,IAAI;IAErD,IAAI,EAAEC,aAAa,CAAC,EAAEC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAE,GAAGR;IACnD,8BAA8B;IAC9BK,aAAaI,KAAKC,GAAG,CAACL,YAAY;IAClCC,YAAYG,KAAKC,GAAG,CAACJ,aAAaD,aAAa,GAAG;IAClDE,QAAQE,KAAKC,GAAG,CAAC,GAAGH,SAASJ;IAC7BK,SAASC,KAAKC,GAAG,CAAC,GAAGF,UAAUL,WAAWG;IAE1CH,WAAWI;IACXD,YAAYG,KAAKE,KAAK,CAACH,SAASL;IAChC,OAAO;QACNI;QACAC;QACAL;QACAE,YAAYC,YAAY;QACxBA;IACD;AACD"}
@@ -1,6 +1,6 @@
1
1
  import Ajv from "ajv";
2
2
  import addFormats from "ajv-formats";
3
- import localize from "ajv-i18n/localize/zh";
3
+ // import localize from 'ajv-i18n/localize/zh';
4
4
  import addKeywords from "ajv-keywords";
5
5
  import { isNil } from "es-toolkit";
6
6
  import { match, P } from "ts-pattern";
@@ -34,7 +34,7 @@ function validate({ schema, data, mutate, clone, ajv }) {
34
34
  // consider reusing validate instance
35
35
  const valid = validate(data);
36
36
  const errors = validate.errors;
37
- localize(errors);
37
+ // localize(errors);
38
38
  return {
39
39
  data,
40
40
  success: valid,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/jsonschema/JsonSchema.ts"],"sourcesContent":["import type { Static, TSchema } from '@sinclair/typebox';\nimport Ajv, { type ErrorObject, type Options } from 'ajv';\nimport addFormats from 'ajv-formats';\nimport localize from 'ajv-i18n/localize/zh';\nimport addKeywords from 'ajv-keywords';\nimport { isNil } from 'es-toolkit';\nimport { match, P } from 'ts-pattern';\nimport type { JsonSchemaDef } from './types';\n\nfunction _createAjv(opt: Options) {\n\tconst ajv = new Ajv(opt);\n\taddKeywords(ajv);\n\taddFormats(ajv);\n\treturn ajv;\n}\n\ntype ValidateOptions = { mutate?: boolean; clone?: boolean; ajv?: Ajv };\n\ntype ValidateResult<T> =\n\t| { data: T; success: true; message: undefined }\n\t| { data: undefined; success: false; message: string; errors: ErrorObject[] };\n\nfunction validate({ schema, data, mutate, clone, ajv }: ValidateOptions & { schema: any; data: any }) {\n\tlet opts: Options = {\n\t\t// strict: 'log',\n\t\tstrict: true,\n\t\tstrictSchema: 'log', // skip unknown keywords in schema\n\t};\n\n\tif (mutate) {\n\t\tObject.assign(opts, { removeAdditional: true, useDefaults: true, coerceTypes: true, allErrors: true });\n\t}\n\n\tif (clone) {\n\t\tdata = structuredClone(data);\n\t}\n\n\tif (!ajv) {\n\t\tajv = JsonSchema.createAjv(opts);\n\t}\n\n\tconst validate = ajv.compile(schema);\n\n\t// consider reusing validate instance\n\n\tconst valid = validate(data);\n\tconst errors = validate.errors;\n\tlocalize(errors);\n\n\treturn { data, success: valid, message: ajv.errorsText(errors), errors: errors };\n}\n\ntype TypeOfSchema<S> = S extends TSchema ? Static<S> : any;\n\nexport namespace JsonSchema {\n\texport let schemas: JsonSchemaDef[] = [];\n\n\texport const createAjv = _createAjv;\n\n\texport function addSchema(\n\t\tschema: JsonSchemaDef,\n\t\t{\n\t\t\tonConflict = 'throw',\n\t\t}: {\n\t\t\tonConflict?: 'throw' | 'ignore' | 'replace' | ((old: JsonSchemaDef, neo: JsonSchemaDef) => JsonSchemaDef);\n\t\t} = {},\n\t) {\n\t\tif (!schema.$id) throw new Error('Schema must have $id');\n\t\tswitch (onConflict) {\n\t\t\tcase 'ignore':\n\t\t\t\tonConflict = (old) => old;\n\t\t\t\tbreak;\n\t\t\tcase 'replace':\n\t\t\t\tonConflict = (_, neo) => neo;\n\t\t\t\tbreak;\n\t\t\tcase 'throw':\n\t\t\t\tonConflict = (old, neo) => {\n\t\t\t\t\tthrow new Error(`Schema ${neo.$id} already exists`);\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t}\n\t\tlet idx = schemas.findIndex((s) => s.$id === schema.$id);\n\t\tif (idx >= 0) {\n\t\t\tschemas[idx] = onConflict(schemas[idx], schema);\n\t\t} else {\n\t\t\tschemas.push(schema);\n\t\t}\n\t}\n\n\t/**\n\t * Check data is valid, will not use default\n\t */\n\texport function check<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {\n\t\treturn validate({ schema, data, mutate: false, clone: true }) as any;\n\t}\n\n\t/**\n\t * Parse data with default value and coerceTypes\n\t */\n\texport function safeParse<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {\n\t\treturn validate({ schema, data, mutate: true, clone: true }) as any;\n\t}\n\n\texport function parse<S>(schema: S, data: any): TypeOfSchema<S> {\n\t\tconst { data: out, message, errors } = validate({ schema, data, mutate: true, clone: true });\n\t\tif (errors) {\n\t\t\tthrow new Error(message);\n\t\t}\n\t\treturn out;\n\t}\n\n\texport function create<S>(schema: S, data?: any): TypeOfSchema<S> {\n\t\t// will not ensure value match the rule\n\t\treturn match(schema as JsonSchemaDef)\n\t\t\t.returnType<any>()\n\t\t\t.with({ const: P.select() }, (v) => v)\n\t\t\t.with({ default: P.select() }, (v) => v)\n\t\t\t.with({ anyOf: P.nonNullable }, (schema) => {\n\t\t\t\treturn create(schema.anyOf[0]);\n\t\t\t})\n\t\t\t.with({ oneOf: P.nonNullable }, (schema) => {\n\t\t\t\treturn create(schema.oneOf[0]);\n\t\t\t})\n\t\t\t.with({ type: 'string' }, (schema) => '')\n\t\t\t.with({ type: P.union('number', 'integer') }, (schema) => 0)\n\t\t\t.with({ type: 'object' }, (schema) => {\n\t\t\t\tlet out = validate({ schema, data: data ?? {}, mutate: true });\n\t\t\t\tif (!out.success) {\n\t\t\t\t\t// fallback\n\t\t\t\t\tlet obj = data || {};\n\t\t\t\t\tschema.required?.forEach((key) => {\n\t\t\t\t\t\tif (!(key in obj)) {\n\t\t\t\t\t\t\tlet last = obj[key];\n\t\t\t\t\t\t\tlet prop = schema.properties?.[key];\n\t\t\t\t\t\t\tif (prop && isNil(last)) obj[key] = JsonSchema.create(prop, last);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tout = validate({ schema, data: obj, mutate: true });\n\t\t\t\t\tif (!out.success) {\n\t\t\t\t\t\tconsole.warn(`Failed to create object with schema: ${out.message}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn out.data;\n\t\t\t})\n\t\t\t.with({ type: 'null' }, () => null)\n\t\t\t.with({ type: 'boolean' }, (schema) => false)\n\t\t\t.with({ type: 'array' }, (schema) => [])\n\t\t\t.otherwise(() => {\n\t\t\t\treturn undefined;\n\t\t\t});\n\t}\n\n\texport function isPrimitiveType(schema: any): boolean {\n\t\treturn match(schema as JsonSchemaDef)\n\t\t\t.returnType<boolean>()\n\t\t\t.with({ type: P.union('number', 'integer', 'string', 'boolean') }, () => true)\n\t\t\t.with({ anyOf: P.nonNullable }, (schema) => {\n\t\t\t\treturn isPrimitiveType(schema.anyOf[0]);\n\t\t\t})\n\t\t\t.with({ oneOf: P.nonNullable }, (schema) => {\n\t\t\t\treturn isPrimitiveType(schema.oneOf[0]);\n\t\t\t})\n\t\t\t.otherwise(() => false);\n\t}\n}\n"],"names":["Ajv","addFormats","localize","addKeywords","isNil","match","P","_createAjv","opt","ajv","validate","schema","data","mutate","clone","opts","strict","strictSchema","Object","assign","removeAdditional","useDefaults","coerceTypes","allErrors","structuredClone","JsonSchema","createAjv","compile","valid","errors","success","message","errorsText","schemas","addSchema","onConflict","$id","Error","old","_","neo","idx","findIndex","s","push","check","safeParse","parse","out","create","returnType","with","const","select","v","default","anyOf","nonNullable","oneOf","type","union","obj","required","forEach","key","last","prop","properties","console","warn","otherwise","undefined","isPrimitiveType"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/jsonschema/JsonSchema.ts"],"sourcesContent":["import type { Static, TSchema } from '@sinclair/typebox';\nimport Ajv, { type ErrorObject, type Options } from 'ajv';\nimport addFormats from 'ajv-formats';\n// import localize from 'ajv-i18n/localize/zh';\nimport addKeywords from 'ajv-keywords';\nimport { isNil } from 'es-toolkit';\nimport { match, P } from 'ts-pattern';\nimport type { JsonSchemaDef } from './types';\n\nfunction _createAjv(opt: Options) {\n\tconst ajv = new Ajv(opt);\n\taddKeywords(ajv);\n\taddFormats(ajv);\n\treturn ajv;\n}\n\ntype ValidateOptions = { mutate?: boolean; clone?: boolean; ajv?: Ajv };\n\ntype ValidateResult<T> =\n\t| { data: T; success: true; message: undefined }\n\t| { data: undefined; success: false; message: string; errors: ErrorObject[] };\n\nfunction validate({ schema, data, mutate, clone, ajv }: ValidateOptions & { schema: any; data: any }) {\n\tlet opts: Options = {\n\t\t// strict: 'log',\n\t\tstrict: true,\n\t\tstrictSchema: 'log', // skip unknown keywords in schema\n\t};\n\n\tif (mutate) {\n\t\tObject.assign(opts, { removeAdditional: true, useDefaults: true, coerceTypes: true, allErrors: true });\n\t}\n\n\tif (clone) {\n\t\tdata = structuredClone(data);\n\t}\n\n\tif (!ajv) {\n\t\tajv = JsonSchema.createAjv(opts);\n\t}\n\n\tconst validate = ajv.compile(schema);\n\n\t// consider reusing validate instance\n\n\tconst valid = validate(data);\n\tconst errors = validate.errors;\n\t// localize(errors);\n\n\treturn { data, success: valid, message: ajv.errorsText(errors), errors: errors };\n}\n\ntype TypeOfSchema<S> = S extends TSchema ? Static<S> : any;\n\nexport namespace JsonSchema {\n\texport let schemas: JsonSchemaDef[] = [];\n\n\texport const createAjv = _createAjv;\n\n\texport function addSchema(\n\t\tschema: JsonSchemaDef,\n\t\t{\n\t\t\tonConflict = 'throw',\n\t\t}: {\n\t\t\tonConflict?: 'throw' | 'ignore' | 'replace' | ((old: JsonSchemaDef, neo: JsonSchemaDef) => JsonSchemaDef);\n\t\t} = {},\n\t) {\n\t\tif (!schema.$id) throw new Error('Schema must have $id');\n\t\tswitch (onConflict) {\n\t\t\tcase 'ignore':\n\t\t\t\tonConflict = (old) => old;\n\t\t\t\tbreak;\n\t\t\tcase 'replace':\n\t\t\t\tonConflict = (_, neo) => neo;\n\t\t\t\tbreak;\n\t\t\tcase 'throw':\n\t\t\t\tonConflict = (old, neo) => {\n\t\t\t\t\tthrow new Error(`Schema ${neo.$id} already exists`);\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t}\n\t\tlet idx = schemas.findIndex((s) => s.$id === schema.$id);\n\t\tif (idx >= 0) {\n\t\t\tschemas[idx] = onConflict(schemas[idx], schema);\n\t\t} else {\n\t\t\tschemas.push(schema);\n\t\t}\n\t}\n\n\t/**\n\t * Check data is valid, will not use default\n\t */\n\texport function check<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {\n\t\treturn validate({ schema, data, mutate: false, clone: true }) as any;\n\t}\n\n\t/**\n\t * Parse data with default value and coerceTypes\n\t */\n\texport function safeParse<S>(schema: S, data: any): ValidateResult<TypeOfSchema<S>> {\n\t\treturn validate({ schema, data, mutate: true, clone: true }) as any;\n\t}\n\n\texport function parse<S>(schema: S, data: any): TypeOfSchema<S> {\n\t\tconst { data: out, message, errors } = validate({ schema, data, mutate: true, clone: true });\n\t\tif (errors) {\n\t\t\tthrow new Error(message);\n\t\t}\n\t\treturn out;\n\t}\n\n\texport function create<S>(schema: S, data?: any): TypeOfSchema<S> {\n\t\t// will not ensure value match the rule\n\t\treturn match(schema as JsonSchemaDef)\n\t\t\t.returnType<any>()\n\t\t\t.with({ const: P.select() }, (v) => v)\n\t\t\t.with({ default: P.select() }, (v) => v)\n\t\t\t.with({ anyOf: P.nonNullable }, (schema) => {\n\t\t\t\treturn create(schema.anyOf[0]);\n\t\t\t})\n\t\t\t.with({ oneOf: P.nonNullable }, (schema) => {\n\t\t\t\treturn create(schema.oneOf[0]);\n\t\t\t})\n\t\t\t.with({ type: 'string' }, (schema) => '')\n\t\t\t.with({ type: P.union('number', 'integer') }, (schema) => 0)\n\t\t\t.with({ type: 'object' }, (schema) => {\n\t\t\t\tlet out = validate({ schema, data: data ?? {}, mutate: true });\n\t\t\t\tif (!out.success) {\n\t\t\t\t\t// fallback\n\t\t\t\t\tlet obj = data || {};\n\t\t\t\t\tschema.required?.forEach((key) => {\n\t\t\t\t\t\tif (!(key in obj)) {\n\t\t\t\t\t\t\tlet last = obj[key];\n\t\t\t\t\t\t\tlet prop = schema.properties?.[key];\n\t\t\t\t\t\t\tif (prop && isNil(last)) obj[key] = JsonSchema.create(prop, last);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tout = validate({ schema, data: obj, mutate: true });\n\t\t\t\t\tif (!out.success) {\n\t\t\t\t\t\tconsole.warn(`Failed to create object with schema: ${out.message}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn out.data;\n\t\t\t})\n\t\t\t.with({ type: 'null' }, () => null)\n\t\t\t.with({ type: 'boolean' }, (schema) => false)\n\t\t\t.with({ type: 'array' }, (schema) => [])\n\t\t\t.otherwise(() => {\n\t\t\t\treturn undefined;\n\t\t\t});\n\t}\n\n\texport function isPrimitiveType(schema: any): boolean {\n\t\treturn match(schema as JsonSchemaDef)\n\t\t\t.returnType<boolean>()\n\t\t\t.with({ type: P.union('number', 'integer', 'string', 'boolean') }, () => true)\n\t\t\t.with({ anyOf: P.nonNullable }, (schema) => {\n\t\t\t\treturn isPrimitiveType(schema.anyOf[0]);\n\t\t\t})\n\t\t\t.with({ oneOf: P.nonNullable }, (schema) => {\n\t\t\t\treturn isPrimitiveType(schema.oneOf[0]);\n\t\t\t})\n\t\t\t.otherwise(() => false);\n\t}\n}\n"],"names":["Ajv","addFormats","addKeywords","isNil","match","P","_createAjv","opt","ajv","validate","schema","data","mutate","clone","opts","strict","strictSchema","Object","assign","removeAdditional","useDefaults","coerceTypes","allErrors","structuredClone","JsonSchema","createAjv","compile","valid","errors","success","message","errorsText","schemas","addSchema","onConflict","$id","Error","old","_","neo","idx","findIndex","s","push","check","safeParse","parse","out","create","returnType","with","const","select","v","default","anyOf","nonNullable","oneOf","type","union","obj","required","forEach","key","last","prop","properties","console","warn","otherwise","undefined","isPrimitiveType"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { exec } from "node:child_process";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import * as Codegen from "@sinclair/typebox-codegen";
5
+ export async function generateSchema({ file, dir = path.dirname(file) }) {
6
+ const fn = path.basename(file).replace(/\.d\.ts$/, '.ts');
7
+ const types = await fs.readFile(file, 'utf-8');
8
+ const typeboxDir = path.join(dir, 'typebox');
9
+ const zodDir = path.join(dir, 'zod');
10
+ await fs.mkdir(typeboxDir, {
11
+ recursive: true
12
+ });
13
+ await fs.mkdir(zodDir, {
14
+ recursive: true
15
+ });
16
+ const typeBoxFile = path.join(typeboxDir, fn);
17
+ const zodFile = path.join(zodDir, fn);
18
+ {
19
+ // avoid import type error
20
+ let out = Codegen.TypeScriptToTypeBox.Generate(types);
21
+ out = out.replace(/^import \{ Type, Static\b/, `import { Type, type Static`);
22
+ await fs.writeFile(typeBoxFile, out);
23
+ }
24
+ const model = Codegen.TypeScriptToModel.Generate(types);
25
+ await fs.writeFile(zodFile, Codegen.ModelToZod.Generate(model));
26
+ await new Promise((resolve, reject)=>{
27
+ exec(`pnpm prettier --write "${dir}/{typebox,zod}/*.ts"`, (error, stdout, stderr)=>{
28
+ if (error) {
29
+ console.error(`exec error: ${error}`);
30
+ reject(error);
31
+ return;
32
+ }
33
+ resolve({
34
+ stderr,
35
+ stdout
36
+ });
37
+ stdout && console.log(`prettier:stdout: ${stdout}`);
38
+ stderr && console.error(`prettier:stderr: ${stderr}`);
39
+ });
40
+ });
41
+ }
42
+
43
+ //# sourceMappingURL=generateSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tools/generateSchema.ts"],"sourcesContent":["import { exec } from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport * as Codegen from '@sinclair/typebox-codegen';\n\nexport async function generateSchema({ file, dir = path.dirname(file) }: { file: string; dir?: string }) {\n const fn = path.basename(file).replace(/\\.d\\.ts$/, '.ts');\n const types = await fs.readFile(file, 'utf-8');\n\n const typeboxDir = path.join(dir, 'typebox');\n const zodDir = path.join(dir, 'zod');\n\n await fs.mkdir(typeboxDir, { recursive: true });\n await fs.mkdir(zodDir, { recursive: true });\n\n const typeBoxFile = path.join(typeboxDir, fn);\n const zodFile = path.join(zodDir, fn);\n {\n // avoid import type error\n let out = Codegen.TypeScriptToTypeBox.Generate(types);\n out = out.replace(/^import \\{ Type, Static\\b/, `import { Type, type Static`);\n await fs.writeFile(typeBoxFile, out);\n }\n const model = Codegen.TypeScriptToModel.Generate(types);\n await fs.writeFile(zodFile, Codegen.ModelToZod.Generate(model));\n\n await new Promise((resolve, reject) => {\n exec(`pnpm prettier --write \"${dir}/{typebox,zod}/*.ts\"`, (error, stdout, stderr) => {\n if (error) {\n console.error(`exec error: ${error}`);\n reject(error);\n return;\n }\n resolve({ stderr, stdout });\n stdout && console.log(`prettier:stdout: ${stdout}`);\n stderr && console.error(`prettier:stderr: ${stderr}`);\n });\n });\n}\n"],"names":["exec","fs","path","Codegen","generateSchema","file","dir","dirname","fn","basename","replace","types","readFile","typeboxDir","join","zodDir","mkdir","recursive","typeBoxFile","zodFile","out","TypeScriptToTypeBox","Generate","writeFile","model","TypeScriptToModel","ModelToZod","Promise","resolve","reject","error","stdout","stderr","console","log"],"mappings":"AAAA,SAASA,IAAI,QAAQ,qBAAqB;AAC1C,OAAOC,QAAQ,mBAAmB;AAClC,OAAOC,UAAU,YAAY;AAC7B,YAAYC,aAAa,4BAA4B;AAErD,OAAO,eAAeC,eAAe,EAAEC,IAAI,EAAEC,MAAMJ,KAAKK,OAAO,CAACF,KAAK,EAAkC;IACrG,MAAMG,KAAKN,KAAKO,QAAQ,CAACJ,MAAMK,OAAO,CAAC,YAAY;IACnD,MAAMC,QAAQ,MAAMV,GAAGW,QAAQ,CAACP,MAAM;IAEtC,MAAMQ,aAAaX,KAAKY,IAAI,CAACR,KAAK;IAClC,MAAMS,SAASb,KAAKY,IAAI,CAACR,KAAK;IAE9B,MAAML,GAAGe,KAAK,CAACH,YAAY;QAAEI,WAAW;IAAK;IAC7C,MAAMhB,GAAGe,KAAK,CAACD,QAAQ;QAAEE,WAAW;IAAK;IAEzC,MAAMC,cAAchB,KAAKY,IAAI,CAACD,YAAYL;IAC1C,MAAMW,UAAUjB,KAAKY,IAAI,CAACC,QAAQP;IAClC;QACE,0BAA0B;QAC1B,IAAIY,MAAMjB,QAAQkB,mBAAmB,CAACC,QAAQ,CAACX;QAC/CS,MAAMA,IAAIV,OAAO,CAAC,6BAA6B,CAAC,0BAA0B,CAAC;QAC3E,MAAMT,GAAGsB,SAAS,CAACL,aAAaE;IAClC;IACA,MAAMI,QAAQrB,QAAQsB,iBAAiB,CAACH,QAAQ,CAACX;IACjD,MAAMV,GAAGsB,SAAS,CAACJ,SAAShB,QAAQuB,UAAU,CAACJ,QAAQ,CAACE;IAExD,MAAM,IAAIG,QAAQ,CAACC,SAASC;QAC1B7B,KAAK,CAAC,uBAAuB,EAAEM,IAAI,oBAAoB,CAAC,EAAE,CAACwB,OAAOC,QAAQC;YACxE,IAAIF,OAAO;gBACTG,QAAQH,KAAK,CAAC,CAAC,YAAY,EAAEA,OAAO;gBACpCD,OAAOC;gBACP;YACF;YACAF,QAAQ;gBAAEI;gBAAQD;YAAO;YACzBA,UAAUE,QAAQC,GAAG,CAAC,CAAC,iBAAiB,EAAEH,QAAQ;YAClDC,UAAUC,QAAQH,KAAK,CAAC,CAAC,iBAAiB,EAAEE,QAAQ;QACtD;IACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wener/common",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "author": "",
@@ -14,6 +14,10 @@
14
14
  "types": "./src/cn/index.ts",
15
15
  "default": "./lib/cn/index.js"
16
16
  },
17
+ "./consola": {
18
+ "types": "./src/consola/index.ts",
19
+ "default": "./lib/consola/index.js"
20
+ },
17
21
  "./data": {
18
22
  "types": "./src/data/index.ts",
19
23
  "default": "./lib/data/index.js"
@@ -45,12 +49,14 @@
45
49
  "keywords": [],
46
50
  "dependencies": {
47
51
  "es-toolkit": "^1.32.0",
52
+ "std-env": "^3.8.1",
48
53
  "ts-pattern": "^5.6.2",
49
54
  "zod": "^3.24.2",
50
55
  "@wener/utils": "1.1.51"
51
56
  },
52
57
  "devDependencies": {
53
58
  "@sinclair/typebox": "^0.34.28",
59
+ "@sinclair/typebox-codegen": "^0.10.5",
54
60
  "@types/argon2-browser": "^1.18.4",
55
61
  "@types/bcrypt": "^5.0.2",
56
62
  "@types/bcryptjs": "^2.4.6",
@@ -61,7 +67,10 @@
61
67
  "argon2": "^0.41.1",
62
68
  "argon2-browser": "^1.18.0",
63
69
  "bcrypt": "^5.1.1",
64
- "bcryptjs": "^3.0.2"
70
+ "bcryptjs": "^3.0.2",
71
+ "chalk": "^5.4.1",
72
+ "consola": "^3.4.2",
73
+ "dayjs": "^1.11.13"
65
74
  },
66
75
  "scripts": {
67
76
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -0,0 +1,31 @@
1
+ import type { ConsolaOptions, ConsolaReporter, LogObject } from 'consola/core';
2
+ import { formatLogObject } from './formatLogObject';
3
+
4
+ type Formatter = (
5
+ o: LogObject,
6
+ ctx: {
7
+ options: ConsolaOptions;
8
+ },
9
+ ) => string;
10
+
11
+ export function createStandardConsolaReporter({
12
+ format = formatLogObject,
13
+ }: {
14
+ format?: Formatter;
15
+ } = {}): ConsolaReporter {
16
+ return {
17
+ log: (o, ctx) => {
18
+ let out = format(o, ctx);
19
+ let fn = console.log;
20
+
21
+ const { level } = o;
22
+ if (level < 1) {
23
+ fn = console.error;
24
+ } else if (level === 1) {
25
+ fn = console.warn;
26
+ }
27
+
28
+ fn(out);
29
+ },
30
+ };
31
+ }
@@ -0,0 +1,171 @@
1
+ import colors from 'chalk';
2
+ import type { ConsolaOptions, FormatOptions, LogObject, LogType } from 'consola/core';
3
+ import dayjs from 'dayjs';
4
+ import { isDevelopment } from 'std-env';
5
+
6
+ const levelColors: Record<LogType, (str: string) => string> = {
7
+ trace: colors.gray,
8
+ debug: colors.cyan,
9
+ info: colors.blueBright,
10
+ warn: colors.yellow,
11
+ error: colors.red,
12
+ fatal: colors.bgRed.white,
13
+ silent: colors.white,
14
+ log: colors.white,
15
+ success: colors.green,
16
+ fail: colors.red,
17
+ ready: colors.green,
18
+ start: colors.cyan,
19
+ box: colors.white,
20
+ verbose: colors.green,
21
+ };
22
+
23
+ const levelShort: Record<LogType, string> = {
24
+ trace: 'TRAC',
25
+ debug: 'DEBG',
26
+ info: 'INFO',
27
+ warn: 'WARN',
28
+ error: 'ERRO',
29
+ fatal: 'FATL',
30
+ silent: 'SLNT',
31
+ log: 'LOG ', // Added space to make it 4 characters
32
+ success: 'SUCC',
33
+ fail: 'FAIL',
34
+ ready: 'READ',
35
+ start: 'STRT',
36
+ box: 'BOX ', // Added space to make it 4 characters
37
+ verbose: 'VERB',
38
+ };
39
+ const start = Date.now();
40
+
41
+ export function formatLogObject(
42
+ o: LogObject,
43
+ ctx: {
44
+ options: ConsolaOptions;
45
+ },
46
+ ) {
47
+ let { date, type, tag } = o;
48
+ type = type === 'log' ? 'info' : type;
49
+
50
+ const color = levelColors[type] || colors.white;
51
+ const levelText = levelShort[type] || type.toUpperCase().slice(0, 4); // Get first 4 chars, consistent uppercase
52
+
53
+ let line = '';
54
+ let out: string[] = [];
55
+
56
+ // Timestamp
57
+ if (isDevelopment) {
58
+ // process.hrtime.bigint()
59
+ let diff = (date.getTime() - start) / 1000;
60
+
61
+ out.push(colors.gray(diff.toFixed(3).padStart(7, ' ')));
62
+ } else {
63
+ out.push(colors.gray(dayjs(date).format('YYYY-MM-DD HH:mm:ss.SSS')));
64
+ }
65
+
66
+ // Log Level (colored)
67
+ // Pad to 4 characters
68
+ out.push(color(levelText.padEnd(4, ' ')));
69
+
70
+ if (tag) {
71
+ out.push(colors.yellow(`[${tag}]`)); // Added color for tag
72
+ }
73
+
74
+ {
75
+ const [message, ...additional] = formatArgs(o.args, ctx).split('\n');
76
+
77
+ out.push(characterFormat(message));
78
+
79
+ line = out.join(' ');
80
+ if (additional.length > 0) {
81
+ line += characterFormat(additional.join('\n'));
82
+ }
83
+
84
+ if (type === 'trace') {
85
+ const _err = new Error('Trace: ' + o.message);
86
+ line += formatStack(_err.stack || '', _err.message);
87
+ }
88
+ }
89
+
90
+ // if (!message && typeof args[0] === 'string') {
91
+ // message = args.shift();
92
+ // }
93
+ // if (message) {
94
+ // out.push(message);
95
+ // }
96
+ // if (args.length) {
97
+ // out.push(...args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a)))); // Handle non-string args
98
+ // }
99
+
100
+ // todo format error
101
+ // https://github.com/unjs/consola/blob/main/src/reporters/fancy.ts
102
+
103
+ // return out.join(' '); // Increased spacing for better readability
104
+ return line;
105
+ }
106
+
107
+ function characterFormat(str: string) {
108
+ return (
109
+ str
110
+ // highlight backticks
111
+ .replace(/`([^`]+)`/gm, (_, m) => colors.cyan(m))
112
+ // underline underscores
113
+ .replace(/\s+_([^_]+)_\s+/gm, (_, m) => ` ${colors.underline(m)} `)
114
+ );
115
+ }
116
+
117
+ function parseStack(stack: string, message: string) {
118
+ // const cwd = process.cwd() + sep;
119
+
120
+ const lines = stack
121
+ .split('\n')
122
+ .splice(message.split('\n').length)
123
+ .map(
124
+ (l) => l.trim().replace('file://', ''),
125
+ // .replace(cwd, '')
126
+ );
127
+
128
+ return lines;
129
+ }
130
+
131
+ function formatStack(stack: string, message: string, opts?: FormatOptions) {
132
+ const indent = ' '.repeat((opts?.errorLevel || 0) + 1);
133
+ return (
134
+ `\n${indent}`
135
+ + parseStack(stack, message)
136
+ .map(
137
+ (line) =>
138
+ ' ' + line.replace(/^at +/, (m) => colors.gray(m)).replace(/\((.+)\)/, (_, m) => `(${colors.cyan(m)})`),
139
+ )
140
+ .join(`\n${indent}`)
141
+ );
142
+ }
143
+
144
+ function formatArgs(args: any[], opts: FormatOptions) {
145
+ const _args = args.map((arg) => {
146
+ if (arg && typeof arg.stack === 'string') {
147
+ return formatError(arg, opts);
148
+ }
149
+ return arg;
150
+ });
151
+
152
+ // Only supported with Node >= 10
153
+ // https://nodejs.org/api/util.html#util_util_inspect_object_options
154
+ return formatWithOptions(opts, ..._args);
155
+ }
156
+
157
+ function formatWithOptions(o: any, ...params: any[]) {
158
+ // import { formatWithOptions } from 'node:util';
159
+ return params.join(' ');
160
+ }
161
+
162
+ function formatError(err: any, opts: FormatOptions): string {
163
+ const message = err.message ?? formatWithOptions(opts, err);
164
+ const stack = err.stack ? formatStack(err.stack, message, opts) : '';
165
+
166
+ const level = opts?.errorLevel || 0;
167
+ const causedPrefix = level > 0 ? `${' '.repeat(level)}[cause]: ` : '';
168
+ const causedError = err.cause ? '\n\n' + formatError(err.cause, { ...opts, errorLevel: level + 1 }) : '';
169
+
170
+ return causedPrefix + message + '\n' + stack + causedError;
171
+ }
@@ -0,0 +1,2 @@
1
+ export { formatLogObject } from './formatLogObject';
2
+ export { createStandardConsolaReporter } from './createStandardConsolaReporter';
@@ -39,7 +39,7 @@ export function resolvePagination(
39
39
  pageSize = maybeFunction(options.pageSize, pageSize);
40
40
  }
41
41
  pageSize ??= 20;
42
- pageSize = clamp(pageSize, 1, options.maxPageSize ?? 100);
42
+ pageSize = clamp(pageSize, 1, options.maxPageSize ?? 1000);
43
43
 
44
44
  let { pageNumber = 1, pageIndex, limit, offset } = out;
45
45
  // page index over page number
@@ -1,7 +1,7 @@
1
1
  import type { Static, TSchema } from '@sinclair/typebox';
2
2
  import Ajv, { type ErrorObject, type Options } from 'ajv';
3
3
  import addFormats from 'ajv-formats';
4
- import localize from 'ajv-i18n/localize/zh';
4
+ // import localize from 'ajv-i18n/localize/zh';
5
5
  import addKeywords from 'ajv-keywords';
6
6
  import { isNil } from 'es-toolkit';
7
7
  import { match, P } from 'ts-pattern';
@@ -45,7 +45,7 @@ function validate({ schema, data, mutate, clone, ajv }: ValidateOptions & { sche
45
45
 
46
46
  const valid = validate(data);
47
47
  const errors = validate.errors;
48
- localize(errors);
48
+ // localize(errors);
49
49
 
50
50
  return { data, success: valid, message: ajv.errorsText(errors), errors: errors };
51
51
  }
@@ -0,0 +1,39 @@
1
+ import { exec } from 'node:child_process';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import * as Codegen from '@sinclair/typebox-codegen';
5
+
6
+ export async function generateSchema({ file, dir = path.dirname(file) }: { file: string; dir?: string }) {
7
+ const fn = path.basename(file).replace(/\.d\.ts$/, '.ts');
8
+ const types = await fs.readFile(file, 'utf-8');
9
+
10
+ const typeboxDir = path.join(dir, 'typebox');
11
+ const zodDir = path.join(dir, 'zod');
12
+
13
+ await fs.mkdir(typeboxDir, { recursive: true });
14
+ await fs.mkdir(zodDir, { recursive: true });
15
+
16
+ const typeBoxFile = path.join(typeboxDir, fn);
17
+ const zodFile = path.join(zodDir, fn);
18
+ {
19
+ // avoid import type error
20
+ let out = Codegen.TypeScriptToTypeBox.Generate(types);
21
+ out = out.replace(/^import \{ Type, Static\b/, `import { Type, type Static`);
22
+ await fs.writeFile(typeBoxFile, out);
23
+ }
24
+ const model = Codegen.TypeScriptToModel.Generate(types);
25
+ await fs.writeFile(zodFile, Codegen.ModelToZod.Generate(model));
26
+
27
+ await new Promise((resolve, reject) => {
28
+ exec(`pnpm prettier --write "${dir}/{typebox,zod}/*.ts"`, (error, stdout, stderr) => {
29
+ if (error) {
30
+ console.error(`exec error: ${error}`);
31
+ reject(error);
32
+ return;
33
+ }
34
+ resolve({ stderr, stdout });
35
+ stdout && console.log(`prettier:stdout: ${stdout}`);
36
+ stderr && console.error(`prettier:stderr: ${stderr}`);
37
+ });
38
+ });
39
+ }