@anjianshi/utils 2.5.0 → 2.7.0

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 (147) hide show
  1. package/README.md +10 -0
  2. package/eslint.config.cjs +33 -0
  3. package/package.json +26 -15
  4. package/publish-prepare.cjs +16 -0
  5. package/src/env-browser/device.ts +62 -0
  6. package/src/env-browser/global.ts +21 -0
  7. package/src/env-browser/load-script.ts +13 -0
  8. package/src/env-browser/logging.ts +58 -0
  9. package/src/env-browser/manage-vconsole.ts +54 -0
  10. package/src/env-node/crypto-random.ts +30 -0
  11. package/src/env-node/fs.ts +50 -0
  12. package/src/env-node/index.ts +6 -0
  13. package/src/env-node/logging/handlers.ts +190 -0
  14. package/src/env-node/logging/index.ts +16 -0
  15. package/src/env-node/safe-request.ts +66 -0
  16. package/src/env-react/emotion.tsx +42 -0
  17. package/src/env-service/controllers.ts +93 -0
  18. package/src/env-service/env-reader.ts +141 -0
  19. package/src/env-service/index.ts +6 -0
  20. package/src/env-service/prisma/adapt-logging.ts +39 -0
  21. package/src/env-service/prisma/extensions/exist.ts +21 -0
  22. package/src/env-service/prisma/extensions/find-and-count.ts +24 -0
  23. package/src/env-service/prisma/extensions/soft-delete.ts +162 -0
  24. package/src/env-service/prisma/extensions/with-transaction.ts +65 -0
  25. package/src/env-service/prisma/index.ts +6 -0
  26. package/src/env-service/prisma/transaction-contexted.ts +80 -0
  27. package/src/env-service/redis-cache.ts +142 -0
  28. package/src/env-service/tasks.ts +45 -0
  29. package/src/index.ts +3 -0
  30. package/src/init-dayjs.ts +8 -0
  31. package/src/lang/async.ts +47 -0
  32. package/src/lang/color.ts +119 -0
  33. package/src/lang/index.ts +7 -0
  34. package/src/lang/may-success.ts +57 -0
  35. package/src/lang/object.ts +39 -0
  36. package/src/lang/random.ts +25 -0
  37. package/src/lang/string.ts +95 -0
  38. package/src/lang/time.ts +19 -0
  39. package/{lang/types.d.ts → src/lang/types.ts} +43 -23
  40. package/src/logging/adapt.ts +49 -0
  41. package/src/logging/formatters.ts +23 -0
  42. package/src/logging/index.ts +106 -0
  43. package/src/md5.ts +318 -0
  44. package/src/url.ts +185 -0
  45. package/src/validators/array.ts +97 -0
  46. package/src/validators/base.ts +145 -0
  47. package/src/validators/boolean.ts +21 -0
  48. package/src/validators/datetime.ts +39 -0
  49. package/src/validators/factory.ts +244 -0
  50. package/src/validators/index.ts +9 -0
  51. package/src/validators/number.ts +54 -0
  52. package/src/validators/object.ts +101 -0
  53. package/src/validators/one-of.ts +33 -0
  54. package/src/validators/string.ts +72 -0
  55. package/env-browser/device.d.ts +0 -24
  56. package/env-browser/device.js +0 -50
  57. package/env-browser/global.d.ts +0 -10
  58. package/env-browser/global.js +0 -15
  59. package/env-browser/load-script.d.ts +0 -5
  60. package/env-browser/load-script.js +0 -13
  61. package/env-browser/logging.d.ts +0 -18
  62. package/env-browser/logging.js +0 -49
  63. package/env-browser/manage-vconsole.d.ts +0 -16
  64. package/env-browser/manage-vconsole.js +0 -38
  65. package/env-node/crypto-random.d.ts +0 -13
  66. package/env-node/crypto-random.js +0 -28
  67. package/env-node/fs.d.ts +0 -19
  68. package/env-node/fs.js +0 -48
  69. package/env-node/index.d.ts +0 -5
  70. package/env-node/index.js +0 -5
  71. package/env-node/logging/handlers.d.ts +0 -58
  72. package/env-node/logging/handlers.js +0 -154
  73. package/env-node/logging/index.d.ts +0 -11
  74. package/env-node/logging/index.js +0 -14
  75. package/env-react/emotion.d.ts +0 -20
  76. package/env-react/emotion.jsx +0 -34
  77. package/env-service/controllers.d.ts +0 -30
  78. package/env-service/controllers.js +0 -41
  79. package/env-service/env-reader.d.ts +0 -55
  80. package/env-service/env-reader.js +0 -79
  81. package/env-service/index.d.ts +0 -6
  82. package/env-service/index.js +0 -6
  83. package/env-service/prisma/adapt-logging.d.ts +0 -21
  84. package/env-service/prisma/adapt-logging.js +0 -30
  85. package/env-service/prisma/extensions/exist.d.ts +0 -10
  86. package/env-service/prisma/extensions/exist.js +0 -16
  87. package/env-service/prisma/extensions/find-and-count.d.ts +0 -7
  88. package/env-service/prisma/extensions/find-and-count.js +0 -19
  89. package/env-service/prisma/extensions/soft-delete.d.ts +0 -52
  90. package/env-service/prisma/extensions/soft-delete.js +0 -123
  91. package/env-service/prisma/extensions/with-transaction.d.ts +0 -9
  92. package/env-service/prisma/extensions/with-transaction.js +0 -54
  93. package/env-service/prisma/index.d.ts +0 -6
  94. package/env-service/prisma/index.js +0 -6
  95. package/env-service/prisma/transaction-contexted.d.ts +0 -11
  96. package/env-service/prisma/transaction-contexted.js +0 -52
  97. package/env-service/redis-cache.d.ts +0 -39
  98. package/env-service/redis-cache.js +0 -116
  99. package/env-service/tasks.d.ts +0 -12
  100. package/env-service/tasks.js +0 -37
  101. package/index.d.ts +0 -3
  102. package/index.js +0 -3
  103. package/init-dayjs.d.ts +0 -2
  104. package/init-dayjs.js +0 -7
  105. package/lang/async.d.ts +0 -19
  106. package/lang/async.js +0 -34
  107. package/lang/index.d.ts +0 -7
  108. package/lang/index.js +0 -7
  109. package/lang/may-success.d.ts +0 -40
  110. package/lang/may-success.js +0 -27
  111. package/lang/object.d.ts +0 -5
  112. package/lang/object.js +0 -31
  113. package/lang/random.d.ts +0 -13
  114. package/lang/random.js +0 -24
  115. package/lang/string.d.ts +0 -29
  116. package/lang/string.js +0 -92
  117. package/lang/time.d.ts +0 -10
  118. package/lang/time.js +0 -18
  119. package/lang/types.js +0 -28
  120. package/logging/adapt.d.ts +0 -10
  121. package/logging/adapt.js +0 -43
  122. package/logging/formatters.d.ts +0 -10
  123. package/logging/formatters.js +0 -22
  124. package/logging/index.d.ts +0 -45
  125. package/logging/index.js +0 -90
  126. package/md5.d.ts +0 -30
  127. package/md5.js +0 -308
  128. package/url.d.ts +0 -77
  129. package/url.js +0 -149
  130. package/validators/array.d.ts +0 -30
  131. package/validators/array.js +0 -47
  132. package/validators/base.d.ts +0 -82
  133. package/validators/base.js +0 -42
  134. package/validators/boolean.d.ts +0 -3
  135. package/validators/boolean.js +0 -22
  136. package/validators/factory.d.ts +0 -66
  137. package/validators/factory.js +0 -109
  138. package/validators/index.d.ts +0 -8
  139. package/validators/index.js +0 -8
  140. package/validators/number.d.ts +0 -19
  141. package/validators/number.js +0 -26
  142. package/validators/object.d.ts +0 -28
  143. package/validators/object.js +0 -49
  144. package/validators/oneOf.d.ts +0 -10
  145. package/validators/oneOf.js +0 -15
  146. package/validators/string.d.ts +0 -22
  147. package/validators/string.js +0 -35
