@scpxl/nodejs-framework 1.0.30 → 1.0.42

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 (56) hide show
  1. package/README.md +1 -0
  2. package/dist/application/base-application.d.ts +7 -7
  3. package/dist/application/base-application.d.ts.map +1 -1
  4. package/dist/application/base-application.interface.d.ts +1 -1
  5. package/dist/application/base-application.interface.d.ts.map +1 -1
  6. package/dist/application/base-application.js +122 -14
  7. package/dist/application/base-application.js.map +2 -2
  8. package/dist/application/web-application.d.ts.map +1 -1
  9. package/dist/application/web-application.js +2 -4
  10. package/dist/application/web-application.js.map +2 -2
  11. package/dist/cache/manager.d.ts +1 -0
  12. package/dist/cache/manager.d.ts.map +1 -1
  13. package/dist/cache/manager.js +11 -2
  14. package/dist/cache/manager.js.map +2 -2
  15. package/dist/cli/index.js +24 -10
  16. package/dist/cli/index.js.map +2 -2
  17. package/dist/config/schema.d.ts +2 -63
  18. package/dist/config/schema.d.ts.map +1 -1
  19. package/dist/config/schema.js +1 -7
  20. package/dist/config/schema.js.map +2 -2
  21. package/dist/event/manager.js +2 -2
  22. package/dist/event/manager.js.map +2 -2
  23. package/dist/logger/logger.js +0 -1
  24. package/dist/logger/logger.js.map +2 -2
  25. package/dist/queue/manager.d.ts.map +1 -1
  26. package/dist/queue/manager.js +19 -7
  27. package/dist/queue/manager.js.map +2 -2
  28. package/dist/redis/instance.d.ts.map +1 -1
  29. package/dist/redis/instance.js +9 -1
  30. package/dist/redis/instance.js.map +2 -2
  31. package/dist/redis/manager.d.ts.map +1 -1
  32. package/dist/redis/manager.js +26 -16
  33. package/dist/redis/manager.js.map +3 -3
  34. package/dist/webserver/controller/entity.js +1 -1
  35. package/dist/webserver/controller/entity.js.map +2 -2
  36. package/dist/webserver/controller/health.js.map +1 -1
  37. package/dist/webserver/util.d.ts +1 -1
  38. package/dist/webserver/util.d.ts.map +1 -1
  39. package/dist/webserver/util.js +5 -23
  40. package/dist/webserver/util.js.map +2 -2
  41. package/dist/webserver/webserver.d.ts +2 -13
  42. package/dist/webserver/webserver.d.ts.map +1 -1
  43. package/dist/webserver/webserver.interface.d.ts +1 -21
  44. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  45. package/dist/webserver/webserver.interface.js.map +1 -1
  46. package/dist/webserver/webserver.js +34 -36
  47. package/dist/webserver/webserver.js.map +2 -2
  48. package/dist/websocket/utils.d.ts.map +1 -1
  49. package/dist/websocket/utils.js +5 -1
  50. package/dist/websocket/utils.js.map +2 -2
  51. package/dist/websocket/websocket-base.d.ts.map +1 -1
  52. package/dist/websocket/websocket-base.js +9 -1
  53. package/dist/websocket/websocket-base.js.map +2 -2
  54. package/dist/websocket/websocket-server.d.ts.map +1 -1
  55. package/dist/websocket/websocket-server.js.map +2 -2
  56. package/package.json +5 -6
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/cache/manager.ts"],
4
- "sourcesContent": ["import type RedisManager from '../redis/manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport { safeSerializeError } from '../error/error-reporter.js';\n\n/**\n * CacheManager\n *\n * Thin abstraction over Redis for basic JSON value caching. Unifies all Redis\n * access through the framework RedisManager / RedisInstance (ioredis) so we\n * avoid maintaining a second client implementation (node-redis).\n *\n * Lazy acquisition: the first call to any cache method will either reuse an\n * existing connected RedisInstance (if already established by application\n * startup) or trigger a connection via RedisManager.\n *\n * **Important:** All values are stored as JSON strings. Only JSON-serializable\n * values are supported. Complex types like Date, Map, Set, RegExp, etc. will\n * lose their type information during serialization:\n * - `Date` objects \u2192 ISO strings\n * - `Map` / `Set` \u2192 empty objects `{}`\n * - `undefined` \u2192 omitted from objects, `null` in arrays\n * - Functions \u2192 omitted\n *\n * @example\n * ```typescript\n * // Supported types\n * await cache.setItem({ key: 'user', value: { id: 1, name: 'John' } }); // \u2713\n * await cache.setItem({ key: 'count', value: 42 }); // \u2713\n * await cache.setItem({ key: 'tags', value: ['a', 'b', 'c'] }); // \u2713\n *\n * // Unsupported types (will lose type information)\n * await cache.setItem({ key: 'date', value: new Date() }); // \u2192 ISO string\n * await cache.setItem({ key: 'map', value: new Map() }); // \u2192 {}\n * ```\n */\n\nexport interface CacheManagerProps {\n /** Redis manager (shared across the application) */\n redisManager: RedisManager;\n}\n\nexport default class CacheManager {\n private redisManager: RedisManager;\n private redisInstance?: RedisInstance;\n\n constructor({ redisManager }: CacheManagerProps) {\n this.redisManager = redisManager;\n }\n\n /**\n * Ensure we have a connected RedisInstance. Reuses the first existing\n * instance if already connected by the application bootstrap.\n */\n private async getRedisInstance(): Promise<RedisInstance> {\n if (this.redisInstance) return this.redisInstance;\n\n if (this.redisManager.instances.length > 0) {\n this.redisInstance = this.redisManager.instances[0];\n return this.redisInstance;\n }\n\n // Lazily connect if no instances yet (e.g., used before app onBeforeStart)\n this.redisInstance = await this.redisManager.connect();\n return this.redisInstance;\n }\n\n /**\n * Get a cached JSON value (deserialized) or null if not present.\n *\n * @param key - Cache key\n * @returns Deserialized value or null if not found\n * @throws {Error} If the cached value is not valid JSON\n *\n * @example\n * ```typescript\n * const user = await cache.getItem<{ id: number; name: string }>({ key: 'user:123' });\n * if (user) {\n * console.log(user.name);\n * }\n * ```\n */\n public async getItem<T>({ key }: { key: string }): Promise<T | null> {\n const instance = await this.getRedisInstance();\n const raw = await instance.getCache({ key });\n if (raw === null) return null;\n\n // Validate that we received a string (Redis should always return string or null)\n if (typeof raw !== 'string') {\n throw new Error(`Cache value for key \"${key}\" must be a string, got ${typeof raw}`);\n }\n\n try {\n return JSON.parse(raw) as T;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : safeSerializeError(error);\n throw new Error(`Failed to parse cached value for key \"${key}\": ${errorMessage}`);\n }\n }\n\n /**\n * Set a JSON-serializable value. Optionally specify lifetime (seconds).\n *\n * @param key - Cache key\n * @param value - Value to cache (must be JSON-serializable)\n * @param lifetime - Optional expiration in seconds\n *\n * @example\n * ```typescript\n * // Cache with no expiration\n * await cache.setItem({ key: 'config', value: { theme: 'dark' } });\n *\n * // Cache with 1 hour expiration\n * await cache.setItem({\n * key: 'session:abc',\n * value: { userId: 123 },\n * lifetime: 3600\n * });\n * ```\n */\n public async setItem<T>({ key, value, lifetime }: { key: string; value: T; lifetime?: number }): Promise<void> {\n const instance = await this.getRedisInstance();\n await instance.setCache({ key, value, expiration: lifetime });\n }\n\n /**\n * Delete a cached value.\n *\n * @param key - Cache key to delete\n *\n * @example\n * ```typescript\n * await cache.clearItem({ key: 'session:abc' });\n * ```\n */\n public async clearItem({ key }: { key: string }): Promise<void> {\n const instance = await this.getRedisInstance();\n await instance.deleteCache({ key });\n }\n\n /**\n * No-op: lifecycle handles Redis disconnection globally.\n */\n public async close(): Promise<void> {\n // Intentionally empty; RedisManager handles disconnect.\n }\n}\n"],
5
- "mappings": ";;AAEA,SAAS,0BAA0B;AAuCnC,MAAO,aAA2B;AAAA,EAzClC,OAyCkC;AAAA;AAAA;AAAA,EACxB;AAAA,EACA;AAAA,EAER,YAAY,EAAE,aAAa,GAAsB;AAC/C,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,mBAA2C;AACvD,QAAI,KAAK,cAAe,QAAO,KAAK;AAEpC,QAAI,KAAK,aAAa,UAAU,SAAS,GAAG;AAC1C,WAAK,gBAAgB,KAAK,aAAa,UAAU,CAAC;AAClD,aAAO,KAAK;AAAA,IACd;AAGA,SAAK,gBAAgB,MAAM,KAAK,aAAa,QAAQ;AACrD,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAa,QAAW,EAAE,IAAI,GAAuC;AACnE,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,MAAM,MAAM,SAAS,SAAS,EAAE,IAAI,CAAC;AAC3C,QAAI,QAAQ,KAAM,QAAO;AAGzB,QAAI,OAAO,QAAQ,UAAU;AAC3B,YAAM,IAAI,MAAM,wBAAwB,GAAG,2BAA2B,OAAO,GAAG,EAAE;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,mBAAmB,KAAK;AACtF,YAAM,IAAI,MAAM,yCAAyC,GAAG,MAAM,YAAY,EAAE;AAAA,IAClF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAa,QAAW,EAAE,KAAK,OAAO,SAAS,GAAgE;AAC7G,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,SAAS,SAAS,EAAE,KAAK,OAAO,YAAY,SAAS,CAAC;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAa,UAAU,EAAE,IAAI,GAAmC;AAC9D,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,SAAS,YAAY,EAAE,IAAI,CAAC;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAuB;AAAA,EAEpC;AACF;",
4
+ "sourcesContent": ["import type RedisManager from '../redis/manager.js';\nimport type RedisInstance from '../redis/instance.js';\nimport { safeSerializeError } from '../error/error-reporter.js';\n\n/**\n * CacheManager\n *\n * Thin abstraction over Redis for basic JSON value caching. Unifies all Redis\n * access through the framework RedisManager / RedisInstance (ioredis) so we\n * avoid maintaining a second client implementation (node-redis).\n *\n * Lazy acquisition: the first call to any cache method will either reuse an\n * existing connected RedisInstance (if already established by application\n * startup) or trigger a connection via RedisManager.\n *\n * **Important:** All values are stored as JSON strings. Only JSON-serializable\n * values are supported. Complex types like Date, Map, Set, RegExp, etc. will\n * lose their type information during serialization:\n * - `Date` objects \u2192 ISO strings\n * - `Map` / `Set` \u2192 empty objects `{}`\n * - `undefined` \u2192 omitted from objects, `null` in arrays\n * - Functions \u2192 omitted\n *\n * @example\n * ```typescript\n * // Supported types\n * await cache.setItem({ key: 'user', value: { id: 1, name: 'John' } }); // \u2713\n * await cache.setItem({ key: 'count', value: 42 }); // \u2713\n * await cache.setItem({ key: 'tags', value: ['a', 'b', 'c'] }); // \u2713\n *\n * // Unsupported types (will lose type information)\n * await cache.setItem({ key: 'date', value: new Date() }); // \u2192 ISO string\n * await cache.setItem({ key: 'map', value: new Map() }); // \u2192 {}\n * ```\n */\n\nexport interface CacheManagerProps {\n /** Redis manager (shared across the application) */\n redisManager: RedisManager;\n}\n\nexport default class CacheManager {\n private redisManager: RedisManager;\n private redisInstance?: RedisInstance;\n private redisInstancePromise?: Promise<RedisInstance>;\n\n constructor({ redisManager }: CacheManagerProps) {\n this.redisManager = redisManager;\n }\n\n /**\n * Ensure we have a connected RedisInstance. Reuses the first existing\n * instance if already connected by the application bootstrap.\n */\n private async getRedisInstance(): Promise<RedisInstance> {\n if (this.redisInstance) return this.redisInstance;\n if (this.redisInstancePromise) return this.redisInstancePromise;\n\n if (this.redisManager.instances.length > 0) {\n this.redisInstance = this.redisManager.instances[0];\n return this.redisInstance;\n }\n\n // Lazily connect if no instances yet (e.g., used before app onBeforeStart)\n this.redisInstancePromise = this.redisManager\n .connect()\n .then(instance => {\n this.redisInstance = instance;\n this.redisInstancePromise = undefined;\n return instance;\n })\n .catch(error => {\n this.redisInstancePromise = undefined;\n throw error;\n });\n\n return this.redisInstancePromise;\n }\n\n /**\n * Get a cached JSON value (deserialized) or null if not present.\n *\n * @param key - Cache key\n * @returns Deserialized value or null if not found\n * @throws {Error} If the cached value is not valid JSON\n *\n * @example\n * ```typescript\n * const user = await cache.getItem<{ id: number; name: string }>({ key: 'user:123' });\n * if (user) {\n * console.log(user.name);\n * }\n * ```\n */\n public async getItem<T>({ key }: { key: string }): Promise<T | null> {\n const instance = await this.getRedisInstance();\n const raw = await instance.getCache({ key });\n if (raw === null) return null;\n\n // Validate that we received a string (Redis should always return string or null)\n if (typeof raw !== 'string') {\n throw new Error(`Cache value for key \"${key}\" must be a string, got ${typeof raw}`);\n }\n\n try {\n return JSON.parse(raw) as T;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : safeSerializeError(error);\n throw new Error(`Failed to parse cached value for key \"${key}\": ${errorMessage}`);\n }\n }\n\n /**\n * Set a JSON-serializable value. Optionally specify lifetime (seconds).\n *\n * @param key - Cache key\n * @param value - Value to cache (must be JSON-serializable)\n * @param lifetime - Optional expiration in seconds\n *\n * @example\n * ```typescript\n * // Cache with no expiration\n * await cache.setItem({ key: 'config', value: { theme: 'dark' } });\n *\n * // Cache with 1 hour expiration\n * await cache.setItem({\n * key: 'session:abc',\n * value: { userId: 123 },\n * lifetime: 3600\n * });\n * ```\n */\n public async setItem<T>({ key, value, lifetime }: { key: string; value: T; lifetime?: number }): Promise<void> {\n const instance = await this.getRedisInstance();\n await instance.setCache({ key, value, expiration: lifetime });\n }\n\n /**\n * Delete a cached value.\n *\n * @param key - Cache key to delete\n *\n * @example\n * ```typescript\n * await cache.clearItem({ key: 'session:abc' });\n * ```\n */\n public async clearItem({ key }: { key: string }): Promise<void> {\n const instance = await this.getRedisInstance();\n await instance.deleteCache({ key });\n }\n\n /**\n * No-op: lifecycle handles Redis disconnection globally.\n */\n public async close(): Promise<void> {\n // Intentionally empty; RedisManager handles disconnect.\n }\n}\n"],
5
+ "mappings": ";;AAEA,SAAS,0BAA0B;AAuCnC,MAAO,aAA2B;AAAA,EAzClC,OAyCkC;AAAA;AAAA;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,EAAE,aAAa,GAAsB;AAC/C,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,mBAA2C;AACvD,QAAI,KAAK,cAAe,QAAO,KAAK;AACpC,QAAI,KAAK,qBAAsB,QAAO,KAAK;AAE3C,QAAI,KAAK,aAAa,UAAU,SAAS,GAAG;AAC1C,WAAK,gBAAgB,KAAK,aAAa,UAAU,CAAC;AAClD,aAAO,KAAK;AAAA,IACd;AAGA,SAAK,uBAAuB,KAAK,aAC9B,QAAQ,EACR,KAAK,cAAY;AAChB,WAAK,gBAAgB;AACrB,WAAK,uBAAuB;AAC5B,aAAO;AAAA,IACT,CAAC,EACA,MAAM,WAAS;AACd,WAAK,uBAAuB;AAC5B,YAAM;AAAA,IACR,CAAC;AAEH,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAa,QAAW,EAAE,IAAI,GAAuC;AACnE,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,MAAM,MAAM,SAAS,SAAS,EAAE,IAAI,CAAC;AAC3C,QAAI,QAAQ,KAAM,QAAO;AAGzB,QAAI,OAAO,QAAQ,UAAU;AAC3B,YAAM,IAAI,MAAM,wBAAwB,GAAG,2BAA2B,OAAO,GAAG,EAAE;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,KAAK,MAAM,GAAG;AAAA,IACvB,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,mBAAmB,KAAK;AACtF,YAAM,IAAI,MAAM,yCAAyC,GAAG,MAAM,YAAY,EAAE;AAAA,IAClF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAa,QAAW,EAAE,KAAK,OAAO,SAAS,GAAgE;AAC7G,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,SAAS,SAAS,EAAE,KAAK,OAAO,YAAY,SAAS,CAAC;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAa,UAAU,EAAE,IAAI,GAAmC;AAC9D,UAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,UAAM,SAAS,YAAY,EAAE,IAAI,CAAC;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAuB;AAAA,EAEpC;AACF;",
6
6
  "names": []
