@sapphire-sh/utils 1.38.0 → 1.40.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.
- package/lib/eslint.d.ts +2 -24
- package/lib/eslint.js +58 -65
- package/lib/esm/eslint.d.ts +2 -0
- package/lib/esm/eslint.js +64 -0
- package/lib/esm/getEnumValue.d.ts +1 -0
- package/lib/esm/getEnumValue.js +4 -0
- package/lib/esm/index.d.ts +7 -0
- package/lib/esm/index.js +7 -0
- package/lib/esm/isNonNullable.d.ts +1 -0
- package/lib/esm/isNonNullable.js +9 -0
- package/lib/esm/logger.d.ts +15 -0
- package/lib/esm/logger.js +52 -0
- package/lib/esm/notify.d.ts +2 -0
- package/lib/esm/notify.js +30 -0
- package/lib/esm/package.json +1 -0
- package/lib/esm/prettier.d.ts +3 -0
- package/lib/esm/prettier.js +12 -0
- package/lib/esm/queue.d.ts +16 -0
- package/lib/esm/queue.js +94 -0
- package/lib/esm/sleep.d.ts +1 -0
- package/lib/esm/sleep.js +4 -0
- package/lib/esm/throttle.d.ts +1 -0
- package/lib/esm/throttle.js +11 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +4 -4
- package/lib/logger.js +4 -4
- package/lib/notify.d.ts +2 -2
- package/lib/notify.js +8 -7
- package/lib/queue.d.ts +2 -1
- package/lib/queue.js +12 -7
- package/package.json +78 -58
package/lib/eslint.d.ts
CHANGED
|
@@ -1,24 +1,2 @@
|
|
|
1
|
-
declare const
|
|
2
|
-
|
|
3
|
-
} | import("typescript-eslint/dist/compatibility-types").CompatibleConfig | {
|
|
4
|
-
rules: {
|
|
5
|
-
'@typescript-eslint/no-floating-promises': string;
|
|
6
|
-
'@typescript-eslint/no-misused-promises': string;
|
|
7
|
-
'@typescript-eslint/no-unnecessary-condition': string;
|
|
8
|
-
'@typescript-eslint/switch-exhaustiveness-check': string;
|
|
9
|
-
'@typescript-eslint/return-await': string[];
|
|
10
|
-
'@typescript-eslint/prefer-readonly': string;
|
|
11
|
-
'@typescript-eslint/strict-boolean-expressions': string;
|
|
12
|
-
};
|
|
13
|
-
languageOptions: {
|
|
14
|
-
parserOptions: {
|
|
15
|
-
project: boolean;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
ignores?: undefined;
|
|
19
|
-
} | {
|
|
20
|
-
ignores: string[];
|
|
21
|
-
rules?: undefined;
|
|
22
|
-
languageOptions?: undefined;
|
|
23
|
-
})[];
|
|
24
|
-
export default config;
|
|
1
|
+
declare const _default: import("@eslint/config-helpers").Config[];
|
|
2
|
+
export default _default;
|
package/lib/eslint.js
CHANGED
|
@@ -5,72 +5,65 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const js_1 = __importDefault(require("@eslint/js"));
|
|
7
7
|
const eslint_config_prettier_1 = __importDefault(require("eslint-config-prettier"));
|
|
8
|
+
const config_1 = require("eslint/config");
|
|
8
9
|
const typescript_eslint_1 = __importDefault(require("typescript-eslint"));
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
'
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
'
|
|
37
|
-
{
|
|
38
|
-
selector: 'interface',
|
|
39
|
-
format: ['PascalCase'],
|
|
40
|
-
custom: { regex: '^I[A-Z]', match: false },
|
|
41
|
-
},
|
|
42
|
-
],
|
|
43
|
-
'@typescript-eslint/no-namespace': 'off',
|
|
44
|
-
'@typescript-eslint/no-shadow': 'off',
|
|
45
|
-
'@typescript-eslint/consistent-type-imports': 'error',
|
|
46
|
-
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
|
|
47
|
-
'@typescript-eslint/no-explicit-any': 'warn',
|
|
48
|
-
'@typescript-eslint/no-non-null-assertion': 'warn',
|
|
49
|
-
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
|
50
|
-
'@typescript-eslint/array-type': ['error', { default: 'array' }],
|
|
51
|
-
'@typescript-eslint/prefer-nullish-coalescing': 'error',
|
|
52
|
-
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
// Type-aware rules (requires parserOptions.project in consumer config)
|
|
57
|
-
rules: {
|
|
58
|
-
'@typescript-eslint/no-floating-promises': 'error',
|
|
59
|
-
'@typescript-eslint/no-misused-promises': 'error',
|
|
60
|
-
'@typescript-eslint/no-unnecessary-condition': 'error',
|
|
61
|
-
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
|
62
|
-
'@typescript-eslint/return-await': ['error', 'in-try-catch'],
|
|
63
|
-
'@typescript-eslint/prefer-readonly': 'error',
|
|
64
|
-
'@typescript-eslint/strict-boolean-expressions': 'error',
|
|
65
|
-
},
|
|
66
|
-
languageOptions: {
|
|
67
|
-
parserOptions: {
|
|
68
|
-
project: true,
|
|
10
|
+
exports.default = (0, config_1.defineConfig)(js_1.default.configs.recommended, ...typescript_eslint_1.default.configs.recommended, eslint_config_prettier_1.default, {
|
|
11
|
+
rules: {
|
|
12
|
+
// General
|
|
13
|
+
'no-console': 'off',
|
|
14
|
+
'no-constant-condition': ['error', { checkLoops: false }],
|
|
15
|
+
'no-var': 'error',
|
|
16
|
+
'no-throw-literal': 'error',
|
|
17
|
+
'no-param-reassign': 'error',
|
|
18
|
+
'no-nested-ternary': 'error',
|
|
19
|
+
'no-unneeded-ternary': 'error',
|
|
20
|
+
'prefer-const': 'error',
|
|
21
|
+
'prefer-template': 'error',
|
|
22
|
+
'prefer-destructuring': 'error',
|
|
23
|
+
'prefer-arrow-callback': 'error',
|
|
24
|
+
eqeqeq: ['error', 'always'],
|
|
25
|
+
'object-shorthand': 'error',
|
|
26
|
+
'no-else-return': 'error',
|
|
27
|
+
'arrow-body-style': ['error', 'as-needed'],
|
|
28
|
+
'func-style': ['error', 'expression'],
|
|
29
|
+
yoda: 'error',
|
|
30
|
+
// TypeScript
|
|
31
|
+
'@typescript-eslint/no-unused-vars': ['error', { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }],
|
|
32
|
+
'@typescript-eslint/naming-convention': [
|
|
33
|
+
'error',
|
|
34
|
+
{
|
|
35
|
+
selector: 'interface',
|
|
36
|
+
format: ['PascalCase'],
|
|
37
|
+
custom: { regex: '^I[A-Z]', match: false },
|
|
69
38
|
},
|
|
70
|
-
|
|
39
|
+
],
|
|
40
|
+
'@typescript-eslint/no-namespace': 'off',
|
|
41
|
+
'@typescript-eslint/no-shadow': 'off',
|
|
42
|
+
'@typescript-eslint/consistent-type-imports': 'error',
|
|
43
|
+
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
|
|
44
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
45
|
+
'@typescript-eslint/no-non-null-assertion': 'warn',
|
|
46
|
+
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
|
47
|
+
'@typescript-eslint/array-type': ['error', { default: 'array' }],
|
|
48
|
+
'@typescript-eslint/prefer-nullish-coalescing': 'error',
|
|
49
|
+
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
50
|
+
},
|
|
51
|
+
}, {
|
|
52
|
+
// Type-aware rules (requires parserOptions.project in consumer config)
|
|
53
|
+
rules: {
|
|
54
|
+
'@typescript-eslint/no-floating-promises': 'error',
|
|
55
|
+
'@typescript-eslint/no-misused-promises': 'error',
|
|
56
|
+
'@typescript-eslint/no-unnecessary-condition': 'error',
|
|
57
|
+
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
|
58
|
+
'@typescript-eslint/return-await': ['error', 'in-try-catch'],
|
|
59
|
+
'@typescript-eslint/prefer-readonly': 'error',
|
|
60
|
+
'@typescript-eslint/strict-boolean-expressions': 'error',
|
|
71
61
|
},
|
|
72
|
-
{
|
|
73
|
-
|
|
62
|
+
languageOptions: {
|
|
63
|
+
parserOptions: {
|
|
64
|
+
project: true,
|
|
65
|
+
},
|
|
74
66
|
},
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
}, {
|
|
68
|
+
ignores: ['**/*.json', 'node_modules/', 'coverage/', 'lib/'],
|
|
69
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import prettier from 'eslint-config-prettier';
|
|
3
|
+
import { defineConfig } from 'eslint/config';
|
|
4
|
+
import tseslint from 'typescript-eslint';
|
|
5
|
+
export default defineConfig(eslint.configs.recommended, ...tseslint.configs.recommended, prettier, {
|
|
6
|
+
rules: {
|
|
7
|
+
// General
|
|
8
|
+
'no-console': 'off',
|
|
9
|
+
'no-constant-condition': ['error', { checkLoops: false }],
|
|
10
|
+
'no-var': 'error',
|
|
11
|
+
'no-throw-literal': 'error',
|
|
12
|
+
'no-param-reassign': 'error',
|
|
13
|
+
'no-nested-ternary': 'error',
|
|
14
|
+
'no-unneeded-ternary': 'error',
|
|
15
|
+
'prefer-const': 'error',
|
|
16
|
+
'prefer-template': 'error',
|
|
17
|
+
'prefer-destructuring': 'error',
|
|
18
|
+
'prefer-arrow-callback': 'error',
|
|
19
|
+
eqeqeq: ['error', 'always'],
|
|
20
|
+
'object-shorthand': 'error',
|
|
21
|
+
'no-else-return': 'error',
|
|
22
|
+
'arrow-body-style': ['error', 'as-needed'],
|
|
23
|
+
'func-style': ['error', 'expression'],
|
|
24
|
+
yoda: 'error',
|
|
25
|
+
// TypeScript
|
|
26
|
+
'@typescript-eslint/no-unused-vars': ['error', { varsIgnorePattern: '^_', argsIgnorePattern: '^_' }],
|
|
27
|
+
'@typescript-eslint/naming-convention': [
|
|
28
|
+
'error',
|
|
29
|
+
{
|
|
30
|
+
selector: 'interface',
|
|
31
|
+
format: ['PascalCase'],
|
|
32
|
+
custom: { regex: '^I[A-Z]', match: false },
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
'@typescript-eslint/no-namespace': 'off',
|
|
36
|
+
'@typescript-eslint/no-shadow': 'off',
|
|
37
|
+
'@typescript-eslint/consistent-type-imports': 'error',
|
|
38
|
+
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
|
|
39
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
40
|
+
'@typescript-eslint/no-non-null-assertion': 'warn',
|
|
41
|
+
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
|
42
|
+
'@typescript-eslint/array-type': ['error', { default: 'array' }],
|
|
43
|
+
'@typescript-eslint/prefer-nullish-coalescing': 'error',
|
|
44
|
+
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
45
|
+
},
|
|
46
|
+
}, {
|
|
47
|
+
// Type-aware rules (requires parserOptions.project in consumer config)
|
|
48
|
+
rules: {
|
|
49
|
+
'@typescript-eslint/no-floating-promises': 'error',
|
|
50
|
+
'@typescript-eslint/no-misused-promises': 'error',
|
|
51
|
+
'@typescript-eslint/no-unnecessary-condition': 'error',
|
|
52
|
+
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
|
53
|
+
'@typescript-eslint/return-await': ['error', 'in-try-catch'],
|
|
54
|
+
'@typescript-eslint/prefer-readonly': 'error',
|
|
55
|
+
'@typescript-eslint/strict-boolean-expressions': 'error',
|
|
56
|
+
},
|
|
57
|
+
languageOptions: {
|
|
58
|
+
parserOptions: {
|
|
59
|
+
project: true,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
}, {
|
|
63
|
+
ignores: ['**/*.json', 'node_modules/', 'coverage/', 'lib/'],
|
|
64
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getEnumValue: <T extends string, TEnum extends string>(value: { [key in T]: TEnum; }) => (value?: string) => TEnum | null;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { getEnumValue } from './getEnumValue';
|
|
2
|
+
export { isNonNullable } from './isNonNullable';
|
|
3
|
+
export { LogLevel, logger } from './logger';
|
|
4
|
+
export { notifyMattermost, notifySlack } from './notify';
|
|
5
|
+
export { Queue } from './queue';
|
|
6
|
+
export { sleep } from './sleep';
|
|
7
|
+
export { throttle } from './throttle';
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { getEnumValue } from './getEnumValue';
|
|
2
|
+
export { isNonNullable } from './isNonNullable';
|
|
3
|
+
export { LogLevel, logger } from './logger';
|
|
4
|
+
export { notifyMattermost, notifySlack } from './notify';
|
|
5
|
+
export { Queue } from './queue';
|
|
6
|
+
export { sleep } from './sleep';
|
|
7
|
+
export { throttle } from './throttle';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isNonNullable: <T>(value?: T | null) => value is NonNullable<T>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare enum LogLevel {
|
|
2
|
+
DEBUG = 1,
|
|
3
|
+
INFO = 2,
|
|
4
|
+
WARN = 3,
|
|
5
|
+
ERROR = 4
|
|
6
|
+
}
|
|
7
|
+
type Payload = Record<string, unknown> | Error;
|
|
8
|
+
export declare const logger: {
|
|
9
|
+
debug: (message: string, payload?: Payload) => void;
|
|
10
|
+
info: (message: string, payload?: Payload) => void;
|
|
11
|
+
warn: (message: string, payload?: Payload) => void;
|
|
12
|
+
error: (message: string, payload?: Payload) => void;
|
|
13
|
+
setLevel: (level: LogLevel | string) => void;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export var LogLevel;
|
|
2
|
+
(function (LogLevel) {
|
|
3
|
+
LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
|
|
4
|
+
LogLevel[LogLevel["INFO"] = 2] = "INFO";
|
|
5
|
+
LogLevel[LogLevel["WARN"] = 3] = "WARN";
|
|
6
|
+
LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
|
|
7
|
+
})(LogLevel || (LogLevel = {}));
|
|
8
|
+
const serializePayload = (payload) => {
|
|
9
|
+
const json = JSON.stringify(payload instanceof Error ? { error: payload.message, name: payload.name, stack: payload.stack } : payload);
|
|
10
|
+
return json.padStart(json.length + 1);
|
|
11
|
+
};
|
|
12
|
+
let currentLevel = LogLevel.INFO;
|
|
13
|
+
const log = (level, message, payload) => {
|
|
14
|
+
if (level < currentLevel) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const ts = new Date().toISOString();
|
|
18
|
+
const prefix = `[${ts}] [${LogLevel[level].toUpperCase()}]`;
|
|
19
|
+
const payloadStr = payload === undefined ? '' : serializePayload(payload);
|
|
20
|
+
const output = `${prefix} ${message}${payloadStr}`;
|
|
21
|
+
if (level === LogLevel.ERROR) {
|
|
22
|
+
console.error(output);
|
|
23
|
+
}
|
|
24
|
+
else if (level === LogLevel.WARN) {
|
|
25
|
+
console.warn(output);
|
|
26
|
+
}
|
|
27
|
+
else if (level === LogLevel.DEBUG) {
|
|
28
|
+
console.debug(output);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.log(output);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
export const logger = {
|
|
35
|
+
debug: (message, payload) => log(LogLevel.DEBUG, message, payload),
|
|
36
|
+
info: (message, payload) => log(LogLevel.INFO, message, payload),
|
|
37
|
+
warn: (message, payload) => log(LogLevel.WARN, message, payload),
|
|
38
|
+
error: (message, payload) => log(LogLevel.ERROR, message, payload),
|
|
39
|
+
setLevel: (level) => {
|
|
40
|
+
if (typeof level === 'string') {
|
|
41
|
+
const resolved = LogLevel[level.toUpperCase()];
|
|
42
|
+
if (resolved === undefined) {
|
|
43
|
+
console.warn(`[logger] Invalid log level: "${level}", keeping current level`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
currentLevel = resolved;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
currentLevel = level;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { logger } from './logger';
|
|
2
|
+
export const notifySlack = async (url, text) => {
|
|
3
|
+
logger.debug('[notifySlack] posting to webhook', { textLength: text.length });
|
|
4
|
+
const resp = await fetch(url, {
|
|
5
|
+
method: 'POST',
|
|
6
|
+
headers: {
|
|
7
|
+
'Content-Type': 'application/json',
|
|
8
|
+
},
|
|
9
|
+
body: JSON.stringify({ text }),
|
|
10
|
+
});
|
|
11
|
+
logger.debug('[notifySlack] response received', { status: resp.status });
|
|
12
|
+
if (!resp.ok) {
|
|
13
|
+
throw new Error(`Slack webhook failed: HTTP ${resp.status}`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
export const notifyMattermost = async (baseUrl, token, channelId, message) => {
|
|
17
|
+
logger.debug('[notifyMattermost] posting to channel', { channelId, messageLength: message.length });
|
|
18
|
+
const resp = await fetch(`${baseUrl}/api/v4/posts`, {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
headers: {
|
|
21
|
+
Authorization: `Bearer ${token}`,
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
},
|
|
24
|
+
body: JSON.stringify({ channel_id: channelId, message }),
|
|
25
|
+
});
|
|
26
|
+
logger.debug('[notifyMattermost] response received', { status: resp.status });
|
|
27
|
+
if (!resp.ok) {
|
|
28
|
+
throw new Error(`Mattermost post failed: HTTP ${resp.status}`);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type Value = object | number | string | boolean;
|
|
2
|
+
export declare class Queue<T extends Value> {
|
|
3
|
+
private head;
|
|
4
|
+
private tail;
|
|
5
|
+
private _size;
|
|
6
|
+
enqueue(value: T): void;
|
|
7
|
+
dequeue(): T | undefined;
|
|
8
|
+
dequeueMultiple(count: number): T[];
|
|
9
|
+
get size(): number;
|
|
10
|
+
isEmpty(): boolean;
|
|
11
|
+
peek(): T | undefined;
|
|
12
|
+
has(value: T): boolean;
|
|
13
|
+
some(predicate: (value: T) => boolean): boolean;
|
|
14
|
+
toArray(): T[];
|
|
15
|
+
}
|
|
16
|
+
export {};
|
package/lib/esm/queue.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
class QueueNode {
|
|
2
|
+
value;
|
|
3
|
+
_next = null;
|
|
4
|
+
constructor(value) {
|
|
5
|
+
this.value = value;
|
|
6
|
+
}
|
|
7
|
+
get next() {
|
|
8
|
+
return this._next;
|
|
9
|
+
}
|
|
10
|
+
setNext(newNode) {
|
|
11
|
+
this._next = newNode;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class Queue {
|
|
15
|
+
head = null;
|
|
16
|
+
tail = null;
|
|
17
|
+
_size = 0;
|
|
18
|
+
enqueue(value) {
|
|
19
|
+
const newNode = new QueueNode(value);
|
|
20
|
+
if (this.isEmpty() || !this.tail) {
|
|
21
|
+
this.head = newNode;
|
|
22
|
+
this.tail = newNode;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.tail.setNext(newNode);
|
|
26
|
+
this.tail = newNode;
|
|
27
|
+
}
|
|
28
|
+
this._size += 1;
|
|
29
|
+
}
|
|
30
|
+
dequeue() {
|
|
31
|
+
if (this.isEmpty() || !this.head) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const { value } = this.head;
|
|
35
|
+
this.head = this.head.next;
|
|
36
|
+
this._size -= 1;
|
|
37
|
+
if (this.isEmpty()) {
|
|
38
|
+
this.tail = null;
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
dequeueMultiple(count) {
|
|
43
|
+
const array = [];
|
|
44
|
+
for (let i = 0; i < count; ++i) {
|
|
45
|
+
const value = this.dequeue();
|
|
46
|
+
if (value === undefined) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
array.push(value);
|
|
50
|
+
}
|
|
51
|
+
return array;
|
|
52
|
+
}
|
|
53
|
+
get size() {
|
|
54
|
+
return this._size;
|
|
55
|
+
}
|
|
56
|
+
isEmpty() {
|
|
57
|
+
return this._size === 0;
|
|
58
|
+
}
|
|
59
|
+
peek() {
|
|
60
|
+
return this.head?.value;
|
|
61
|
+
}
|
|
62
|
+
has(value) {
|
|
63
|
+
let node = this.head;
|
|
64
|
+
while (node !== null) {
|
|
65
|
+
if (node.value === value) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
node = node.next;
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
some(predicate) {
|
|
73
|
+
let node = this.head;
|
|
74
|
+
while (node !== null) {
|
|
75
|
+
if (predicate(node.value)) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
node = node.next;
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
toArray() {
|
|
83
|
+
let node = this.head;
|
|
84
|
+
if (!node) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
const array = [];
|
|
88
|
+
while (node) {
|
|
89
|
+
array.push(node.value);
|
|
90
|
+
node = node.next;
|
|
91
|
+
}
|
|
92
|
+
return array;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const sleep: (ms: number, jitter?: number) => Promise<void>;
|
package/lib/esm/sleep.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const throttle: <T, R>(fn: (...args: T[]) => R, interval: number) => (...args: T[]) => R | undefined;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { getEnumValue } from './getEnumValue';
|
|
2
2
|
export { isNonNullable } from './isNonNullable';
|
|
3
|
-
export {
|
|
4
|
-
export { Queue } from './queue';
|
|
3
|
+
export { LogLevel, logger } from './logger';
|
|
5
4
|
export { notifyMattermost, notifySlack } from './notify';
|
|
5
|
+
export { Queue } from './queue';
|
|
6
6
|
export { sleep } from './sleep';
|
|
7
7
|
export { throttle } from './throttle';
|
package/lib/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.throttle = exports.sleep = exports.
|
|
3
|
+
exports.throttle = exports.sleep = exports.Queue = exports.notifySlack = exports.notifyMattermost = exports.logger = exports.LogLevel = exports.isNonNullable = exports.getEnumValue = void 0;
|
|
4
4
|
var getEnumValue_1 = require("./getEnumValue");
|
|
5
5
|
Object.defineProperty(exports, "getEnumValue", { enumerable: true, get: function () { return getEnumValue_1.getEnumValue; } });
|
|
6
6
|
var isNonNullable_1 = require("./isNonNullable");
|
|
7
7
|
Object.defineProperty(exports, "isNonNullable", { enumerable: true, get: function () { return isNonNullable_1.isNonNullable; } });
|
|
8
8
|
var logger_1 = require("./logger");
|
|
9
|
-
Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
|
|
10
9
|
Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return logger_1.LogLevel; } });
|
|
11
|
-
|
|
12
|
-
Object.defineProperty(exports, "Queue", { enumerable: true, get: function () { return queue_1.Queue; } });
|
|
10
|
+
Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
|
|
13
11
|
var notify_1 = require("./notify");
|
|
14
12
|
Object.defineProperty(exports, "notifyMattermost", { enumerable: true, get: function () { return notify_1.notifyMattermost; } });
|
|
15
13
|
Object.defineProperty(exports, "notifySlack", { enumerable: true, get: function () { return notify_1.notifySlack; } });
|
|
14
|
+
var queue_1 = require("./queue");
|
|
15
|
+
Object.defineProperty(exports, "Queue", { enumerable: true, get: function () { return queue_1.Queue; } });
|
|
16
16
|
var sleep_1 = require("./sleep");
|
|
17
17
|
Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return sleep_1.sleep; } });
|
|
18
18
|
var throttle_1 = require("./throttle");
|
package/lib/logger.js
CHANGED
|
@@ -8,12 +8,12 @@ var LogLevel;
|
|
|
8
8
|
LogLevel[LogLevel["WARN"] = 3] = "WARN";
|
|
9
9
|
LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
|
|
10
10
|
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
11
|
-
|
|
11
|
+
const serializePayload = (payload) => {
|
|
12
12
|
const json = JSON.stringify(payload instanceof Error ? { error: payload.message, name: payload.name, stack: payload.stack } : payload);
|
|
13
13
|
return json.padStart(json.length + 1);
|
|
14
|
-
}
|
|
14
|
+
};
|
|
15
15
|
let currentLevel = LogLevel.INFO;
|
|
16
|
-
|
|
16
|
+
const log = (level, message, payload) => {
|
|
17
17
|
if (level < currentLevel) {
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
@@ -33,7 +33,7 @@ function log(level, message, payload) {
|
|
|
33
33
|
else {
|
|
34
34
|
console.log(output);
|
|
35
35
|
}
|
|
36
|
-
}
|
|
36
|
+
};
|
|
37
37
|
exports.logger = {
|
|
38
38
|
debug: (message, payload) => log(LogLevel.DEBUG, message, payload),
|
|
39
39
|
info: (message, payload) => log(LogLevel.INFO, message, payload),
|
package/lib/notify.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
export declare
|
|
1
|
+
export declare const notifySlack: (url: string, text: string) => Promise<void>;
|
|
2
|
+
export declare const notifyMattermost: (baseUrl: string, token: string, channelId: string, message: string) => Promise<void>;
|
package/lib/notify.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.notifySlack =
|
|
4
|
-
exports.notifyMattermost = notifyMattermost;
|
|
3
|
+
exports.notifyMattermost = exports.notifySlack = void 0;
|
|
5
4
|
const logger_1 = require("./logger");
|
|
6
|
-
async
|
|
5
|
+
const notifySlack = async (url, text) => {
|
|
7
6
|
logger_1.logger.debug('[notifySlack] posting to webhook', { textLength: text.length });
|
|
8
7
|
const resp = await fetch(url, {
|
|
9
8
|
method: 'POST',
|
|
@@ -16,13 +15,14 @@ async function notifySlack(url, text) {
|
|
|
16
15
|
if (!resp.ok) {
|
|
17
16
|
throw new Error(`Slack webhook failed: HTTP ${resp.status}`);
|
|
18
17
|
}
|
|
19
|
-
}
|
|
20
|
-
|
|
18
|
+
};
|
|
19
|
+
exports.notifySlack = notifySlack;
|
|
20
|
+
const notifyMattermost = async (baseUrl, token, channelId, message) => {
|
|
21
21
|
logger_1.logger.debug('[notifyMattermost] posting to channel', { channelId, messageLength: message.length });
|
|
22
22
|
const resp = await fetch(`${baseUrl}/api/v4/posts`, {
|
|
23
23
|
method: 'POST',
|
|
24
24
|
headers: {
|
|
25
|
-
|
|
25
|
+
Authorization: `Bearer ${token}`,
|
|
26
26
|
'Content-Type': 'application/json',
|
|
27
27
|
},
|
|
28
28
|
body: JSON.stringify({ channel_id: channelId, message }),
|
|
@@ -31,4 +31,5 @@ async function notifyMattermost(baseUrl, token, channelId, message) {
|
|
|
31
31
|
if (!resp.ok) {
|
|
32
32
|
throw new Error(`Mattermost post failed: HTTP ${resp.status}`);
|
|
33
33
|
}
|
|
34
|
-
}
|
|
34
|
+
};
|
|
35
|
+
exports.notifyMattermost = notifyMattermost;
|
package/lib/queue.d.ts
CHANGED
|
@@ -9,7 +9,8 @@ export declare class Queue<T extends Value> {
|
|
|
9
9
|
get size(): number;
|
|
10
10
|
isEmpty(): boolean;
|
|
11
11
|
peek(): T | undefined;
|
|
12
|
-
has(value: T
|
|
12
|
+
has(value: T): boolean;
|
|
13
|
+
some(predicate: (value: T) => boolean): boolean;
|
|
13
14
|
toArray(): T[];
|
|
14
15
|
}
|
|
15
16
|
export {};
|
package/lib/queue.js
CHANGED
|
@@ -34,7 +34,7 @@ class Queue {
|
|
|
34
34
|
if (this.isEmpty() || !this.head) {
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
const value = this.head
|
|
37
|
+
const { value } = this.head;
|
|
38
38
|
this.head = this.head.next;
|
|
39
39
|
this._size -= 1;
|
|
40
40
|
if (this.isEmpty()) {
|
|
@@ -46,7 +46,7 @@ class Queue {
|
|
|
46
46
|
const array = [];
|
|
47
47
|
for (let i = 0; i < count; ++i) {
|
|
48
48
|
const value = this.dequeue();
|
|
49
|
-
if (
|
|
49
|
+
if (value === undefined) {
|
|
50
50
|
break;
|
|
51
51
|
}
|
|
52
52
|
array.push(value);
|
|
@@ -65,12 +65,17 @@ class Queue {
|
|
|
65
65
|
has(value) {
|
|
66
66
|
let node = this.head;
|
|
67
67
|
while (node !== null) {
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
68
|
+
if (node.value === value) {
|
|
69
|
+
return true;
|
|
72
70
|
}
|
|
73
|
-
|
|
71
|
+
node = node.next;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
some(predicate) {
|
|
76
|
+
let node = this.head;
|
|
77
|
+
while (node !== null) {
|
|
78
|
+
if (predicate(node.value)) {
|
|
74
79
|
return true;
|
|
75
80
|
}
|
|
76
81
|
node = node.next;
|
package/package.json
CHANGED
|
@@ -1,60 +1,80 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
2
|
+
"name": "@sapphire-sh/utils",
|
|
3
|
+
"version": "1.40.0",
|
|
4
|
+
"description": "@sapphire-sh/utils",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./lib/index.js",
|
|
7
|
+
"types": "./lib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"require": "./lib/index.js",
|
|
11
|
+
"types": "./lib/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./eslint": {
|
|
14
|
+
"import": "./lib/esm/eslint.js",
|
|
15
|
+
"require": "./lib/eslint.js",
|
|
16
|
+
"types": "./lib/eslint.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./prettier": {
|
|
19
|
+
"require": "./lib/prettier.js",
|
|
20
|
+
"types": "./lib/prettier.d.ts"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"lib/**/*"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"prebuild": "rm -fr ./lib",
|
|
28
|
+
"build": "tsc && tsc -p tsconfig.esm.json && printf '{\"type\":\"module\"}' > lib/esm/package.json",
|
|
29
|
+
"prepare": "npm run build",
|
|
30
|
+
"lint": "eslint .",
|
|
31
|
+
"lint:fix": "eslint . --fix",
|
|
32
|
+
"prettier": "prettier --check .",
|
|
33
|
+
"prettier:fix": "prettier --write .",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"coverage": "vitest run --coverage"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/sapphire-sh/sapphire-utils.git"
|
|
40
|
+
},
|
|
41
|
+
"author": "sapphire",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/sapphire-sh/sapphire-utils/issues"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/sapphire-sh/sapphire-utils#readme",
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@eslint/js": ">=9.0.0",
|
|
49
|
+
"eslint": ">=9.0.0",
|
|
50
|
+
"eslint-config-prettier": ">=9.0.0",
|
|
51
|
+
"prettier": ">=3.0.0",
|
|
52
|
+
"prettier-plugin-organize-imports": ">=4.0.0",
|
|
53
|
+
"typescript-eslint": ">=8.0.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"@eslint/js": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"eslint": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"eslint-config-prettier": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"typescript-eslint": {
|
|
66
|
+
"optional": true
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@eslint/js": "^9.24.0",
|
|
71
|
+
"@vitest/coverage-v8": "^4.1.1",
|
|
72
|
+
"eslint": "^9.24.0",
|
|
73
|
+
"eslint-config-prettier": "^10.1.2",
|
|
74
|
+
"prettier": "^3.8.1",
|
|
75
|
+
"prettier-plugin-organize-imports": "^4.3.0",
|
|
76
|
+
"typescript": "^5.9.3",
|
|
77
|
+
"typescript-eslint": "^8.29.1",
|
|
78
|
+
"vitest": "^4.1.1"
|
|
79
|
+
}
|
|
60
80
|
}
|