@@ -1,49 +0,0 @@
1
- /**
2
- * 针对浏览器环境定制 logging
3
- */
4
- import { logger as defaultLogger, LogLevel, LogHandler, formatters, } from '../logging/index.js';
5
- export * from '../logging/index.js';
6
- /**
7
- * 实现向浏览器 console 输出日志
8
- */
9
- export class ConsoleHandler extends LogHandler {
10
- log(info) {
11
- const color = (value = 'black') => `color: ${value};`;
12
- const prefix = '%c' + [formatters.time(info), info.logger].map((v) => (v ? `[${v}]` : '')).join('');
13
- const prefixColor = info.logger ? color(ConsoleHandler.getColor(info.logger)) : color();
14
- const values = [prefix, prefixColor, ...info.args];
15
- if (info.level === LogLevel.Debug)
16
- console.debug(...values);
17
- else if (info.level === LogLevel.Info)
18
- console.log(...values);
19
- else if (info.level === LogLevel.Warning)
20
- console.warn(...values);
21
- else
22
- console.error(...values);
23
- }
24
- // 按顺序给各主题分配颜色(取自 http://chriskempson.com/projects/base16/)
25
- static colors = [
26
- '#dc9656',
27
- '#7cafc2',
28
- '#ba8baf',
29
- '#a16946',
30
- '#ab4642',
31
- '#86c1b9',
32
- '#a1b56c',
33
- '#f7ca88',
34
- ];
35
- static colorMap = new Map();
36
- static getColor(name) {
37
- if (!ConsoleHandler.colorMap.has(name)) {
38
- const nextIndex = ConsoleHandler.colorMap.size % ConsoleHandler.colors.length;
39
- ConsoleHandler.colorMap.set(name, ConsoleHandler.colors[nextIndex]);
40
- }
41
- return ConsoleHandler.colorMap.get(name);
42
- }
43
- }
44
- /**
45
- * 预设的初始化行为
46
- */
47
- export function initLogger(logger = defaultLogger) {
48
- logger.addHandler(new ConsoleHandler());
49
- }
@@ -1,16 +0,0 @@
1
- import { type default as VConsole } from 'vconsole';
2
- export declare function registerVConsoleLib(lib: new () => VConsole): void;
3
- /**
4
- * 管理 VConsole 实例
5
- */
6
- declare global {
7
- interface Window {
8
- VConsole: VConsole | null;
9
- }
10
- }
11
- export declare function isVConsoleEnabled(): boolean;
12
- export declare function detectVConsole(): void;
13
- export declare function enableVConsole(): void;
14
- export declare function disableVConsole(): void;
15
- export declare function runVConsole(): void;
16
- export declare function destoryVConsole(): void;
@@ -1,38 +0,0 @@
1
- /**
2
- * 注册 VConsole 代码
3
- * 此类库自己并不加载 VConsole,需使用者自行通过依赖或者 CDN 加载 VConsole 然后传给此类库
4
- */
5
- let VConsoleLib;
6
- export function registerVConsoleLib(lib) {
7
- VConsoleLib = lib;
8
- }
9
- window.VConsole = null;
10
- export function isVConsoleEnabled() {
11
- return localStorage.getItem('vconsole') === '1';
12
- }
13
- export function detectVConsole() {
14
- if (isVConsoleEnabled()) {
15
- runVConsole();
16
- }
17
- }
18
- export function enableVConsole() {
19
- localStorage.setItem('vconsole', '1');
20
- runVConsole();
21
- }
22
- export function disableVConsole() {
23
- localStorage.setItem('vconsole', '0');
24
- destoryVConsole();
25
- }
26
- export function runVConsole() {
27
- if (window.VConsole !== null)
28
- return;
29
- if (VConsoleLib === undefined)
30
- return console.warn('尚未传入 VConsole 对象,无法启动');
31
- window.VConsole = new VConsoleLib();
32
- }
33
- export function destoryVConsole() {
34
- if (!window.VConsole)
35
- return;
36
- window.VConsole.destroy();
37
- window.VConsole = null;
38
- }
@@ -1,13 +0,0 @@
1
- /**
2
- * 返回随机数,包含 min 和 max
3
- */
4
- export declare function getCryptoRandomInt(min: number, max: number): number;
5
- /**
6
- * 返回随机字符串
7
- */
8
- export declare function getCryptoRandomString(length?: number, seed?: string): string;
9
- /**
10
- * 从给定的选择中随机选中一项
11
- * 如果数组为空,会返回 undefined
12
- */
13
- export declare function cryptoChoiceRandom<T>(choices: T[]): T | undefined;
@@ -1,28 +0,0 @@
1
- /**
2
- * 类似 lang/random.ts,但基于 Node.js 的 crypto 模块,提供密码级的随机数。
3
- */
4
- import crypto from 'node:crypto';
5
- /**
6
- * 返回随机数,包含 min 和 max
7
- */
8
- export function getCryptoRandomInt(min, max) {
9
- // 如果传入的 max 小于 min,把它拉到和 min 一样。不然 crypto.randomInt 无法处理
10
- const fixedMax = Math.max(min, max);
11
- return crypto.randomInt(min, fixedMax + 1);
12
- }
13
- /**
14
- * 返回随机字符串
15
- */
16
- export function getCryptoRandomString(length = 6, seed = '0123456789abcdefghijklmnopqrstuvwxyz') {
17
- let result = '';
18
- while (result.length < length)
19
- result += seed[getCryptoRandomInt(0, seed.length - 1)];
20
- return result;
21
- }
22
- /**
23
- * 从给定的选择中随机选中一项
24
- * 如果数组为空,会返回 undefined
25
- */
26
- export function cryptoChoiceRandom(choices) {
27
- return choices[getCryptoRandomInt(0, choices.length - 1)];
28
- }
package/env-node/fs.d.ts DELETED
@@ -1,19 +0,0 @@
1
- /**
2
- * 确认一个路径是否存在且是文件
3
- */
4
- export declare function isFileExists(filepath: string): Promise<boolean>;
5
- /**
6
- * 确认一个路径是否存在且是文件夹
7
- */
8
- export declare function isDirectoryExists(dirpath: string): Promise<boolean>;
9
- /**
10
- * 返回当前文件的绝对路径
11
- * 需要传入当前文件的 ImportMeta 对象(可通过 import.meta 取得)
12
- */
13
- export declare function getFilePath(fileUrl: string | ImportMeta): string;
14
- /**
15
- * 返回文件所处目录的绝对路径
16
- */
17
- export declare function getDirectoryPath(fileUrl: string | ImportMeta): string;
18
- /** 确保目录存在,如果不存在就创建(会递归创建上级目录) */
19
- export declare function mkdirp(dirpath: string, mode?: number | string): Promise<void>;
package/env-node/fs.js DELETED
@@ -1,48 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- /**
5
- * 确认一个路径是否存在且是文件
6
- */
7
- export async function isFileExists(filepath) {
8
- try {
9
- const res = await fs.promises.stat(filepath);
10
- return res.isFile();
11
- }
12
- catch (e) {
13
- return false;
14
- }
15
- }
16
- /**
17
- * 确认一个路径是否存在且是文件夹
18
- */
19
- export async function isDirectoryExists(dirpath) {
20
- try {
21
- const res = await fs.promises.stat(dirpath);
22
- return res.isDirectory();
23
- }
24
- catch (e) {
25
- return false;
26
- }
27
- }
28
- /**
29
- * 返回当前文件的绝对路径
30
- * 需要传入当前文件的 ImportMeta 对象(可通过 import.meta 取得)
31
- */
32
- export function getFilePath(fileUrl) {
33
- if (typeof fileUrl !== 'string')
34
- fileUrl = fileUrl.url;
35
- return fileURLToPath(new URL(fileUrl));
36
- }
37
- /**
38
- * 返回文件所处目录的绝对路径
39
- */
40
- export function getDirectoryPath(fileUrl) {
41
- return path.dirname(getFilePath(fileUrl));
42
- }
43
- /** 确保目录存在,如果不存在就创建(会递归创建上级目录) */
44
- export async function mkdirp(dirpath, mode) {
45
- if (!(await isDirectoryExists(dirpath))) {
46
- await fs.promises.mkdir(dirpath, { recursive: true, mode });
47
- }
48
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Node.js 环境下的工具函数
3
- */
4
- export * from './fs.js';
5
- export * from './crypto-random.js';
package/env-node/index.js DELETED
@@ -1,5 +0,0 @@
1
- /**
2
- * Node.js 环境下的工具函数
3
- */
4
- export * from './fs.js';
5
- export * from './crypto-random.js';
@@ -1,58 +0,0 @@
1
- import { type LogInfo, LogHandler } from '../../logging/index.js';
2
- /**
3
- * 向 console 输出日志
4
- */
5
- export declare class ConsoleHandler extends LogHandler {
6
- log(info: LogInfo): void;
7
- static readonly consoleMethods: {
8
- 1: {
9
- (...data: any[]): void;
10
- (message?: any, ...optionalParams: any[]): void;
11
- };
12
- 2: {
13
- (...data: any[]): void;
14
- (message?: any, ...optionalParams: any[]): void;
15
- };
16
- 3: {
17
- (...data: any[]): void;
18
- (message?: any, ...optionalParams: any[]): void;
19
- };
20
- 4: {
21
- (...data: any[]): void;
22
- (message?: any, ...optionalParams: any[]): void;
23
- };
24
- };
25
- static readonly levelColors: {
26
- 1: import("chalk").ChalkInstance;
27
- 2: import("chalk").ChalkInstance;
28
- 3: import("chalk").ChalkInstance;
29
- 4: import("chalk").ChalkInstance;
30
- };
31
- private static readonly loggerColors;
32
- private static readonly loggerColorMap;
33
- static getLoggerColor(logger: string): "green" | "yellow" | "blue" | "cyan" | "magenta" | "greenBright" | "yellowBright" | "blueBright" | "cyanBright" | "magentaBright";
34
- }
35
- /**
36
- * 写入文件日志
37
- */
38
- export interface FileHandlerOptions {
39
- dir: string;
40
- filePrefix: string;
41
- maxLength: number;
42
- flushLength: number;
43
- flushInterval: number;
44
- }
45
- export declare class FileHandler extends LogHandler {
46
- readonly options: FileHandlerOptions;
47
- constructor(options?: Partial<FileHandlerOptions>);
48
- log(info: LogInfo): void;
49
- protected stringifyDataItem(item: unknown): string;
50
- private buffer;
51
- private bufferSize;
52
- private flushTimeoutId;
53
- protected pushBuffer(...strings: string[]): void;
54
- protected flush(sync?: boolean): void;
55
- get filepath(): string;
56
- protected initLogDir(): void;
57
- protected write(content: string, sync?: boolean): void;
58
- }
@@ -1,154 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- import util from 'node:util';
5
- import chalk from 'chalk';
6
- import dayjs from 'dayjs';
7
- import { LogLevel, LogHandler, formatters } from '../../logging/index.js';
8
- /**
9
- * 向 console 输出日志
10
- */
11
- export class ConsoleHandler extends LogHandler {
12
- log(info) {
13
- const { logger, level, args } = info;
14
- const method = ConsoleHandler.consoleMethods[level];
15
- const levelColor = ConsoleHandler.levelColors[level];
16
- const levelName = formatters.level(info);
17
- const loggerColor = chalk[ConsoleHandler.getLoggerColor(logger)];
18
- const prefix = [
19
- chalk.white(`[${formatters.time(info)}]`),
20
- levelColor(`[${levelName}]`),
21
- ...(logger ? [loggerColor(`[${logger}]`)] : []),
22
- ].join('');
23
- method(prefix, ...args);
24
- }
25
- static consoleMethods = {
26
- [LogLevel.Debug]: console.debug.bind(console),
27
- [LogLevel.Info]: console.info.bind(console),
28
- [LogLevel.Warning]: console.warn.bind(console),
29
- [LogLevel.Error]: console.error.bind(console),
30
- };
31
- static levelColors = {
32
- [LogLevel.Debug]: chalk.whiteBright,
33
- [LogLevel.Info]: chalk.white,
34
- [LogLevel.Warning]: chalk.yellowBright,
35
- [LogLevel.Error]: chalk.redBright,
36
- };
37
- // 可供 logger 选择的颜色
38
- static loggerColors = [
39
- 'green',
40
- 'yellow',
41
- 'blue',
42
- 'magenta',
43
- 'cyan',
44
- 'greenBright',
45
- 'yellowBright',
46
- 'blueBright',
47
- 'magentaBright',
48
- 'cyanBright',
49
- ];
50
- static loggerColorMap = new Map();
51
- static getLoggerColor(logger) {
52
- if (!ConsoleHandler.loggerColorMap.has(logger)) {
53
- const color = ConsoleHandler.loggerColors[ConsoleHandler.loggerColorMap.size % ConsoleHandler.loggerColors.length];
54
- ConsoleHandler.loggerColorMap.set(logger, color);
55
- }
56
- return ConsoleHandler.loggerColorMap.get(logger);
57
- }
58
- }
59
- export class FileHandler extends LogHandler {
60
- options;
61
- constructor(options) {
62
- super();
63
- const dirname = path.dirname(fileURLToPath(new URL(import.meta.url)));
64
- this.options = {
65
- dir: path.resolve(dirname, 'logs'),
66
- filePrefix: '',
67
- maxLength: 10000,
68
- flushLength: 100000,
69
- flushInterval: 1000,
70
- ...(options ?? {}),
71
- };
72
- this.initLogDir();
73
- // 进程退出前把尚未写入文件的日志强制写入
74
- // 这里必须用同步的方式来写,不然会写入不进去(可能是因为异步的话是放到下一个事件循环,但进程在这个事件循环内就退出了)
75
- process.on('exit', () => this.flush(true));
76
- }
77
- // Format log content
78
- log(info) {
79
- const { logger, args } = info;
80
- const prefix = [
81
- `[${formatters.datetime(info)}]`,
82
- `[${formatters.level(info)}]`,
83
- logger ? `[${logger}]` : '',
84
- ].join('') + ' ';
85
- const itemStrings = [];
86
- let totalLength = prefix.length;
87
- for (const item of args) {
88
- const itemString = this.stringifyDataItem(item);
89
- // 截断过长的日志内容 Truncate overly long log messages
90
- if (totalLength + itemString.length < this.options.maxLength) {
91
- itemStrings.push((totalLength === prefix.length ? '' : ' ') + itemString);
92
- totalLength += itemString.length;
93
- }
94
- else {
95
- itemStrings.push(itemString.slice(0, this.options.maxLength - totalLength) + ' [too long, sliced]');
96
- break;
97
- }
98
- }
99
- this.pushBuffer(prefix, ...itemStrings, '\n');
100
- }
101
- stringifyDataItem(item) {
102
- // 去掉颜色控制字符
103
- if (typeof item === 'string')
104
- item = item.replace(/\x1b\[\d+m/g, '');
105
- // 利用 util.format() 获得和 console.log() 相同的输出(因为 console.log() 底层也是用的 util.format())
106
- return util.format(item);
107
- }
108
- // Handle buffer & flush
109
- buffer = [];
110
- bufferSize = 0;
111
- flushTimeoutId = null;
112
- pushBuffer(...strings) {
113
- this.buffer.push(...strings);
114
- this.bufferSize = strings.reduce((sum, v) => sum + v.length, this.bufferSize);
115
- if (this.options.flushInterval === 0 || this.bufferSize >= this.options.flushLength) {
116
- this.flush();
117
- }
118
- else if (!this.flushTimeoutId) {
119
- this.flushTimeoutId = setTimeout(() => this.flush(), this.options.flushInterval);
120
- }
121
- }
122
- flush(sync) {
123
- if (this.flushTimeoutId) {
124
- clearTimeout(this.flushTimeoutId);
125
- this.flushTimeoutId = null;
126
- }
127
- if (this.buffer.length) {
128
- const content = this.buffer.join('');
129
- this.buffer = [];
130
- this.bufferSize = 0;
131
- this.write(content, sync);
132
- }
133
- }
134
- // 文件系统交互 File system interaction
135
- get filepath() {
136
- const { dir, filePrefix } = this.options;
137
- return path.join(dir, `${filePrefix ? `${filePrefix}-` : ''}${dayjs().format('YYYY-MM-DD')}.log`);
138
- }
139
- initLogDir() {
140
- if (!fs.existsSync(this.options.dir))
141
- fs.mkdirSync(this.options.dir);
142
- }
143
- write(content, sync = false) {
144
- if (sync) {
145
- fs.appendFileSync(this.filepath, content);
146
- }
147
- else {
148
- fs.appendFile(this.filepath, content, error => {
149
- if (error)
150
- console.error('[logger] write failed: ', error);
151
- });
152
- }
153
- }
154
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * 针对 Node.js 环境定制 logging
3
- * 注意:使用此模块需要 chalk 依赖
4
- */
5
- import { type Logger } from '../../logging/index.js';
6
- export * from './handlers.js';
7
- export * from '../../logging/index.js';
8
- /**
9
- * 预设的初始化行为
10
- */
11
- export declare function initLogger(logger?: Logger): void;
@@ -1,14 +0,0 @@
1
- /**
2
- * 针对 Node.js 环境定制 logging
3
- * 注意:使用此模块需要 chalk 依赖
4
- */
5
- import { logger as defaultLogger } from '../../logging/index.js';
6
- import { ConsoleHandler } from './handlers.js';
7
- export * from './handlers.js';
8
- export * from '../../logging/index.js';
9
- /**
10
- * 预设的初始化行为
11
- */
12
- export function initLogger(logger = defaultLogger) {
13
- logger.addHandler(new ConsoleHandler());
14
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * 通过 React Hook 把 emotion css 转换成 className
3
- * (不再需要 <ClassName>)
4
- *
5
- * 使用前提:
6
- * 1. 只支持浏览器渲染
7
- * 2. 用 EmotionCacheProvider 包裹 App 根元素
8
- *
9
- * 来自:
10
- * https://github.com/emotion-js/emotion/issues/1853#issuecomment-623349622
11
- */
12
- import { type EmotionCache } from '@emotion/react';
13
- import { type CSSInterpolation } from '@emotion/serialize';
14
- export declare const useEmotionCache: () => EmotionCache | undefined;
15
- export declare const EmotionCacheProvider: import("react").FC<{
16
- children: React.ReactNode;
17
- } & import("react").RefAttributes<any>> | import("react").ForwardRefExoticComponent<{
18
- children: React.ReactNode;
19
- } & import("react").RefAttributes<any>>;
20
- export declare function useEmotionClassName(): (...args: CSSInterpolation[]) => string;
@@ -1,34 +0,0 @@
1
- /**
2
- * 通过 React Hook 把 emotion css 转换成 className
3
- * (不再需要 <ClassName>)
4
- *
5
- * 使用前提:
6
- * 1. 只支持浏览器渲染
7
- * 2. 用 EmotionCacheProvider 包裹 App 根元素
8
- *
9
- * 来自:
10
- * https://github.com/emotion-js/emotion/issues/1853#issuecomment-623349622
11
- */
12
- import { withEmotionCache } from '@emotion/react';
13
- import { serializeStyles } from '@emotion/serialize';
14
- import { insertStyles } from '@emotion/utils';
15
- import { createContext, useContext, useCallback } from 'react';
16
- const CacheContext = createContext(undefined);
17
- export const useEmotionCache = () => useContext(CacheContext);
18
- export const EmotionCacheProvider = withEmotionCache(({ children }, cache) => {
19
- return <CacheContext.Provider value={cache}>{children}</CacheContext.Provider>;
20
- });
21
- export function useEmotionClassName() {
22
- const cache = useEmotionCache();
23
- return useCallback((...args) => {
24
- if (!cache) {
25
- if (process.env.NODE_ENV === 'production') {
26
- return 'emotion-cache-missing';
27
- }
28
- throw new Error('No emotion cache found!');
29
- }
30
- const serialized = serializeStyles(args, cache.registered);
31
- insertStyles(cache, serialized, false);
32
- return cache.key + '-' + serialized.name;
33
- }, [cache]);
34
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * 把业务功能整理成各个 Controller,
3
- * 并整合成一个 controllers 对象方便外部引用和 Controller 之间互相引用。
4
- *
5
- * 支持自定义 Controller 类,例如把 context 中的内容定义成属性。
6
- */
7
- export type AnyObject = Record<string, unknown>;
8
- export type AnyController<Context> = Controller<Context, any>;
9
- type AnyControllerClass<Context> = typeof Controller<Context, any>;
10
- export type ControllersFrom<Context, T extends AnyObject> = {
11
- [K in keyof T]: T[K] extends AnyControllerClass<Context> ? InstanceType<T[K]> : never;
12
- };
13
- /**
14
- * Controller 基类
15
- */
16
- export declare class Controller<Context, AllControllers extends Record<string, AnyController<Context>>> {
17
- /** 调用其他 controllers */
18
- protected readonly controllers: AllControllers;
19
- protected readonly context: Context;
20
- protected readonly name: string;
21
- constructor(
22
- /** 调用其他 controllers */
23
- controllers: AllControllers, context: Context, name?: string);
24
- }
25
- /**
26
- * 传入 Controller 类列表,返回 controller 实例集合。
27
- * 为优化性能,每个 controller 只有在被使用到时才会实例化。
28
- */
29
- export declare function initializeControllers<Context, T extends AnyObject>(controllerClasses: T, context: Context): ControllersFrom<Context, T>;
30
- export {};
@@ -1,41 +0,0 @@
1
- /**
2
- * 把业务功能整理成各个 Controller,
3
- * 并整合成一个 controllers 对象方便外部引用和 Controller 之间互相引用。
4
- *
5
- * 支持自定义 Controller 类,例如把 context 中的内容定义成属性。
6
- */
7
- /**
8
- * Controller 基类
9
- */
10
- export class Controller {
11
- controllers;
12
- context;
13
- name;
14
- constructor(
15
- /** 调用其他 controllers */
16
- controllers, context, name = this.constructor.name) {
17
- this.controllers = controllers;
18
- this.context = context;
19
- this.name = name;
20
- }
21
- }
22
- /**
23
- * 传入 Controller 类列表,返回 controller 实例集合。
24
- * 为优化性能,每个 controller 只有在被使用到时才会实例化。
25
- */
26
- export function initializeControllers(controllerClasses, context) {
27
- const proxy = new Proxy({}, {
28
- get(controllers, prop) {
29
- if (typeof prop !== 'string')
30
- return;
31
- if (prop in controllers)
32
- return controllers[prop];
33
- if (prop in controllerClasses) {
34
- const Class = controllerClasses[prop];
35
- controllers[prop] = new Class(proxy, context, prop);
36
- return controllers[prop];
37
- }
38
- },
39
- });
40
- return proxy;
41
- }
@@ -1,55 +0,0 @@
1
- import * as dotenv from 'dotenv';
2
- type EnvValue = string | number | boolean | unknown[] | Record<string, unknown>;
3
- type TypeDef = 'string' | 'number' | 'boolean' | unknown[] | Record<string, unknown>;
4
- type TypeFrom<D extends TypeDef> = D extends 'string' ? string : D extends 'number' ? number : D extends 'boolean' ? boolean : D;
5
- type ResultFrom<Defs extends Record<string, TypeDef>> = {
6
- [K in keyof Defs]: TypeFrom<Defs[K]>;
7
- };
8
- /**
9
- * 读取 .env 文件,并获取格式化后的数据
10
- * 注意:依赖 dotenv 包
11
- */
12
- export declare class EnvReader {
13
- protected loadedEnvs: Record<string, string>;
14
- constructor(options?: dotenv.DotenvConfigOptions);
15
- protected toNumber(raw: string): number | undefined;
16
- protected toBoolean(raw: string): boolean | undefined;
17
- getRaw(key: string): string | undefined;
18
- /**
19
- * 获取指定 env 的值,并转换成与 defaults 匹配的类型。
20
- * 若值不存在,返回 defaults。
21
- */
22
- get(key: string, defaults: string): string;
23
- get(key: string, defaults: number): number;
24
- get(key: string, defaults: boolean): boolean;
25
- get<T extends unknown[] | Record<string, unknown>>(key: string, defaults: T): T;
26
- /**
27
- * 获取指定 env 的值,并转换成指定类型,无需提供默认值。
28
- * 值不存在或转换失败时,返回 undefined。
29
- */
30
- getByType(key: string, type?: 'string'): string | undefined;
31
- getByType(key: string, type: 'number'): number | undefined;
32
- getByType(key: string, type: 'boolean'): boolean | undefined;
33
- getByType<T extends unknown[] | Record<string, unknown>>(key: string, type: 'json'): T | undefined;
34
- /**
35
- * 同 envReader.get(),只不过是通过对象指定各 env 的默认值来批量获取
36
- * envReader.batchGet({ port: 8000, debug: false, mobiles: ['123', '456'] }
37
- */
38
- batchGet<Defs extends Record<string, EnvValue>>(definitions: Defs): { [K in keyof Defs]: Defs[K] extends string ? string : Defs[K] extends number ? number : Defs[K] extends boolean ? boolean : Defs[K]; };
39
- /**
40
- * 同 envReader.getByType(),只不过是通过对象指定各 env 的类型来批量获取。
41
- *
42
- * - required=false(默认)时,不存在或值为 undefined 的 env 不会出现在返回对象里,以保证 { ...defaults, ...envReader.batchGetByType(...) } 的用法能正常保留默认值。
43
- * - required=true 时要求所有 env 都必须有值,否则会抛出异常
44
- *
45
- * envReader.batchGetByType({
46
- * port: 'number',
47
- * debug: 'boolean',
48
- * mobiles: [] as string[], // 用此格式定义内容是数组的 JSON 值
49
- * obj: {} as { a: number, b: string } // 用此格式定义内容是对象的 JSON 值
50
- * })
51
- */
52
- batchGetByType<Defs extends Record<string, TypeDef>>(definitions: Defs, required?: false): Partial<ResultFrom<Defs>>;
53
- batchGetByType<Defs extends Record<string, TypeDef>>(definitions: Defs, required: true): ResultFrom<Defs>;
54
- }
55
- export {};