@cldmv/slothlet 2.1.0 → 2.3.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/dist/lib/helpers/sanitize.mjs +11 -1
- package/dist/lib/runtime/runtime.mjs +107 -2
- package/package.json +1 -1
- package/types/dist/lib/helpers/sanitize.d.mts +18 -0
- package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts +2 -0
- package/types/dist/slothlet.d.mts.map +1 -1
|
@@ -46,7 +46,7 @@ function globToRegex(pattern, caseSensitive = true) {
|
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
export function sanitizePathName(input, opts = {}) {
|
|
49
|
-
const { lowerFirst = true, rules = {} } = opts;
|
|
49
|
+
const { lowerFirst = true, preserveAllUpper = false, preserveAllLower = false, rules = {} } = opts;
|
|
50
50
|
|
|
51
51
|
const leaveRules = (rules.leave || []).map((s) => String(s));
|
|
52
52
|
const leaveInsensitiveRules = (rules.leaveInsensitive || []).map((s) => String(s));
|
|
@@ -117,6 +117,16 @@ export function sanitizePathName(input, opts = {}) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
|
|
120
|
+
if (preserveAllUpper && seg === seg.toUpperCase() && seg !== seg.toLowerCase() && /[A-Z]/.test(seg)) {
|
|
121
|
+
return seg;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
if (preserveAllLower && seg === seg.toLowerCase() && seg !== seg.toUpperCase() && /[a-z]/.test(seg)) {
|
|
126
|
+
return seg;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
120
130
|
if (segmentMatchesPreSplitPattern(seg, upperRules, false)) {
|
|
121
131
|
return seg.toUpperCase();
|
|
122
132
|
}
|
|
@@ -35,8 +35,98 @@ export const runWithCtx = (ctx, fn, thisArg, args) => {
|
|
|
35
35
|
export const getCtx = () => als.getStore() || null;
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
const EXCLUDED_CONSTRUCTORS = new Set([Object, Array, Promise, Date, RegExp, Error]);
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
const EXCLUDED_INSTANCEOF_CLASSES = [ArrayBuffer, Map, Set, WeakMap, WeakSet];
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
function runtime_shouldWrapMethod(value, prop) {
|
|
45
|
+
return (
|
|
46
|
+
typeof value === "function" &&
|
|
47
|
+
typeof prop === "string" &&
|
|
48
|
+
prop !== "constructor" &&
|
|
49
|
+
!(prop in Object.prototype) &&
|
|
50
|
+
!prop.startsWith("__")
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
function runtime_isClassInstance(val) {
|
|
56
|
+
if (
|
|
57
|
+
val == null ||
|
|
58
|
+
typeof val !== "object" ||
|
|
59
|
+
!val.constructor ||
|
|
60
|
+
typeof val.constructor !== "function" ||
|
|
61
|
+
EXCLUDED_CONSTRUCTORS.has(val.constructor)
|
|
62
|
+
) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const cls of EXCLUDED_INSTANCEOF_CLASSES) {
|
|
67
|
+
if (typeof cls === "function" && val instanceof cls) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
function runtime_wrapClassInstance(instance, ctx, wrapFn, instanceCache) {
|
|
77
|
+
if (instanceCache.has(instance)) {
|
|
78
|
+
return instanceCache.get(instance);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
const methodCache = new Map();
|
|
83
|
+
|
|
84
|
+
const wrappedInstance = new Proxy(instance, {
|
|
85
|
+
get(target, prop, receiver) {
|
|
86
|
+
|
|
87
|
+
if (methodCache.has(prop)) {
|
|
88
|
+
return methodCache.get(prop);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const value = Reflect.get(target, prop, receiver);
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if (runtime_shouldWrapMethod(value, prop)) {
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
const runtime_contextPreservingMethod = function (...args) {
|
|
99
|
+
const result = runWithCtx(ctx, value, target, args);
|
|
100
|
+
|
|
101
|
+
return wrapFn(result);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
methodCache.set(prop, runtime_contextPreservingMethod);
|
|
106
|
+
return runtime_contextPreservingMethod;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
return wrapFn(value);
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
set(target, prop, value, receiver) {
|
|
114
|
+
|
|
115
|
+
if (methodCache.has(prop)) {
|
|
116
|
+
methodCache.delete(prop);
|
|
117
|
+
}
|
|
118
|
+
return Reflect.set(target, prop, value, receiver);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
instanceCache.set(instance, wrappedInstance);
|
|
123
|
+
return wrappedInstance;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
38
127
|
export const makeWrapper = (ctx) => {
|
|
39
128
|
const cache = new WeakMap();
|
|
129
|
+
const instanceCache = new WeakMap();
|
|
40
130
|
const wrap = (val) => {
|
|
41
131
|
if (val == null || (typeof val !== "object" && typeof val !== "function")) return val;
|
|
42
132
|
if (cache.has(val)) return cache.get(val);
|
|
@@ -53,11 +143,26 @@ export const makeWrapper = (ctx) => {
|
|
|
53
143
|
|
|
54
144
|
|
|
55
145
|
|
|
56
|
-
|
|
146
|
+
|
|
147
|
+
const result = runWithCtx(ctx, target, thisArg, args);
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
if (runtime_isClassInstance(result)) {
|
|
151
|
+
return runtime_wrapClassInstance(result, ctx, wrap, instanceCache);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return result;
|
|
57
155
|
},
|
|
58
156
|
construct(target, args, newTarget) {
|
|
59
157
|
|
|
60
|
-
|
|
158
|
+
const result = runWithCtx(ctx, Reflect.construct, undefined, [target, args, newTarget]);
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
if (runtime_isClassInstance(result)) {
|
|
162
|
+
return runtime_wrapClassInstance(result, ctx, wrap, instanceCache);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return result;
|
|
61
166
|
},
|
|
62
167
|
get(target, prop, receiver) {
|
|
63
168
|
return wrap(Reflect.get(target, prop, receiver));
|
package/package.json
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* @param {string} input - The input string to sanitize (e.g., file name, path segment)
|
|
6
6
|
* @param {Object} [opts={}] - Sanitization configuration options
|
|
7
7
|
* @param {boolean} [opts.lowerFirst=true] - Lowercase the first character of the first segment for camelCase convention
|
|
8
|
+
* @param {boolean} [opts.preserveAllUpper=false] - Automatically preserve any identifier that is already in all-uppercase format
|
|
9
|
+
* @param {boolean} [opts.preserveAllLower=false] - Automatically preserve any identifier that is already in all-lowercase format
|
|
8
10
|
* @param {Object} [opts.rules={}] - Advanced segment transformation rules (supports glob patterns: *, ?, **STRING**)
|
|
9
11
|
* @param {string[]} [opts.rules.leave=[]] - Segments to preserve exactly as-is (case-sensitive, supports globs)
|
|
10
12
|
* @param {string[]} [opts.rules.leaveInsensitive=[]] - Segments to preserve exactly as-is (case-insensitive, supports globs)
|
|
@@ -48,6 +50,20 @@
|
|
|
48
50
|
* }); // Result: "getAPIStatus" (api becomes API due to pattern)
|
|
49
51
|
*
|
|
50
52
|
* @example
|
|
53
|
+
* // Automatic case preservation
|
|
54
|
+
* sanitizePathName("COMMON_APPS", { preserveAllUpper: true }); // "COMMON_APPS" (preserved)
|
|
55
|
+
* sanitizePathName("cOMMON_APPS", { preserveAllUpper: true }); // "cOMMON_APPS" (not all-uppercase, transformed)
|
|
56
|
+
* sanitizePathName("common_apps", { preserveAllLower: true }); // "common_apps" (preserved)
|
|
57
|
+
* sanitizePathName("Common_apps", { preserveAllLower: true }); // "commonApps" (not all-lowercase, transformed)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // Combining preserve options with other rules
|
|
61
|
+
* sanitizePathName("parse-XML-data", {
|
|
62
|
+
* preserveAllUpper: true,
|
|
63
|
+
* rules: { upper: ["xml"] }
|
|
64
|
+
* }); // "parseXMLData" (XML preserved by preserveAllUpper)
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
51
67
|
* // Boundary-requiring patterns with **STRING** syntax
|
|
52
68
|
* sanitizePathName("buildUrlWithParams", {
|
|
53
69
|
* rules: {
|
|
@@ -69,6 +85,8 @@
|
|
|
69
85
|
*/
|
|
70
86
|
export function sanitizePathName(input: string, opts?: {
|
|
71
87
|
lowerFirst?: boolean;
|
|
88
|
+
preserveAllUpper?: boolean;
|
|
89
|
+
preserveAllLower?: boolean;
|
|
72
90
|
rules?: {
|
|
73
91
|
leave?: string[];
|
|
74
92
|
leaveInsensitive?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.mts","sourceRoot":"","sources":["../../../../dist/lib/helpers/sanitize.mjs"],"names":[],"mappings":"AAmEA
|
|
1
|
+
{"version":3,"file":"sanitize.d.mts","sourceRoot":"","sources":["../../../../dist/lib/helpers/sanitize.mjs"],"names":[],"mappings":"AAmEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AACH,wCAjFW,MAAM,SAEd;IAAuB,UAAU,GAAzB,OAAO;IACQ,gBAAgB,GAA/B,OAAO;IACQ,gBAAgB,GAA/B,OAAO;IACO,KAAK,GAC3B;QAA8B,KAAK,GAA3B,MAAM,EAAE;QACc,gBAAgB,GAAtC,MAAM,EAAE;QACc,KAAK,GAA3B,MAAM,EAAE;QACc,KAAK,GAA3B,MAAM,EAAE;KAChB;CAAA,GAAU,MAAM,CAuSlB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.mts","sourceRoot":"","sources":["../../../../dist/lib/runtime/runtime.mjs"],"names":[],"mappings":"AA0CO,gCAdI,MAAM,yBAEN,GAAG,gBAED,GAAG,CA6Bf;AAiBM,0BAZM,MAAM,GAAC,IAAI,CAY0B;
|
|
1
|
+
{"version":3,"file":"runtime.d.mts","sourceRoot":"","sources":["../../../../dist/lib/runtime/runtime.mjs"],"names":[],"mappings":"AA0CO,gCAdI,MAAM,yBAEN,GAAG,gBAED,GAAG,CA6Bf;AAiBM,0BAZM,MAAM,GAAC,IAAI,CAY0B;AA8K3C,iCAjBI,MAAM,YAwEhB;AA4RD;;;;;;;;;;;;;GAaG;AACH,mBATU,WAAS,MAAM,CAS6B;AAEtD;;;;;;;;;;;;;GAaG;AACH,sBATU,MAAM,CAS4C;AAE5D;;;;;;;;;;;;;GAaG;AACH,wBATU,MAAM,CASgD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slothlet.d.mts","sourceRoot":"","sources":["../../dist/slothlet.mjs"],"names":[],"mappings":"AAi5CA;;;;;;;;;GASG;AACH,kDARW,WAAS,MAAM,UACf,WAAS,MAAM,QAwCzB;AAzzCD;;;;;GAKG;AACH,sBAJU,MAAM,CAIoE;AAKpF;;;;;;;GAOG;AACH,mBAJU,MAAM,CAIO;AAEvB;;;;;GAKG;AACH,sBAJU,MAAM,CAIU;AAE1B;;;;;GAKG;AACH,wBAJU,MAAM,CAIY;;;;;;;;;UAiyCd,MAAM;;;;;;WAIN,OAAO;;;;;;;eAGP,MAAM;;;;;;;;YAIN,OAAO;;;;;;;;WAKP,MAAM;;;;;;;eAKN,MAAM;;;;;;cAIN,MAAM;;;;;;gBAGN,MAAM;;;;;;eAMjB;QAA8B,UAAU,GAA7B,OAAO;QACW,KAAK,GAClC;YAAqC,KAAK,GAA/B,MAAM,EAAE;YACkB,gBAAgB,GAA1C,MAAM,EAAE;YACkB,KAAK,GAA/B,MAAM,EAAE;YACkB,KAAK,GAA/B,MAAM,EAAE;SACrB;KAAA;;
|
|
1
|
+
{"version":3,"file":"slothlet.d.mts","sourceRoot":"","sources":["../../dist/slothlet.mjs"],"names":[],"mappings":"AAi5CA;;;;;;;;;GASG;AACH,kDARW,WAAS,MAAM,UACf,WAAS,MAAM,QAwCzB;AAzzCD;;;;;GAKG;AACH,sBAJU,MAAM,CAIoE;AAKpF;;;;;;;GAOG;AACH,mBAJU,MAAM,CAIO;AAEvB;;;;;GAKG;AACH,sBAJU,MAAM,CAIU;AAE1B;;;;;GAKG;AACH,wBAJU,MAAM,CAIY;;;;;;;;;UAiyCd,MAAM;;;;;;WAIN,OAAO;;;;;;;eAGP,MAAM;;;;;;;;YAIN,OAAO;;;;;;;;WAKP,MAAM;;;;;;;eAKN,MAAM;;;;;;cAIN,MAAM;;;;;;gBAGN,MAAM;;;;;;eAMjB;QAA8B,UAAU,GAA7B,OAAO;QACY,gBAAgB,GAAnC,OAAO;QACY,gBAAgB,GAAnC,OAAO;QACW,KAAK,GAClC;YAAqC,KAAK,GAA/B,MAAM,EAAE;YACkB,gBAAgB,GAA1C,MAAM,EAAE;YACkB,KAAK,GAA/B,MAAM,EAAE;YACkB,KAAK,GAA/B,MAAM,EAAE;SACrB;KAAA;;AAz0CD;;;;;;;;GAQG;AACH,mCAJW,eAAe,GACb,OAAO,CAAC,WAAS,MAAM,CAAC,CAiCpC"}
|