7
7
  }
package/dist/cli/index.js CHANGED
@@ -448,8 +448,11 @@ var unescape;
448
448
  var init_unescape = __esm({
449
449
  "node_modules/glob/node_modules/minimatch/dist/esm/unescape.js"() {
450
450
  "use strict";
451
- unescape = /* @__PURE__ */ __name((s, { windowsPathsNoEscape = false } = {}) => {
452
- return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
451
+ unescape = /* @__PURE__ */ __name((s, { windowsPathsNoEscape = false, magicalBraces = true } = {}) => {
452
+ if (magicalBraces) {
453
+ return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
454
+ }
455
+ return windowsPathsNoEscape ? s.replace(/\[([^\/\\{}])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\{}])\]/g, "$1$2").replace(/\\([^\/{}])/g, "$1");
453
456
  }, "unescape");
454
457
  }
455
458
  });
@@ -814,7 +817,7 @@ var init_ast = __esm({
814
817
  if (this.#root === this)
815
818
  this.#fillNegs();
816
819
  if (!this.type) {
817
- const noEmpty = this.isStart() && this.isEnd();
820
+ const noEmpty = this.isStart() && this.isEnd() && !this.#parts.some((s) => typeof s !== "string");
818
821
  const src = this.#parts.map((p) => {
819
822
  const [re, _, hasMagic2, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
820
823
  this.#hasMagic = this.#hasMagic || hasMagic2;
@@ -924,10 +927,7 @@ var init_ast = __esm({
924
927
  }
925
928
  }
926
929
  if (c === "*") {
927
- if (noEmpty && glob2 === "*")
928
- re += starNoEmpty;
929
- else
930
- re += star;
930
+ re += noEmpty && glob2 === "*" ? starNoEmpty : star;
931
931
  hasMagic2 = true;
932
932
  continue;
933
933
  }
@@ -949,7 +949,10 @@ var escape;
949
949
  var init_escape = __esm({
950
950
  "node_modules/glob/node_modules/minimatch/dist/esm/escape.js"() {
951
951
  "use strict";
952
- escape = /* @__PURE__ */ __name((s, { windowsPathsNoEscape = false } = {}) => {
952
+ escape = /* @__PURE__ */ __name((s, { windowsPathsNoEscape = false, magicalBraces = false } = {}) => {
953
+ if (magicalBraces) {
954
+ return windowsPathsNoEscape ? s.replace(/[?*()[\]{}]/g, "[$&]") : s.replace(/[?*()[\]\\{}]/g, "\\$&");
955
+ }
953
956
  return windowsPathsNoEscape ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&");
954
957
  }, "escape");
955
958
  }
@@ -1613,16 +1616,27 @@ var init_esm3 = __esm({
1613
1616
  pp[i] = twoStar;
1614
1617
  }
1615
1618
  } else if (next === void 0) {
1616
- pp[i - 1] = prev + "(?:\\/|" + twoStar + ")?";
1619
+ pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + ")?";
1617
1620
  } else if (next !== GLOBSTAR) {
1618
1621
  pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next;
1619
1622
  pp[i + 1] = GLOBSTAR;
1620
1623
  }
1621
1624
  });
1622
- return pp.filter((p) => p !== GLOBSTAR).join("/");
1625
+ const filtered = pp.filter((p) => p !== GLOBSTAR);
1626
+ if (this.partial && filtered.length >= 1) {
1627
+ const prefixes = [];
1628
+ for (let i = 1; i <= filtered.length; i++) {
1629
+ prefixes.push(filtered.slice(0, i).join("/"));
1630
+ }
1631
+ return "(?:" + prefixes.join("|") + ")";
1632
+ }
1633
+ return filtered.join("/");
1623
1634
  }).join("|");
1624
1635
  const [open, close] = set.length > 1 ? ["(?:", ")"] : ["", ""];
1625
1636
  re = "^" + open + re + close + "$";
1637
+ if (this.partial) {
1638
+ re = "^(?:\\/|" + open + re.slice(1, -1) + close + ")$";
1639
+ }
1626
1640
  if (this.negate)
1627
1641
  re = "^(?!" + re + ").+$";
1628
1642
  try {