@ztimson/utils 0.27.14 → 0.27.16

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/index.cjs CHANGED
@@ -1958,7 +1958,7 @@ ${opts.message || this.desc}`;
1958
1958
  Object.assign(this, PathEvent.pathEventCache.get(e));
1959
1959
  return;
1960
1960
  }
1961
- let [p, method] = e.replaceAll(/\/{2,}/g, "/").split(":");
1961
+ let [p, method] = e.replaceAll(/(^|\/)\*+\/?$/g, "").split(":");
1962
1962
  if (!method) method = "*";
1963
1963
  if (p === "" || p === void 0 || p === "*") {
1964
1964
  this.module = "";
@@ -1979,27 +1979,19 @@ ${opts.message || this.desc}`;
1979
1979
  this.methods = new ASet(method.split(""));
1980
1980
  PathEvent.pathEventCache.set(e, this);
1981
1981
  }
1982
- /** Clear the cache of all PathEvents */
1983
- static clearCache() {
1984
- PathEvent.pathEventCache.clear();
1985
- }
1986
- /** Clear the permission cache */
1987
- static clearPermissionCache() {
1988
- PathEvent.permissionCache.clear();
1989
- }
1990
1982
  /**
1991
- * Score a path for specificity ranking (lower = more specific = higher priority)
1983
+ * Check if a filter pattern matches a target path
1992
1984
  * @private
1993
1985
  */
