@deafwave/osrs-botmaker-config-manager 0.2.6
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/README.md +54 -0
- package/dist/data/config-scope.d.ts +31 -0
- package/dist/data/config-scope.js +302 -0
- package/dist/data/group/aliases.d.ts +4 -0
- package/dist/data/group/aliases.js +17 -0
- package/dist/data/group/booleans.d.ts +2 -0
- package/dist/data/group/booleans.js +5 -0
- package/dist/data/group/json.d.ts +2 -0
- package/dist/data/group/json.js +5 -0
- package/dist/data/group/keys.d.ts +4 -0
- package/dist/data/group/keys.js +10 -0
- package/dist/data/group/number-arrays.d.ts +2 -0
- package/dist/data/group/number-arrays.js +5 -0
- package/dist/data/group/numbers.d.ts +4 -0
- package/dist/data/group/numbers.js +7 -0
- package/dist/data/group/string-arrays.d.ts +2 -0
- package/dist/data/group/string-arrays.js +5 -0
- package/dist/data/group/strings.d.ts +4 -0
- package/dist/data/group/strings.js +26 -0
- package/dist/data/group/summary.d.ts +1 -0
- package/dist/data/group/summary.js +30 -0
- package/dist/data/profile/booleans.d.ts +5 -0
- package/dist/data/profile/booleans.js +11 -0
- package/dist/data/profile/config.d.ts +5 -0
- package/dist/data/profile/config.js +23 -0
- package/dist/data/profile/json.d.ts +2 -0
- package/dist/data/profile/json.js +5 -0
- package/dist/data/profile/keys.d.ts +5 -0
- package/dist/data/profile/keys.js +41 -0
- package/dist/data/profile/number-arrays.d.ts +2 -0
- package/dist/data/profile/number-arrays.js +5 -0
- package/dist/data/profile/numbers.d.ts +7 -0
- package/dist/data/profile/numbers.js +15 -0
- package/dist/data/profile/string-arrays.d.ts +2 -0
- package/dist/data/profile/string-arrays.js +5 -0
- package/dist/data/profile/strings.d.ts +6 -0
- package/dist/data/profile/strings.js +43 -0
- package/dist/data/shared/accessors.d.ts +35 -0
- package/dist/data/shared/accessors.js +95 -0
- package/dist/data/shared/normalize-config-value.d.ts +1 -0
- package/dist/data/shared/normalize-config-value.js +6 -0
- package/dist/data/shared/parse-boolean.d.ts +1 -0
- package/dist/data/shared/parse-boolean.js +13 -0
- package/dist/data/shared/parse-number.d.ts +3 -0
- package/dist/data/shared/parse-number.js +20 -0
- package/dist/data/shared/profile-group.d.ts +3 -0
- package/dist/data/shared/profile-group.js +13 -0
- package/dist/data/shared/set-rs-profile-configuration.d.ts +5 -0
- package/dist/data/shared/set-rs-profile-configuration.js +7 -0
- package/dist/data/shared/split-csv.d.ts +1 -0
- package/dist/data/shared/split-csv.js +4 -0
- package/dist/data/shared/storage.d.ts +10 -0
- package/dist/data/shared/storage.js +58 -0
- package/dist/data/shared/string-array-codec.d.ts +2 -0
- package/dist/data/shared/string-array-codec.js +19 -0
- package/dist/data/shared/string-array.d.ts +2 -0
- package/dist/data/shared/string-array.js +14 -0
- package/dist/data/shared/types.d.ts +4 -0
- package/dist/data/shared/types.js +1 -0
- package/dist/data/shared/write-config.d.ts +2 -0
- package/dist/data/shared/write-config.js +6 -0
- package/dist/data/storage.d.ts +14 -0
- package/dist/data/storage.js +62 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +56 -0
- package/dist/index.npm.d.ts +41 -0
- package/dist/index.npm.js +10 -0
- package/package.json +81 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getGroupKeys } from '../group/keys.js';
|
|
2
|
+
import { RS_PROFILE_GROUP_SEGMENT, buildProfileGroupName, extractProfileKeyFromConfigKey } from '../shared/profile-group.js';
|
|
3
|
+
export const getProfileKey = () => configManager.getRSProfileKey();
|
|
4
|
+
export const getProfileGroupName = (groupName, profileKey) => buildProfileGroupName(groupName, profileKey);
|
|
5
|
+
export const getProfileKeysForGroup = (groupName) => {
|
|
6
|
+
const prefix = `${groupName}${RS_PROFILE_GROUP_SEGMENT}`;
|
|
7
|
+
const keys = getGroupKeys(prefix);
|
|
8
|
+
const profileKeys = new Set();
|
|
9
|
+
keys.forEach((fullKey) => {
|
|
10
|
+
const profileKey = extractProfileKeyFromConfigKey(fullKey, prefix);
|
|
11
|
+
if (profileKey) {
|
|
12
|
+
profileKeys.add(profileKey);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return Array.from(profileKeys);
|
|
16
|
+
};
|
|
17
|
+
export const logProfileConfigSummary = (groupName) => {
|
|
18
|
+
const prefix = `${groupName}${RS_PROFILE_GROUP_SEGMENT}`;
|
|
19
|
+
const keys = getGroupKeys(prefix);
|
|
20
|
+
if (keys.length === 0) {
|
|
21
|
+
bot.printLogMessage(`No profile-scoped config keys found for group '${groupName}'.`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const counts = new Map();
|
|
25
|
+
keys.forEach((fullKey) => {
|
|
26
|
+
const profileKey = extractProfileKeyFromConfigKey(fullKey, prefix);
|
|
27
|
+
if (!profileKey) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
counts.set(profileKey, (counts.get(profileKey) ?? 0) + 1);
|
|
31
|
+
});
|
|
32
|
+
const activeProfileKey = getProfileKey();
|
|
33
|
+
bot.printLogMessage(`Profile-scoped config summary for group '${groupName}': ${counts.size} profile(s), ${keys.length} key(s). Active profile: ${activeProfileKey}`);
|
|
34
|
+
Array.from(counts.entries())
|
|
35
|
+
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
36
|
+
.forEach(([profileKey, count]) => {
|
|
37
|
+
const marker = profileKey === activeProfileKey ? ' (active)' : '';
|
|
38
|
+
bot.printLogMessage(`Profile ${profileKey}${marker}: ${count} key(s)`);
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
export const getProfileConfigKeys = (groupName, keyPrefix = '') => configManager.getRSProfileConfigurationKeys(groupName, getProfileKey(), keyPrefix);
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const getProfileNumberArray: (groupName: string, key: string, fallback?: number[] | undefined) => number[];
|
|
2
|
+
export declare const setProfileNumberArray: (groupName: string, key: string, values: number[], options?: import("../shared/types.js").ConfigWriteOptions | undefined) => void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { createNumberArrayAccessors } from '../shared/accessors.js';
|
|
2
|
+
import { getProfileString, setProfileString } from './strings.js';
|
|
3
|
+
const numberArrayAccessors = createNumberArrayAccessors(getProfileString, setProfileString);
|
|
4
|
+
export const getProfileNumberArray = numberArrayAccessors.getNumberArray;
|
|
5
|
+
export const setProfileNumberArray = numberArrayAccessors.setNumberArray;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ConfigWriteOptions } from '../shared/types.js';
|
|
2
|
+
export declare const getProfileNumber: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
3
|
+
export declare const getProfileInt: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
4
|
+
export declare const getProfileFloat: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
5
|
+
export declare const setProfileNumber: (groupName: string, key: string, value: number, options?: ConfigWriteOptions | undefined) => void;
|
|
6
|
+
export declare const getProfileIntForProfileKey: (groupName: string, profileKey: string, key: string, fallback?: number) => number;
|
|
7
|
+
export declare const setProfileNumberForProfileKey: (groupName: string, profileKey: string, key: string, value: number, options?: ConfigWriteOptions) => void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createNumberAccessors, parseStoredNumberWith } from '../shared/accessors.js';
|
|
2
|
+
import { parseIntNumber } from '../shared/parse-number.js';
|
|
3
|
+
import { toStoredJson } from '../shared/storage.js';
|
|
4
|
+
import { getProfileString, getProfileStringForProfileKey, setProfileString, setProfileStringForProfileKey } from './strings.js';
|
|
5
|
+
const numberAccessors = createNumberAccessors(getProfileString, setProfileString);
|
|
6
|
+
export const getProfileNumber = numberAccessors.getNumber;
|
|
7
|
+
export const getProfileInt = numberAccessors.getInt;
|
|
8
|
+
export const getProfileFloat = numberAccessors.getFloat;
|
|
9
|
+
export const setProfileNumber = numberAccessors.setNumber;
|
|
10
|
+
export const getProfileIntForProfileKey = (groupName, profileKey, key, fallback = 0) => {
|
|
11
|
+
return parseStoredNumberWith(getProfileStringForProfileKey(groupName, profileKey, key, ''), fallback, parseIntNumber);
|
|
12
|
+
};
|
|
13
|
+
export const setProfileNumberForProfileKey = (groupName, profileKey, key, value, options) => {
|
|
14
|
+
setProfileStringForProfileKey(groupName, profileKey, key, toStoredJson(value), options);
|
|
15
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const getProfileStringArray: (groupName: string, key: string, fallback?: string[] | undefined) => string[];
|
|
2
|
+
export declare const setProfileStringArray: (groupName: string, key: string, values: string[], options?: import("../shared/types.js").ConfigWriteOptions | undefined) => void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { createStringArrayAccessors } from '../shared/accessors.js';
|
|
2
|
+
import { getProfileString, setProfileString } from './strings.js';
|
|
3
|
+
const stringArrayAccessors = createStringArrayAccessors(getProfileString, setProfileString);
|
|
4
|
+
export const getProfileStringArray = stringArrayAccessors.getStringArray;
|
|
5
|
+
export const setProfileStringArray = stringArrayAccessors.setStringArray;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ConfigWriteOptions } from '../shared/types.js';
|
|
2
|
+
export declare const getProfileRawValue: (groupName: string, key: string) => string | null;
|
|
3
|
+
export declare const getProfileString: (groupName: string, key: string, fallback?: string) => string;
|
|
4
|
+
export declare const setProfileString: (groupName: string, key: string, value: string, options?: ConfigWriteOptions) => void;
|
|
5
|
+
export declare const getProfileStringForProfileKey: (groupName: string, profileKey: string, key: string, fallback?: string) => string;
|
|
6
|
+
export declare const setProfileStringForProfileKey: (groupName: string, profileKey: string, key: string, value: string, options?: ConfigWriteOptions) => void;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getGroupString, setGroupString } from '../group/strings.js';
|
|
2
|
+
import { normalizeConfigValue } from '../shared/normalize-config-value.js';
|
|
3
|
+
import { parseStoredData } from '../shared/storage.js';
|
|
4
|
+
import { buildProfileGroupName } from '../shared/profile-group.js';
|
|
5
|
+
import { setRSProfileConfigurationValue } from '../shared/set-rs-profile-configuration.js';
|
|
6
|
+
import { writeConfig } from '../shared/write-config.js';
|
|
7
|
+
import { getProfileKey } from './keys.js';
|
|
8
|
+
export const getProfileRawValue = (groupName, key) => {
|
|
9
|
+
const rawValue = normalizeConfigValue(configManager.getRSProfileConfiguration(groupName, key));
|
|
10
|
+
if (rawValue === null || rawValue === undefined) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return rawValue;
|
|
14
|
+
};
|
|
15
|
+
export const getProfileString = (groupName, key, fallback = '') => {
|
|
16
|
+
const rawValue = getProfileRawValue(groupName, key);
|
|
17
|
+
if (rawValue === null) {
|
|
18
|
+
return fallback;
|
|
19
|
+
}
|
|
20
|
+
const parsed = parseStoredData(rawValue);
|
|
21
|
+
if (parsed.ok && typeof parsed.value === 'string') {
|
|
22
|
+
return parsed.value;
|
|
23
|
+
}
|
|
24
|
+
return rawValue;
|
|
25
|
+
};
|
|
26
|
+
export const setProfileString = (groupName, key, value, options) => {
|
|
27
|
+
writeConfig(() => {
|
|
28
|
+
setRSProfileConfigurationValue(groupName, key, value);
|
|
29
|
+
}, options);
|
|
30
|
+
};
|
|
31
|
+
export const getProfileStringForProfileKey = (groupName, profileKey, key, fallback = '') => {
|
|
32
|
+
if (profileKey === getProfileKey()) {
|
|
33
|
+
return getProfileString(groupName, key, fallback);
|
|
34
|
+
}
|
|
35
|
+
return getGroupString(buildProfileGroupName(groupName, profileKey), key, fallback);
|
|
36
|
+
};
|
|
37
|
+
export const setProfileStringForProfileKey = (groupName, profileKey, key, value, options) => {
|
|
38
|
+
if (profileKey === getProfileKey()) {
|
|
39
|
+
setProfileString(groupName, key, value, options);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
setGroupString(buildProfileGroupName(groupName, profileKey), key, value, options);
|
|
43
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ConfigWriteOptions } from './types.js';
|
|
2
|
+
export type GetStringAccessor = (groupName: string, key: string, fallback?: string) => string;
|
|
3
|
+
export type SetStringAccessor = (groupName: string, key: string, value: string, options?: ConfigWriteOptions) => void;
|
|
4
|
+
export type GetRawAccessor = (groupName: string, key: string) => string | null;
|
|
5
|
+
export type NumberAccessors = {
|
|
6
|
+
getNumber: (groupName: string, key: string, fallback?: number) => number;
|
|
7
|
+
getInt: (groupName: string, key: string, fallback?: number) => number;
|
|
8
|
+
getFloat: (groupName: string, key: string, fallback?: number) => number;
|
|
9
|
+
setNumber: (groupName: string, key: string, value: number, options?: ConfigWriteOptions) => void;
|
|
10
|
+
};
|
|
11
|
+
export type BooleanAccessors = {
|
|
12
|
+
getBoolean: (groupName: string, key: string, fallback?: boolean) => boolean;
|
|
13
|
+
setBoolean: (groupName: string, key: string, value: boolean, options?: ConfigWriteOptions) => void;
|
|
14
|
+
};
|
|
15
|
+
export type NumberArrayAccessors = {
|
|
16
|
+
getNumberArray: (groupName: string, key: string, fallback?: number[]) => number[];
|
|
17
|
+
setNumberArray: (groupName: string, key: string, values: number[], options?: ConfigWriteOptions) => void;
|
|
18
|
+
};
|
|
19
|
+
export type StringArrayAccessors = {
|
|
20
|
+
getStringArray: (groupName: string, key: string, fallback?: string[]) => string[];
|
|
21
|
+
setStringArray: (groupName: string, key: string, values: string[], options?: ConfigWriteOptions) => void;
|
|
22
|
+
};
|
|
23
|
+
export type JsonAccessors = {
|
|
24
|
+
getJson: <T>(groupName: string, key: string, fallback: T) => T;
|
|
25
|
+
setJson: <T>(groupName: string, key: string, value: T, options?: ConfigWriteOptions) => void;
|
|
26
|
+
};
|
|
27
|
+
export declare const parseStoredNumberWith: (rawValue: string, fallback: number, parser: (value: string) => number | null) => number;
|
|
28
|
+
export declare const parseStoredBoolean: (rawValue: string, fallback: boolean) => boolean;
|
|
29
|
+
export declare const parseStoredNumberArray: (rawValue: string, fallback: number[]) => number[];
|
|
30
|
+
export declare const parseStoredJson: <T>(rawValue: string, fallback: T) => T;
|
|
31
|
+
export declare const createNumberAccessors: (getString: GetStringAccessor, setString: SetStringAccessor) => NumberAccessors;
|
|
32
|
+
export declare const createBooleanAccessors: (getString: GetStringAccessor, setString: SetStringAccessor) => BooleanAccessors;
|
|
33
|
+
export declare const createNumberArrayAccessors: (getString: GetStringAccessor, setString: SetStringAccessor) => NumberArrayAccessors;
|
|
34
|
+
export declare const createStringArrayAccessors: (getString: GetStringAccessor, setString: SetStringAccessor) => StringArrayAccessors;
|
|
35
|
+
export declare const createJsonAccessors: (getRawValue: GetRawAccessor, setString: SetStringAccessor) => JsonAccessors;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { parseBoolean } from './parse-boolean.js';
|
|
2
|
+
import { parseFloatNumber, parseIntNumber, parseNumber } from './parse-number.js';
|
|
3
|
+
import { splitCsv } from './split-csv.js';
|
|
4
|
+
import { isNumberArray, parseStoredData, toStoredJson } from './storage.js';
|
|
5
|
+
import { parseStringArrayValue, serializeStringArrayValue } from './string-array.js';
|
|
6
|
+
export const parseStoredNumberWith = (rawValue, fallback, parser) => {
|
|
7
|
+
const parsed = parseStoredData(rawValue);
|
|
8
|
+
if (parsed.ok && typeof parsed.value === 'number' && Number.isFinite(parsed.value)) {
|
|
9
|
+
const parsedNumber = parser(String(parsed.value));
|
|
10
|
+
return parsedNumber === null ? fallback : parsedNumber;
|
|
11
|
+
}
|
|
12
|
+
if (parsed.ok && typeof parsed.value === 'string') {
|
|
13
|
+
const parsedStringValue = parser(parsed.value);
|
|
14
|
+
if (parsedStringValue !== null) {
|
|
15
|
+
return parsedStringValue;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const parsedRawValue = parser(rawValue);
|
|
19
|
+
return parsedRawValue === null ? fallback : parsedRawValue;
|
|
20
|
+
};
|
|
21
|
+
export const parseStoredBoolean = (rawValue, fallback) => {
|
|
22
|
+
const parsed = parseStoredData(rawValue);
|
|
23
|
+
if (parsed.ok && typeof parsed.value === 'boolean') {
|
|
24
|
+
return parsed.value;
|
|
25
|
+
}
|
|
26
|
+
if (parsed.ok && typeof parsed.value === 'string') {
|
|
27
|
+
return parseBoolean(parsed.value, fallback);
|
|
28
|
+
}
|
|
29
|
+
return parseBoolean(rawValue, fallback);
|
|
30
|
+
};
|
|
31
|
+
export const parseStoredNumberArray = (rawValue, fallback) => {
|
|
32
|
+
if (!rawValue.trim()) {
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
const parsed = parseStoredData(rawValue);
|
|
36
|
+
if (parsed.ok && isNumberArray(parsed.value)) {
|
|
37
|
+
return parsed.value;
|
|
38
|
+
}
|
|
39
|
+
const numbers = splitCsv(rawValue)
|
|
40
|
+
.map(parseNumber)
|
|
41
|
+
.filter((number_) => number_ !== null);
|
|
42
|
+
return numbers.length > 0 ? numbers : fallback;
|
|
43
|
+
};
|
|
44
|
+
export const parseStoredJson = (rawValue, fallback) => {
|
|
45
|
+
if (!rawValue.trim()) {
|
|
46
|
+
return fallback;
|
|
47
|
+
}
|
|
48
|
+
const parsed = parseStoredData(rawValue);
|
|
49
|
+
return parsed.ok ? parsed.value : fallback;
|
|
50
|
+
};
|
|
51
|
+
export const createNumberAccessors = (getString, setString) => ({
|
|
52
|
+
getNumber: (groupName, key, fallback = 0) => parseStoredNumberWith(getString(groupName, key, ''), fallback, parseNumber),
|
|
53
|
+
getInt: (groupName, key, fallback = 0) => parseStoredNumberWith(getString(groupName, key, ''), fallback, parseIntNumber),
|
|
54
|
+
getFloat: (groupName, key, fallback = 0) => parseStoredNumberWith(getString(groupName, key, ''), fallback, parseFloatNumber),
|
|
55
|
+
setNumber: (groupName, key, value, options) => {
|
|
56
|
+
setString(groupName, key, toStoredJson(value), options);
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
export const createBooleanAccessors = (getString, setString) => ({
|
|
60
|
+
getBoolean: (groupName, key, fallback = false) => parseStoredBoolean(getString(groupName, key, ''), fallback),
|
|
61
|
+
setBoolean: (groupName, key, value, options) => {
|
|
62
|
+
setString(groupName, key, value ? 'true' : 'false', options);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
export const createNumberArrayAccessors = (getString, setString) => ({
|
|
66
|
+
getNumberArray: (groupName, key, fallback = []) => parseStoredNumberArray(getString(groupName, key, ''), fallback),
|
|
67
|
+
setNumberArray: (groupName, key, values, options) => {
|
|
68
|
+
setString(groupName, key, toStoredJson(values), options);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
export const createStringArrayAccessors = (getString, setString) => ({
|
|
72
|
+
getStringArray: (groupName, key, fallback = []) => {
|
|
73
|
+
const rawValue = getString(groupName, key, '');
|
|
74
|
+
if (!rawValue.trim()) {
|
|
75
|
+
return fallback;
|
|
76
|
+
}
|
|
77
|
+
const entries = parseStringArrayValue(rawValue);
|
|
78
|
+
return entries.length > 0 ? entries : fallback;
|
|
79
|
+
},
|
|
80
|
+
setStringArray: (groupName, key, values, options) => {
|
|
81
|
+
setString(groupName, key, serializeStringArrayValue(values), options);
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
export const createJsonAccessors = (getRawValue, setString) => ({
|
|
85
|
+
getJson: (groupName, key, fallback) => {
|
|
86
|
+
const rawValue = getRawValue(groupName, key);
|
|
87
|
+
if (rawValue === null) {
|
|
88
|
+
return fallback;
|
|
89
|
+
}
|
|
90
|
+
return parseStoredJson(rawValue, fallback);
|
|
91
|
+
},
|
|
92
|
+
setJson: (groupName, key, value, options) => {
|
|
93
|
+
setString(groupName, key, toStoredJson(value), options);
|
|
94
|
+
},
|
|
95
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const normalizeConfigValue: (value: unknown) => string | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const parseBoolean: (value: string, fallback: boolean) => boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const parseBoolean = (value, fallback) => {
|
|
2
|
+
const normalized = value.trim().toLowerCase();
|
|
3
|
+
if (!normalized) {
|
|
4
|
+
return fallback;
|
|
5
|
+
}
|
|
6
|
+
if (['true', '1', 'yes', 'y', 'on'].includes(normalized)) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (['false', '0', 'no', 'n', 'off'].includes(normalized)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
return fallback;
|
|
13
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const NUMERIC_PATTERN = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[Ee][+-]?\d+)?$/;
|
|
2
|
+
const INTEGER_PATTERN = /^[+-]?\d+$/;
|
|
3
|
+
const parseFiniteNumber = (value) => {
|
|
4
|
+
const trimmed = value.trim();
|
|
5
|
+
if (!trimmed || !NUMERIC_PATTERN.test(trimmed)) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
const parsed = Number(trimmed);
|
|
9
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
10
|
+
};
|
|
11
|
+
export const parseNumber = (value) => parseFiniteNumber(value);
|
|
12
|
+
export const parseFloatNumber = (value) => parseFiniteNumber(value);
|
|
13
|
+
export const parseIntNumber = (value) => {
|
|
14
|
+
const trimmed = value.trim();
|
|
15
|
+
if (!trimmed || !INTEGER_PATTERN.test(trimmed)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
19
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
20
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const RS_PROFILE_GROUP_SEGMENT = '.rsprofile.';
|
|
2
|
+
export const buildProfileGroupName = (groupName, profileKey) => `${groupName}${RS_PROFILE_GROUP_SEGMENT}${profileKey}`;
|
|
3
|
+
export const extractProfileKeyFromConfigKey = (fullKey, prefix) => {
|
|
4
|
+
if (!fullKey.startsWith(prefix)) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
const remainder = fullKey.slice(prefix.length);
|
|
8
|
+
if (!remainder) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const profileKey = remainder.split('.')[0]?.trim();
|
|
12
|
+
return profileKey || null;
|
|
13
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type RSProfileConfigValue = object | string | boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Upstream typing only accepts `object`, but runtime supports scalar values as well.
|
|
4
|
+
*/
|
|
5
|
+
export declare const setRSProfileConfigurationValue: (groupName: string, key: string, value: RSProfileConfigValue) => void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upstream typing only accepts `object`, but runtime supports scalar values as well.
|
|
3
|
+
*/
|
|
4
|
+
export const setRSProfileConfigurationValue = (groupName, key, value) => {
|
|
5
|
+
const typedConfigManager = configManager;
|
|
6
|
+
typedConfigManager.setRSProfileConfiguration(groupName, key, value);
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const splitCsv: (value: string) => string[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ParseOutcome = {
|
|
2
|
+
ok: true;
|
|
3
|
+
value: unknown;
|
|
4
|
+
} | {
|
|
5
|
+
ok: false;
|
|
6
|
+
};
|
|
7
|
+
export declare const toStoredJson: (value: unknown) => string;
|
|
8
|
+
export declare const parseStoredData: (rawValue: string) => ParseOutcome;
|
|
9
|
+
export declare const isStringArray: (value: unknown) => value is string[];
|
|
10
|
+
export declare const isNumberArray: (value: unknown) => value is number[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const INVALID_VALUE_ERROR = 'Config value must be JSON-serializable.';
|
|
2
|
+
const ESCAPED_COLON_REGEX = /\\:/g;
|
|
3
|
+
const TRAILING_COMMA_REGEX = /,\s*([\]}])/g;
|
|
4
|
+
const safeParseJson = (value) => {
|
|
5
|
+
try {
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
value: JSON.parse(value),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return {
|
|
13
|
+
ok: false,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
// eslint-disable-next-line unicorn/prefer-string-replace-all -- NEEDED DO NOT CHANGE
|
|
18
|
+
const stripTrailingCommas = (value) => value.replace(TRAILING_COMMA_REGEX, '$1');
|
|
19
|
+
// eslint-disable-next-line unicorn/prefer-string-replace-all -- NEEDED DO NOT CHANGE
|
|
20
|
+
const unescapeColons = (value) => value.replace(ESCAPED_COLON_REGEX, ':');
|
|
21
|
+
const buildCandidates = (rawValue) => {
|
|
22
|
+
const candidates = [rawValue, unescapeColons(rawValue), stripTrailingCommas(rawValue), stripTrailingCommas(unescapeColons(rawValue))];
|
|
23
|
+
return Array.from(new Set(candidates));
|
|
24
|
+
};
|
|
25
|
+
export const toStoredJson = (value) => {
|
|
26
|
+
if (value === undefined || typeof value === 'function' || typeof value === 'symbol' || typeof value === 'bigint') {
|
|
27
|
+
throw new TypeError(INVALID_VALUE_ERROR);
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const serialized = JSON.stringify(value);
|
|
31
|
+
if (serialized === undefined) {
|
|
32
|
+
throw new TypeError(INVALID_VALUE_ERROR);
|
|
33
|
+
}
|
|
34
|
+
return serialized;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
throw new TypeError(INVALID_VALUE_ERROR);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
export const parseStoredData = (rawValue) => {
|
|
41
|
+
const trimmedValue = rawValue.trim();
|
|
42
|
+
if (!trimmedValue) {
|
|
43
|
+
return {
|
|
44
|
+
ok: false,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
for (const candidate of buildCandidates(trimmedValue)) {
|
|
48
|
+
const parsed = safeParseJson(candidate);
|
|
49
|
+
if (parsed.ok) {
|
|
50
|
+
return parsed;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
ok: false,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export const isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === 'string');
|
|
58
|
+
export const isNumberArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === 'number' && Number.isFinite(entry));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { splitCsv } from './split-csv.js';
|
|
2
|
+
const isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === 'string');
|
|
3
|
+
export const parseStringArrayValue = (rawValue) => {
|
|
4
|
+
const trimmed = rawValue.trim();
|
|
5
|
+
if (!trimmed) {
|
|
6
|
+
return [];
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
const parsed = JSON.parse(trimmed);
|
|
10
|
+
if (isStringArray(parsed)) {
|
|
11
|
+
return parsed;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Fall back to legacy CSV storage.
|
|
16
|
+
}
|
|
17
|
+
return splitCsv(rawValue);
|
|
18
|
+
};
|
|
19
|
+
export const serializeStringArrayValue = (values) => JSON.stringify(values);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { splitCsv } from './split-csv.js';
|
|
2
|
+
import { isStringArray, parseStoredData, toStoredJson } from './storage.js';
|
|
3
|
+
export const parseStringArrayValue = (rawValue) => {
|
|
4
|
+
const trimmed = rawValue.trim();
|
|
5
|
+
if (!trimmed) {
|
|
6
|
+
return [];
|
|
7
|
+
}
|
|
8
|
+
const parsed = parseStoredData(trimmed);
|
|
9
|
+
if (parsed.ok && isStringArray(parsed.value)) {
|
|
10
|
+
return parsed.value;
|
|
11
|
+
}
|
|
12
|
+
return splitCsv(rawValue);
|
|
13
|
+
};
|
|
14
|
+
export const serializeStringArrayValue = (values) => toStoredJson(values);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type RsProfileStorage = {
|
|
2
|
+
group: string;
|
|
3
|
+
sync?: boolean;
|
|
4
|
+
/** optional profile key override to read/write a specific profile. */
|
|
5
|
+
profileKey?: string;
|
|
6
|
+
/** Use group-level (non-profile) config storage instead of profile-scoped. */
|
|
7
|
+
scope?: 'profile' | 'group';
|
|
8
|
+
};
|
|
9
|
+
export declare const getStoredString: (storage: RsProfileStorage | undefined, key: string, fallback: string) => string;
|
|
10
|
+
export declare const setStoredString: (storage: RsProfileStorage | undefined, key: string, value: string) => void;
|
|
11
|
+
export declare const getStoredInt: (storage: RsProfileStorage | undefined, key: string, fallback: number) => number;
|
|
12
|
+
export declare const setStoredInt: (storage: RsProfileStorage | undefined, key: string, value: number) => void;
|
|
13
|
+
export declare const getStoredBoolean: (storage: RsProfileStorage | undefined, key: string, fallback: boolean) => boolean;
|
|
14
|
+
export declare const setStoredBoolean: (storage: RsProfileStorage | undefined, key: string, value: boolean) => void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createConfigScope } from './config-scope.js';
|
|
2
|
+
const INVALID_STORAGE_GROUP_ERROR = "Invalid RsProfileStorage: 'group' must be a non-empty string when storage is provided.";
|
|
3
|
+
const resolveStorage = (storage) => {
|
|
4
|
+
if (storage === undefined) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
if (typeof storage.group !== 'string' || storage.group.trim().length === 0) {
|
|
8
|
+
throw new TypeError(INVALID_STORAGE_GROUP_ERROR);
|
|
9
|
+
}
|
|
10
|
+
return storage;
|
|
11
|
+
};
|
|
12
|
+
const getScope = (storage) => createConfigScope({
|
|
13
|
+
group: storage.group,
|
|
14
|
+
scope: storage.scope,
|
|
15
|
+
profileKey: storage.profileKey,
|
|
16
|
+
syncDefault: storage.sync,
|
|
17
|
+
});
|
|
18
|
+
export const getStoredString = (storage, key, fallback) => {
|
|
19
|
+
const validStorage = resolveStorage(storage);
|
|
20
|
+
if (validStorage) {
|
|
21
|
+
return getScope(validStorage).getString(key, fallback);
|
|
22
|
+
}
|
|
23
|
+
return bot.bmCache.getString(key, fallback);
|
|
24
|
+
};
|
|
25
|
+
export const setStoredString = (storage, key, value) => {
|
|
26
|
+
const validStorage = resolveStorage(storage);
|
|
27
|
+
if (validStorage) {
|
|
28
|
+
getScope(validStorage).set(key, value);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
bot.bmCache.saveString(key, value);
|
|
32
|
+
};
|
|
33
|
+
export const getStoredInt = (storage, key, fallback) => {
|
|
34
|
+
const validStorage = resolveStorage(storage);
|
|
35
|
+
if (validStorage) {
|
|
36
|
+
return getScope(validStorage).getInt(key, fallback);
|
|
37
|
+
}
|
|
38
|
+
return bot.bmCache.getInt(key, fallback);
|
|
39
|
+
};
|
|
40
|
+
export const setStoredInt = (storage, key, value) => {
|
|
41
|
+
const validStorage = resolveStorage(storage);
|
|
42
|
+
if (validStorage) {
|
|
43
|
+
getScope(validStorage).set(key, value);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
bot.bmCache.saveInt(key, value);
|
|
47
|
+
};
|
|
48
|
+
export const getStoredBoolean = (storage, key, fallback) => {
|
|
49
|
+
const validStorage = resolveStorage(storage);
|
|
50
|
+
if (validStorage) {
|
|
51
|
+
return getScope(validStorage).getBoolean(key, fallback);
|
|
52
|
+
}
|
|
53
|
+
return bot.bmCache.getBoolean(key, fallback);
|
|
54
|
+
};
|
|
55
|
+
export const setStoredBoolean = (storage, key, value) => {
|
|
56
|
+
const validStorage = resolveStorage(storage);
|
|
57
|
+
if (validStorage) {
|
|
58
|
+
getScope(validStorage).set(key, value);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
bot.bmCache.saveBoolean(key, value);
|
|
62
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare const group: {
|
|
2
|
+
get: (groupName: string, key: string) => import("./data/group/aliases.js").ConfigAliasValue;
|
|
3
|
+
getBoolean: (groupName: string, key: string, fallback?: boolean | undefined) => boolean;
|
|
4
|
+
getFloat: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
5
|
+
getInt: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
6
|
+
getJson: <T>(groupName: string, key: string, fallback: T) => T;
|
|
7
|
+
getKeys: (prefix: string) => string[];
|
|
8
|
+
getNumber: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
9
|
+
getNumberArray: (groupName: string, key: string, fallback?: number[] | undefined) => number[];
|
|
10
|
+
getString: (groupName: string, key: string, fallback?: string) => string;
|
|
11
|
+
getStringArray: (groupName: string, key: string, fallback?: string[] | undefined) => string[];
|
|
12
|
+
logSummary: (groupName: string) => void;
|
|
13
|
+
set: (groupName: string, key: string, value: unknown, options?: import("./data/shared/types.js").ConfigWriteOptions | undefined) => void;
|
|
14
|
+
unset: (groupName: string, key: string, options?: import("./data/shared/types.js").ConfigWriteOptions | undefined) => void;
|
|
15
|
+
};
|
|
16
|
+
export declare const profile: {
|
|
17
|
+
get: (groupName: string, key: string) => import("./data/profile/config.js").ProfileConfigAliasValue;
|
|
18
|
+
getBoolean: (groupName: string, key: string, fallback?: boolean | undefined) => boolean;
|
|
19
|
+
getBooleanForProfileKey: (groupName: string, profileKey: string, key: string, fallback?: boolean) => boolean;
|
|
20
|
+
getConfigKeys: (groupName: string, keyPrefix?: string) => string[];
|
|
21
|
+
getFloat: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
22
|
+
getGroupName: (groupName: string, profileKey: string) => string;
|
|
23
|
+
getInt: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
24
|
+
getIntForProfileKey: (groupName: string, profileKey: string, key: string, fallback?: number) => number;
|
|
25
|
+
getJson: <T>(groupName: string, key: string, fallback: T) => T;
|
|
26
|
+
getKey: () => string;
|
|
27
|
+
getKeysForGroup: (groupName: string) => string[];
|
|
28
|
+
getNumber: (groupName: string, key: string, fallback?: number | undefined) => number;
|
|
29
|
+
getNumberArray: (groupName: string, key: string, fallback?: number[] | undefined) => number[];
|
|
30
|
+
getString: (groupName: string, key: string, fallback?: string) => string;
|
|
31
|
+
getStringArray: (groupName: string, key: string, fallback?: string[] | undefined) => string[];
|
|
32
|
+
getStringForProfileKey: (groupName: string, profileKey: string, key: string, fallback?: string) => string;
|
|
33
|
+
logSummary: (groupName: string) => void;
|
|
34
|
+
set: (groupName: string, key: string, value: unknown, options?: import("./data/shared/types.js").ConfigWriteOptions | undefined) => void;
|
|
35
|
+
unset: (groupName: string, key: string, options?: import("./data/shared/types.js").ConfigWriteOptions | undefined) => void;
|
|
36
|
+
};
|
|
37
|
+
export { sendConfig } from './data/group/keys.js';
|
|
38
|
+
export { createConfigScope, logConfigValues } from './data/config-scope.js';
|
|
39
|
+
export type { ConfigScope, ConfigScopeMode, ConfigScopeOptions, LogConfigValuesOptions } from './data/config-scope.js';
|
|
40
|
+
export type { ConfigWriteOptions } from './data/shared/types.js';
|
|
41
|
+
export { getStoredBoolean, getStoredInt, getStoredString, setStoredBoolean, setStoredInt, setStoredString } from './data/storage.js';
|
|
42
|
+
export type { RsProfileStorage } from './data/storage.js';
|