@cldmv/slothlet 3.3.0 → 3.3.2

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 (127) hide show
  1. package/README.md +6 -8
  2. package/REFERENCE.md +23 -0
  3. package/dist/lib/builders/api-assignment.mjs +1 -589
  4. package/dist/lib/builders/api_builder.mjs +1 -1385
  5. package/dist/lib/builders/builder.mjs +1 -78
  6. package/dist/lib/builders/modes-processor.mjs +1 -1800
  7. package/dist/lib/errors.mjs +9 -211
  8. package/dist/lib/factories/component-base.mjs +1 -80
  9. package/dist/lib/factories/context.mjs +1 -22
  10. package/dist/lib/handlers/api-cache-manager.mjs +1 -200
  11. package/dist/lib/handlers/api-manager.mjs +1 -2536
  12. package/dist/lib/handlers/context-async.mjs +1 -172
  13. package/dist/lib/handlers/context-live.mjs +1 -173
  14. package/dist/lib/handlers/hook-manager.mjs +1 -667
  15. package/dist/lib/handlers/lifecycle-token.mjs +1 -28
  16. package/dist/lib/handlers/lifecycle.mjs +1 -115
  17. package/dist/lib/handlers/materialize-manager.mjs +1 -48
  18. package/dist/lib/handlers/metadata.mjs +1 -501
  19. package/dist/lib/handlers/ownership.mjs +1 -322
  20. package/dist/lib/handlers/permission-manager.mjs +1 -392
  21. package/dist/lib/handlers/unified-wrapper.mjs +1 -3110
  22. package/dist/lib/handlers/version-manager.mjs +1 -885
  23. package/dist/lib/helpers/class-instance-wrapper.mjs +1 -109
  24. package/dist/lib/helpers/config.mjs +1 -439
  25. package/dist/lib/helpers/eventemitter-context.mjs +1 -349
  26. package/dist/lib/helpers/hint-detector.mjs +1 -47
  27. package/dist/lib/helpers/modes-utils.mjs +1 -37
  28. package/dist/lib/helpers/pattern-matcher.mjs +1 -125
  29. package/dist/lib/helpers/resolve-from-caller.mjs +1 -169
  30. package/dist/lib/helpers/sanitize.mjs +1 -340
  31. package/dist/lib/helpers/utilities.mjs +1 -70
  32. package/dist/lib/i18n/translations.mjs +1 -126
  33. package/dist/lib/modes/eager.mjs +1 -59
  34. package/dist/lib/modes/lazy.mjs +1 -81
  35. package/dist/lib/processors/flatten.mjs +1 -437
  36. package/dist/lib/processors/loader.mjs +1 -339
  37. package/dist/lib/processors/type-generator.mjs +1 -275
  38. package/dist/lib/processors/typescript.mjs +1 -172
  39. package/dist/lib/runtime/runtime-asynclocalstorage.mjs +1 -113
  40. package/dist/lib/runtime/runtime-livebindings.mjs +1 -78
  41. package/dist/lib/runtime/runtime.mjs +1 -102
  42. package/dist/slothlet.mjs +1 -817
  43. package/package.json +34 -31
  44. package/types/dist/lib/builders/api-assignment.d.mts +3 -92
  45. package/types/dist/lib/builders/api-assignment.d.mts.map +1 -1
  46. package/types/dist/lib/builders/api_builder.d.mts +102 -91
  47. package/types/dist/lib/builders/api_builder.d.mts.map +1 -1
  48. package/types/dist/lib/builders/builder.d.mts +1 -55
  49. package/types/dist/lib/builders/builder.d.mts.map +1 -1
  50. package/types/dist/lib/builders/modes-processor.d.mts +3 -27
  51. package/types/dist/lib/builders/modes-processor.d.mts.map +1 -1
  52. package/types/dist/lib/errors.d.mts +19 -109
  53. package/types/dist/lib/errors.d.mts.map +1 -1
  54. package/types/dist/lib/factories/component-base.d.mts +7 -177
  55. package/types/dist/lib/factories/component-base.d.mts.map +1 -1
  56. package/types/dist/lib/factories/context.d.mts +4 -22
  57. package/types/dist/lib/factories/context.d.mts.map +1 -1
  58. package/types/dist/lib/handlers/api-cache-manager.d.mts +20 -203
  59. package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -1
  60. package/types/dist/lib/handlers/api-manager.d.mts +33 -408
  61. package/types/dist/lib/handlers/api-manager.d.mts.map +1 -1
  62. package/types/dist/lib/handlers/context-async.d.mts +23 -61
  63. package/types/dist/lib/handlers/context-async.d.mts.map +1 -1
  64. package/types/dist/lib/handlers/context-live.d.mts +22 -59
  65. package/types/dist/lib/handlers/context-live.d.mts.map +1 -1
  66. package/types/dist/lib/handlers/hook-manager.d.mts +46 -185
  67. package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -1
  68. package/types/dist/lib/handlers/lifecycle-token.d.mts +3 -48
  69. package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -1
  70. package/types/dist/lib/handlers/lifecycle.d.mts +5 -82
  71. package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -1
  72. package/types/dist/lib/handlers/materialize-manager.d.mts +8 -70
  73. package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -1
  74. package/types/dist/lib/handlers/metadata.d.mts +17 -221
  75. package/types/dist/lib/handlers/metadata.d.mts.map +1 -1
  76. package/types/dist/lib/handlers/ownership.d.mts +44 -160
  77. package/types/dist/lib/handlers/ownership.d.mts.map +1 -1
  78. package/types/dist/lib/handlers/permission-manager.d.mts +37 -141
  79. package/types/dist/lib/handlers/permission-manager.d.mts.map +1 -1
  80. package/types/dist/lib/handlers/unified-wrapper.d.mts +26 -239
  81. package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -1
  82. package/types/dist/lib/handlers/version-manager.d.mts +28 -225
  83. package/types/dist/lib/handlers/version-manager.d.mts.map +1 -1
  84. package/types/dist/lib/helpers/class-instance-wrapper.d.mts +2 -52
  85. package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -1
  86. package/types/dist/lib/helpers/config.d.mts +125 -139
  87. package/types/dist/lib/helpers/config.d.mts.map +1 -1
  88. package/types/dist/lib/helpers/eventemitter-context.d.mts +3 -29
  89. package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -1
  90. package/types/dist/lib/helpers/hint-detector.d.mts +2 -15
  91. package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -1
  92. package/types/dist/lib/helpers/modes-utils.d.mts +3 -30
  93. package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -1
  94. package/types/dist/lib/helpers/pattern-matcher.d.mts +3 -43
  95. package/types/dist/lib/helpers/pattern-matcher.d.mts.map +1 -1
  96. package/types/dist/lib/helpers/resolve-from-caller.d.mts +3 -27
  97. package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
  98. package/types/dist/lib/helpers/sanitize.d.mts +4 -92
  99. package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
  100. package/types/dist/lib/helpers/utilities.d.mts +4 -52
  101. package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
  102. package/types/dist/lib/i18n/translations.d.mts +4 -37
  103. package/types/dist/lib/i18n/translations.d.mts.map +1 -1
  104. package/types/dist/lib/modes/eager.d.mts +8 -30
  105. package/types/dist/lib/modes/eager.d.mts.map +1 -1
  106. package/types/dist/lib/modes/lazy.d.mts +10 -43
  107. package/types/dist/lib/modes/lazy.d.mts.map +1 -1
  108. package/types/dist/lib/processors/flatten.d.mts +56 -107
  109. package/types/dist/lib/processors/flatten.d.mts.map +1 -1
  110. package/types/dist/lib/processors/loader.d.mts +6 -41
  111. package/types/dist/lib/processors/loader.d.mts.map +1 -1
  112. package/types/dist/lib/processors/type-generator.d.mts +2 -16
  113. package/types/dist/lib/processors/type-generator.d.mts.map +1 -1
  114. package/types/dist/lib/processors/typescript.d.mts +6 -53
  115. package/types/dist/lib/processors/typescript.d.mts.map +1 -1
  116. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +3 -71
  117. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
  118. package/types/dist/lib/runtime/runtime-livebindings.d.mts +2 -37
  119. package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
  120. package/types/dist/lib/runtime/runtime.d.mts +3 -39
  121. package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
  122. package/types/dist/slothlet.d.mts +3 -249
  123. package/types/dist/slothlet.d.mts.map +1 -1
  124. package/types/index.d.mts +36 -16
  125. package/types/index.d.mts.map +1 -0
  126. package/AGENT-USAGE.md +0 -736
  127. package/docs/API-RULES.md +0 -712
