@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.
@@ -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
- return runWithCtx(ctx, target, thisArg, args);
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
- return runWithCtx(ctx, Reflect.construct, undefined, [target, args, newTarget]);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cldmv/slothlet",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "moduleVersions": {
5
5
  "lazy": "1.0.0",
6
6
  "eager": "1.0.0"
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,wCAjEW,MAAM,SAEd;IAAuB,UAAU,GAAzB,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,CA+QlB"}
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;AAsB3C,iCAjBI,MAAM,YAwDhB;AA4RD;;;;;;;;;;;;;GAaG;AACH,mBATU,WAAS,MAAM,CAS6B;AAEtD;;;;;;;;;;;;;GAaG;AACH,sBATU,MAAM,CAS4C;AAE5D;;;;;;;;;;;;;GAaG;AACH,wBATU,MAAM,CASgD"}
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"}
@@ -103,6 +103,8 @@ export type SlothletOptions = {
103
103
  */
104
104
  sanitize?: {
105
105
  lowerFirst?: boolean;
106
+ preserveAllUpper?: boolean;
107
+ preserveAllLower?: boolean;
106
108
  rules?: {
107
109
  leave?: string[];
108
110
  leaveInsensitive?: string[];
@@ -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;;AAv0CD;;;;;;;;GAQG;AACH,mCAJW,eAAe,GACb,OAAO,CAAC,WAAS,MAAM,CAAC,CAiCpC"}
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"}