1994
- static scoreSpecificity(path) {
1995
- if (path === "**" || path === "") return Number.MAX_SAFE_INTEGER;
1996
- const segments = path.split("/").filter((p) => !!p);
1997
- let score = -segments.length;
1998
- segments.forEach((seg) => {
1999
- if (seg === "**") score += 0.5;
2000
- else if (seg === "*") score += 0.25;
2001
- });
2002
- return score;
1986
+ static matches(pattern, target) {
1987
+ const methodsMatch = pattern.all || target.all || pattern.methods.intersection(target.methods).length > 0;
1988
+ if (!methodsMatch) return false;
1989
+ if (!pattern.hasGlob && !target.hasGlob) {
1990
+ const last = pattern.fullPath[target.fullPath.length];
1991
+ return pattern.fullPath.startsWith(target.fullPath) && (last == null || last == "/");
1992
+ }
1993
+ if (pattern.hasGlob) return this.pathMatchesGlob(target.fullPath, pattern.fullPath);
1994
+ return this.pathMatchesGlob(pattern.fullPath, target.fullPath);
2003
1995
  }
2004
1996
  /**
2005
1997
  * Check if a path matches a glob pattern
@@ -2014,14 +2006,9 @@ ${opts.message || this.desc}`;
2014
2006
  while (patternIdx < patternParts.length && pathIdx < pathParts.length) {
2015
2007
  const patternPart = patternParts[patternIdx];
2016
2008
  if (patternPart === "**") {
2017
- if (patternIdx === patternParts.length - 1) {
2018
- return true;
2019
- }
2020
- patternParts[patternIdx + 1];
2009
+ if (patternIdx === patternParts.length - 1) return true;
2021
2010
  while (pathIdx < pathParts.length) {
2022
- if (PathEvent.pathMatchesGlob(pathParts.slice(pathIdx).join("/"), patternParts.slice(patternIdx + 1).join("/"))) {
2023
- return true;
2024
- }
2011
+ if (PathEvent.pathMatchesGlob(pathParts.slice(pathIdx).join("/"), patternParts.slice(patternIdx + 1).join("/"))) return true;
2025
2012
  pathIdx++;
2026
2013
  }
2027
2014
  return false;
@@ -2029,18 +2016,36 @@ ${opts.message || this.desc}`;
2029
2016
  pathIdx++;
2030
2017
  patternIdx++;
2031
2018
  } else {
2032
- if (patternPart !== pathParts[pathIdx]) {
2033
- return false;
2034
- }
2019
+ if (patternPart !== pathParts[pathIdx]) return false;
2035
2020
  pathIdx++;
2036
2021
  patternIdx++;
2037
2022
  }
2038
2023
  }
2039
- if (patternIdx < patternParts.length) {
2040
- return patternParts.slice(patternIdx).every((p) => p === "**");
2041
- }
2024
+ if (patternIdx < patternParts.length) return patternParts.slice(patternIdx).every((p) => p === "**");
2042
2025
  return pathIdx === pathParts.length;
2043
2026
  }
2027
+ /**
2028
+ * Score a path for specificity ranking (lower = more specific = higher priority)
2029
+ * @private
2030
+ */
2031
+ static scoreSpecificity(path) {
2032
+ if (path === "**" || path === "") return Number.MAX_SAFE_INTEGER;
2033
+ const segments = path.split("/").filter((p) => !!p);
2034
+ let score = -segments.length;
2035
+ segments.forEach((seg) => {
2036
+ if (seg === "**") score += 0.5;
2037
+ else if (seg === "*") score += 0.25;
2038
+ });
2039
+ return score;
2040
+ }
2041
+ /** Clear the cache of all PathEvents */
2042
+ static clearCache() {
2043
+ PathEvent.pathEventCache.clear();
2044
+ }
2045
+ /** Clear the permission cache */
2046
+ static clearPermissionCache() {
2047
+ PathEvent.permissionCache.clear();
2048
+ }
2044
2049
  /**
2045
2050
  * Combine multiple events into one parsed object. Longest path takes precedent, but all subsequent methods are
2046
2051
  * combined until a "none" is reached
@@ -2061,9 +2066,7 @@ ${opts.message || this.desc}`;
2061
2066
  result = p;
2062
2067
  } else {
2063
2068
  if (result.fullPath.startsWith(p.fullPath)) {
2064
- if (p.none) {
2065
- break;
2066
- }
2069
+ if (p.none) break;
2067
2070
  result.methods = new ASet([...result.methods, ...p.methods]);
2068
2071
  }
2069
2072
  }
@@ -2082,24 +2085,6 @@ ${opts.message || this.desc}`;
2082
2085
  const parsedFilter = makeArray(filter).map((pe) => pe instanceof PathEvent ? pe : new PathEvent(pe));
2083
2086
  return parsedTarget.filter((t) => !!parsedFilter.find((r) => PathEvent.matches(r, t)));
2084
2087
  }
2085
- /**
2086
- * Check if a filter pattern matches a target path
2087
- * @private
2088
- */
2089
- static matches(pattern, target) {
2090
- if (pattern.fullPath === "" || target.fullPath === "") return false;
2091
- if (pattern.fullPath === "**") return pattern.methods.has("*") || pattern.methods.intersection(target.methods).length > 0;
2092
- if (target.fullPath === "**") return pattern.methods.has("*") || target.methods.has("*") || pattern.methods.intersection(target.methods).length > 0;
2093
- const methodsMatch = pattern.all || target.all || pattern.methods.intersection(target.methods).length > 0;
2094
- if (!methodsMatch) return false;
2095
- if (!pattern.hasGlob && !target.hasGlob) {
2096
- return pattern.fullPath === target.fullPath;
2097
- }
2098
- if (pattern.hasGlob) {
2099
- return this.pathMatchesGlob(target.fullPath, pattern.fullPath);
2100
- }
2101
- return this.pathMatchesGlob(pattern.fullPath, target.fullPath);
2102
- }
2103
2088
  /**
2104
2089
  * Squash 2 sets of paths & return true if any overlap is found
2105
2090
  *
@@ -2308,6 +2293,68 @@ ${opts.message || this.desc}`;
2308
2293
  }).length == and.length;
2309
2294
  });
2310
2295
  }
2296
+ class TemplateError extends BadRequestError {
2297
+ }
2298
+ async function renderTemplate(template, data, fetch2) {
2299
+ let content = template, found;
2300
+ const now = /* @__PURE__ */ new Date(), d = {
2301
+ date: {
2302
+ day: now.getDate(),
2303
+ month: now.toLocaleString("default", { month: "long" }),
2304
+ year: now.getFullYear(),
2305
+ time: now.toLocaleTimeString(),
2306
+ format: formatDate
2307
+ },
2308
+ ...data || {}
2309
+ };
2310
+ if (!fetch2) fetch2 = (file) => {
2311
+ throw new TemplateError(`Unable to fetch template: ${file}`);
2312
+ };
2313
+ const evaluate = (code, data2, fatal = true) => {
2314
+ try {
2315
+ return Function("data", `Object.assign(this, data); return ${code};`)(data2);
2316
+ } catch {
2317
+ if (fatal) throw new TemplateError(`Failed to evaluate: ${code}`);
2318
+ else return false;
2319
+ }
2320
+ };
2321
+ while (!!(found = /\{\{\s*?\?\s*?(.+?)\s*?}}([\s\S]*?)(?:\{\{\s*?!\?\s*?}}([\s\S]*?))?\{\{\s*?\/\?\s*?}}/g.exec(content))) {
2322
+ const nested = matchAll(found[0], /\{\{\s*?\?.+?}}/g).slice(-1)?.[0]?.index;
2323
+ if (nested != 0)
2324
+ found = /\{\{\s*?\?\s*?(.+?)\s*?}}([\s\S]*?)(?:\{\{\s*?!\?\s*?}}([\s\S]*?))?\{\{\s*?\/\?\s*?}}/g.exec(content.slice(found.index + nested));
2325
+ content = content.replaceAll(found[0], (evaluate(found[1], d, false) ? found[2] : found[3]) || "");
2326
+ }
2327
+ while (!!(found = /\{\{\s*?<\s*?(.+?)\s*?}}/g.exec(content))) {
2328
+ content = content.replaceAll(found[0], await renderTemplate(await fetch2(found[1].trim()), data, fetch2));
2329
+ }
2330
+ while (!!(found = /\{\{\s*?\*\s*?(.+?)\s+in\s+(.+?)\s*?}}([\s\S]*?)\{\{\s*?\/\*\s*?}}/g.exec(content))) {
2331
+ const split = found[1].replaceAll(/[()\s]/g, "").split(",");
2332
+ const element = split[0];
2333
+ const index = split[1] || "index";
2334
+ const array = dotNotation(data, found[2]);
2335
+ if (!array || typeof array != "object")
2336
+ throw new TemplateError(`Cannot iterate: ${found[2]}`);
2337
+ let compiled = [];
2338
+ for (let i = 0; i < array.length; i++) {
2339
+ compiled.push(renderTemplate(found[3], {
2340
+ ...d,
2341
+ [element]: array[i],
2342
+ [index]: i
2343
+ }, fetch2));
2344
+ }
2345
+ content = content.replaceAll(found[0], compiled.join("\n"));
2346
+ }
2347
+ while (!!(found = /\{\{\s*([^<>\*\?!/}\s][^}]*?)\s*}}/g.exec(content))) {
2348
+ content = content.replaceAll(found[0], evaluate(found[1].trim(), d) || "");
2349
+ }
2350
+ while (!!(found = /\{\{\s*?>\s*?(.+?):(.+?)\s*?}}([\s\S]*?)\{\{\s*?\/>\s*?}}/g.exec(content))) {
2351
+ content = content.replace(found[0], await renderTemplate(await fetch2(found[1].trim), {
2352
+ ...data,
2353
+ [found[2].trim()]: found[3]
2354
+ }, fetch2));
2355
+ }
2356
+ return content;
2357
+ }
2311
2358
  var dist = {};
2312
2359
  var persist = {};
2313
2360
  var hasRequiredPersist;
@@ -2531,6 +2578,7 @@ ${opts.message || this.desc}`;
2531
2578
  exports2.SYMBOL_LIST = SYMBOL_LIST;
2532
2579
  exports2.ServiceUnavailableError = ServiceUnavailableError;
2533
2580
  exports2.Table = Table;
2581
+ exports2.TemplateError = TemplateError;
2534
2582
  exports2.TypedEmitter = TypedEmitter;
2535
2583
  exports2.UnauthorizedError = UnauthorizedError;
2536
2584
  exports2.addUnique = addUnique;
@@ -2592,6 +2640,7 @@ ${opts.message || this.desc}`;
2592
2640
  exports2.randomHex = randomHex;
2593
2641
  exports2.randomString = randomString;
2594
2642
  exports2.randomStringBuilder = randomStringBuilder;
2643
+ exports2.renderTemplate = renderTemplate;
2595
2644
  exports2.reservedIp = reservedIp;
2596
2645
  exports2.search = search;
2597
2646
  exports2.sleep = sleep;