@@ -14,172 +14,4 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
-
18
-
19
-
20
-
21
- import fs from "node:fs";
22
- import path from "node:path";
23
- import { fileURLToPath } from "node:url";
24
- import { ComponentBase } from "@cldmv/slothlet/factories/component-base";
25
-
26
-
27
- const __filename = fileURLToPath(import.meta.url);
28
- const __dirname = path.dirname(__filename);
29
- const SLOTHLET_LIB_ROOT = path.resolve(__dirname, "../..");
30
- const SLOTHLET_PKG_ROOT = path.normalize(path.resolve(__dirname, "../../.."));
31
-
32
- export class Resolver extends ComponentBase {
33
- static slothletProperty = "resolver";
34
-
35
-
36
- getStack(skipFn) {
37
- const orig = Error.prepareStackTrace;
38
- try {
39
- Error.prepareStackTrace = (_, s) => s;
40
- const e = new Error("Stack trace");
41
- if (skipFn) Error.captureStackTrace(e, skipFn);
42
- return e.stack;
43
- } finally {
44
- Error.prepareStackTrace = orig;
45
- }
46
- }
47
-
48
-
49
- #getStack() {
50
- const originalPrepare = Error.prepareStackTrace;
51
- Error.prepareStackTrace = (___, stack) => stack;
52
- const stack = new Error().stack;
53
- Error.prepareStackTrace = originalPrepare;
54
- return stack;
55
- }
56
-
57
-
58
- toFsPath(v) {
59
- if (!v) return null;
60
- const str = String(v);
61
- return str.startsWith("file://") ? fileURLToPath(str) : str;
62
- }
63
-
64
-
65
- #isSlothletInternal(filePath) {
66
-
67
- const normalized = path.normalize(filePath);
68
- const normalizedLibRoot = path.normalize(SLOTHLET_LIB_ROOT);
69
-
70
-
71
- if (normalized.startsWith(normalizedLibRoot)) {
72
- return true;
73
- }
74
-
75
-
76
-
77
-
78
-
79
-
80
- const basename = path.basename(normalized);
81
- if (basename === "index.mjs" || basename === "index.cjs") {
82
-
83
-
84
-
85
-
86
- if (path.dirname(normalized) === SLOTHLET_PKG_ROOT) return true;
87
- }
88
-
89
- return false;
90
- }
91
-
92
-
93
- #findCallerBase() {
94
- const stack = this.#getStack();
95
- const files = stack.map((s) => this.toFsPath(s.getFileName())).filter(Boolean);
96
-
97
-
98
- const slothletIndex = files.findIndex((f) => path.basename(f).toLowerCase() === "slothlet.mjs");
99
-
100
- if (slothletIndex === -1) {
101
-
102
- for (const file of files) {
103
- if (!this.#isSlothletInternal(file)) {
104
- return file;
105
- }
106
- }
107
-
108
-
109
-
110
-
111
-
112
- return null;
113
- }
114
-
115
-
116
- for (let i = slothletIndex + 1; i < files.length; i++) {
117
- const file = files[i];
118
-
119
-
120
- if (file.startsWith?.("node:")) continue;
121
-
122
-
123
- if (this.#isSlothletInternal(file)) continue;
124
-
125
-
126
- return file;
127
- }
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
- for (const file of files) {
136
- if (!this.#isSlothletInternal(file)) {
137
- return file;
138
- }
139
- }
140
-
141
-
142
-
143
-
144
-
145
- return null;
146
- }
147
-
148
-
149
- resolvePathFromCaller(rel) {
150
-
151
- if (rel.startsWith?.("file://")) return fileURLToPath(rel);
152
- if (path.isAbsolute(rel)) return rel;
153
-
154
-
155
- const callerFile = this.#findCallerBase();
156
-
157
-
158
-
159
-
160
-
161
- if (!callerFile) {
162
-
163
- return path.resolve(process.cwd(), rel);
164
- }
165
-
166
-
167
- const callerDir = path.dirname(callerFile);
168
- const resolved = path.resolve(callerDir, rel);
169
-
170
-
171
- if (fs.existsSync(resolved)) {
172
- return resolved;
173
- }
174
-
175
-
176
- const cwdResolved = path.resolve(process.cwd(), rel);
177
- if (fs.existsSync(cwdResolved)) {
178
- return cwdResolved;
179
- }
180
-
181
-
182
-
183
- return resolved;
184
- }
185
- }
17
+ import fs from"node:fs";import path from"node:path";import{fileURLToPath}from"node:url";import{ComponentBase}from"@cldmv/slothlet/factories/component-base";const __filename=fileURLToPath(import.meta.url);const __dirname=path.dirname(__filename);const SLOTHLET_LIB_ROOT=path.resolve(__dirname,"../..");const SLOTHLET_PKG_ROOT=path.normalize(path.resolve(__dirname,"../../.."));class Resolver extends ComponentBase{static slothletProperty="resolver";getStack(skipFn){const orig=Error.prepareStackTrace;try{Error.prepareStackTrace=(_,s)=>s;const e=new Error("Stack trace");if(skipFn)Error.captureStackTrace(e,skipFn);return e.stack}finally{Error.prepareStackTrace=orig}}#getStack(){const originalPrepare=Error.prepareStackTrace;Error.prepareStackTrace=(___,stack2)=>stack2;const stack=new Error().stack;Error.prepareStackTrace=originalPrepare;return stack}toFsPath(v){if(!v)return null;const str=String(v);return str.startsWith("file://")?fileURLToPath(str):str}#isSlothletInternal(filePath){const normalized=path.normalize(filePath);const normalizedLibRoot=path.normalize(SLOTHLET_LIB_ROOT);if(normalized.startsWith(normalizedLibRoot)){return true}const basename=path.basename(normalized);if(basename==="index.mjs"||basename==="index.cjs"){if(path.dirname(normalized)===SLOTHLET_PKG_ROOT)return true}return false}#findCallerBase(){const stack=this.#getStack();const files=stack.map(s=>this.toFsPath(s.getFileName())).filter(Boolean);const slothletIndex=files.findIndex(f=>path.basename(f).toLowerCase()==="slothlet.mjs");if(slothletIndex===-1){for(const file of files){if(!this.#isSlothletInternal(file)){return file}}return null}for(let i=slothletIndex+1;i<files.length;i++){const file=files[i];if(file.startsWith?.("node:"))continue;if(this.#isSlothletInternal(file))continue;return file}for(const file of files){if(!this.#isSlothletInternal(file)){return file}}return null}resolvePathFromCaller(rel){if(rel.startsWith?.("file://"))return fileURLToPath(rel);if(path.isAbsolute(rel))return rel;const callerFile=this.#findCallerBase();if(!callerFile){return path.resolve(process.cwd(),rel)}const callerDir=path.dirname(callerFile);const resolved=path.resolve(callerDir,rel);if(fs.existsSync(resolved)){return resolved}const cwdResolved=path.resolve(process.cwd(),rel);if(fs.existsSync(cwdResolved)){return cwdResolved}return resolved}}export{Resolver};
@@ -14,343 +14,4 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
-
18
-
19
-
20
-
21
- import { ComponentBase } from "@cldmv/slothlet/factories/component-base";
22
-
23
-
24
-
25
-
26
-
27
-
28
- export class Sanitize extends ComponentBase {
29
- static slothletProperty = "sanitize";
30
-
31
-
32
-
33
-
34
-
35
-
36
- #compileGlobPattern(pattern, caseSensitive = true) {
37
-
38
- if (pattern.startsWith("**") && pattern.endsWith("**") && pattern.length > 4) {
39
- const innerString = pattern.slice(2, -2);
40
- const escapedString = innerString.replace(/[.+^${}()|[\]\\*?]/g, "\\$&");
41
- const flags = caseSensitive ? "" : "i";
42
- return new RegExp(`(?<=.)${escapedString}(?=.)`, flags);
43
- }
44
-
45
-
46
- const regexPattern = pattern
47
- .replace(/[.+^${}()|[\]\\]/g, "\\$&")
48
- .replace(/\*/g, ".*")
49
- .replace(/\?/g, ".");
50
-
51
- const flags = caseSensitive ? "" : "i";
52
- return new RegExp(`^${regexPattern}$`, flags);
53
- }
54
-
55
-
56
- #matchesAnyPattern(input, patterns, caseSensitive = false) {
57
- for (const pattern of patterns) {
58
- if (pattern.includes("*") || pattern.includes("?")) {
59
- const regex = this.#compileGlobPattern(pattern, caseSensitive);
60
- if (regex && regex.test(input)) return true;
61
- } else {
62
- const match = caseSensitive ? input === pattern : input.toLowerCase() === pattern.toLowerCase();
63
- if (match) return true;
64
- }
65
- }
66
- return false;
67
- }
68
-
69
-
70
- #extractPatternLiterals(pattern) {
71
- return pattern.split(/[*?]+/).filter(Boolean);
72
- }
73
-
74
-
75
-
76
-
77
-
78
-
79
- #applySegmentRules(segment, index, originalString, config) {
80
- const { preserveAllUpper, preserveAllLower, leaveRules, leaveInsensitiveRules, upperRules, lowerRules } = config;
81
-
82
-
83
- if (this.#matchesAnyPattern(segment, leaveRules, true)) {
84
- return segment;
85
- }
86
-
87
-
88
- if (this.#matchesAnyPattern(segment, leaveInsensitiveRules, false)) {
89
- return segment;
90
- }
91
-
92
-
93
-
94
- if (preserveAllUpper && segment === segment.toUpperCase() && segment !== segment.toLowerCase() && /[A-Z]/.test(segment)) {
95
- return segment;
96
- }
97
-
98
-
99
-
100
- if (preserveAllLower && segment === segment.toLowerCase() && segment !== segment.toUpperCase() && /[a-z]/.test(segment)) {
101
- return segment;
102
- }
103
-
104
-
105
-
106
- for (const pattern of [...upperRules, ...lowerRules]) {
107
- if (pattern.includes("*") || pattern.includes("?")) {
108
- const regex = this.#compileGlobPattern(pattern, false);
109
- if (regex && regex.test(originalString)) {
110
-
111
- const literals = this.#extractPatternLiterals(pattern);
112
- for (const literal of literals) {
113
-
114
- const cleanLiteral = literal.replace(/[^A-Za-z0-9_$]/g, "").replace(/^_+|_+$/g, "");
115
- if (cleanLiteral && segment.toLowerCase() === cleanLiteral.toLowerCase()) {
116
- return upperRules.includes(pattern) ? segment.toUpperCase() : segment.toLowerCase();
117
- }
118
- }
119
- }
120
- } else {
121
-
122
- if (segment.toLowerCase() === pattern.toLowerCase()) {
123
- return upperRules.includes(pattern) ? segment.toUpperCase() : segment.toLowerCase();
124
- }
125
- }
126
- }
127
-
128
-
129
- let transformed = this.#applyWithinSegmentPatterns(segment, upperRules, lowerRules);
130
- if (transformed !== segment) {
131
- return transformed;
132
- }
133
-
134
-
135
-
136
- return segment;
137
- }
138
-
139
-
140
- #applyWithinSegmentPatterns(segment, upperRules, lowerRules) {
141
- let result = segment;
142
-
143
- const applyBoundaryPattern = (pattern, toUpper) => {
144
-
145
- if (pattern.startsWith("**") && pattern.endsWith("**") && pattern.length > 4) {
146
- const innerString = pattern.slice(2, -2);
147
- const innerRegex = new RegExp(innerString.replace(/[.+^${}()|[\]\\*?]/g, "\\$&"), "gi");
148
- const matches = [...result.matchAll(innerRegex)];
149
-
150
- for (const match of matches) {
151
- const startPos = match.index;
152
- const endPos = startPos + match[0].length;
153
- const hasCharBefore = startPos > 0;
154
- const hasCharAfter = endPos < result.length;
155
-
156
- if (hasCharBefore && hasCharAfter) {
157
- const replacement = toUpper ? innerString.toUpperCase() : innerString.toLowerCase();
158
- result = result.substring(0, startPos) + replacement + result.substring(endPos);
159
- break;
160
- }
161
- }
162
- }
163
-
164
- else if (pattern.includes("*") && !pattern.startsWith("**")) {
165
-
166
- const literalParts = pattern.split("*").filter(Boolean);
167
- for (const literal of literalParts) {
168
- const literalRegex = new RegExp(literal.replace(/[.+^${}()|[\]\\]/g, "\\$&"), "gi");
169
- const replacement = toUpper ? literal.toUpperCase() : literal.toLowerCase();
170
- result = result.replace(literalRegex, replacement);
171
- }
172
- }
173
- };
174
-
175
- upperRules.forEach((pattern) => applyBoundaryPattern(pattern, true));
176
- lowerRules.forEach((pattern) => applyBoundaryPattern(pattern, false));
177
-
178
- return result;
179
- }
180
-
181
-
182
-
183
-
184
-
185
-
186
- sanitizePropertyName(input, options = {}) {
187
- const { lowerFirst = true, preserveAllUpper = false, preserveAllLower = false, rules = {} } = options;
188
-
189
-
190
- const leaveRules = (rules.leave || []).map((s) => String(s));
191
- const leaveInsensitiveRules = (rules.leaveInsensitive || []).map((s) => String(s));
192
- const upperRules = (rules.upper || []).map((s) => String(s));
193
- const lowerRules = (rules.lower || []).map((s) => String(s));
194
-
195
- const originalString = String(input).trim();
196
-
197
-
198
- const isAllUpper =
199
- originalString === originalString.toUpperCase() && originalString !== originalString.toLowerCase() && /[A-Z]/.test(originalString);
200
- const isAllLower =
201
- originalString === originalString.toLowerCase() && originalString !== originalString.toUpperCase() && /[a-z]/.test(originalString);
202
-
203
- if (preserveAllUpper && isAllUpper) {
204
- return originalString;
205
- }
206
-
207
-
208
- if (preserveAllLower && isAllLower && !/-/.test(originalString)) {
209
- return originalString;
210
- }
211
-
212
-
213
-
214
- let primarySegments = originalString.split(/[-]+|[^A-Za-z0-9_$]+/).filter(Boolean);
215
-
216
-
217
- if (primarySegments.length === 0) return "_";
218
-
219
-
220
- while (primarySegments.length && !/^[A-Za-z_$]/.test(primarySegments[0][0])) {
221
- primarySegments[0] = primarySegments[0].replace(/^[^A-Za-z_$]+/, "");
222
- if (!primarySegments[0]) primarySegments.shift();
223
- }
224
- if (primarySegments.length === 0) return "_";
225
-
226
-
227
-
228
-
229
-
230
-
231
- const lowerRuleApplied = [];
232
- const processedPrimarySegments = primarySegments.map((primarySeg, primaryIdx) => {
233
-
234
- const parts = primarySeg.split(/(_+)/);
235
-
236
-
237
- const processedParts = parts.map((part, partIdx) => {
238
-
239
- if (partIdx % 2 === 1) return part;
240
- if (!part) return part;
241
-
242
-
243
- const cleanSeg = part.replace(/[^A-Za-z0-9_$]/g, "");
244
-
245
-
246
- const config = { preserveAllUpper, preserveAllLower, leaveRules, leaveInsensitiveRules, upperRules, lowerRules };
247
- const result = this.#applySegmentRules(cleanSeg, 0, originalString, config);
248
-
249
-
250
-
251
- const matchesLower = lowerRules.some((pattern) => {
252
- if (pattern.includes("*") || pattern.includes("?")) {
253
- const regex = this.#compileGlobPattern(pattern, false);
254
- if (regex && regex.test(originalString)) {
255
-
256
- const literals = this.#extractPatternLiterals(pattern);
257
- for (const literal of literals) {
258
- const cleanLiteral = literal.replace(/[^A-Za-z0-9_$]/g, "").replace(/^_+|_+$/g, "");
259
- if (cleanLiteral && cleanSeg.toLowerCase() === cleanLiteral.toLowerCase()) {
260
- return true;
261
- }
262
- }
263
- }
264
- } else {
265
-
266
- if (cleanSeg.toLowerCase() === pattern.toLowerCase()) {
267
- return true;
268
- }
269
- }
270
- return false;
271
- });
272
-
273
- if (matchesLower && result === cleanSeg.toLowerCase()) {
274
- lowerRuleApplied[primaryIdx] = true;
275
- }
276
-
277
- return result;
278
- });
279
-
280
-
281
- return processedParts.join("");
282
- });
283
-
284
-
285
- const camelCasedSegments = processedPrimarySegments.map((seg, idx) => {
286
-
287
- const matchesLeave = this.#matchesAnyPattern(seg, leaveRules, true);
288
- const matchesLeaveInsensitive = this.#matchesAnyPattern(seg, leaveInsensitiveRules, false);
289
- const matchesUpper = this.#matchesAnyPattern(seg, upperRules, false);
290
-
291
-
292
- const hasUnderscores = seg.includes("_");
293
- const isAllUpper = !hasUnderscores && preserveAllUpper && seg === seg.toUpperCase() && seg !== seg.toLowerCase() && /[A-Z]/.test(seg);
294
- const isAllLower = !hasUnderscores && preserveAllLower && seg === seg.toLowerCase() && seg !== seg.toUpperCase() && /[a-z]/.test(seg);
295
-
296
-
297
- if (matchesLeave || matchesLeaveInsensitive || matchesUpper || isAllUpper || isAllLower) {
298
- return seg;
299
- }
300
-
301
-
302
-
303
- let transformed;
304
- if (idx === 0) {
305
-
306
- transformed = lowerFirst ? seg[0].toLowerCase() + seg.slice(1) : seg;
307
- } else {
308
-
309
-
310
- if (lowerRuleApplied[idx]) {
311
- transformed = seg;
312
- } else {
313
- transformed = seg[0].toUpperCase() + seg.slice(1);
314
- }
315
- }
316
-
317
- return transformed;
318
- });
319
-
320
-
321
- let result = camelCasedSegments.join("");
322
- result = result.replace(/[^A-Za-z0-9_$]/g, "");
323
-
324
- return result;
325
- }
326
-
327
-
328
- getModuleId(filePath, baseDir) {
329
-
330
- let relative = filePath.replace(baseDir, "").replace(/\\/g, "/");
331
- relative = relative.replace(/^\//, "");
332
- relative = relative.replace(/\.(mjs|cjs|js)$/, "");
333
-
334
- return relative;
335
- }
336
-
337
-
338
- shouldPreserveFunctionCase(name) {
339
- const preservePatterns = [
340
- /^[A-Z]{2,}$/,
341
- /[A-Z]{2,}/
342
- ];
343
-
344
- return preservePatterns.some((pattern) => pattern.test(name));
345
- }
346
- }
347
-
348
-
349
-
350
-
351
-
352
-
353
- export function sanitizePropertyName(input, options = {}) {
354
- const sanitizer = new Sanitize(null);
355
- return sanitizer.sanitizePropertyName(input, options);
356
- }
17
+ import{ComponentBase}from"@cldmv/slothlet/factories/component-base";class Sanitize extends ComponentBase{static slothletProperty="sanitize";#compileGlobPattern(pattern,caseSensitive=true){if(pattern.startsWith("**")&&pattern.endsWith("**")&&pattern.length>4){const innerString=pattern.slice(2,-2);const escapedString=innerString.replace(/[.+^${}()|[\]\\*?]/g,"\\$&");const flags2=caseSensitive?"":"i";return new RegExp(`(?<=.)${escapedString}(?=.)`,flags2)}const regexPattern=pattern.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");const flags=caseSensitive?"":"i";return new RegExp(`^${regexPattern}$`,flags)}#matchesAnyPattern(input,patterns,caseSensitive=false){for(const pattern of patterns){if(pattern.includes("*")||pattern.includes("?")){const regex=this.#compileGlobPattern(pattern,caseSensitive);if(regex&&regex.test(input))return true}else{const match=caseSensitive?input===pattern:input.toLowerCase()===pattern.toLowerCase();if(match)return true}}return false}#extractPatternLiterals(pattern){return pattern.split(/[*?]+/).filter(Boolean)}#applySegmentRules(segment,index,originalString,config){const{preserveAllUpper,preserveAllLower,leaveRules,leaveInsensitiveRules,upperRules,lowerRules}=config;if(this.#matchesAnyPattern(segment,leaveRules,true)){return segment}if(this.#matchesAnyPattern(segment,leaveInsensitiveRules,false)){return segment}if(preserveAllUpper&&segment===segment.toUpperCase()&&segment!==segment.toLowerCase()&&/[A-Z]/.test(segment)){return segment}if(preserveAllLower&&segment===segment.toLowerCase()&&segment!==segment.toUpperCase()&&/[a-z]/.test(segment)){return segment}for(const pattern of[...upperRules,...lowerRules]){if(pattern.includes("*")||pattern.includes("?")){const regex=this.#compileGlobPattern(pattern,false);if(regex&&regex.test(originalString)){const literals=this.#extractPatternLiterals(pattern);for(const literal of literals){const cleanLiteral=literal.replace(/[^A-Za-z0-9_$]/g,"").replace(/^_+|_+$/g,"");if(cleanLiteral&&segment.toLowerCase()===cleanLiteral.toLowerCase()){return upperRules.includes(pattern)?segment.toUpperCase():segment.toLowerCase()}}}}else{if(segment.toLowerCase()===pattern.toLowerCase()){return upperRules.includes(pattern)?segment.toUpperCase():segment.toLowerCase()}}}let transformed=this.#applyWithinSegmentPatterns(segment,upperRules,lowerRules);if(transformed!==segment){return transformed}return segment}#applyWithinSegmentPatterns(segment,upperRules,lowerRules){let result=segment;const applyBoundaryPattern=(pattern,toUpper)=>{if(pattern.startsWith("**")&&pattern.endsWith("**")&&pattern.length>4){const innerString=pattern.slice(2,-2);const innerRegex=new RegExp(innerString.replace(/[.+^${}()|[\]\\*?]/g,"\\$&"),"gi");const matches=[...result.matchAll(innerRegex)];for(const match of matches){const startPos=match.index;const endPos=startPos+match[0].length;const hasCharBefore=startPos>0;const hasCharAfter=endPos<result.length;if(hasCharBefore&&hasCharAfter){const replacement=toUpper?innerString.toUpperCase():innerString.toLowerCase();result=result.substring(0,startPos)+replacement+result.substring(endPos);break}}}else if(pattern.includes("*")&&!pattern.startsWith("**")){const literalParts=pattern.split("*").filter(Boolean);for(const literal of literalParts){const literalRegex=new RegExp(literal.replace(/[.+^${}()|[\]\\]/g,"\\$&"),"gi");const replacement=toUpper?literal.toUpperCase():literal.toLowerCase();result=result.replace(literalRegex,replacement)}}};upperRules.forEach(pattern=>applyBoundaryPattern(pattern,true));lowerRules.forEach(pattern=>applyBoundaryPattern(pattern,false));return result}sanitizePropertyName(input,options={}){const{lowerFirst=true,preserveAllUpper=false,preserveAllLower=false,rules={}}=options;const leaveRules=(rules.leave||[]).map(s=>String(s));const leaveInsensitiveRules=(rules.leaveInsensitive||[]).map(s=>String(s));const upperRules=(rules.upper||[]).map(s=>String(s));const lowerRules=(rules.lower||[]).map(s=>String(s));const originalString=String(input).trim();const isAllUpper=originalString===originalString.toUpperCase()&&originalString!==originalString.toLowerCase()&&/[A-Z]/.test(originalString);const isAllLower=originalString===originalString.toLowerCase()&&originalString!==originalString.toUpperCase()&&/[a-z]/.test(originalString);if(preserveAllUpper&&isAllUpper){return originalString}if(preserveAllLower&&isAllLower&&!/-/.test(originalString)){return originalString}let primarySegments=originalString.split(/[-]+|[^A-Za-z0-9_$]+/).filter(Boolean);if(primarySegments.length===0)return"_";while(primarySegments.length&&!/^[A-Za-z_$]/.test(primarySegments[0][0])){primarySegments[0]=primarySegments[0].replace(/^[^A-Za-z_$]+/,"");if(!primarySegments[0])primarySegments.shift()}if(primarySegments.length===0)return"_";const lowerRuleApplied=[];const processedPrimarySegments=primarySegments.map((primarySeg,primaryIdx)=>{const parts=primarySeg.split(/(_+)/);const processedParts=parts.map((part,partIdx)=>{if(partIdx%2===1)return part;if(!part)return part;const cleanSeg=part.replace(/[^A-Za-z0-9_$]/g,"");const config={preserveAllUpper,preserveAllLower,leaveRules,leaveInsensitiveRules,upperRules,lowerRules};const result2=this.#applySegmentRules(cleanSeg,0,originalString,config);const matchesLower=lowerRules.some(pattern=>{if(pattern.includes("*")||pattern.includes("?")){const regex=this.#compileGlobPattern(pattern,false);if(regex&&regex.test(originalString)){const literals=this.#extractPatternLiterals(pattern);for(const literal of literals){const cleanLiteral=literal.replace(/[^A-Za-z0-9_$]/g,"").replace(/^_+|_+$/g,"");if(cleanLiteral&&cleanSeg.toLowerCase()===cleanLiteral.toLowerCase()){return true}}}}else{if(cleanSeg.toLowerCase()===pattern.toLowerCase()){return true}}return false});if(matchesLower&&result2===cleanSeg.toLowerCase()){lowerRuleApplied[primaryIdx]=true}return result2});return processedParts.join("")});const camelCasedSegments=processedPrimarySegments.map((seg,idx)=>{const matchesLeave=this.#matchesAnyPattern(seg,leaveRules,true);const matchesLeaveInsensitive=this.#matchesAnyPattern(seg,leaveInsensitiveRules,false);const matchesUpper=this.#matchesAnyPattern(seg,upperRules,false);const hasUnderscores=seg.includes("_");const isAllUpper2=!hasUnderscores&&preserveAllUpper&&seg===seg.toUpperCase()&&seg!==seg.toLowerCase()&&/[A-Z]/.test(seg);const isAllLower2=!hasUnderscores&&preserveAllLower&&seg===seg.toLowerCase()&&seg!==seg.toUpperCase()&&/[a-z]/.test(seg);if(matchesLeave||matchesLeaveInsensitive||matchesUpper||isAllUpper2||isAllLower2){return seg}let transformed;if(idx===0){transformed=lowerFirst?seg[0].toLowerCase()+seg.slice(1):seg}else{if(lowerRuleApplied[idx]){transformed=seg}else{transformed=seg[0].toUpperCase()+seg.slice(1)}}return transformed});let result=camelCasedSegments.join("");result=result.replace(/[^A-Za-z0-9_$]/g,"");return result}getModuleId(filePath,baseDir){let relative=filePath.replace(baseDir,"").replace(/\\/g,"/");relative=relative.replace(/^\//,"");relative=relative.replace(/\.(mjs|cjs|js)$/,"");return relative}shouldPreserveFunctionCase(name){const preservePatterns=[/^[A-Z]{2,}$/,/[A-Z]{2,}/];return preservePatterns.some(pattern=>pattern.test(name))}}function sanitizePropertyName(input,options={}){const sanitizer=new Sanitize(null);return sanitizer.sanitizePropertyName(input,options)}export{Sanitize,sanitizePropertyName};
@@ -14,73 +14,4 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
-
18
-
19
-
20
-
21
- import { ComponentBase } from "@cldmv/slothlet/factories/component-base";
22
-
23
-
24
- export class Utilities extends ComponentBase {
25
- static slothletProperty = "utilities";
26
-
27
-
28
- isPlainObject(obj) {
29
- if (typeof obj !== "object" || obj === null) return false;
30
- const proto = Object.getPrototypeOf(obj);
31
- return proto === null || proto === Object.prototype;
32
- }
33
-
34
-
35
- deepMerge(target, source) {
36
- if (!this.isPlainObject(target) || !this.isPlainObject(source)) {
37
- return source;
38
- }
39
-
40
- const result = { ...target };
41
-
42
- for (const key in source) {
43
- if (Object.prototype.hasOwnProperty.call(source, key)) {
44
- if (this.isPlainObject(source[key])) {
45
-
46
-
47
- result[key] = this.deepMerge(this.isPlainObject(target[key]) ? target[key] : {}, source[key]);
48
- } else {
49
- result[key] = source[key];
50
- }
51
- }
52
- }
53
-
54
- return result;
55
- }
56
-
57
-
58
- deepClone(obj) {
59
- try {
60
- return structuredClone(obj);
61
- } catch {
62
-
63
-
64
- const objType = obj?.__type || typeof obj;
65
- if (obj === null || (objType !== "object" && objType !== "function")) return obj;
66
- if (obj instanceof Date) return new Date(obj.getTime());
67
- if (Array.isArray(obj)) return obj.map((item) => this.deepClone(item));
68
-
69
- const cloned = {};
70
- for (const key in obj) {
71
- try {
72
- cloned[key] = this.deepClone(obj[key]);
73
- } catch {
74
-
75
- cloned[key] = obj[key];
76
- }
77
- }
78
- return cloned;
79
- }
80
- }
81
-
82
-
83
- generateId() {
84
- return `slothlet_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
85
- }
86
- }
17
+ import{ComponentBase}from"@cldmv/slothlet/factories/component-base";class Utilities extends ComponentBase{static slothletProperty="utilities";isPlainObject(obj){if(typeof obj!=="object"||obj===null)return false;const proto=Object.getPrototypeOf(obj);return proto===null||proto===Object.prototype}deepMerge(target,source){if(!this.isPlainObject(target)||!this.isPlainObject(source)){return source}const result={...target};for(const key in source){if(Object.prototype.hasOwnProperty.call(source,key)){if(this.isPlainObject(source[key])){result[key]=this.deepMerge(this.isPlainObject(target[key])?target[key]:{},source[key])}else{result[key]=source[key]}}}return result}deepClone(obj){try{return structuredClone(obj)}catch{const objType=obj?.__type||typeof obj;if(obj===null||objType!=="object"&&objType!=="function")return obj;if(obj instanceof Date)return new Date(obj.getTime());if(Array.isArray(obj))return obj.map(item=>this.deepClone(item));const cloned={};for(const key in obj){try{cloned[key]=this.deepClone(obj[key])}catch{cloned[key]=obj[key]}}return cloned}}generateId(){return`slothlet_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}}export{Utilities};