@forinda/kickjs 5.7.1 → 5.8.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.
Files changed (131) hide show
  1. package/dist/{adapter-CoJp35rz.d.mts → adapter-RzfEzd-c.d.mts} +46 -11
  2. package/dist/adapter-RzfEzd-c.d.mts.map +1 -0
  3. package/dist/app-module-BE7hAASB.d.mts.map +1 -1
  4. package/dist/{application-DmekGKp7.d.mts → application-CwLcDTyg.d.mts} +3 -3
  5. package/dist/application-CwLcDTyg.d.mts.map +1 -0
  6. package/dist/application-h14rczhJ.mjs +12 -0
  7. package/dist/application-h14rczhJ.mjs.map +1 -0
  8. package/dist/{bootstrap-CwP2GGu0.d.mts → bootstrap-B8y526yc.d.mts} +2 -2
  9. package/dist/bootstrap-B8y526yc.d.mts.map +1 -0
  10. package/dist/{bootstrap-Dqyit14A.mjs → bootstrap-V0q7pgA4.mjs} +3 -3
  11. package/dist/{bootstrap-Dqyit14A.mjs.map → bootstrap-V0q7pgA4.mjs.map} +1 -1
  12. package/dist/cache-XrNWj1KQ.d.mts.map +1 -1
  13. package/dist/config/index.mjs +2 -2
  14. package/dist/{config-DsD1NCSn.mjs → config-C_oycBvB.mjs} +3 -3
  15. package/dist/{config-DsD1NCSn.mjs.map → config-C_oycBvB.mjs.map} +1 -1
  16. package/dist/container-BZKeHc5X.d.mts.map +1 -1
  17. package/dist/{container-jPCvIZH2.mjs → container-BvRsVif5.mjs} +3 -3
  18. package/dist/{container-jPCvIZH2.mjs.map → container-BvRsVif5.mjs.map} +1 -1
  19. package/dist/context-ByhFuf19.mjs +12 -0
  20. package/dist/context-ByhFuf19.mjs.map +1 -0
  21. package/dist/context-aocg9gO-.d.mts.map +1 -1
  22. package/dist/context-decorator-BYf8HdMl.d.mts.map +1 -1
  23. package/dist/core/adapter.d.mts +2 -2
  24. package/dist/core/adapter.mjs +1 -1
  25. package/dist/core/app-module.mjs +1 -1
  26. package/dist/core/cache.mjs +1 -1
  27. package/dist/core/cache.mjs.map +1 -1
  28. package/dist/core/container.mjs +2 -2
  29. package/dist/core/cron.mjs +2 -2
  30. package/dist/core/cron.mjs.map +1 -1
  31. package/dist/core/decorators.mjs +2 -2
  32. package/dist/core/decorators.mjs.map +1 -1
  33. package/dist/core/errors.mjs +2 -2
  34. package/dist/core/errors.mjs.map +1 -1
  35. package/dist/core/interfaces.mjs +1 -1
  36. package/dist/core/interfaces.mjs.map +1 -1
  37. package/dist/core/logger.mjs +1 -1
  38. package/dist/core/logger.mjs.map +1 -1
  39. package/dist/core/path.mjs +1 -1
  40. package/dist/core/path.mjs.map +1 -1
  41. package/dist/core/plugin.d.mts +1 -1
  42. package/dist/core/plugin.mjs +1 -1
  43. package/dist/core/reactivity.mjs +1 -1
  44. package/dist/core/reactivity.mjs.map +1 -1
  45. package/dist/{core-DR36jGxB.mjs → core-BQHQsimv.mjs} +3 -3
  46. package/dist/{core-DR36jGxB.mjs.map → core-BQHQsimv.mjs.map} +1 -1
  47. package/dist/cors-BfgqfLPd.d.mts.map +1 -1
  48. package/dist/cron-GNoYydfg.d.mts.map +1 -1
  49. package/dist/csrf-DiK9zept.d.mts.map +1 -1
  50. package/dist/decorators-BYi8lB37.d.mts.map +1 -1
  51. package/dist/{env-CDmi8uj3.mjs → env-D3Q6sGZP.mjs} +3 -3
  52. package/dist/{env-CDmi8uj3.mjs.map → env-D3Q6sGZP.mjs.map} +1 -1
  53. package/dist/errors-uaHCeXRz.d.mts.map +1 -1
  54. package/dist/execution-context-DKnt61pY.d.mts.map +1 -1
  55. package/dist/helmet-CaMbjzBG.d.mts.map +1 -1
  56. package/dist/http/application.d.mts +1 -1
  57. package/dist/http/application.mjs +2 -2
  58. package/dist/http/bootstrap.d.mts +1 -1
  59. package/dist/http/bootstrap.mjs +2 -2
  60. package/dist/http/context.mjs +2 -2
  61. package/dist/http/middleware/cors.mjs +1 -1
  62. package/dist/http/middleware/cors.mjs.map +1 -1
  63. package/dist/http/middleware/csrf.mjs +1 -1
  64. package/dist/http/middleware/csrf.mjs.map +1 -1
  65. package/dist/http/middleware/error-handler.mjs +2 -2
  66. package/dist/http/middleware/error-handler.mjs.map +1 -1
  67. package/dist/http/middleware/helmet.mjs +1 -1
  68. package/dist/http/middleware/helmet.mjs.map +1 -1
  69. package/dist/http/middleware/rate-limit.mjs +2 -2
  70. package/dist/http/middleware/rate-limit.mjs.map +1 -1
  71. package/dist/http/middleware/request-id.mjs +1 -1
  72. package/dist/http/middleware/request-id.mjs.map +1 -1
  73. package/dist/http/middleware/request-logger.mjs +2 -2
  74. package/dist/http/middleware/request-logger.mjs.map +1 -1
  75. package/dist/http/middleware/session.mjs +1 -1
  76. package/dist/http/middleware/session.mjs.map +1 -1
  77. package/dist/http/middleware/spa.d.mts +1 -1
  78. package/dist/http/middleware/spa.mjs +2 -2
  79. package/dist/http/middleware/spa.mjs.map +1 -1
  80. package/dist/http/middleware/upload.mjs +1 -1
  81. package/dist/http/middleware/upload.mjs.map +1 -1
  82. package/dist/http/middleware/validate.mjs +2 -2
  83. package/dist/http/middleware/validate.mjs.map +1 -1
  84. package/dist/http/middleware/views.d.mts +1 -1
  85. package/dist/http/middleware/views.mjs +2 -2
  86. package/dist/http/middleware/views.mjs.map +1 -1
  87. package/dist/http/query/index.mjs +2 -2
  88. package/dist/http/router-builder.d.mts +1 -1
  89. package/dist/http/router-builder.mjs +2 -2
  90. package/dist/http/router-builder.mjs.map +1 -1
  91. package/dist/index-B9cyOQAe.d.mts.map +1 -1
  92. package/dist/{index-CkKLXZHg.d.mts → index-C5aLtJkk.d.mts} +3 -3
  93. package/dist/index-C5aLtJkk.d.mts.map +1 -0
  94. package/dist/index-DM1PteZT.d.mts.map +1 -1
  95. package/dist/index.d.mts +9 -9
  96. package/dist/index.mjs +2 -2
  97. package/dist/index.mjs.map +1 -1
  98. package/dist/interfaces-B50n7dwl.d.mts.map +1 -1
  99. package/dist/logger-CLVRZf2N.d.mts.map +1 -1
  100. package/dist/{metadata-Chvfoj23.mjs → metadata-DN0sBHmY.mjs} +2 -2
  101. package/dist/{metadata-Chvfoj23.mjs.map → metadata-DN0sBHmY.mjs.map} +1 -1
  102. package/dist/path-Diviu6hv.d.mts.map +1 -1
  103. package/dist/{plugin-NMHVmDRF.d.mts → plugin-BGK3PJOJ.d.mts} +2 -2
  104. package/dist/plugin-BGK3PJOJ.d.mts.map +1 -0
  105. package/dist/{query-CtctnbW6.mjs → query-BuX74AmB.mjs} +2 -2
  106. package/dist/{query-CtctnbW6.mjs.map → query-BuX74AmB.mjs.map} +1 -1
  107. package/dist/reactivity-CfJceo4H.d.mts.map +1 -1
  108. package/dist/request-id-BgglvZHN.d.mts.map +1 -1
  109. package/dist/request-logger-CWHbAzTE.d.mts.map +1 -1
  110. package/dist/{router-builder-BfCCeQB-.d.mts → router-builder-QNfwAjQ8.d.mts} +2 -2
  111. package/dist/router-builder-QNfwAjQ8.d.mts.map +1 -0
  112. package/dist/session-N0hActOO.d.mts.map +1 -1
  113. package/dist/{spa-DIXtRBj-.d.mts → spa-BlW5xxU5.d.mts} +2 -2
  114. package/dist/spa-BlW5xxU5.d.mts.map +1 -0
  115. package/dist/upload-5goxbO9A.d.mts.map +1 -1
  116. package/dist/validate-HwAyWTwH.d.mts.map +1 -1
  117. package/dist/{views-DDT9vghc.d.mts → views-CNCTSpcw.d.mts} +2 -2
  118. package/dist/views-CNCTSpcw.d.mts.map +1 -0
  119. package/package.json +4 -4
  120. package/dist/adapter-CoJp35rz.d.mts.map +0 -1
  121. package/dist/application-DbUe_4St.mjs +0 -12
  122. package/dist/application-DbUe_4St.mjs.map +0 -1
  123. package/dist/application-DmekGKp7.d.mts.map +0 -1
  124. package/dist/bootstrap-CwP2GGu0.d.mts.map +0 -1
  125. package/dist/context-CPW8cxav.mjs +0 -12
  126. package/dist/context-CPW8cxav.mjs.map +0 -1
  127. package/dist/index-CkKLXZHg.d.mts.map +0 -1
  128. package/dist/plugin-NMHVmDRF.d.mts.map +0 -1
  129. package/dist/router-builder-BfCCeQB-.d.mts.map +0 -1
  130. package/dist/spa-DIXtRBj-.d.mts.map +0 -1
  131. package/dist/views-DDT9vghc.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cache.mjs","names":[],"sources":["../../src/core/cache.ts"],"sourcesContent":["import 'reflect-metadata'\n\n// String metadata key (post-Symbol migration). Slash-delimited\n// `kick/cacheable` so it can't collide with adopter metadata keys.\nconst CACHEABLE_META = 'kick/cacheable'\n\n// ── CacheProvider Interface ─────────────────────────────────────────────\n\n/**\n * Abstract cache backend. Implement this interface to use Redis, Memcached,\n * or any other cache store with @Cacheable and @CacheEvict.\n *\n * @example\n * ```ts\n * class RedisCacheProvider implements CacheProvider {\n * private client: RedisClient\n * constructor(client: RedisClient) { this.client = client }\n * async get(key: string) {\n * const val = await this.client.get(key)\n * return val ? JSON.parse(val) : null\n * }\n * async set(key: string, value: any, ttlMs: number) {\n * await this.client.set(key, JSON.stringify(value), 'PX', ttlMs)\n * }\n * async del(key: string) { await this.client.del(key) }\n * async delByPrefix(prefix: string) {\n * const keys = await this.client.keys(prefix + '*')\n * if (keys.length) await this.client.del(...keys)\n * }\n * }\n * ```\n */\nexport interface CacheProvider {\n /** Retrieve a cached value. Return null if not found or expired. */\n get(key: string): Promise<any | null>\n /** Store a value with a TTL in milliseconds. */\n set(key: string, value: any, ttlMs: number): Promise<void>\n /** Delete a specific cache key. */\n del(key: string): Promise<void>\n /** Delete all keys matching a prefix. Used by @CacheEvict. */\n delByPrefix?(prefix: string): Promise<void>\n /** Optional cleanup on shutdown. */\n shutdown?(): Promise<void>\n}\n\n// ── Built-in Memory Provider ────────────────────────────────────────────\n\n/**\n * Default in-memory cache provider using a Map.\n * Suitable for development and single-instance deployments.\n * For multi-instance or production, use a Redis-backed provider.\n */\nexport class MemoryCacheProvider implements CacheProvider {\n private store = new Map<string, { data: any; expiresAt: number }>()\n\n async get(key: string): Promise<any | null> {\n const entry = this.store.get(key)\n if (!entry) return null\n if (entry.expiresAt <= Date.now()) {\n this.store.delete(key)\n return null\n }\n return entry.data\n }\n\n async set(key: string, value: any, ttlMs: number): Promise<void> {\n this.store.set(key, { data: value, expiresAt: Date.now() + ttlMs })\n }\n\n async del(key: string): Promise<void> {\n this.store.delete(key)\n }\n\n async delByPrefix(prefix: string): Promise<void> {\n for (const key of this.store.keys()) {\n if (key.startsWith(prefix)) {\n this.store.delete(key)\n }\n }\n }\n\n async shutdown(): Promise<void> {\n this.store.clear()\n }\n}\n\n// ── Global Cache Registry ───────────────────────────────────────────────\n\nlet _cacheProvider: CacheProvider = new MemoryCacheProvider()\n\n/**\n * Set the global cache provider used by @Cacheable and @CacheEvict.\n * Call this before bootstrapping your app.\n *\n * @example\n * ```ts\n * import { setCacheProvider } from '@forinda/kickjs'\n * import { RedisCacheProvider } from './redis-cache'\n *\n * setCacheProvider(new RedisCacheProvider(redisClient))\n * ```\n */\nexport function setCacheProvider(provider: CacheProvider): void {\n _cacheProvider = provider\n}\n\n/** Get the current cache provider */\nexport function getCacheProvider(): CacheProvider {\n return _cacheProvider\n}\n\n// ── Cache Options ───────────────────────────────────────────────────────\n\nexport interface CacheOptions {\n /** Time-to-live in seconds (default: 60) */\n ttl?: number\n /** Cache key prefix (default: ClassName.methodName) */\n key?: string\n}\n\n// ── @Cacheable Decorator ────────────────────────────────────────────────\n\n/**\n * Cache the return value of a method for the specified TTL.\n * Uses the globally registered CacheProvider (default: MemoryCacheProvider).\n *\n * Call `setCacheProvider()` to use Redis or any custom backend.\n *\n * @param ttl - Time-to-live in seconds (default: 60)\n * @param options.key - Custom cache key prefix\n */\nexport function Cacheable(ttl?: number, options?: { key?: string }): MethodDecorator {\n return (_target, propertyKey, descriptor: PropertyDescriptor) => {\n const original = descriptor.value\n const cacheTtl = (ttl ?? 60) * 1000\n const keyPrefix = options?.key ?? String(propertyKey)\n\n descriptor.value = async function (...args: any[]) {\n const cacheKey = `${keyPrefix}:${JSON.stringify(args)}`\n const provider = getCacheProvider()\n\n const cached = await provider.get(cacheKey)\n if (cached !== null) {\n return cached\n }\n\n const result = await original.apply(this, args)\n await provider.set(cacheKey, result, cacheTtl)\n return result\n }\n\n return descriptor\n }\n}\n\n// ── @CacheEvict Decorator ───────────────────────────────────────────────\n\n/**\n * Evict cached values matching a key prefix after the method executes.\n * Works with any CacheProvider that implements `delByPrefix`.\n *\n * @param key - Cache key prefix to evict (matches the @Cacheable key)\n */\nexport function CacheEvict(key: string): MethodDecorator {\n return (_target, _propertyKey, descriptor: PropertyDescriptor) => {\n const original = descriptor.value\n\n descriptor.value = async function (...args: any[]) {\n const result = await original.apply(this, args)\n const provider = getCacheProvider()\n if (provider.delByPrefix) {\n await provider.delByPrefix(key)\n }\n return result\n }\n\n return descriptor\n }\n}\n\nexport { CACHEABLE_META }\n"],"mappings":";;;;;;;;;;yBAIA,MAAM,eAAiB,iBAgDvB,IAAa,oBAAb,KAA0D,CACxD,MAAgB,IAAI,IAEpB,MAAM,IAAI,IAAkC,CAC1C,IAAM,MAAQ,KAAK,MAAM,IAAI,IAAI,CAMjC,OALK,MACD,MAAM,WAAa,KAAK,KAAK,EAC/B,KAAK,MAAM,OAAO,IAAI,CACf,MAEF,MAAM,KALM,KAQrB,MAAM,IAAI,IAAa,MAAY,MAA8B,CAC/D,KAAK,MAAM,IAAI,IAAK,CAAE,KAAM,MAAO,UAAW,KAAK,KAAK,CAAG,MAAO,CAAC,CAGrE,MAAM,IAAI,IAA4B,CACpC,KAAK,MAAM,OAAO,IAAI,CAGxB,MAAM,YAAY,OAA+B,CAC/C,IAAK,IAAM,OAAO,KAAK,MAAM,MAAM,CAC7B,IAAI,WAAW,OAAO,EACxB,KAAK,MAAM,OAAO,IAAI,CAK5B,MAAM,UAA0B,CAC9B,KAAK,MAAM,OAAO,GAMtB,IAAI,eAAgC,IAAI,oBAcxC,SAAgB,iBAAiB,SAA+B,CAC9D,eAAiB,SAInB,SAAgB,kBAAkC,CAChD,OAAO,eAuBT,SAAgB,UAAU,IAAc,QAA6C,CACnF,OAAQ,QAAS,YAAa,aAAmC,CAC/D,IAAM,SAAW,WAAW,MACtB,UAAY,KAAO,IAAM,IACzB,UAAY,SAAS,KAAO,OAAO,YAAY,CAgBrD,MAdA,YAAW,MAAQ,eAAgB,GAAG,KAAa,CACjD,IAAM,SAAW,GAAG,UAAU,GAAG,KAAK,UAAU,KAAK,GAC/C,SAAW,kBAAkB,CAE7B,OAAS,MAAM,SAAS,IAAI,SAAS,CAC3C,GAAI,SAAW,KACb,OAAO,OAGT,IAAM,OAAS,MAAM,SAAS,MAAM,KAAM,KAAK,CAE/C,OADA,MAAM,SAAS,IAAI,SAAU,OAAQ,SAAS,CACvC,QAGF,YAYX,SAAgB,WAAW,IAA8B,CACvD,OAAQ,QAAS,aAAc,aAAmC,CAChE,IAAM,SAAW,WAAW,MAW5B,MATA,YAAW,MAAQ,eAAgB,GAAG,KAAa,CACjD,IAAM,OAAS,MAAM,SAAS,MAAM,KAAM,KAAK,CACzC,SAAW,kBAAkB,CAInC,OAHI,SAAS,aACX,MAAM,SAAS,YAAY,IAAI,CAE1B,QAGF"}
1
+ {"version":3,"file":"cache.mjs","names":[],"sources":["../../src/core/cache.ts"],"sourcesContent":["import 'reflect-metadata'\n\n// String metadata key (post-Symbol migration). Slash-delimited\n// `kick/cacheable` so it can't collide with adopter metadata keys.\nconst CACHEABLE_META = 'kick/cacheable'\n\n// ── CacheProvider Interface ─────────────────────────────────────────────\n\n/**\n * Abstract cache backend. Implement this interface to use Redis, Memcached,\n * or any other cache store with @Cacheable and @CacheEvict.\n *\n * @example\n * ```ts\n * class RedisCacheProvider implements CacheProvider {\n * private client: RedisClient\n * constructor(client: RedisClient) { this.client = client }\n * async get(key: string) {\n * const val = await this.client.get(key)\n * return val ? JSON.parse(val) : null\n * }\n * async set(key: string, value: any, ttlMs: number) {\n * await this.client.set(key, JSON.stringify(value), 'PX', ttlMs)\n * }\n * async del(key: string) { await this.client.del(key) }\n * async delByPrefix(prefix: string) {\n * const keys = await this.client.keys(prefix + '*')\n * if (keys.length) await this.client.del(...keys)\n * }\n * }\n * ```\n */\nexport interface CacheProvider {\n /** Retrieve a cached value. Return null if not found or expired. */\n get(key: string): Promise<any | null>\n /** Store a value with a TTL in milliseconds. */\n set(key: string, value: any, ttlMs: number): Promise<void>\n /** Delete a specific cache key. */\n del(key: string): Promise<void>\n /** Delete all keys matching a prefix. Used by @CacheEvict. */\n delByPrefix?(prefix: string): Promise<void>\n /** Optional cleanup on shutdown. */\n shutdown?(): Promise<void>\n}\n\n// ── Built-in Memory Provider ────────────────────────────────────────────\n\n/**\n * Default in-memory cache provider using a Map.\n * Suitable for development and single-instance deployments.\n * For multi-instance or production, use a Redis-backed provider.\n */\nexport class MemoryCacheProvider implements CacheProvider {\n private store = new Map<string, { data: any; expiresAt: number }>()\n\n async get(key: string): Promise<any | null> {\n const entry = this.store.get(key)\n if (!entry) return null\n if (entry.expiresAt <= Date.now()) {\n this.store.delete(key)\n return null\n }\n return entry.data\n }\n\n async set(key: string, value: any, ttlMs: number): Promise<void> {\n this.store.set(key, { data: value, expiresAt: Date.now() + ttlMs })\n }\n\n async del(key: string): Promise<void> {\n this.store.delete(key)\n }\n\n async delByPrefix(prefix: string): Promise<void> {\n for (const key of this.store.keys()) {\n if (key.startsWith(prefix)) {\n this.store.delete(key)\n }\n }\n }\n\n async shutdown(): Promise<void> {\n this.store.clear()\n }\n}\n\n// ── Global Cache Registry ───────────────────────────────────────────────\n\nlet _cacheProvider: CacheProvider = new MemoryCacheProvider()\n\n/**\n * Set the global cache provider used by @Cacheable and @CacheEvict.\n * Call this before bootstrapping your app.\n *\n * @example\n * ```ts\n * import { setCacheProvider } from '@forinda/kickjs'\n * import { RedisCacheProvider } from './redis-cache'\n *\n * setCacheProvider(new RedisCacheProvider(redisClient))\n * ```\n */\nexport function setCacheProvider(provider: CacheProvider): void {\n _cacheProvider = provider\n}\n\n/** Get the current cache provider */\nexport function getCacheProvider(): CacheProvider {\n return _cacheProvider\n}\n\n// ── Cache Options ───────────────────────────────────────────────────────\n\nexport interface CacheOptions {\n /** Time-to-live in seconds (default: 60) */\n ttl?: number\n /** Cache key prefix (default: ClassName.methodName) */\n key?: string\n}\n\n// ── @Cacheable Decorator ────────────────────────────────────────────────\n\n/**\n * Cache the return value of a method for the specified TTL.\n * Uses the globally registered CacheProvider (default: MemoryCacheProvider).\n *\n * Call `setCacheProvider()` to use Redis or any custom backend.\n *\n * @param ttl - Time-to-live in seconds (default: 60)\n * @param options.key - Custom cache key prefix\n */\nexport function Cacheable(ttl?: number, options?: { key?: string }): MethodDecorator {\n return (_target, propertyKey, descriptor: PropertyDescriptor) => {\n const original = descriptor.value\n const cacheTtl = (ttl ?? 60) * 1000\n const keyPrefix = options?.key ?? String(propertyKey)\n\n descriptor.value = async function (...args: any[]) {\n const cacheKey = `${keyPrefix}:${JSON.stringify(args)}`\n const provider = getCacheProvider()\n\n const cached = await provider.get(cacheKey)\n if (cached !== null) {\n return cached\n }\n\n const result = await original.apply(this, args)\n await provider.set(cacheKey, result, cacheTtl)\n return result\n }\n\n return descriptor\n }\n}\n\n// ── @CacheEvict Decorator ───────────────────────────────────────────────\n\n/**\n * Evict cached values matching a key prefix after the method executes.\n * Works with any CacheProvider that implements `delByPrefix`.\n *\n * @param key - Cache key prefix to evict (matches the @Cacheable key)\n */\nexport function CacheEvict(key: string): MethodDecorator {\n return (_target, _propertyKey, descriptor: PropertyDescriptor) => {\n const original = descriptor.value\n\n descriptor.value = async function (...args: any[]) {\n const result = await original.apply(this, args)\n const provider = getCacheProvider()\n if (provider.delByPrefix) {\n await provider.delByPrefix(key)\n }\n return result\n }\n\n return descriptor\n }\n}\n\nexport { CACHEABLE_META }\n"],"mappings":";;;;;;;;;;yBAIA,MAAM,eAAiB,iBAgDvB,IAAa,oBAAb,KAA0D,CACxD,MAAgB,IAAI,IAEpB,MAAM,IAAI,IAAkC,CAC1C,IAAM,MAAQ,KAAK,MAAM,IAAI,GAAG,EAMhC,OALK,MACD,MAAM,WAAa,KAAK,IAAI,GAC9B,KAAK,MAAM,OAAO,GAAG,EACd,MAEF,MAAM,KALM,IAMrB,CAEA,MAAM,IAAI,IAAa,MAAY,MAA8B,CAC/D,KAAK,MAAM,IAAI,IAAK,CAAE,KAAM,MAAO,UAAW,KAAK,IAAI,EAAI,KAAM,CAAC,CACpE,CAEA,MAAM,IAAI,IAA4B,CACpC,KAAK,MAAM,OAAO,GAAG,CACvB,CAEA,MAAM,YAAY,OAA+B,CAC/C,IAAK,IAAM,OAAO,KAAK,MAAM,KAAK,EAC5B,IAAI,WAAW,MAAM,GACvB,KAAK,MAAM,OAAO,GAAG,CAG3B,CAEA,MAAM,UAA0B,CAC9B,KAAK,MAAM,MAAM,CACnB,CACF,EAIA,IAAI,eAAgC,IAAI,oBAcxC,SAAgB,iBAAiB,SAA+B,CAC9D,eAAiB,QACnB,CAGA,SAAgB,kBAAkC,CAChD,OAAO,cACT,CAsBA,SAAgB,UAAU,IAAc,QAA6C,CACnF,OAAQ,QAAS,YAAa,aAAmC,CAC/D,IAAM,SAAW,WAAW,MACtB,UAAY,KAAO,IAAM,IACzB,UAAY,SAAS,KAAO,OAAO,WAAW,EAgBpD,MAdA,YAAW,MAAQ,eAAgB,GAAG,KAAa,CACjD,IAAM,SAAW,GAAG,UAAU,GAAG,KAAK,UAAU,IAAI,IAC9C,SAAW,iBAAiB,EAE5B,OAAS,MAAM,SAAS,IAAI,QAAQ,EAC1C,GAAI,SAAW,KACb,OAAO,OAGT,IAAM,OAAS,MAAM,SAAS,MAAM,KAAM,IAAI,EAE9C,OADA,MAAM,SAAS,IAAI,SAAU,OAAQ,QAAQ,EACtC,MACT,EAEO,UACT,CACF,CAUA,SAAgB,WAAW,IAA8B,CACvD,OAAQ,QAAS,aAAc,aAAmC,CAChE,IAAM,SAAW,WAAW,MAW5B,MATA,YAAW,MAAQ,eAAgB,GAAG,KAAa,CACjD,IAAM,OAAS,MAAM,SAAS,MAAM,KAAM,IAAI,EACxC,SAAW,iBAAiB,EAIlC,OAHI,SAAS,aACX,MAAM,SAAS,YAAY,GAAG,EAEzB,MACT,EAEO,UACT,CACF"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,4 +8,4 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{n as tokenName,t as Container}from"../container-jPCvIZH2.mjs";export{Container,tokenName};
11
+ import{n as tokenName,t as Container}from"../container-BvRsVif5.mjs";export{Container,tokenName};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,5 +8,5 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{c as pushClassMeta,t as getClassMeta}from"../metadata-Chvfoj23.mjs";const CRON_META=`kick/cron`;function Cron(expression,options){return(target,propertyKey)=>{pushClassMeta(CRON_META,target.constructor,{expression,handlerName:propertyKey,description:options?.description,timezone:options?.timezone,runOnInit:options?.runOnInit})}}function getCronJobs(target){return getClassMeta(CRON_META,target,[])}export{CRON_META,Cron,getCronJobs};
11
+ import{c as pushClassMeta,t as getClassMeta}from"../metadata-DN0sBHmY.mjs";const CRON_META=`kick/cron`;function Cron(expression,options){return(target,propertyKey)=>{pushClassMeta(CRON_META,target.constructor,{expression,handlerName:propertyKey,description:options?.description,timezone:options?.timezone,runOnInit:options?.runOnInit})}}function getCronJobs(target){return getClassMeta(CRON_META,target,[])}export{CRON_META,Cron,getCronJobs};
12
12
  //# sourceMappingURL=cron.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cron.mjs","names":[],"sources":["../../src/core/cron.ts"],"sourcesContent":["import { pushClassMeta, getClassMeta } from './metadata'\n\n// String metadata key (post-Symbol migration). Slash-delimited\n// `kick/cron` so it can't collide with adopter metadata keys.\nconst CRON_META = 'kick/cron'\n\nexport interface CronJobMeta {\n expression: string\n handlerName: string\n description?: string\n timezone?: string\n runOnInit?: boolean\n}\n\n// Cron format: minute hour day month weekday\n// Examples:\n// '* * * * *' - every minute\n// '0 * * * *' - every hour\n// '0 0 * * *' - daily at midnight\n// '0 9 * * MON-FRI' - weekdays at 9am\n// '0 0 1 * *' - first of each month\n\n/**\n * Schedule a method to run on a cron expression.\n * Requires a CronAdapter to be registered in bootstrap().\n *\n * @param expression - Standard 5-part cron: minute hour day month weekday.\n * Use forward-slash for intervals (e.g. every 5 min, every 2 hours).\n * @param options.description - Human-readable label for logging\n * @param options.timezone - IANA timezone (e.g. 'America/New_York', 'UTC')\n * @param options.runOnInit - Run immediately on startup before first scheduled tick\n */\nexport function Cron(\n expression: string,\n options?: { description?: string; timezone?: string; runOnInit?: boolean },\n): MethodDecorator {\n return (target, propertyKey) => {\n pushClassMeta<CronJobMeta>(CRON_META, target.constructor, {\n expression,\n handlerName: propertyKey as string,\n description: options?.description,\n timezone: options?.timezone,\n runOnInit: options?.runOnInit,\n })\n }\n}\n\n/** Read cron jobs registered on a class */\nexport function getCronJobs(target: any): CronJobMeta[] {\n return getClassMeta<CronJobMeta[]>(CRON_META, target, [])\n}\n\nexport { CRON_META }\n"],"mappings":";;;;;;;;;;2EAIA,MAAM,UAAY,YA4BlB,SAAgB,KACd,WACA,QACiB,CACjB,OAAQ,OAAQ,cAAgB,CAC9B,cAA2B,UAAW,OAAO,YAAa,CACxD,WACA,YAAa,YACb,YAAa,SAAS,YACtB,SAAU,SAAS,SACnB,UAAW,SAAS,UACrB,CAAC,EAKN,SAAgB,YAAY,OAA4B,CACtD,OAAO,aAA4B,UAAW,OAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"cron.mjs","names":[],"sources":["../../src/core/cron.ts"],"sourcesContent":["import { pushClassMeta, getClassMeta } from './metadata'\n\n// String metadata key (post-Symbol migration). Slash-delimited\n// `kick/cron` so it can't collide with adopter metadata keys.\nconst CRON_META = 'kick/cron'\n\nexport interface CronJobMeta {\n expression: string\n handlerName: string\n description?: string\n timezone?: string\n runOnInit?: boolean\n}\n\n// Cron format: minute hour day month weekday\n// Examples:\n// '* * * * *' - every minute\n// '0 * * * *' - every hour\n// '0 0 * * *' - daily at midnight\n// '0 9 * * MON-FRI' - weekdays at 9am\n// '0 0 1 * *' - first of each month\n\n/**\n * Schedule a method to run on a cron expression.\n * Requires a CronAdapter to be registered in bootstrap().\n *\n * @param expression - Standard 5-part cron: minute hour day month weekday.\n * Use forward-slash for intervals (e.g. every 5 min, every 2 hours).\n * @param options.description - Human-readable label for logging\n * @param options.timezone - IANA timezone (e.g. 'America/New_York', 'UTC')\n * @param options.runOnInit - Run immediately on startup before first scheduled tick\n */\nexport function Cron(\n expression: string,\n options?: { description?: string; timezone?: string; runOnInit?: boolean },\n): MethodDecorator {\n return (target, propertyKey) => {\n pushClassMeta<CronJobMeta>(CRON_META, target.constructor, {\n expression,\n handlerName: propertyKey as string,\n description: options?.description,\n timezone: options?.timezone,\n runOnInit: options?.runOnInit,\n })\n }\n}\n\n/** Read cron jobs registered on a class */\nexport function getCronJobs(target: any): CronJobMeta[] {\n return getClassMeta<CronJobMeta[]>(CRON_META, target, [])\n}\n\nexport { CRON_META }\n"],"mappings":";;;;;;;;;;2EAIA,MAAM,UAAY,YA4BlB,SAAgB,KACd,WACA,QACiB,CACjB,OAAQ,OAAQ,cAAgB,CAC9B,cAA2B,UAAW,OAAO,YAAa,CACxD,WACA,YAAa,YACb,YAAa,SAAS,YACtB,SAAU,SAAS,SACnB,UAAW,SAAS,SACtB,CAAC,CACH,CACF,CAGA,SAAgB,YAAY,OAA4B,CACtD,OAAO,aAA4B,UAAW,OAAQ,CAAC,CAAC,CAC1D"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,5 +8,5 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{t as Container}from"../container-jPCvIZH2.mjs";import{METADATA}from"./interfaces.mjs";import{c as pushClassMeta,d as setInMetaMap,f as setInMetaRecord,l as pushMethodMeta,p as setMethodMeta,u as setClassMeta}from"../metadata-Chvfoj23.mjs";import"reflect-metadata";const pendingRegistrations=[],allRegistrations=new Map;let containerRef=null;function flushPending(container){containerRef=container;for(let{target,scope}of pendingRegistrations)container.has(target)||container.register(target,target,scope);pendingRegistrations.length=0}Container._onReady=flushPending,Container._onReset=container=>{containerRef=container;for(let[,{target,scope}]of allRegistrations)container.has(target)||container.register(target,target,scope)};function registerInContainer(target,scope){setClassMeta(METADATA.INJECTABLE,!0,target),setClassMeta(METADATA.SCOPE,scope,target);let name=target.name||String(target);allRegistrations.set(name,{target,scope}),containerRef?containerRef.has(target)||containerRef.register(target,target,scope):pendingRegistrations.push({target,scope})}function Injectable(options){return target=>{setClassMeta(METADATA.CLASS_KIND,`injectable`,target),registerInContainer(target,options?.scope??`singleton`)}}function Service(options){return target=>{setClassMeta(METADATA.CLASS_KIND,`service`,target),registerInContainer(target,options?.scope??`singleton`)}}function Component(options){return target=>{setClassMeta(METADATA.CLASS_KIND,`component`,target),registerInContainer(target,options?.scope??`singleton`)}}function Repository(options){return target=>{setClassMeta(METADATA.CLASS_KIND,`repository`,target),registerInContainer(target,options?.scope??`singleton`)}}function Controller(){return target=>{setClassMeta(METADATA.CLASS_KIND,`controller`,target),registerInContainer(target,`singleton`)}}function PostConstruct(){return(target,propertyKey)=>{setClassMeta(METADATA.POST_CONSTRUCT,propertyKey,target)}}function applyInjection(token,target,propertyKey,parameterIndex){if(typeof parameterIndex==`number`){setInMetaRecord(METADATA.INJECT,target,parameterIndex,token);return}propertyKey!=null&&setInMetaMap(METADATA.AUTOWIRED,target,propertyKey,token)}function Autowired(token){return((target,propertyKey,parameterIndex)=>{applyInjection(token,target,propertyKey,parameterIndex)})}function Inject(token){return((target,propertyKey,parameterIndex)=>{applyInjection(token,target,propertyKey,parameterIndex)})}function Value(envKey,defaultValue){return(target,propertyKey)=>{setInMetaMap(METADATA.VALUE,target,propertyKey,{envKey,defaultValue})}}function Asset(assetKey){return(target,propertyKey)=>{setInMetaMap(METADATA.ASSET,target,propertyKey,{assetKey})}}function createRouteDecorator(method){return(path,validation)=>(target,propertyKey)=>{pushClassMeta(METADATA.ROUTES,target.constructor,{method,path:path||`/`,handlerName:propertyKey,validation})}}const Get=createRouteDecorator(`GET`),Post=createRouteDecorator(`POST`),Put=createRouteDecorator(`PUT`),Delete=createRouteDecorator(`DELETE`),Patch=createRouteDecorator(`PATCH`);function normalizeApiQueryParamsConfig(config){return`columns`in config&&config.columns&&typeof config.columns==`object`?{filterable:Object.keys(config.columns),sortable:config.sortable?Object.keys(config.sortable):void 0,searchable:config.searchColumns?config.searchColumns.map(col=>col?.name??``).filter(Boolean):void 0}:config}function ApiQueryParams(config){return(target,propertyKey)=>{let normalized=normalizeApiQueryParamsConfig(config);setMethodMeta(METADATA.QUERY_PARAMS,normalized,target.constructor,propertyKey)}}function Middleware(...handlers){return(target,propertyKey)=>{propertyKey?pushMethodMeta(METADATA.METHOD_MIDDLEWARES,target.constructor,propertyKey,...handlers):pushClassMeta(METADATA.CLASS_MIDDLEWARES,target,...handlers)}}function FileUpload(config){return(target,propertyKey)=>{setMethodMeta(METADATA.FILE_UPLOAD,config,target.constructor,propertyKey)}}function attachBuilder(target){setClassMeta(METADATA.BUILDER,!0,target),target.builder=function(){let props={},proxy=new Proxy({},{get(_,key){return key===`build`?()=>Object.assign(new target,props):value=>(props[key]=value,proxy)}});return proxy}}function Builder(target){attachBuilder(target)}function withBuilder(ctor){return attachBuilder(ctor),ctor}export{ApiQueryParams,Asset,Autowired,Builder,Component,Controller,Delete,FileUpload,Get,Inject,Injectable,Middleware,Patch,Post,PostConstruct,Put,Repository,Service,Value,normalizeApiQueryParamsConfig,withBuilder};
11
+ import{t as Container}from"../container-BvRsVif5.mjs";import{METADATA}from"./interfaces.mjs";import{c as pushClassMeta,d as setInMetaMap,f as setInMetaRecord,l as pushMethodMeta,p as setMethodMeta,u as setClassMeta}from"../metadata-DN0sBHmY.mjs";import"reflect-metadata";const pendingRegistrations=[],allRegistrations=new Map;let containerRef=null;function flushPending(container){containerRef=container;for(let{target,scope}of pendingRegistrations)container.has(target)||container.register(target,target,scope);pendingRegistrations.length=0}Container._onReady=flushPending,Container._onReset=container=>{containerRef=container;for(let[,{target,scope}]of allRegistrations)container.has(target)||container.register(target,target,scope)};function registerInContainer(target,scope){setClassMeta(METADATA.INJECTABLE,!0,target),setClassMeta(METADATA.SCOPE,scope,target);let name=target.name||String(target);allRegistrations.set(name,{target,scope}),containerRef?containerRef.has(target)||containerRef.register(target,target,scope):pendingRegistrations.push({target,scope})}function Injectable(options){return target=>{setClassMeta(METADATA.CLASS_KIND,`injectable`,target),registerInContainer(target,options?.scope??`singleton`)}}function Service(options){return target=>{setClassMeta(METADATA.CLASS_KIND,`service`,target),registerInContainer(target,options?.scope??`singleton`)}}function Component(options){return target=>{setClassMeta(METADATA.CLASS_KIND,`component`,target),registerInContainer(target,options?.scope??`singleton`)}}function Repository(options){return target=>{setClassMeta(METADATA.CLASS_KIND,`repository`,target),registerInContainer(target,options?.scope??`singleton`)}}function Controller(){return target=>{setClassMeta(METADATA.CLASS_KIND,`controller`,target),registerInContainer(target,`singleton`)}}function PostConstruct(){return(target,propertyKey)=>{setClassMeta(METADATA.POST_CONSTRUCT,propertyKey,target)}}function applyInjection(token,target,propertyKey,parameterIndex){if(typeof parameterIndex==`number`){setInMetaRecord(METADATA.INJECT,target,parameterIndex,token);return}propertyKey!=null&&setInMetaMap(METADATA.AUTOWIRED,target,propertyKey,token)}function Autowired(token){return((target,propertyKey,parameterIndex)=>{applyInjection(token,target,propertyKey,parameterIndex)})}function Inject(token){return((target,propertyKey,parameterIndex)=>{applyInjection(token,target,propertyKey,parameterIndex)})}function Value(envKey,defaultValue){return(target,propertyKey)=>{setInMetaMap(METADATA.VALUE,target,propertyKey,{envKey,defaultValue})}}function Asset(assetKey){return(target,propertyKey)=>{setInMetaMap(METADATA.ASSET,target,propertyKey,{assetKey})}}function createRouteDecorator(method){return(path,validation)=>(target,propertyKey)=>{pushClassMeta(METADATA.ROUTES,target.constructor,{method,path:path||`/`,handlerName:propertyKey,validation})}}const Get=createRouteDecorator(`GET`),Post=createRouteDecorator(`POST`),Put=createRouteDecorator(`PUT`),Delete=createRouteDecorator(`DELETE`),Patch=createRouteDecorator(`PATCH`);function normalizeApiQueryParamsConfig(config){return`columns`in config&&config.columns&&typeof config.columns==`object`?{filterable:Object.keys(config.columns),sortable:config.sortable?Object.keys(config.sortable):void 0,searchable:config.searchColumns?config.searchColumns.map(col=>col?.name??``).filter(Boolean):void 0}:config}function ApiQueryParams(config){return(target,propertyKey)=>{let normalized=normalizeApiQueryParamsConfig(config);setMethodMeta(METADATA.QUERY_PARAMS,normalized,target.constructor,propertyKey)}}function Middleware(...handlers){return(target,propertyKey)=>{propertyKey?pushMethodMeta(METADATA.METHOD_MIDDLEWARES,target.constructor,propertyKey,...handlers):pushClassMeta(METADATA.CLASS_MIDDLEWARES,target,...handlers)}}function FileUpload(config){return(target,propertyKey)=>{setMethodMeta(METADATA.FILE_UPLOAD,config,target.constructor,propertyKey)}}function attachBuilder(target){setClassMeta(METADATA.BUILDER,!0,target),target.builder=function(){let props={},proxy=new Proxy({},{get(_,key){return key===`build`?()=>Object.assign(new target,props):value=>(props[key]=value,proxy)}});return proxy}}function Builder(target){attachBuilder(target)}function withBuilder(ctor){return attachBuilder(ctor),ctor}export{ApiQueryParams,Asset,Autowired,Builder,Component,Controller,Delete,FileUpload,Get,Inject,Injectable,Middleware,Patch,Post,PostConstruct,Put,Repository,Service,Value,normalizeApiQueryParamsConfig,withBuilder};
12
12
  //# sourceMappingURL=decorators.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.mjs","names":[],"sources":["../../src/core/decorators.ts"],"sourcesContent":["import 'reflect-metadata'\nimport { METADATA, Scope, type BuilderOf, type ServiceOptions } from './interfaces'\nimport { Container, type KickJsRegistry } from './container'\nimport {\n setClassMeta,\n setMethodMeta,\n pushClassMeta,\n pushMethodMeta,\n setInMetaMap,\n setInMetaRecord,\n} from './metadata'\n\n// ── Decorator Registration System ───────────────────────────────────────\n// Decorators execute at class-definition time (module load). The Container\n// may not exist yet when the first decorator fires. We queue registrations\n// and flush them on first Container.getInstance() call.\n//\n// `allRegistrations` is a persistent registry that survives Container.reset().\n// On reset (HMR), all previously decorated classes are re-registered on the\n// fresh container. This ensures @Service, @Controller, @Repository, etc.\n// all survive HMR without manual re-registration.\n\ntype PendingRegistration = { target: any; scope: Scope }\nconst pendingRegistrations: PendingRegistration[] = []\n// Keyed by class name to prevent memory leaks during HMR — new class with\n// the same name replaces the old entry instead of accumulating references.\nconst allRegistrations = new Map<string, { target: any; scope: Scope }>()\nlet containerRef: any = null\n\nfunction flushPending(container: any): void {\n containerRef = container\n for (const { target, scope } of pendingRegistrations) {\n if (!container.has(target)) {\n container.register(target, target, scope)\n }\n }\n pendingRegistrations.length = 0\n}\n\n// Wire up synchronously — Container._onReady is called on first getInstance()\nContainer._onReady = flushPending\n\n// On Container.reset(), update containerRef and replay ALL decorator\n// registrations on the fresh container. This handles HMR where the container\n// is wiped but not all decorated modules are re-evaluated.\nContainer._onReset = (container: any) => {\n containerRef = container\n for (const [, { target, scope }] of allRegistrations) {\n if (!container.has(target)) {\n container.register(target, target, scope)\n }\n }\n}\n\n// ── Class Decorators ────────────────────────────────────────────────────\n\nfunction registerInContainer(target: any, scope: Scope): void {\n setClassMeta(METADATA.INJECTABLE, true, target)\n setClassMeta(METADATA.SCOPE, scope, target)\n\n // Track in persistent registry — survives Container.reset() for HMR replay.\n // Keyed by name so HMR class re-creation replaces the old entry.\n const name = target.name || String(target)\n allRegistrations.set(name, { target, scope })\n\n if (containerRef) {\n // Container already initialized — register immediately\n if (!containerRef.has(target)) {\n containerRef.register(target, target, scope)\n }\n } else {\n // Container not ready yet — queue for later\n pendingRegistrations.push({ target, scope })\n }\n}\n\n/** Mark a class as injectable with lifecycle scope */\nexport function Injectable(options?: ServiceOptions): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'injectable', target)\n registerInContainer(target, options?.scope ?? Scope.SINGLETON)\n }\n}\n\n/** Mark a class as a service (semantic alias for Injectable) */\nexport function Service(options?: ServiceOptions): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'service', target)\n registerInContainer(target, options?.scope ?? Scope.SINGLETON)\n }\n}\n\n/** Mark a class as a generic managed component */\nexport function Component(options?: ServiceOptions): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'component', target)\n registerInContainer(target, options?.scope ?? Scope.SINGLETON)\n }\n}\n\n/** Mark a class as a repository */\nexport function Repository(options?: ServiceOptions): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'repository', target)\n registerInContainer(target, options?.scope ?? Scope.SINGLETON)\n }\n}\n\n/**\n * Mark a class as an HTTP controller and register it in the DI container.\n *\n * Route prefixes are defined by the module's `routes().path` — the single\n * source of truth for where routes mount. The legacy\n * `@Controller('/path')` parameter was removed in v4; if your code\n * still passes a string, see `docs/guide/migration-v3-to-v4.md` for\n * the rename map.\n */\nexport function Controller(): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'controller', target)\n registerInContainer(target, Scope.SINGLETON)\n }\n}\n\n// ── Method Decorators ───────────────────────────────────────────────────\n\n/** Mark a method as a lifecycle hook called after instantiation */\nexport function PostConstruct(): MethodDecorator {\n return (target, propertyKey) => {\n setClassMeta(METADATA.POST_CONSTRUCT, propertyKey, target)\n }\n}\n\n// ── Injection Decorators (property + constructor parameter) ─────────────\n\n/**\n * A decorator that's valid as either a property decorator OR a\n * constructor-parameter decorator. forinda/kick-js#235 §2 — `@Autowired`\n * and `@Inject` previously diverged at the type level (property-only\n * vs parameter-only) and adopters who picked the wrong name for the\n * position got a cryptic TS1240 error. Both names now accept either\n * position and route to the correct metadata bucket at runtime.\n */\nexport interface PropertyOrParameterDecorator {\n /** Property decorator form — `@Autowired(TOKEN) private foo!: Foo`. */\n (target: object, propertyKey: string | symbol): void\n /** Constructor-parameter form — `constructor(@Inject(TOKEN) foo: Foo) {}`. */\n (target: object, propertyKey: string | symbol | undefined, parameterIndex: number): void\n}\n\nfunction applyInjection(\n token: unknown,\n target: object,\n propertyKey: string | symbol | undefined,\n parameterIndex: number | undefined,\n): void {\n // Legacy parameter decorators receive 3 args (target, propertyKey,\n // parameterIndex); property decorators receive 2 (target, propertyKey).\n // The 3rd-arg-number-vs-undefined check is the canonical position\n // detection in TypeScript's legacy decorator runtime.\n if (typeof parameterIndex === 'number') {\n setInMetaRecord(METADATA.INJECT, target, parameterIndex, token)\n return\n }\n if (propertyKey != null) {\n // `target` for a property decorator on a non-static field is the\n // class prototype; the AUTOWIRED bucket is keyed off the prototype\n // identity at resolution time, so pass it through unchanged.\n setInMetaMap(METADATA.AUTOWIRED, target, propertyKey as string, token)\n }\n}\n\n/**\n * Inject a dependency. Works in two positions:\n *\n * - **Property decorator** — `@Autowired(TOKEN) private repo!: UserRepo`.\n * Resolved lazily from the container the first time the property is\n * read.\n * - **Constructor parameter decorator** — `constructor(@Autowired(TOKEN) repo: UserRepo) {}`.\n * Resolved at instantiation; injected into the ctor call.\n *\n * `@Inject` is the same function under another name — they share\n * runtime + types so the two names are interchangeable. Pick whichever\n * reads better at the call site.\n *\n * Like `@Inject`, the typed string-literal overload narrows the token\n * to a key of the augmented `KickJsRegistry`. After `kick typegen`\n * populates the registry, `@Autowired('kick/prisma/Client')` auto-\n * completes the key and typo'd literals become TS2345 errors.\n */\nexport function Autowired<K extends keyof KickJsRegistry & string>(\n token: K,\n): PropertyOrParameterDecorator\nexport function Autowired(token?: unknown): PropertyOrParameterDecorator\nexport function Autowired(token?: unknown): PropertyOrParameterDecorator {\n return ((\n target: object,\n propertyKey: string | symbol | undefined,\n parameterIndex?: number,\n ): void => {\n applyInjection(token, target, propertyKey, parameterIndex)\n }) as PropertyOrParameterDecorator\n}\n\n/**\n * Inject a dependency by token. Same shape as {@link Autowired} —\n * works as either a property decorator or a constructor-parameter\n * decorator. Pick whichever name reads better at the call site.\n *\n * ## Typed string-literal overload\n *\n * When called with a string literal that matches a key of the\n * augmented `KickJsRegistry`, TypeScript narrows the parameter type\n * to the registered type. Typo'd literals become compile errors\n * (the string isn't `keyof KickJsRegistry`). Class identities and\n * `InjectionToken<T>` keep working unchanged via the second overload.\n *\n * @example\n * ```ts\n * import { Service, Inject } from '@forinda/kickjs'\n * import type { PrismaClient } from '@prisma/client'\n *\n * `@Service()`\n * class UserRepo {\n * constructor(@Inject('kick/prisma/Client') private db: PrismaClient) {}\n * // OR property form, same decorator:\n * @Inject('kick/prisma/Client') private db2!: PrismaClient\n * }\n * ```\n *\n * After `kick typegen` runs, the literal autocompletes from the\n * registry and a typo (`@Inject('kick/prisma/Cleint')`) becomes a\n * TS2345 error.\n */\nexport function Inject<K extends keyof KickJsRegistry & string>(\n token: K,\n): PropertyOrParameterDecorator\nexport function Inject(token?: unknown): PropertyOrParameterDecorator\nexport function Inject(token?: unknown): PropertyOrParameterDecorator {\n return ((\n target: object,\n propertyKey: string | symbol | undefined,\n parameterIndex?: number,\n ): void => {\n applyInjection(token, target, propertyKey, parameterIndex)\n }) as PropertyOrParameterDecorator\n}\n\n/**\n * Global ambient registry of typed environment variables, populated by\n * `kick typegen` from the project's env schema (typically\n * `src/env.ts`'s `export default defineEnv(...)`).\n *\n * Empty by default — declarations come from `.kickjs/types/env.ts`\n * generated alongside the rest of the typegen output. Once populated,\n * `@Value('PORT')` autocompletes the key, type-checks the default\n * value, and `process.env.PORT` is also typed via the parallel\n * `NodeJS.ProcessEnv` augmentation in the same generated file.\n */\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface KickEnv {}\n}\n\n/** A string key known to the typed env registry (`never` until typegen runs) */\nexport type EnvKey = keyof KickEnv & string\n\n/**\n * Look up the type of a typed env entry.\n *\n * Decorators can't propagate the property type from the key, so users\n * still need to write the property's type — but `Env<K>` lets them\n * derive it from `KickEnv` instead of duplicating the schema:\n *\n * ```ts\n * @Service()\n * class MyService {\n * @Value('PORT')\n * private port!: Env<'PORT'> // → number, narrowed from KickEnv['PORT']\n * }\n * ```\n */\nexport type Env<K extends EnvKey = EnvKey> = KickEnv[K]\n\n/**\n * Constraint that allows any string when the typed env registry is\n * empty (no `kick typegen` has run yet, so existing code with raw\n * string keys keeps working) but locks the argument down to known\n * `EnvKey` literals once the registry is populated.\n *\n * Implementation: when `EnvKey` is `never`, the conditional resolves\n * to the user's `K`, accepting anything. Once typegen has populated\n * `KickEnv`, `EnvKey` becomes a real union and the conditional forces\n * `K` to be assignable to it.\n */\ntype ValueKey<K extends string> = [EnvKey] extends [never] ? K : K & EnvKey\n\n/**\n * Inject an environment variable value. Evaluated lazily so the env\n * is available at access time, not at decoration time.\n *\n * If no default is provided and the env var is missing, throws at access time\n * to catch misconfiguration early instead of returning undefined.\n *\n * Uses metadata + instance getter to work correctly with `useDefineForClassFields`.\n *\n * Type-safety:\n * - Without `kick typegen` run, any string key is accepted (back-compat).\n * - After typegen, `KickEnv` is populated and unknown keys become a tsc\n * error. The optional `defaultValue` is type-checked against the\n * schema's inferred type for that key.\n */\nexport function Value<K extends string>(\n envKey: ValueKey<K>,\n defaultValue?: K extends EnvKey ? KickEnv[K] : unknown,\n): PropertyDecorator {\n return (target, propertyKey) => {\n setInMetaMap(METADATA.VALUE, target, propertyKey as string, { envKey, defaultValue })\n }\n}\n\n// ── @Asset — typed asset path injection (assets-plan.md PR 3+) ─────────\n\nimport type { KickAssets } from './assets'\n\n/**\n * Flatten the nested `KickAssets` augmentation (typegen-emitted in\n * PR 4) into a string-literal union of dot/slash-joined paths.\n *\n * `interface KickAssets { mails: { welcome: () => string; orders: {\n * confirmation: () => string } } }` becomes\n * `'mails/welcome' | 'mails/orders/confirmation'`.\n *\n * Returns `never` when `KickAssets` is empty (no typegen has run yet)\n * so `AssetKeyArg` falls through to accept any string.\n */\ntype FlattenAssets<T, Prefix extends string = ''> = {\n [K in keyof T & string]: T[K] extends () => string\n ? `${Prefix}${K}`\n : T[K] extends Record<string, unknown>\n ? FlattenAssets<T[K], `${Prefix}${K}/`>\n : never\n}[keyof T & string]\n\n/** Flat union of every known `<namespace>/<key>` path. */\nexport type AssetKey = FlattenAssets<KickAssets>\n\n/**\n * Constraint mirroring `ValueKey<K>` — accepts any string when\n * `AssetKey` is `never` (back-compat for adopters who haven't run\n * `kick typegen` yet) but locks the argument to known literals once\n * the typegen-augmented `KickAssets` interface is populated.\n */\ntype AssetKeyArg<K extends string> = [AssetKey] extends [never] ? K : K & AssetKey\n\n/**\n * Inject the resolved file-system path for a typed asset. Mirrors\n * `@Value`'s lazy-getter pattern — the asset is resolved on every\n * property access, NOT at class instantiation, so:\n *\n * - Tests can swap fixtures + clear the cache without re-instantiating\n * the consuming class.\n * - The first access cost is paid once per process (the manifest cache\n * in `core/assets.ts` makes subsequent calls cheap).\n *\n * Type-safety:\n *\n * - Without typegen, any string key is accepted (back-compat — same\n * trick as `@Value`).\n * - After typegen, `KickAssets` is populated and `AssetKey` is a\n * union of every flattened `<namespace>/<key>` path. Unknown keys\n * become a TS error.\n *\n * @example\n * ```ts\n * import { Service, Asset } from '@forinda/kickjs'\n *\n * `@Service()`\n * class MailService {\n * `@Asset('mails/welcome')`\n * private welcomeTemplate!: string\n *\n * send(user: User) {\n * return ejs.renderFile(this.welcomeTemplate, { user })\n * }\n * }\n * ```\n */\nexport function Asset<K extends string>(assetKey: AssetKeyArg<K>): PropertyDecorator {\n return (target, propertyKey) => {\n setInMetaMap(METADATA.ASSET, target, propertyKey as string, { assetKey })\n }\n}\n\n// ── HTTP Route Decorators ───────────────────────────────────────────────\n\nexport interface RouteDefinition {\n method: string\n path: string\n handlerName: string\n validation?: {\n /** JSON Schema object for validating the request body */\n body?: any\n /** JSON Schema object for validating query parameters */\n query?: any\n /** JSON Schema object for validating URL params */\n params?: any\n /** Schema name in OpenAPI components/schemas for the request body. Auto-generated from handler name if omitted. */\n name?: string\n }\n}\n\nfunction createRouteDecorator(method: string) {\n return (path?: string, validation?: RouteDefinition['validation']): MethodDecorator => {\n return (target, propertyKey) => {\n pushClassMeta<RouteDefinition>(METADATA.ROUTES, target.constructor, {\n method,\n path: path || '/',\n handlerName: propertyKey as string,\n validation,\n })\n }\n }\n}\n\nexport const Get = createRouteDecorator('GET')\nexport const Post = createRouteDecorator('POST')\nexport const Put = createRouteDecorator('PUT')\nexport const Delete = createRouteDecorator('DELETE')\nexport const Patch = createRouteDecorator('PATCH')\n\n// ── Query Params Decorator ─────────────────────────────────────────────\n\nexport interface ApiQueryParamsConfig {\n /** Fields that can be used in filter queries (e.g., `?filter=status:eq:active`) */\n filterable?: string[]\n /** Fields that can be used in sort queries (e.g., `?sort=createdAt:desc`) */\n sortable?: string[]\n /** Fields that are searched with the `?q=` parameter */\n searchable?: string[]\n}\n\n/**\n * Column-object-based query params config (e.g., from DrizzleQueryParamsConfig).\n * `Object.keys()` is used to derive field names for OpenAPI docs.\n */\nexport interface ColumnApiQueryParamsConfig {\n columns: Record<string, any>\n sortable?: Record<string, any>\n searchColumns?: any[]\n [key: string]: any\n}\n\n/**\n * Normalize a query params config to the string-based ApiQueryParamsConfig.\n * Handles both string-based and column-object-based configs.\n */\nexport function normalizeApiQueryParamsConfig(\n config: ApiQueryParamsConfig | ColumnApiQueryParamsConfig,\n): ApiQueryParamsConfig {\n if ('columns' in config && config.columns && typeof config.columns === 'object') {\n return {\n filterable: Object.keys(config.columns),\n sortable: config.sortable ? Object.keys(config.sortable) : undefined,\n searchable: config.searchColumns\n ? config.searchColumns.map((col: any) => col?.name ?? '').filter(Boolean)\n : undefined,\n }\n }\n return config as ApiQueryParamsConfig\n}\n\n/**\n * Document the query parameters accepted by a GET endpoint.\n * Used by SwaggerAdapter to generate `filter`, `sort`, `page`, `limit`, and `q` params\n * in the OpenAPI spec, with descriptions listing the allowed fields.\n *\n * Accepts both string-based configs and column-object configs (e.g., DrizzleQueryParamsConfig).\n *\n * @example\n * ```ts\n * // String-based\n * @ApiQueryParams({\n * filterable: ['status', 'category', 'price'],\n * sortable: ['name', 'createdAt', 'price'],\n * searchable: ['name', 'description'],\n * })\n *\n * // Column-object-based (Drizzle)\n * @ApiQueryParams(TASK_QUERY_CONFIG)\n * ```\n */\nexport function ApiQueryParams(\n config: ApiQueryParamsConfig | ColumnApiQueryParamsConfig,\n): MethodDecorator {\n return (target, propertyKey) => {\n const normalized = normalizeApiQueryParamsConfig(config)\n setMethodMeta(METADATA.QUERY_PARAMS, normalized, target.constructor, propertyKey as string)\n }\n}\n\n// ── Middleware Decorators ───────────────────────────────────────────────\n\n/**\n * Middleware handler function.\n * Generic `TCtx` defaults to `any` — import `RequestContext` from\n * `@forinda/kickjs` for full type safety:\n *\n * ```ts\n * import type { MiddlewareHandler } from '@forinda/kickjs'\n * import type { RequestContext } from '@forinda/kickjs'\n *\n * const auth: MiddlewareHandler<RequestContext> = (ctx, next) => {\n * ctx.body // fully typed\n * next()\n * }\n * ```\n */\nexport type MiddlewareHandler<TCtx = any> = (ctx: TCtx, next: () => void) => void | Promise<void>\n\n/** Attach middleware handlers to a class or method */\nexport function Middleware(...handlers: MiddlewareHandler[]): ClassDecorator & MethodDecorator {\n return (target: any, propertyKey?: string | symbol) => {\n if (propertyKey) {\n pushMethodMeta(\n METADATA.METHOD_MIDDLEWARES,\n target.constructor,\n propertyKey as string,\n ...handlers,\n )\n } else {\n pushClassMeta(METADATA.CLASS_MIDDLEWARES, target, ...handlers)\n }\n }\n}\n\n// ── File Upload Decorator ───────────────────────────────────────────────\n\n/**\n * File filter — accepts short extensions ('jpg'), full MIME types ('image/jpeg'),\n * wildcards ('image/*'), or a function `(mimetype, filename) => boolean` for full control.\n */\nexport type FileTypeFilter = string[] | ((mimetype: string, filename: string) => boolean)\n\n/**\n * Shared upload options used by both the `@FileUpload` decorator and the\n * `upload.single()` / `upload.array()` / `upload.none()` middleware.\n */\nexport interface BaseUploadOptions {\n /** Max file size in bytes (default: 5MB) */\n maxSize?: number\n /**\n * Allowed file types:\n * - **string[]** — short extensions ('jpg'), full MIME types ('image/jpeg'), or wildcards ('image/*')\n * - **function** — `(mimetype, filename) => boolean` for full control\n */\n allowedTypes?: FileTypeFilter\n /** Extend the built-in extension-to-MIME map */\n customMimeMap?: Record<string, string>\n}\n\nexport interface FileUploadConfig extends BaseUploadOptions {\n mode: 'single' | 'array' | 'none'\n /** Form field name (default: 'file') */\n fieldName?: string\n /** Max files for array mode (default: 10) */\n maxCount?: number\n}\n\n/** Configure file upload handling for a controller method */\nexport function FileUpload(config: FileUploadConfig): MethodDecorator {\n return (target, propertyKey) => {\n setMethodMeta(METADATA.FILE_UPLOAD, config, target.constructor, propertyKey as string)\n }\n}\n\n// ── Builder Decorator ───────────────────────────────────────────────────\n\nfunction attachBuilder(target: any): void {\n setClassMeta(METADATA.BUILDER, true, target)\n target.builder = function () {\n const props: Record<string, any> = {}\n const proxy: any = new Proxy(\n {},\n {\n get(_, key) {\n if (key === 'build') {\n return () => Object.assign(new target(), props)\n }\n return (value: any) => {\n props[key as string] = value\n return proxy\n }\n },\n },\n )\n return proxy\n }\n}\n\n/**\n * Add a static `builder()` method for fluent construction.\n *\n * Legacy decorators cannot widen the class type, so by default the\n * caller sees the unmodified shape. Opt into typing by adding a single\n * `declare static` line:\n *\n * ```ts\n * @Builder\n * class UserDto {\n * name!: string\n * email!: string\n * declare static readonly builder: () => BuilderOf<UserDto>\n * }\n * ```\n *\n * `readonly` keeps SonarQube's `typescript:S1444` quiet — the runtime\n * assigns `target.builder` once at decoration time and never again.\n *\n * If you'd rather not write the `declare`, use `withBuilder()` instead —\n * same runtime, types inferred automatically.\n */\nexport function Builder(target: any): void {\n attachBuilder(target)\n}\n\n/**\n * Factory variant of `@Builder`. Wraps the class with the same runtime\n * and returns it intersected with `{ builder(): BuilderOf<T> }` so the\n * static is fully typed without any `declare` boilerplate.\n *\n * ```ts\n * class UserDtoBase {\n * name!: string\n * email!: string\n * }\n * export const UserDto = withBuilder(UserDtoBase)\n * export type UserDto = InstanceType<typeof UserDto>\n *\n * UserDto.builder().name('Alice').email('a@b.com').build() // fully typed\n * ```\n */\nexport function withBuilder<C extends new (...args: any[]) => any>(\n ctor: C,\n): C & { builder(): BuilderOf<InstanceType<C>> } {\n attachBuilder(ctor)\n return ctor as C & { builder(): BuilderOf<InstanceType<C>> }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"decorators.mjs","names":[],"sources":["../../src/core/decorators.ts"],"sourcesContent":["import 'reflect-metadata'\nimport { METADATA, Scope, type BuilderOf, type ServiceOptions } from './interfaces'\nimport { Container, type KickJsRegistry } from './container'\nimport {\n setClassMeta,\n setMethodMeta,\n pushClassMeta,\n pushMethodMeta,\n setInMetaMap,\n setInMetaRecord,\n} from './metadata'\n\n// ── Decorator Registration System ───────────────────────────────────────\n// Decorators execute at class-definition time (module load). The Container\n// may not exist yet when the first decorator fires. We queue registrations\n// and flush them on first Container.getInstance() call.\n//\n// `allRegistrations` is a persistent registry that survives Container.reset().\n// On reset (HMR), all previously decorated classes are re-registered on the\n// fresh container. This ensures @Service, @Controller, @Repository, etc.\n// all survive HMR without manual re-registration.\n\ntype PendingRegistration = { target: any; scope: Scope }\nconst pendingRegistrations: PendingRegistration[] = []\n// Keyed by class name to prevent memory leaks during HMR — new class with\n// the same name replaces the old entry instead of accumulating references.\nconst allRegistrations = new Map<string, { target: any; scope: Scope }>()\nlet containerRef: any = null\n\nfunction flushPending(container: any): void {\n containerRef = container\n for (const { target, scope } of pendingRegistrations) {\n if (!container.has(target)) {\n container.register(target, target, scope)\n }\n }\n pendingRegistrations.length = 0\n}\n\n// Wire up synchronously — Container._onReady is called on first getInstance()\nContainer._onReady = flushPending\n\n// On Container.reset(), update containerRef and replay ALL decorator\n// registrations on the fresh container. This handles HMR where the container\n// is wiped but not all decorated modules are re-evaluated.\nContainer._onReset = (container: any) => {\n containerRef = container\n for (const [, { target, scope }] of allRegistrations) {\n if (!container.has(target)) {\n container.register(target, target, scope)\n }\n }\n}\n\n// ── Class Decorators ────────────────────────────────────────────────────\n\nfunction registerInContainer(target: any, scope: Scope): void {\n setClassMeta(METADATA.INJECTABLE, true, target)\n setClassMeta(METADATA.SCOPE, scope, target)\n\n // Track in persistent registry — survives Container.reset() for HMR replay.\n // Keyed by name so HMR class re-creation replaces the old entry.\n const name = target.name || String(target)\n allRegistrations.set(name, { target, scope })\n\n if (containerRef) {\n // Container already initialized — register immediately\n if (!containerRef.has(target)) {\n containerRef.register(target, target, scope)\n }\n } else {\n // Container not ready yet — queue for later\n pendingRegistrations.push({ target, scope })\n }\n}\n\n/** Mark a class as injectable with lifecycle scope */\nexport function Injectable(options?: ServiceOptions): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'injectable', target)\n registerInContainer(target, options?.scope ?? Scope.SINGLETON)\n }\n}\n\n/** Mark a class as a service (semantic alias for Injectable) */\nexport function Service(options?: ServiceOptions): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'service', target)\n registerInContainer(target, options?.scope ?? Scope.SINGLETON)\n }\n}\n\n/** Mark a class as a generic managed component */\nexport function Component(options?: ServiceOptions): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'component', target)\n registerInContainer(target, options?.scope ?? Scope.SINGLETON)\n }\n}\n\n/** Mark a class as a repository */\nexport function Repository(options?: ServiceOptions): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'repository', target)\n registerInContainer(target, options?.scope ?? Scope.SINGLETON)\n }\n}\n\n/**\n * Mark a class as an HTTP controller and register it in the DI container.\n *\n * Route prefixes are defined by the module's `routes().path` — the single\n * source of truth for where routes mount. The legacy\n * `@Controller('/path')` parameter was removed in v4; if your code\n * still passes a string, see `docs/guide/migration-v3-to-v4.md` for\n * the rename map.\n */\nexport function Controller(): ClassDecorator {\n return (target: any) => {\n setClassMeta(METADATA.CLASS_KIND, 'controller', target)\n registerInContainer(target, Scope.SINGLETON)\n }\n}\n\n// ── Method Decorators ───────────────────────────────────────────────────\n\n/** Mark a method as a lifecycle hook called after instantiation */\nexport function PostConstruct(): MethodDecorator {\n return (target, propertyKey) => {\n setClassMeta(METADATA.POST_CONSTRUCT, propertyKey, target)\n }\n}\n\n// ── Injection Decorators (property + constructor parameter) ─────────────\n\n/**\n * A decorator that's valid as either a property decorator OR a\n * constructor-parameter decorator. forinda/kick-js#235 §2 — `@Autowired`\n * and `@Inject` previously diverged at the type level (property-only\n * vs parameter-only) and adopters who picked the wrong name for the\n * position got a cryptic TS1240 error. Both names now accept either\n * position and route to the correct metadata bucket at runtime.\n */\nexport interface PropertyOrParameterDecorator {\n /** Property decorator form — `@Autowired(TOKEN) private foo!: Foo`. */\n (target: object, propertyKey: string | symbol): void\n /** Constructor-parameter form — `constructor(@Inject(TOKEN) foo: Foo) {}`. */\n (target: object, propertyKey: string | symbol | undefined, parameterIndex: number): void\n}\n\nfunction applyInjection(\n token: unknown,\n target: object,\n propertyKey: string | symbol | undefined,\n parameterIndex: number | undefined,\n): void {\n // Legacy parameter decorators receive 3 args (target, propertyKey,\n // parameterIndex); property decorators receive 2 (target, propertyKey).\n // The 3rd-arg-number-vs-undefined check is the canonical position\n // detection in TypeScript's legacy decorator runtime.\n if (typeof parameterIndex === 'number') {\n setInMetaRecord(METADATA.INJECT, target, parameterIndex, token)\n return\n }\n if (propertyKey != null) {\n // `target` for a property decorator on a non-static field is the\n // class prototype; the AUTOWIRED bucket is keyed off the prototype\n // identity at resolution time, so pass it through unchanged.\n setInMetaMap(METADATA.AUTOWIRED, target, propertyKey as string, token)\n }\n}\n\n/**\n * Inject a dependency. Works in two positions:\n *\n * - **Property decorator** — `@Autowired(TOKEN) private repo!: UserRepo`.\n * Resolved lazily from the container the first time the property is\n * read.\n * - **Constructor parameter decorator** — `constructor(@Autowired(TOKEN) repo: UserRepo) {}`.\n * Resolved at instantiation; injected into the ctor call.\n *\n * `@Inject` is the same function under another name — they share\n * runtime + types so the two names are interchangeable. Pick whichever\n * reads better at the call site.\n *\n * Like `@Inject`, the typed string-literal overload narrows the token\n * to a key of the augmented `KickJsRegistry`. After `kick typegen`\n * populates the registry, `@Autowired('kick/prisma/Client')` auto-\n * completes the key and typo'd literals become TS2345 errors.\n */\nexport function Autowired<K extends keyof KickJsRegistry & string>(\n token: K,\n): PropertyOrParameterDecorator\nexport function Autowired(token?: unknown): PropertyOrParameterDecorator\nexport function Autowired(token?: unknown): PropertyOrParameterDecorator {\n return ((\n target: object,\n propertyKey: string | symbol | undefined,\n parameterIndex?: number,\n ): void => {\n applyInjection(token, target, propertyKey, parameterIndex)\n }) as PropertyOrParameterDecorator\n}\n\n/**\n * Inject a dependency by token. Same shape as {@link Autowired} —\n * works as either a property decorator or a constructor-parameter\n * decorator. Pick whichever name reads better at the call site.\n *\n * ## Typed string-literal overload\n *\n * When called with a string literal that matches a key of the\n * augmented `KickJsRegistry`, TypeScript narrows the parameter type\n * to the registered type. Typo'd literals become compile errors\n * (the string isn't `keyof KickJsRegistry`). Class identities and\n * `InjectionToken<T>` keep working unchanged via the second overload.\n *\n * @example\n * ```ts\n * import { Service, Inject } from '@forinda/kickjs'\n * import type { PrismaClient } from '@prisma/client'\n *\n * `@Service()`\n * class UserRepo {\n * constructor(@Inject('kick/prisma/Client') private db: PrismaClient) {}\n * // OR property form, same decorator:\n * @Inject('kick/prisma/Client') private db2!: PrismaClient\n * }\n * ```\n *\n * After `kick typegen` runs, the literal autocompletes from the\n * registry and a typo (`@Inject('kick/prisma/Cleint')`) becomes a\n * TS2345 error.\n */\nexport function Inject<K extends keyof KickJsRegistry & string>(\n token: K,\n): PropertyOrParameterDecorator\nexport function Inject(token?: unknown): PropertyOrParameterDecorator\nexport function Inject(token?: unknown): PropertyOrParameterDecorator {\n return ((\n target: object,\n propertyKey: string | symbol | undefined,\n parameterIndex?: number,\n ): void => {\n applyInjection(token, target, propertyKey, parameterIndex)\n }) as PropertyOrParameterDecorator\n}\n\n/**\n * Global ambient registry of typed environment variables, populated by\n * `kick typegen` from the project's env schema (typically\n * `src/env.ts`'s `export default defineEnv(...)`).\n *\n * Empty by default — declarations come from `.kickjs/types/env.ts`\n * generated alongside the rest of the typegen output. Once populated,\n * `@Value('PORT')` autocompletes the key, type-checks the default\n * value, and `process.env.PORT` is also typed via the parallel\n * `NodeJS.ProcessEnv` augmentation in the same generated file.\n */\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface KickEnv {}\n}\n\n/** A string key known to the typed env registry (`never` until typegen runs) */\nexport type EnvKey = keyof KickEnv & string\n\n/**\n * Look up the type of a typed env entry.\n *\n * Decorators can't propagate the property type from the key, so users\n * still need to write the property's type — but `Env<K>` lets them\n * derive it from `KickEnv` instead of duplicating the schema:\n *\n * ```ts\n * @Service()\n * class MyService {\n * @Value('PORT')\n * private port!: Env<'PORT'> // → number, narrowed from KickEnv['PORT']\n * }\n * ```\n */\nexport type Env<K extends EnvKey = EnvKey> = KickEnv[K]\n\n/**\n * Constraint that allows any string when the typed env registry is\n * empty (no `kick typegen` has run yet, so existing code with raw\n * string keys keeps working) but locks the argument down to known\n * `EnvKey` literals once the registry is populated.\n *\n * Implementation: when `EnvKey` is `never`, the conditional resolves\n * to the user's `K`, accepting anything. Once typegen has populated\n * `KickEnv`, `EnvKey` becomes a real union and the conditional forces\n * `K` to be assignable to it.\n */\ntype ValueKey<K extends string> = [EnvKey] extends [never] ? K : K & EnvKey\n\n/**\n * Inject an environment variable value. Evaluated lazily so the env\n * is available at access time, not at decoration time.\n *\n * If no default is provided and the env var is missing, throws at access time\n * to catch misconfiguration early instead of returning undefined.\n *\n * Uses metadata + instance getter to work correctly with `useDefineForClassFields`.\n *\n * Type-safety:\n * - Without `kick typegen` run, any string key is accepted (back-compat).\n * - After typegen, `KickEnv` is populated and unknown keys become a tsc\n * error. The optional `defaultValue` is type-checked against the\n * schema's inferred type for that key.\n */\nexport function Value<K extends string>(\n envKey: ValueKey<K>,\n defaultValue?: K extends EnvKey ? KickEnv[K] : unknown,\n): PropertyDecorator {\n return (target, propertyKey) => {\n setInMetaMap(METADATA.VALUE, target, propertyKey as string, { envKey, defaultValue })\n }\n}\n\n// ── @Asset — typed asset path injection (assets-plan.md PR 3+) ─────────\n\nimport type { KickAssets } from './assets'\n\n/**\n * Flatten the nested `KickAssets` augmentation (typegen-emitted in\n * PR 4) into a string-literal union of dot/slash-joined paths.\n *\n * `interface KickAssets { mails: { welcome: () => string; orders: {\n * confirmation: () => string } } }` becomes\n * `'mails/welcome' | 'mails/orders/confirmation'`.\n *\n * Returns `never` when `KickAssets` is empty (no typegen has run yet)\n * so `AssetKeyArg` falls through to accept any string.\n */\ntype FlattenAssets<T, Prefix extends string = ''> = {\n [K in keyof T & string]: T[K] extends () => string\n ? `${Prefix}${K}`\n : T[K] extends Record<string, unknown>\n ? FlattenAssets<T[K], `${Prefix}${K}/`>\n : never\n}[keyof T & string]\n\n/** Flat union of every known `<namespace>/<key>` path. */\nexport type AssetKey = FlattenAssets<KickAssets>\n\n/**\n * Constraint mirroring `ValueKey<K>` — accepts any string when\n * `AssetKey` is `never` (back-compat for adopters who haven't run\n * `kick typegen` yet) but locks the argument to known literals once\n * the typegen-augmented `KickAssets` interface is populated.\n */\ntype AssetKeyArg<K extends string> = [AssetKey] extends [never] ? K : K & AssetKey\n\n/**\n * Inject the resolved file-system path for a typed asset. Mirrors\n * `@Value`'s lazy-getter pattern — the asset is resolved on every\n * property access, NOT at class instantiation, so:\n *\n * - Tests can swap fixtures + clear the cache without re-instantiating\n * the consuming class.\n * - The first access cost is paid once per process (the manifest cache\n * in `core/assets.ts` makes subsequent calls cheap).\n *\n * Type-safety:\n *\n * - Without typegen, any string key is accepted (back-compat — same\n * trick as `@Value`).\n * - After typegen, `KickAssets` is populated and `AssetKey` is a\n * union of every flattened `<namespace>/<key>` path. Unknown keys\n * become a TS error.\n *\n * @example\n * ```ts\n * import { Service, Asset } from '@forinda/kickjs'\n *\n * `@Service()`\n * class MailService {\n * `@Asset('mails/welcome')`\n * private welcomeTemplate!: string\n *\n * send(user: User) {\n * return ejs.renderFile(this.welcomeTemplate, { user })\n * }\n * }\n * ```\n */\nexport function Asset<K extends string>(assetKey: AssetKeyArg<K>): PropertyDecorator {\n return (target, propertyKey) => {\n setInMetaMap(METADATA.ASSET, target, propertyKey as string, { assetKey })\n }\n}\n\n// ── HTTP Route Decorators ───────────────────────────────────────────────\n\nexport interface RouteDefinition {\n method: string\n path: string\n handlerName: string\n validation?: {\n /** JSON Schema object for validating the request body */\n body?: any\n /** JSON Schema object for validating query parameters */\n query?: any\n /** JSON Schema object for validating URL params */\n params?: any\n /** Schema name in OpenAPI components/schemas for the request body. Auto-generated from handler name if omitted. */\n name?: string\n }\n}\n\nfunction createRouteDecorator(method: string) {\n return (path?: string, validation?: RouteDefinition['validation']): MethodDecorator => {\n return (target, propertyKey) => {\n pushClassMeta<RouteDefinition>(METADATA.ROUTES, target.constructor, {\n method,\n path: path || '/',\n handlerName: propertyKey as string,\n validation,\n })\n }\n }\n}\n\nexport const Get = createRouteDecorator('GET')\nexport const Post = createRouteDecorator('POST')\nexport const Put = createRouteDecorator('PUT')\nexport const Delete = createRouteDecorator('DELETE')\nexport const Patch = createRouteDecorator('PATCH')\n\n// ── Query Params Decorator ─────────────────────────────────────────────\n\nexport interface ApiQueryParamsConfig {\n /** Fields that can be used in filter queries (e.g., `?filter=status:eq:active`) */\n filterable?: string[]\n /** Fields that can be used in sort queries (e.g., `?sort=createdAt:desc`) */\n sortable?: string[]\n /** Fields that are searched with the `?q=` parameter */\n searchable?: string[]\n}\n\n/**\n * Column-object-based query params config (e.g., from DrizzleQueryParamsConfig).\n * `Object.keys()` is used to derive field names for OpenAPI docs.\n */\nexport interface ColumnApiQueryParamsConfig {\n columns: Record<string, any>\n sortable?: Record<string, any>\n searchColumns?: any[]\n [key: string]: any\n}\n\n/**\n * Normalize a query params config to the string-based ApiQueryParamsConfig.\n * Handles both string-based and column-object-based configs.\n */\nexport function normalizeApiQueryParamsConfig(\n config: ApiQueryParamsConfig | ColumnApiQueryParamsConfig,\n): ApiQueryParamsConfig {\n if ('columns' in config && config.columns && typeof config.columns === 'object') {\n return {\n filterable: Object.keys(config.columns),\n sortable: config.sortable ? Object.keys(config.sortable) : undefined,\n searchable: config.searchColumns\n ? config.searchColumns.map((col: any) => col?.name ?? '').filter(Boolean)\n : undefined,\n }\n }\n return config as ApiQueryParamsConfig\n}\n\n/**\n * Document the query parameters accepted by a GET endpoint.\n * Used by SwaggerAdapter to generate `filter`, `sort`, `page`, `limit`, and `q` params\n * in the OpenAPI spec, with descriptions listing the allowed fields.\n *\n * Accepts both string-based configs and column-object configs (e.g., DrizzleQueryParamsConfig).\n *\n * @example\n * ```ts\n * // String-based\n * @ApiQueryParams({\n * filterable: ['status', 'category', 'price'],\n * sortable: ['name', 'createdAt', 'price'],\n * searchable: ['name', 'description'],\n * })\n *\n * // Column-object-based (Drizzle)\n * @ApiQueryParams(TASK_QUERY_CONFIG)\n * ```\n */\nexport function ApiQueryParams(\n config: ApiQueryParamsConfig | ColumnApiQueryParamsConfig,\n): MethodDecorator {\n return (target, propertyKey) => {\n const normalized = normalizeApiQueryParamsConfig(config)\n setMethodMeta(METADATA.QUERY_PARAMS, normalized, target.constructor, propertyKey as string)\n }\n}\n\n// ── Middleware Decorators ───────────────────────────────────────────────\n\n/**\n * Middleware handler function.\n * Generic `TCtx` defaults to `any` — import `RequestContext` from\n * `@forinda/kickjs` for full type safety:\n *\n * ```ts\n * import type { MiddlewareHandler } from '@forinda/kickjs'\n * import type { RequestContext } from '@forinda/kickjs'\n *\n * const auth: MiddlewareHandler<RequestContext> = (ctx, next) => {\n * ctx.body // fully typed\n * next()\n * }\n * ```\n */\nexport type MiddlewareHandler<TCtx = any> = (ctx: TCtx, next: () => void) => void | Promise<void>\n\n/** Attach middleware handlers to a class or method */\nexport function Middleware(...handlers: MiddlewareHandler[]): ClassDecorator & MethodDecorator {\n return (target: any, propertyKey?: string | symbol) => {\n if (propertyKey) {\n pushMethodMeta(\n METADATA.METHOD_MIDDLEWARES,\n target.constructor,\n propertyKey as string,\n ...handlers,\n )\n } else {\n pushClassMeta(METADATA.CLASS_MIDDLEWARES, target, ...handlers)\n }\n }\n}\n\n// ── File Upload Decorator ───────────────────────────────────────────────\n\n/**\n * File filter — accepts short extensions ('jpg'), full MIME types ('image/jpeg'),\n * wildcards ('image/*'), or a function `(mimetype, filename) => boolean` for full control.\n */\nexport type FileTypeFilter = string[] | ((mimetype: string, filename: string) => boolean)\n\n/**\n * Shared upload options used by both the `@FileUpload` decorator and the\n * `upload.single()` / `upload.array()` / `upload.none()` middleware.\n */\nexport interface BaseUploadOptions {\n /** Max file size in bytes (default: 5MB) */\n maxSize?: number\n /**\n * Allowed file types:\n * - **string[]** — short extensions ('jpg'), full MIME types ('image/jpeg'), or wildcards ('image/*')\n * - **function** — `(mimetype, filename) => boolean` for full control\n */\n allowedTypes?: FileTypeFilter\n /** Extend the built-in extension-to-MIME map */\n customMimeMap?: Record<string, string>\n}\n\nexport interface FileUploadConfig extends BaseUploadOptions {\n mode: 'single' | 'array' | 'none'\n /** Form field name (default: 'file') */\n fieldName?: string\n /** Max files for array mode (default: 10) */\n maxCount?: number\n}\n\n/** Configure file upload handling for a controller method */\nexport function FileUpload(config: FileUploadConfig): MethodDecorator {\n return (target, propertyKey) => {\n setMethodMeta(METADATA.FILE_UPLOAD, config, target.constructor, propertyKey as string)\n }\n}\n\n// ── Builder Decorator ───────────────────────────────────────────────────\n\nfunction attachBuilder(target: any): void {\n setClassMeta(METADATA.BUILDER, true, target)\n target.builder = function () {\n const props: Record<string, any> = {}\n const proxy: any = new Proxy(\n {},\n {\n get(_, key) {\n if (key === 'build') {\n return () => Object.assign(new target(), props)\n }\n return (value: any) => {\n props[key as string] = value\n return proxy\n }\n },\n },\n )\n return proxy\n }\n}\n\n/**\n * Add a static `builder()` method for fluent construction.\n *\n * Legacy decorators cannot widen the class type, so by default the\n * caller sees the unmodified shape. Opt into typing by adding a single\n * `declare static` line:\n *\n * ```ts\n * @Builder\n * class UserDto {\n * name!: string\n * email!: string\n * declare static readonly builder: () => BuilderOf<UserDto>\n * }\n * ```\n *\n * `readonly` keeps SonarQube's `typescript:S1444` quiet — the runtime\n * assigns `target.builder` once at decoration time and never again.\n *\n * If you'd rather not write the `declare`, use `withBuilder()` instead —\n * same runtime, types inferred automatically.\n */\nexport function Builder(target: any): void {\n attachBuilder(target)\n}\n\n/**\n * Factory variant of `@Builder`. Wraps the class with the same runtime\n * and returns it intersected with `{ builder(): BuilderOf<T> }` so the\n * static is fully typed without any `declare` boilerplate.\n *\n * ```ts\n * class UserDtoBase {\n * name!: string\n * email!: string\n * }\n * export const UserDto = withBuilder(UserDtoBase)\n * export type UserDto = InstanceType<typeof UserDto>\n *\n * UserDto.builder().name('Alice').email('a@b.com').build() // fully typed\n * ```\n */\nexport function withBuilder<C extends new (...args: any[]) => any>(\n ctor: C,\n): C & { builder(): BuilderOf<InstanceType<C>> } {\n attachBuilder(ctor)\n return ctor as C & { builder(): BuilderOf<InstanceType<C>> }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,5 +8,5 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- const HttpStatus={OK:200,CREATED:201,ACCEPTED:202,NO_CONTENT:204,MOVED_PERMANENTLY:301,FOUND:302,NOT_MODIFIED:304,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,BAD_REQUEST:400,UNAUTHORIZED:401,PAYMENT_REQUIRED:402,FORBIDDEN:403,NOT_FOUND:404,METHOD_NOT_ALLOWED:405,NOT_ACCEPTABLE:406,CONFLICT:409,GONE:410,UNPROCESSABLE_ENTITY:422,TOO_MANY_REQUESTS:429,INTERNAL_SERVER_ERROR:500,NOT_IMPLEMENTED:501,BAD_GATEWAY:502,SERVICE_UNAVAILABLE:503,GATEWAY_TIMEOUT:504};var HttpException=class HttpException extends Error{constructor(status,message,details,headers){super(message),this.status=status,this.details=details,this.headers=headers,this.name=`HttpException`}withHeaders(headers){return new HttpException(this.status,this.message,this.details,{...this.headers,...headers})}static fromZodError(error,message){let firstIssue=error.issues?.[0],details=(error.issues||[]).map(issue=>({field:issue.path?.join(`.`)||``,message:issue.message,code:issue.code}));return new HttpException(HttpStatus.UNPROCESSABLE_ENTITY,message||firstIssue?.message||`Validation failed`,details)}static badRequest(message=`Bad Request`){return new HttpException(HttpStatus.BAD_REQUEST,message)}static unauthorized(message=`Unauthorized`,wwwAuthenticate){return new HttpException(HttpStatus.UNAUTHORIZED,message,void 0,wwwAuthenticate?{"WWW-Authenticate":wwwAuthenticate}:void 0)}static forbidden(message=`Forbidden`){return new HttpException(HttpStatus.FORBIDDEN,message)}static notFound(message=`Not Found`){return new HttpException(HttpStatus.NOT_FOUND,message)}static methodNotAllowed(allowedMethods,message=`Method Not Allowed`){return new HttpException(HttpStatus.METHOD_NOT_ALLOWED,message,void 0,{Allow:allowedMethods.join(`, `)})}static conflict(message=`Conflict`){return new HttpException(HttpStatus.CONFLICT,message)}static unprocessable(message=`Unprocessable Entity`,details){return new HttpException(HttpStatus.UNPROCESSABLE_ENTITY,message,details)}static tooManyRequests(message=`Too Many Requests`,retryAfterSeconds){return new HttpException(HttpStatus.TOO_MANY_REQUESTS,message,void 0,retryAfterSeconds===void 0?void 0:{"Retry-After":String(retryAfterSeconds)})}static serviceUnavailable(message=`Service Unavailable`,retryAfterSeconds){return new HttpException(HttpStatus.SERVICE_UNAVAILABLE,message,void 0,retryAfterSeconds===void 0?void 0:{"Retry-After":String(retryAfterSeconds)})}static internal(message=`Internal Server Error`){return new HttpException(HttpStatus.INTERNAL_SERVER_ERROR,message)}};export{HttpException,HttpStatus};
11
+ const HttpStatus={OK:200,CREATED:201,ACCEPTED:202,NO_CONTENT:204,MOVED_PERMANENTLY:301,FOUND:302,NOT_MODIFIED:304,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,BAD_REQUEST:400,UNAUTHORIZED:401,PAYMENT_REQUIRED:402,FORBIDDEN:403,NOT_FOUND:404,METHOD_NOT_ALLOWED:405,NOT_ACCEPTABLE:406,CONFLICT:409,GONE:410,UNPROCESSABLE_ENTITY:422,TOO_MANY_REQUESTS:429,INTERNAL_SERVER_ERROR:500,NOT_IMPLEMENTED:501,BAD_GATEWAY:502,SERVICE_UNAVAILABLE:503,GATEWAY_TIMEOUT:504};var HttpException=class HttpException extends Error{status;details;headers;constructor(status,message,details,headers){super(message),this.status=status,this.details=details,this.headers=headers,this.name=`HttpException`}withHeaders(headers){return new HttpException(this.status,this.message,this.details,{...this.headers,...headers})}static fromZodError(error,message){let firstIssue=error.issues?.[0],details=(error.issues||[]).map(issue=>({field:issue.path?.join(`.`)||``,message:issue.message,code:issue.code}));return new HttpException(HttpStatus.UNPROCESSABLE_ENTITY,message||firstIssue?.message||`Validation failed`,details)}static badRequest(message=`Bad Request`){return new HttpException(HttpStatus.BAD_REQUEST,message)}static unauthorized(message=`Unauthorized`,wwwAuthenticate){return new HttpException(HttpStatus.UNAUTHORIZED,message,void 0,wwwAuthenticate?{"WWW-Authenticate":wwwAuthenticate}:void 0)}static forbidden(message=`Forbidden`){return new HttpException(HttpStatus.FORBIDDEN,message)}static notFound(message=`Not Found`){return new HttpException(HttpStatus.NOT_FOUND,message)}static methodNotAllowed(allowedMethods,message=`Method Not Allowed`){return new HttpException(HttpStatus.METHOD_NOT_ALLOWED,message,void 0,{Allow:allowedMethods.join(`, `)})}static conflict(message=`Conflict`){return new HttpException(HttpStatus.CONFLICT,message)}static unprocessable(message=`Unprocessable Entity`,details){return new HttpException(HttpStatus.UNPROCESSABLE_ENTITY,message,details)}static tooManyRequests(message=`Too Many Requests`,retryAfterSeconds){return new HttpException(HttpStatus.TOO_MANY_REQUESTS,message,void 0,retryAfterSeconds===void 0?void 0:{"Retry-After":String(retryAfterSeconds)})}static serviceUnavailable(message=`Service Unavailable`,retryAfterSeconds){return new HttpException(HttpStatus.SERVICE_UNAVAILABLE,message,void 0,retryAfterSeconds===void 0?void 0:{"Retry-After":String(retryAfterSeconds)})}static internal(message=`Internal Server Error`){return new HttpException(HttpStatus.INTERNAL_SERVER_ERROR,message)}};export{HttpException,HttpStatus};
12
12
  //# sourceMappingURL=errors.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.mjs","names":[],"sources":["../../src/core/errors.ts"],"sourcesContent":["/**\n * Standard HTTP status codes as a const enum.\n * Use instead of raw numbers for readability and type safety.\n *\n * @example\n * ```ts\n * throw new HttpException(HttpStatus.NOT_FOUND, 'User not found')\n * ctx.res.status(HttpStatus.CREATED).json(data)\n * ```\n */\nexport const HttpStatus = {\n // 2xx Success\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n\n // 3xx Redirection\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n // 4xx Client Errors\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n CONFLICT: 409,\n GONE: 410,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n\n // 5xx Server Errors\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const\n\nexport type HttpStatusCode = (typeof HttpStatus)[keyof typeof HttpStatus]\n\n/** Validation error detail — shape used by `unprocessable()` and `fromZodError()`. */\nexport interface ValidationError {\n field: string\n message: string\n code?: string\n}\n\n/**\n * Typed HTTP exception with status code, free-form details, and optional\n * response headers. Provides static factory methods for common HTTP errors.\n *\n * `details` is intentionally typed as `unknown` — it serializes straight into\n * the response body's `errors` field, so any JSON-compatible shape works\n * (string, object, array of mixed values, ValidationError[]).\n *\n * `headers` are merged into the response by the global error handler so\n * spec-mandated headers (Retry-After, WWW-Authenticate, Allow, Location)\n * stay on the exception, not on ad-hoc try/catch chains.\n */\nexport class HttpException extends Error {\n constructor(\n public readonly status: number,\n message: string,\n public readonly details?: unknown,\n public readonly headers?: Record<string, string>,\n ) {\n super(message)\n this.name = 'HttpException'\n }\n\n /** Return a new exception with `headers` shallow-merged onto this one. */\n withHeaders(headers: Record<string, string>): HttpException {\n return new HttpException(this.status, this.message, this.details, {\n ...this.headers,\n ...headers,\n })\n }\n\n /** Create from a Zod error */\n static fromZodError(error: any, message?: string): HttpException {\n const firstIssue = error.issues?.[0]\n const details: ValidationError[] = (error.issues || []).map((issue: any) => ({\n field: issue.path?.join('.') || '',\n message: issue.message,\n code: issue.code,\n }))\n return new HttpException(\n HttpStatus.UNPROCESSABLE_ENTITY,\n message || firstIssue?.message || 'Validation failed',\n details,\n )\n }\n\n static badRequest(message = 'Bad Request') {\n return new HttpException(HttpStatus.BAD_REQUEST, message)\n }\n static unauthorized(message = 'Unauthorized', wwwAuthenticate?: string) {\n return new HttpException(\n HttpStatus.UNAUTHORIZED,\n message,\n undefined,\n wwwAuthenticate ? { 'WWW-Authenticate': wwwAuthenticate } : undefined,\n )\n }\n static forbidden(message = 'Forbidden') {\n return new HttpException(HttpStatus.FORBIDDEN, message)\n }\n static notFound(message = 'Not Found') {\n return new HttpException(HttpStatus.NOT_FOUND, message)\n }\n static methodNotAllowed(allowedMethods: string[], message = 'Method Not Allowed') {\n return new HttpException(HttpStatus.METHOD_NOT_ALLOWED, message, undefined, {\n Allow: allowedMethods.join(', '),\n })\n }\n static conflict(message = 'Conflict') {\n return new HttpException(HttpStatus.CONFLICT, message)\n }\n static unprocessable(message = 'Unprocessable Entity', details?: ValidationError[]) {\n return new HttpException(HttpStatus.UNPROCESSABLE_ENTITY, message, details)\n }\n static tooManyRequests(message = 'Too Many Requests', retryAfterSeconds?: number) {\n return new HttpException(\n HttpStatus.TOO_MANY_REQUESTS,\n message,\n undefined,\n retryAfterSeconds !== undefined ? { 'Retry-After': String(retryAfterSeconds) } : undefined,\n )\n }\n static serviceUnavailable(message = 'Service Unavailable', retryAfterSeconds?: number) {\n return new HttpException(\n HttpStatus.SERVICE_UNAVAILABLE,\n message,\n undefined,\n retryAfterSeconds !== undefined ? { 'Retry-After': String(retryAfterSeconds) } : undefined,\n )\n }\n static internal(message = 'Internal Server Error') {\n return new HttpException(HttpStatus.INTERNAL_SERVER_ERROR, message)\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAa,WAAa,CAExB,GAAI,IACJ,QAAS,IACT,SAAU,IACV,WAAY,IAGZ,kBAAmB,IACnB,MAAO,IACP,aAAc,IACd,mBAAoB,IACpB,mBAAoB,IAGpB,YAAa,IACb,aAAc,IACd,iBAAkB,IAClB,UAAW,IACX,UAAW,IACX,mBAAoB,IACpB,eAAgB,IAChB,SAAU,IACV,KAAM,IACN,qBAAsB,IACtB,kBAAmB,IAGnB,sBAAuB,IACvB,gBAAiB,IACjB,YAAa,IACb,oBAAqB,IACrB,gBAAiB,IAClB,CAuBD,IAAa,cAAb,MAAa,sBAAsB,KAAM,CACvC,YACE,OACA,QACA,QACA,QACA,CACA,MAAM,QAAQ,CALE,KAAA,OAAA,OAEA,KAAA,QAAA,QACA,KAAA,QAAA,QAGhB,KAAK,KAAO,gBAId,YAAY,QAAgD,CAC1D,OAAO,IAAI,cAAc,KAAK,OAAQ,KAAK,QAAS,KAAK,QAAS,CAChE,GAAG,KAAK,QACR,GAAG,QACJ,CAAC,CAIJ,OAAO,aAAa,MAAY,QAAiC,CAC/D,IAAM,WAAa,MAAM,SAAS,GAC5B,SAA8B,MAAM,QAAU,EAAE,EAAE,IAAK,QAAgB,CAC3E,MAAO,MAAM,MAAM,KAAK,IAAI,EAAI,GAChC,QAAS,MAAM,QACf,KAAM,MAAM,KACb,EAAE,CACH,OAAO,IAAI,cACT,WAAW,qBACX,SAAW,YAAY,SAAW,oBAClC,QACD,CAGH,OAAO,WAAW,QAAU,cAAe,CACzC,OAAO,IAAI,cAAc,WAAW,YAAa,QAAQ,CAE3D,OAAO,aAAa,QAAU,eAAgB,gBAA0B,CACtE,OAAO,IAAI,cACT,WAAW,aACX,QACA,IAAA,GACA,gBAAkB,CAAE,mBAAoB,gBAAiB,CAAG,IAAA,GAC7D,CAEH,OAAO,UAAU,QAAU,YAAa,CACtC,OAAO,IAAI,cAAc,WAAW,UAAW,QAAQ,CAEzD,OAAO,SAAS,QAAU,YAAa,CACrC,OAAO,IAAI,cAAc,WAAW,UAAW,QAAQ,CAEzD,OAAO,iBAAiB,eAA0B,QAAU,qBAAsB,CAChF,OAAO,IAAI,cAAc,WAAW,mBAAoB,QAAS,IAAA,GAAW,CAC1E,MAAO,eAAe,KAAK,KAAK,CACjC,CAAC,CAEJ,OAAO,SAAS,QAAU,WAAY,CACpC,OAAO,IAAI,cAAc,WAAW,SAAU,QAAQ,CAExD,OAAO,cAAc,QAAU,uBAAwB,QAA6B,CAClF,OAAO,IAAI,cAAc,WAAW,qBAAsB,QAAS,QAAQ,CAE7E,OAAO,gBAAgB,QAAU,oBAAqB,kBAA4B,CAChF,OAAO,IAAI,cACT,WAAW,kBACX,QACA,IAAA,GACA,oBAAsB,IAAA,GAA2D,IAAA,GAA/C,CAAE,cAAe,OAAO,kBAAkB,CAAE,CAC/E,CAEH,OAAO,mBAAmB,QAAU,sBAAuB,kBAA4B,CACrF,OAAO,IAAI,cACT,WAAW,oBACX,QACA,IAAA,GACA,oBAAsB,IAAA,GAA2D,IAAA,GAA/C,CAAE,cAAe,OAAO,kBAAkB,CAAE,CAC/E,CAEH,OAAO,SAAS,QAAU,wBAAyB,CACjD,OAAO,IAAI,cAAc,WAAW,sBAAuB,QAAQ"}
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../../src/core/errors.ts"],"sourcesContent":["/**\n * Standard HTTP status codes as a const enum.\n * Use instead of raw numbers for readability and type safety.\n *\n * @example\n * ```ts\n * throw new HttpException(HttpStatus.NOT_FOUND, 'User not found')\n * ctx.res.status(HttpStatus.CREATED).json(data)\n * ```\n */\nexport const HttpStatus = {\n // 2xx Success\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NO_CONTENT: 204,\n\n // 3xx Redirection\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n NOT_MODIFIED: 304,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n\n // 4xx Client Errors\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n CONFLICT: 409,\n GONE: 410,\n UNPROCESSABLE_ENTITY: 422,\n TOO_MANY_REQUESTS: 429,\n\n // 5xx Server Errors\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n} as const\n\nexport type HttpStatusCode = (typeof HttpStatus)[keyof typeof HttpStatus]\n\n/** Validation error detail — shape used by `unprocessable()` and `fromZodError()`. */\nexport interface ValidationError {\n field: string\n message: string\n code?: string\n}\n\n/**\n * Typed HTTP exception with status code, free-form details, and optional\n * response headers. Provides static factory methods for common HTTP errors.\n *\n * `details` is intentionally typed as `unknown` — it serializes straight into\n * the response body's `errors` field, so any JSON-compatible shape works\n * (string, object, array of mixed values, ValidationError[]).\n *\n * `headers` are merged into the response by the global error handler so\n * spec-mandated headers (Retry-After, WWW-Authenticate, Allow, Location)\n * stay on the exception, not on ad-hoc try/catch chains.\n */\nexport class HttpException extends Error {\n constructor(\n public readonly status: number,\n message: string,\n public readonly details?: unknown,\n public readonly headers?: Record<string, string>,\n ) {\n super(message)\n this.name = 'HttpException'\n }\n\n /** Return a new exception with `headers` shallow-merged onto this one. */\n withHeaders(headers: Record<string, string>): HttpException {\n return new HttpException(this.status, this.message, this.details, {\n ...this.headers,\n ...headers,\n })\n }\n\n /** Create from a Zod error */\n static fromZodError(error: any, message?: string): HttpException {\n const firstIssue = error.issues?.[0]\n const details: ValidationError[] = (error.issues || []).map((issue: any) => ({\n field: issue.path?.join('.') || '',\n message: issue.message,\n code: issue.code,\n }))\n return new HttpException(\n HttpStatus.UNPROCESSABLE_ENTITY,\n message || firstIssue?.message || 'Validation failed',\n details,\n )\n }\n\n static badRequest(message = 'Bad Request') {\n return new HttpException(HttpStatus.BAD_REQUEST, message)\n }\n static unauthorized(message = 'Unauthorized', wwwAuthenticate?: string) {\n return new HttpException(\n HttpStatus.UNAUTHORIZED,\n message,\n undefined,\n wwwAuthenticate ? { 'WWW-Authenticate': wwwAuthenticate } : undefined,\n )\n }\n static forbidden(message = 'Forbidden') {\n return new HttpException(HttpStatus.FORBIDDEN, message)\n }\n static notFound(message = 'Not Found') {\n return new HttpException(HttpStatus.NOT_FOUND, message)\n }\n static methodNotAllowed(allowedMethods: string[], message = 'Method Not Allowed') {\n return new HttpException(HttpStatus.METHOD_NOT_ALLOWED, message, undefined, {\n Allow: allowedMethods.join(', '),\n })\n }\n static conflict(message = 'Conflict') {\n return new HttpException(HttpStatus.CONFLICT, message)\n }\n static unprocessable(message = 'Unprocessable Entity', details?: ValidationError[]) {\n return new HttpException(HttpStatus.UNPROCESSABLE_ENTITY, message, details)\n }\n static tooManyRequests(message = 'Too Many Requests', retryAfterSeconds?: number) {\n return new HttpException(\n HttpStatus.TOO_MANY_REQUESTS,\n message,\n undefined,\n retryAfterSeconds !== undefined ? { 'Retry-After': String(retryAfterSeconds) } : undefined,\n )\n }\n static serviceUnavailable(message = 'Service Unavailable', retryAfterSeconds?: number) {\n return new HttpException(\n HttpStatus.SERVICE_UNAVAILABLE,\n message,\n undefined,\n retryAfterSeconds !== undefined ? { 'Retry-After': String(retryAfterSeconds) } : undefined,\n )\n }\n static internal(message = 'Internal Server Error') {\n return new HttpException(HttpStatus.INTERNAL_SERVER_ERROR, message)\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAa,WAAa,CAExB,GAAI,IACJ,QAAS,IACT,SAAU,IACV,WAAY,IAGZ,kBAAmB,IACnB,MAAO,IACP,aAAc,IACd,mBAAoB,IACpB,mBAAoB,IAGpB,YAAa,IACb,aAAc,IACd,iBAAkB,IAClB,UAAW,IACX,UAAW,IACX,mBAAoB,IACpB,eAAgB,IAChB,SAAU,IACV,KAAM,IACN,qBAAsB,IACtB,kBAAmB,IAGnB,sBAAuB,IACvB,gBAAiB,IACjB,YAAa,IACb,oBAAqB,IACrB,gBAAiB,GACnB,EAuBA,IAAa,cAAb,MAAa,sBAAsB,KAAM,CAErB,OAEA,QACA,QAJlB,YACE,OACA,QACA,QACA,QACA,CACA,MAAM,OAAO,EALG,KAAA,OAAA,OAEA,KAAA,QAAA,QACA,KAAA,QAAA,QAGhB,KAAK,KAAO,eACd,CAGA,YAAY,QAAgD,CAC1D,OAAO,IAAI,cAAc,KAAK,OAAQ,KAAK,QAAS,KAAK,QAAS,CAChE,GAAG,KAAK,QACR,GAAG,OACL,CAAC,CACH,CAGA,OAAO,aAAa,MAAY,QAAiC,CAC/D,IAAM,WAAa,MAAM,SAAS,GAC5B,SAA8B,MAAM,QAAU,CAAC,GAAG,IAAK,QAAgB,CAC3E,MAAO,MAAM,MAAM,KAAK,GAAG,GAAK,GAChC,QAAS,MAAM,QACf,KAAM,MAAM,IACd,EAAE,EACF,OAAO,IAAI,cACT,WAAW,qBACX,SAAW,YAAY,SAAW,oBAClC,OACF,CACF,CAEA,OAAO,WAAW,QAAU,cAAe,CACzC,OAAO,IAAI,cAAc,WAAW,YAAa,OAAO,CAC1D,CACA,OAAO,aAAa,QAAU,eAAgB,gBAA0B,CACtE,OAAO,IAAI,cACT,WAAW,aACX,QACA,IAAA,GACA,gBAAkB,CAAE,mBAAoB,eAAgB,EAAI,IAAA,EAC9D,CACF,CACA,OAAO,UAAU,QAAU,YAAa,CACtC,OAAO,IAAI,cAAc,WAAW,UAAW,OAAO,CACxD,CACA,OAAO,SAAS,QAAU,YAAa,CACrC,OAAO,IAAI,cAAc,WAAW,UAAW,OAAO,CACxD,CACA,OAAO,iBAAiB,eAA0B,QAAU,qBAAsB,CAChF,OAAO,IAAI,cAAc,WAAW,mBAAoB,QAAS,IAAA,GAAW,CAC1E,MAAO,eAAe,KAAK,IAAI,CACjC,CAAC,CACH,CACA,OAAO,SAAS,QAAU,WAAY,CACpC,OAAO,IAAI,cAAc,WAAW,SAAU,OAAO,CACvD,CACA,OAAO,cAAc,QAAU,uBAAwB,QAA6B,CAClF,OAAO,IAAI,cAAc,WAAW,qBAAsB,QAAS,OAAO,CAC5E,CACA,OAAO,gBAAgB,QAAU,oBAAqB,kBAA4B,CAChF,OAAO,IAAI,cACT,WAAW,kBACX,QACA,IAAA,GACA,oBAAsB,IAAA,GAA2D,IAAA,GAA/C,CAAE,cAAe,OAAO,iBAAiB,CAAE,CAC/E,CACF,CACA,OAAO,mBAAmB,QAAU,sBAAuB,kBAA4B,CACrF,OAAO,IAAI,cACT,WAAW,oBACX,QACA,IAAA,GACA,oBAAsB,IAAA,GAA2D,IAAA,GAA/C,CAAE,cAAe,OAAO,iBAAiB,CAAE,CAC/E,CACF,CACA,OAAO,SAAS,QAAU,wBAAyB,CACjD,OAAO,IAAI,cAAc,WAAW,sBAAuB,OAAO,CACpE,CACF"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.mjs","names":[],"sources":["../../src/core/interfaces.ts"],"sourcesContent":["import 'reflect-metadata'\n\n/** Lifecycle scope for DI registrations */\nexport enum Scope {\n SINGLETON = 'singleton',\n TRANSIENT = 'transient',\n /** One instance per HTTP request, cached in AsyncLocalStorage. Throws outside request context. */\n REQUEST = 'request',\n}\n\n/** Generic constructor type */\nexport type Constructor<T = any> = new (...args: any[]) => T\n\n/** A value that may or may not be wrapped in a Promise */\nexport type MaybePromise<T = void> = T | Promise<T>\n\n/** Options for @Service, @Repository, @Component decorators */\nexport interface ServiceOptions {\n scope?: Scope\n}\n\n/** Fluent builder type */\nexport type BuilderOf<T> = {\n [K in keyof T as T[K] extends Function ? never : K]-?: (value: T[K]) => BuilderOf<T>\n} & { build(): T }\n\n/** Class with static builder() method */\nexport interface Buildable<T> {\n builder(): BuilderOf<T>\n}\n\n/** Decorator class kind for devtools introspection */\nexport type ClassKind =\n | 'service'\n | 'controller'\n | 'repository'\n | 'component'\n | 'injectable'\n | 'factory'\n | 'instance'\n | 'unknown'\n\n/** PostConstruct lifecycle status */\nexport type PostConstructStatus = 'pending' | 'completed' | 'failed' | 'skipped'\n\n/**\n * String metadata keys for the DI system + decorator subsystem. Every\n * key starts with the `kick:` prefix; the suffix is a short identifier\n * that may itself contain `:`, `-`, or `_` separators (historical —\n * keys grew alongside the framework). The §22 v4 convention is \"no\n * Symbols\", not \"use a strict naming scheme\" — Symbols don't survive\n * JSON serialisation, can't be addressed by string from worker\n * threads, and don't show up in DevTools snapshots.\n *\n * `reflect-metadata` accepts both Symbol and string keys identically,\n * so the consumer-side change is internal — references go through the\n * `METADATA` enum's named members (e.g. `METADATA.INJECT`), not the\n * underlying string.\n *\n * The `design:*` entries match what TypeScript's\n * `emitDecoratorMetadata` writes; those names are fixed by the\n * compiler + must stay as-is.\n */\nexport const METADATA = {\n INJECTABLE: 'kick:injectable',\n SCOPE: 'kick:scope',\n CLASS_KIND: 'kick:class-kind',\n AUTOWIRED: 'kick:autowired',\n INJECT: 'kick:inject',\n POST_CONSTRUCT: 'kick:post_construct',\n BUILDER: 'kick:builder',\n QUERY_PARAMS: 'kick:query:params',\n ROUTES: 'kick:routes',\n CLASS_MIDDLEWARES: 'kick:class:middlewares',\n METHOD_MIDDLEWARES: 'kick:method:middlewares',\n CLASS_CONTRIBUTORS: 'kick:class:contributors',\n METHOD_CONTRIBUTORS: 'kick:method:contributors',\n FILE_UPLOAD: 'kick:file:upload',\n VALUE: 'kick:value',\n ASSET: 'kick:asset',\n // TypeScript emit metadata keys — fixed by the compiler.\n PARAM_TYPES: 'design:paramtypes',\n PROPERTY_TYPE: 'design:type',\n RETURN_TYPE: 'design:returntype',\n} as const\n"],"mappings":";;;;;;;;;;yBAGA,IAAY,MAAL,SAAA,MAAA,OACL,OAAA,UAAA,YACA,MAAA,UAAA,YAEA,MAAA,QAAA,oBACD,CAuDD,MAAa,SAAW,CACtB,WAAY,kBACZ,MAAO,aACP,WAAY,kBACZ,UAAW,iBACX,OAAQ,cACR,eAAgB,sBAChB,QAAS,eACT,aAAc,oBACd,OAAQ,cACR,kBAAmB,yBACnB,mBAAoB,0BACpB,mBAAoB,0BACpB,oBAAqB,2BACrB,YAAa,mBACb,MAAO,aACP,MAAO,aAEP,YAAa,oBACb,cAAe,cACf,YAAa,oBACd"}
1
+ {"version":3,"file":"interfaces.mjs","names":[],"sources":["../../src/core/interfaces.ts"],"sourcesContent":["import 'reflect-metadata'\n\n/** Lifecycle scope for DI registrations */\nexport enum Scope {\n SINGLETON = 'singleton',\n TRANSIENT = 'transient',\n /** One instance per HTTP request, cached in AsyncLocalStorage. Throws outside request context. */\n REQUEST = 'request',\n}\n\n/** Generic constructor type */\nexport type Constructor<T = any> = new (...args: any[]) => T\n\n/** A value that may or may not be wrapped in a Promise */\nexport type MaybePromise<T = void> = T | Promise<T>\n\n/** Options for @Service, @Repository, @Component decorators */\nexport interface ServiceOptions {\n scope?: Scope\n}\n\n/** Fluent builder type */\nexport type BuilderOf<T> = {\n [K in keyof T as T[K] extends Function ? never : K]-?: (value: T[K]) => BuilderOf<T>\n} & { build(): T }\n\n/** Class with static builder() method */\nexport interface Buildable<T> {\n builder(): BuilderOf<T>\n}\n\n/** Decorator class kind for devtools introspection */\nexport type ClassKind =\n | 'service'\n | 'controller'\n | 'repository'\n | 'component'\n | 'injectable'\n | 'factory'\n | 'instance'\n | 'unknown'\n\n/** PostConstruct lifecycle status */\nexport type PostConstructStatus = 'pending' | 'completed' | 'failed' | 'skipped'\n\n/**\n * String metadata keys for the DI system + decorator subsystem. Every\n * key starts with the `kick:` prefix; the suffix is a short identifier\n * that may itself contain `:`, `-`, or `_` separators (historical —\n * keys grew alongside the framework). The §22 v4 convention is \"no\n * Symbols\", not \"use a strict naming scheme\" — Symbols don't survive\n * JSON serialisation, can't be addressed by string from worker\n * threads, and don't show up in DevTools snapshots.\n *\n * `reflect-metadata` accepts both Symbol and string keys identically,\n * so the consumer-side change is internal — references go through the\n * `METADATA` enum's named members (e.g. `METADATA.INJECT`), not the\n * underlying string.\n *\n * The `design:*` entries match what TypeScript's\n * `emitDecoratorMetadata` writes; those names are fixed by the\n * compiler + must stay as-is.\n */\nexport const METADATA = {\n INJECTABLE: 'kick:injectable',\n SCOPE: 'kick:scope',\n CLASS_KIND: 'kick:class-kind',\n AUTOWIRED: 'kick:autowired',\n INJECT: 'kick:inject',\n POST_CONSTRUCT: 'kick:post_construct',\n BUILDER: 'kick:builder',\n QUERY_PARAMS: 'kick:query:params',\n ROUTES: 'kick:routes',\n CLASS_MIDDLEWARES: 'kick:class:middlewares',\n METHOD_MIDDLEWARES: 'kick:method:middlewares',\n CLASS_CONTRIBUTORS: 'kick:class:contributors',\n METHOD_CONTRIBUTORS: 'kick:method:contributors',\n FILE_UPLOAD: 'kick:file:upload',\n VALUE: 'kick:value',\n ASSET: 'kick:asset',\n // TypeScript emit metadata keys — fixed by the compiler.\n PARAM_TYPES: 'design:paramtypes',\n PROPERTY_TYPE: 'design:type',\n RETURN_TYPE: 'design:returntype',\n} as const\n"],"mappings":";;;;;;;;;;yBAGA,IAAY,MAAL,SAAA,MAAA,OACL,OAAA,UAAA,YACA,MAAA,UAAA,YAEA,MAAA,QAAA,eACF,EAAA,CAAA,CAAA,EAuDA,MAAa,SAAW,CACtB,WAAY,kBACZ,MAAO,aACP,WAAY,kBACZ,UAAW,iBACX,OAAQ,cACR,eAAgB,sBAChB,QAAS,eACT,aAAc,oBACd,OAAQ,cACR,kBAAmB,yBACnB,mBAAoB,0BACpB,mBAAoB,0BACpB,oBAAqB,2BACrB,YAAa,mBACb,MAAO,aACP,MAAO,aAEP,YAAa,oBACb,cAAe,cACf,YAAa,mBACf"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1 +1 @@
1
- {"version":3,"file":"logger.mjs","names":[],"sources":["../../src/core/logger.ts"],"sourcesContent":["import pino from 'pino'\n\nconst isDev = process.env.NODE_ENV !== 'production'\n\n/** Root pino logger instance */\nexport const rootLogger = pino({\n level: process.env.LOG_LEVEL || 'info',\n ...(isDev\n ? {\n transport: {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:HH:MM:ss.l',\n singleLine: true,\n ignore: 'pid,hostname,component',\n messageFormat: '{if component}[{component}] {end}{msg}',\n },\n },\n }\n : {}),\n})\n\n// ── LoggerProvider interface ───────────────────────────────────────────\n\n/**\n * Pluggable logger backend.\n *\n * Implement this interface to replace the default pino-based logging\n * with any logging library (winston, bunyan, console, etc.).\n */\nexport interface LoggerProvider {\n info(msg: string, ...args: any[]): void\n warn(msg: string, ...args: any[]): void\n error(msg: string, ...args: any[]): void\n debug(msg: string, ...args: any[]): void\n trace?(msg: string, ...args: any[]): void\n fatal?(msg: string, ...args: any[]): void\n /** Return a child provider scoped to the given component name */\n child(bindings: { component: string }): LoggerProvider\n}\n\n// ── PinoLoggerProvider (default) ───────────────────────────────────────\n\n/** Default provider that delegates to the root pino instance */\nclass PinoLoggerProvider implements LoggerProvider {\n private log: pino.Logger\n\n constructor(pinoInstance?: pino.Logger) {\n this.log = pinoInstance ?? rootLogger\n }\n\n info(msg: string, ...args: any[]) {\n this.log.info(msg, ...args)\n }\n warn(msg: string, ...args: any[]) {\n this.log.warn(msg, ...args)\n }\n error(msg: string, ...args: any[]) {\n this.log.error(msg, ...args)\n }\n debug(msg: string, ...args: any[]) {\n this.log.debug(msg, ...args)\n }\n trace(msg: string, ...args: any[]) {\n this.log.trace(msg, ...args)\n }\n fatal(msg: string, ...args: any[]) {\n this.log.fatal(msg, ...args)\n }\n child(bindings: { component: string }): LoggerProvider {\n return new PinoLoggerProvider(this.log.child(bindings))\n }\n}\n\n// ── ConsoleLoggerProvider ──────────────────────────────────────────────\n\n/**\n * Built-in fallback provider that uses `console.*` methods.\n * Useful for environments where pino is unavailable or undesired.\n */\nexport class ConsoleLoggerProvider implements LoggerProvider {\n private prefix: string\n\n constructor(prefix?: string) {\n this.prefix = prefix ?? ''\n }\n\n private fmt(msg: string): string {\n return this.prefix ? `[${this.prefix}] ${msg}` : msg\n }\n\n info(msg: string, ...args: any[]) {\n console.log(this.fmt(msg), ...args)\n }\n warn(msg: string, ...args: any[]) {\n console.warn(this.fmt(msg), ...args)\n }\n error(msg: string, ...args: any[]) {\n console.error(this.fmt(msg), ...args)\n }\n debug(msg: string, ...args: any[]) {\n console.debug(this.fmt(msg), ...args)\n }\n trace(msg: string, ...args: any[]) {\n console.trace(this.fmt(msg), ...args)\n }\n fatal(msg: string, ...args: any[]) {\n console.error(this.fmt(msg), ...args)\n }\n child(bindings: { component: string }): LoggerProvider {\n return new ConsoleLoggerProvider(bindings.component)\n }\n}\n\n// ── Active provider ────────────────────────────────────────────────────\n\nlet activeProvider: LoggerProvider = new PinoLoggerProvider()\n\n/** Cache of named loggers to avoid creating duplicates */\nconst loggerCache = new Map<string, Logger>()\n\n/**\n * Named logger with component context.\n *\n * @example\n * ```ts\n * // Static factory — preferred\n * const log = Logger.for('UserService')\n * log.info('User created')\n * // Output: [UserService] User created\n *\n * // Shorthand function\n * const log = createLogger('OrderService')\n *\n * // Pluggable backend\n * Logger.setProvider(new ConsoleLoggerProvider())\n *\n * // Injectable — auto-named from class\n * class MyService {\n * @Autowired() private logger!: Logger\n * // or inject a named one:\n * private log = Logger.for('MyService')\n * }\n * ```\n */\nexport class Logger {\n private _provider: LoggerProvider\n private _providerVersion: number\n private _name?: string\n\n /**\n * Optional context provider for request-scoped log enrichment.\n * Set by the HTTP package to inject requestId from AsyncLocalStorage.\n * Returns extra fields to merge into every log call, or null if outside a request.\n */\n static _contextProvider: (() => Record<string, any> | null) | null = null\n\n /** Incremented on every setProvider/resetProvider so instances know to refresh */\n private static _providerVersion = 0\n\n constructor(name?: string) {\n this._name = name\n this._providerVersion = Logger._providerVersion\n this._provider = name ? activeProvider.child({ component: name }) : activeProvider\n }\n\n /** Re-derive the provider if setProvider() was called since construction/last access */\n private get provider(): LoggerProvider {\n if (this._providerVersion !== Logger._providerVersion) {\n this._providerVersion = Logger._providerVersion\n this._provider = this._name ? activeProvider.child({ component: this._name }) : activeProvider\n }\n return this._provider\n }\n\n /**\n * Replace the logging backend for **all** Logger instances created after\n * this call. Clears the logger cache so subsequent `Logger.for()` calls\n * pick up the new provider.\n *\n * @example\n * ```ts\n * Logger.setProvider(new ConsoleLoggerProvider())\n * ```\n */\n static setProvider(provider: LoggerProvider): void {\n activeProvider = provider\n Logger._providerVersion++\n loggerCache.clear()\n }\n\n /** Return the currently active provider (useful for testing) */\n static getProvider(): LoggerProvider {\n return activeProvider\n }\n\n /**\n * Reset the provider back to the default pino-based implementation.\n * Primarily intended for test teardown.\n */\n static resetProvider(): void {\n activeProvider = new PinoLoggerProvider()\n Logger._providerVersion++\n loggerCache.clear()\n }\n\n /** Create or retrieve a cached named logger */\n static for(name: string): Logger {\n let cached = loggerCache.get(name)\n if (!cached) {\n cached = new Logger(name)\n loggerCache.set(name, cached)\n }\n return cached\n }\n\n /** Create a child logger with a sub-component name */\n child(name: string): Logger {\n return new Logger(name)\n }\n\n /** Get request context (requestId, etc.) if inside a request */\n private ctx(): Record<string, any> | undefined {\n return Logger._contextProvider?.() ?? undefined\n }\n\n info(msg: string, ...args: any[]) {\n this.provider.info(msg, ...args)\n }\n\n warn(msg: string, ...args: any[]) {\n this.provider.warn(msg, ...args)\n }\n\n error(msgOrObj: any, msg?: string, ...args: any[]) {\n if (typeof msgOrObj === 'string') {\n this.provider.error(msgOrObj)\n } else if (msg) {\n this.provider.error(msg, ...args)\n } else {\n this.provider.error(String(msgOrObj))\n }\n }\n\n debug(msg: string, ...args: any[]) {\n this.provider.debug(msg, ...args)\n }\n\n trace(msg: string, ...args: any[]) {\n if (this.provider.trace) this.provider.trace(msg, ...args)\n else this.provider.debug(msg, ...args)\n }\n\n fatal(msg: string, ...args: any[]) {\n if (this.provider.fatal) this.provider.fatal(msg, ...args)\n else this.provider.error(msg, ...args)\n }\n}\n\n/** Shorthand for Logger.for(name) */\nexport function createLogger(name: string): Logger {\n return Logger.for(name)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"logger.mjs","names":[],"sources":["../../src/core/logger.ts"],"sourcesContent":["import pino from 'pino'\n\nconst isDev = process.env.NODE_ENV !== 'production'\n\n/** Root pino logger instance */\nexport const rootLogger = pino({\n level: process.env.LOG_LEVEL || 'info',\n ...(isDev\n ? {\n transport: {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'SYS:HH:MM:ss.l',\n singleLine: true,\n ignore: 'pid,hostname,component',\n messageFormat: '{if component}[{component}] {end}{msg}',\n },\n },\n }\n : {}),\n})\n\n// ── LoggerProvider interface ───────────────────────────────────────────\n\n/**\n * Pluggable logger backend.\n *\n * Implement this interface to replace the default pino-based logging\n * with any logging library (winston, bunyan, console, etc.).\n */\nexport interface LoggerProvider {\n info(msg: string, ...args: any[]): void\n warn(msg: string, ...args: any[]): void\n error(msg: string, ...args: any[]): void\n debug(msg: string, ...args: any[]): void\n trace?(msg: string, ...args: any[]): void\n fatal?(msg: string, ...args: any[]): void\n /** Return a child provider scoped to the given component name */\n child(bindings: { component: string }): LoggerProvider\n}\n\n// ── PinoLoggerProvider (default) ───────────────────────────────────────\n\n/** Default provider that delegates to the root pino instance */\nclass PinoLoggerProvider implements LoggerProvider {\n private log: pino.Logger\n\n constructor(pinoInstance?: pino.Logger) {\n this.log = pinoInstance ?? rootLogger\n }\n\n info(msg: string, ...args: any[]) {\n this.log.info(msg, ...args)\n }\n warn(msg: string, ...args: any[]) {\n this.log.warn(msg, ...args)\n }\n error(msg: string, ...args: any[]) {\n this.log.error(msg, ...args)\n }\n debug(msg: string, ...args: any[]) {\n this.log.debug(msg, ...args)\n }\n trace(msg: string, ...args: any[]) {\n this.log.trace(msg, ...args)\n }\n fatal(msg: string, ...args: any[]) {\n this.log.fatal(msg, ...args)\n }\n child(bindings: { component: string }): LoggerProvider {\n return new PinoLoggerProvider(this.log.child(bindings))\n }\n}\n\n// ── ConsoleLoggerProvider ──────────────────────────────────────────────\n\n/**\n * Built-in fallback provider that uses `console.*` methods.\n * Useful for environments where pino is unavailable or undesired.\n */\nexport class ConsoleLoggerProvider implements LoggerProvider {\n private prefix: string\n\n constructor(prefix?: string) {\n this.prefix = prefix ?? ''\n }\n\n private fmt(msg: string): string {\n return this.prefix ? `[${this.prefix}] ${msg}` : msg\n }\n\n info(msg: string, ...args: any[]) {\n console.log(this.fmt(msg), ...args)\n }\n warn(msg: string, ...args: any[]) {\n console.warn(this.fmt(msg), ...args)\n }\n error(msg: string, ...args: any[]) {\n console.error(this.fmt(msg), ...args)\n }\n debug(msg: string, ...args: any[]) {\n console.debug(this.fmt(msg), ...args)\n }\n trace(msg: string, ...args: any[]) {\n console.trace(this.fmt(msg), ...args)\n }\n fatal(msg: string, ...args: any[]) {\n console.error(this.fmt(msg), ...args)\n }\n child(bindings: { component: string }): LoggerProvider {\n return new ConsoleLoggerProvider(bindings.component)\n }\n}\n\n// ── Active provider ────────────────────────────────────────────────────\n\nlet activeProvider: LoggerProvider = new PinoLoggerProvider()\n\n/** Cache of named loggers to avoid creating duplicates */\nconst loggerCache = new Map<string, Logger>()\n\n/**\n * Named logger with component context.\n *\n * @example\n * ```ts\n * // Static factory — preferred\n * const log = Logger.for('UserService')\n * log.info('User created')\n * // Output: [UserService] User created\n *\n * // Shorthand function\n * const log = createLogger('OrderService')\n *\n * // Pluggable backend\n * Logger.setProvider(new ConsoleLoggerProvider())\n *\n * // Injectable — auto-named from class\n * class MyService {\n * @Autowired() private logger!: Logger\n * // or inject a named one:\n * private log = Logger.for('MyService')\n * }\n * ```\n */\nexport class Logger {\n private _provider: LoggerProvider\n private _providerVersion: number\n private _name?: string\n\n /**\n * Optional context provider for request-scoped log enrichment.\n * Set by the HTTP package to inject requestId from AsyncLocalStorage.\n * Returns extra fields to merge into every log call, or null if outside a request.\n */\n static _contextProvider: (() => Record<string, any> | null) | null = null\n\n /** Incremented on every setProvider/resetProvider so instances know to refresh */\n private static _providerVersion = 0\n\n constructor(name?: string) {\n this._name = name\n this._providerVersion = Logger._providerVersion\n this._provider = name ? activeProvider.child({ component: name }) : activeProvider\n }\n\n /** Re-derive the provider if setProvider() was called since construction/last access */\n private get provider(): LoggerProvider {\n if (this._providerVersion !== Logger._providerVersion) {\n this._providerVersion = Logger._providerVersion\n this._provider = this._name ? activeProvider.child({ component: this._name }) : activeProvider\n }\n return this._provider\n }\n\n /**\n * Replace the logging backend for **all** Logger instances created after\n * this call. Clears the logger cache so subsequent `Logger.for()` calls\n * pick up the new provider.\n *\n * @example\n * ```ts\n * Logger.setProvider(new ConsoleLoggerProvider())\n * ```\n */\n static setProvider(provider: LoggerProvider): void {\n activeProvider = provider\n Logger._providerVersion++\n loggerCache.clear()\n }\n\n /** Return the currently active provider (useful for testing) */\n static getProvider(): LoggerProvider {\n return activeProvider\n }\n\n /**\n * Reset the provider back to the default pino-based implementation.\n * Primarily intended for test teardown.\n */\n static resetProvider(): void {\n activeProvider = new PinoLoggerProvider()\n Logger._providerVersion++\n loggerCache.clear()\n }\n\n /** Create or retrieve a cached named logger */\n static for(name: string): Logger {\n let cached = loggerCache.get(name)\n if (!cached) {\n cached = new Logger(name)\n loggerCache.set(name, cached)\n }\n return cached\n }\n\n /** Create a child logger with a sub-component name */\n child(name: string): Logger {\n return new Logger(name)\n }\n\n /** Get request context (requestId, etc.) if inside a request */\n private ctx(): Record<string, any> | undefined {\n return Logger._contextProvider?.() ?? undefined\n }\n\n info(msg: string, ...args: any[]) {\n this.provider.info(msg, ...args)\n }\n\n warn(msg: string, ...args: any[]) {\n this.provider.warn(msg, ...args)\n }\n\n error(msgOrObj: any, msg?: string, ...args: any[]) {\n if (typeof msgOrObj === 'string') {\n this.provider.error(msgOrObj)\n } else if (msg) {\n this.provider.error(msg, ...args)\n } else {\n this.provider.error(String(msgOrObj))\n }\n }\n\n debug(msg: string, ...args: any[]) {\n this.provider.debug(msg, ...args)\n }\n\n trace(msg: string, ...args: any[]) {\n if (this.provider.trace) this.provider.trace(msg, ...args)\n else this.provider.debug(msg, ...args)\n }\n\n fatal(msg: string, ...args: any[]) {\n if (this.provider.fatal) this.provider.fatal(msg, ...args)\n else this.provider.error(msg, ...args)\n }\n}\n\n/** Shorthand for Logger.for(name) */\nexport function createLogger(name: string): Logger {\n return Logger.for(name)\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1 +1 @@
1
- {"version":3,"file":"path.mjs","names":[],"sources":["../../src/core/path.ts"],"sourcesContent":["/**\n * Normalize a URL path segment:\n * - '/' or '' or undefined → ''\n * - Ensures leading '/' if non-empty\n * - Strips trailing '/'\n * - Collapses consecutive '//' into single '/'\n */\nexport function normalizePath(path?: string): string {\n let p = path?.trim() || ''\n if (p === '/') return ''\n if (p && !p.startsWith('/')) p = `/${p}`\n // Strip trailing slash\n p = p.replace(/\\/+$/, '')\n // Collapse double slashes\n p = p.replace(/\\/\\/+/g, '/')\n return p\n}\n\n/**\n * Join path segments into a single normalized path.\n * Handles leading/trailing slashes and prevents double slashes.\n *\n * @example\n * joinPaths('/api/v1', '/users') // '/api/v1/users'\n * joinPaths('/api/v1/', '/users') // '/api/v1/users'\n * joinPaths('/api/v1', '/') // '/api/v1'\n * joinPaths('/api/v1', '') // '/api/v1'\n * joinPaths('/api/v1', 'users') // '/api/v1/users'\n */\nexport function joinPaths(...segments: (string | undefined)[]): string {\n const joined = segments\n .map((s) => s?.trim() || '')\n .filter(Boolean)\n .join('/')\n // Ensure leading slash, collapse doubles\n const normalized = ('/' + joined).replace(/\\/\\/+/g, '/')\n // Strip trailing slash (unless it's just '/')\n return normalized === '/' ? '/' : normalized.replace(/\\/+$/, '')\n}\n"],"mappings":";;;;;;;;;;AAOA,SAAgB,cAAc,KAAuB,CACnD,IAAI,EAAI,MAAM,MAAM,EAAI,GAOxB,OANI,IAAM,IAAY,IAClB,GAAK,CAAC,EAAE,WAAW,IAAI,GAAE,EAAI,IAAI,KAErC,EAAI,EAAE,QAAQ,OAAQ,GAAG,CAEzB,EAAI,EAAE,QAAQ,SAAU,IAAI,CACrB,GAcT,SAAgB,UAAU,GAAG,SAA0C,CAMrE,IAAM,YAAc,IALL,SACZ,IAAK,GAAM,GAAG,MAAM,EAAI,GAAG,CAC3B,OAAO,QAAQ,CACf,KAAK,IAEwB,EAAE,QAAQ,SAAU,IAAI,CAExD,OAAO,aAAe,IAAM,IAAM,WAAW,QAAQ,OAAQ,GAAG"}
1
+ {"version":3,"file":"path.mjs","names":[],"sources":["../../src/core/path.ts"],"sourcesContent":["/**\n * Normalize a URL path segment:\n * - '/' or '' or undefined → ''\n * - Ensures leading '/' if non-empty\n * - Strips trailing '/'\n * - Collapses consecutive '//' into single '/'\n */\nexport function normalizePath(path?: string): string {\n let p = path?.trim() || ''\n if (p === '/') return ''\n if (p && !p.startsWith('/')) p = `/${p}`\n // Strip trailing slash\n p = p.replace(/\\/+$/, '')\n // Collapse double slashes\n p = p.replace(/\\/\\/+/g, '/')\n return p\n}\n\n/**\n * Join path segments into a single normalized path.\n * Handles leading/trailing slashes and prevents double slashes.\n *\n * @example\n * joinPaths('/api/v1', '/users') // '/api/v1/users'\n * joinPaths('/api/v1/', '/users') // '/api/v1/users'\n * joinPaths('/api/v1', '/') // '/api/v1'\n * joinPaths('/api/v1', '') // '/api/v1'\n * joinPaths('/api/v1', 'users') // '/api/v1/users'\n */\nexport function joinPaths(...segments: (string | undefined)[]): string {\n const joined = segments\n .map((s) => s?.trim() || '')\n .filter(Boolean)\n .join('/')\n // Ensure leading slash, collapse doubles\n const normalized = ('/' + joined).replace(/\\/\\/+/g, '/')\n // Strip trailing slash (unless it's just '/')\n return normalized === '/' ? '/' : normalized.replace(/\\/+$/, '')\n}\n"],"mappings":";;;;;;;;;;AAOA,SAAgB,cAAc,KAAuB,CACnD,IAAI,EAAI,MAAM,KAAK,GAAK,GAOxB,OANI,IAAM,IAAY,IAClB,GAAK,CAAC,EAAE,WAAW,GAAG,IAAG,EAAI,IAAI,KAErC,EAAI,EAAE,QAAQ,OAAQ,EAAE,EAExB,EAAI,EAAE,QAAQ,SAAU,GAAG,EACpB,EACT,CAaA,SAAgB,UAAU,GAAG,SAA0C,CAMrE,IAAM,YAAc,IALL,SACZ,IAAK,GAAM,GAAG,KAAK,GAAK,EAAE,EAC1B,OAAO,OAAO,EACd,KAAK,GAEuB,GAAG,QAAQ,SAAU,GAAG,EAEvD,OAAO,aAAe,IAAM,IAAM,WAAW,QAAQ,OAAQ,EAAE,CACjE"}
@@ -1,3 +1,3 @@
1
1
 
2
- import { t as KickPlugin } from "../plugin-NMHVmDRF.mjs";
2
+ import { t as KickPlugin } from "../plugin-BGK3PJOJ.mjs";
3
3
  export { KickPlugin };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1 +1 @@
1
- {"version":3,"file":"reactivity.mjs","names":[],"sources":["../../src/core/reactivity.ts"],"sourcesContent":["/**\n * Lightweight reactivity system inspired by Vue 3's composition API.\n * Provides ref(), computed(), watch(), and reactive() for observable\n * backend state — config, metrics, health, circuit breakers.\n */\n\n// ── Dependency Tracking ─────────────────────────────────────────────────\n\ntype Effect = () => void\nlet activeEffect: Effect | null = null\nconst targetMap = new WeakMap<object, Map<string | symbol, Set<Effect>>>()\n\nfunction track(target: object, key: string | symbol): void {\n if (!activeEffect) return\n let depsMap = targetMap.get(target)\n if (!depsMap) {\n depsMap = new Map()\n targetMap.set(target, depsMap)\n }\n let deps = depsMap.get(key)\n if (!deps) {\n deps = new Set()\n depsMap.set(key, deps)\n }\n deps.add(activeEffect)\n}\n\nfunction trigger(target: object, key: string | symbol): void {\n const depsMap = targetMap.get(target)\n if (!depsMap) return\n const deps = depsMap.get(key)\n if (!deps) return\n for (const effect of deps) {\n effect()\n }\n}\n\n// ── ref() ────────────────────────────────────────────────────────────────\n\nexport interface Ref<T = any> {\n value: T\n /** Subscribe to changes. Returns unsubscribe function. */\n subscribe(fn: (newValue: T, oldValue: T) => void): () => void\n}\n\n/**\n * Create a reactive reference. Reading `.value` tracks the dependency,\n * writing `.value` triggers watchers and computed recalculations.\n *\n * @example\n * ```ts\n * const count = ref(0)\n * count.value++ // triggers watchers\n * ```\n */\nexport function ref<T>(initialValue: T): Ref<T> {\n const subscribers = new Set<(newValue: T, oldValue: T) => void>()\n const wrapper = { _value: initialValue }\n\n return {\n get value(): T {\n track(wrapper, '_value')\n return wrapper._value\n },\n set value(newValue: T) {\n const oldValue = wrapper._value\n if (Object.is(oldValue, newValue)) return\n wrapper._value = newValue\n trigger(wrapper, '_value')\n for (const fn of subscribers) {\n fn(newValue, oldValue)\n }\n },\n subscribe(fn: (newValue: T, oldValue: T) => void): () => void {\n subscribers.add(fn)\n return () => subscribers.delete(fn)\n },\n }\n}\n\n// ── computed() ───────────────────────────────────────────────────────────\n\nexport interface ComputedRef<T = any> {\n readonly value: T\n}\n\n/**\n * Create a computed value that auto-recalculates when its reactive\n * dependencies change. Cached until a dependency triggers.\n *\n * @example\n * ```ts\n * const count = ref(0)\n * const doubled = computed(() => count.value * 2)\n * count.value = 5\n * console.log(doubled.value) // 10\n * ```\n */\nexport function computed<T>(getter: () => T): ComputedRef<T> {\n let cached: T\n let dirty = true\n const wrapper = { _value: undefined as T }\n\n const effect: Effect = () => {\n dirty = true\n trigger(wrapper, '_value')\n }\n\n return {\n get value(): T {\n track(wrapper, '_value')\n if (dirty) {\n const prev = activeEffect\n activeEffect = effect\n try {\n cached = getter()\n } finally {\n activeEffect = prev\n }\n wrapper._value = cached\n dirty = false\n }\n return cached\n },\n }\n}\n\n// ── watch() ──────────────────────────────────────────────────────────────\n\nexport interface WatchOptions {\n /** Run the callback immediately with the current value (default: false) */\n immediate?: boolean\n}\n\ntype WatchSource<T> = Ref<T> | ComputedRef<T> | (() => T)\n\n/**\n * Watch a reactive source and run a callback when it changes.\n * Returns a stop function to unsubscribe.\n *\n * @example\n * ```ts\n * const count = ref(0)\n * const stop = watch(count, (newVal, oldVal) => {\n * console.log(`Changed from ${oldVal} to ${newVal}`)\n * })\n * count.value = 1 // logs: \"Changed from 0 to 1\"\n * stop() // no more callbacks\n * ```\n */\nexport function watch<T>(\n source: WatchSource<T>,\n callback: (newValue: T, oldValue: T) => void,\n options?: WatchOptions,\n): () => void {\n let oldValue: T\n let stopped = false\n\n const getter = typeof source === 'function' ? source : () => source.value\n\n const job: Effect = () => {\n if (stopped) return\n const newValue = getter()\n if (!Object.is(newValue, oldValue)) {\n callback(newValue, oldValue)\n oldValue = newValue\n }\n }\n\n // Initial run to establish tracking\n const prev = activeEffect\n activeEffect = job\n try {\n oldValue = getter()\n } finally {\n activeEffect = prev\n }\n\n if (options?.immediate) {\n callback(oldValue, undefined as T)\n }\n\n return () => {\n stopped = true\n }\n}\n\n// ── reactive() ───────────────────────────────────────────────────────────\n\n/**\n * Create a deeply reactive proxy around a plain object. Property reads\n * are tracked, property writes trigger watchers and computed recalculations.\n *\n * @example\n * ```ts\n * const state = reactive({ users: 0, errors: 0 })\n * const errorRate = computed(() =>\n * state.users > 0 ? state.errors / state.users : 0\n * )\n * state.users = 100\n * state.errors = 5\n * console.log(errorRate.value) // 0.05\n * ```\n */\nexport function reactive<T extends Record<string, any>>(target: T): T {\n return new Proxy(target, {\n get(obj, key, receiver) {\n const value = Reflect.get(obj, key, receiver)\n if (typeof key === 'symbol') return value\n track(obj, key)\n // Deep reactivity for nested objects\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return reactive(value)\n }\n return value\n },\n set(obj, key, value, receiver) {\n const oldValue = Reflect.get(obj, key, receiver)\n const result = Reflect.set(obj, key, value, receiver)\n if (!Object.is(oldValue, value) && typeof key !== 'symbol') {\n trigger(obj, key)\n }\n return result\n },\n })\n}\n\n// ── Utility ──────────────────────────────────────────────────────────────\n\n/** Check if a value is a Ref */\nexport function isRef(value: any): value is Ref {\n return value !== null && typeof value === 'object' && 'subscribe' in value && 'value' in value\n}\n\n/** Unwrap a ref or return the value as-is */\nexport function unref<T>(value: Ref<T> | T): T {\n return isRef(value) ? value.value : value\n}\n\n/** Convert all properties of an object to refs */\nexport function toRefs<T extends Record<string, any>>(obj: T): { [K in keyof T]: Ref<T[K]> } {\n const result = {} as any\n for (const key in obj) {\n result[key] = ref(obj[key])\n }\n return result\n}\n"],"mappings":";;;;;;;;;;AASA,IAAI,aAA8B,KAClC,MAAM,UAAY,IAAI,QAEtB,SAAS,MAAM,OAAgB,IAA4B,CACzD,GAAI,CAAC,aAAc,OACnB,IAAI,QAAU,UAAU,IAAI,OAAO,CAC9B,UACH,QAAU,IAAI,IACd,UAAU,IAAI,OAAQ,QAAQ,EAEhC,IAAI,KAAO,QAAQ,IAAI,IAAI,CACtB,OACH,KAAO,IAAI,IACX,QAAQ,IAAI,IAAK,KAAK,EAExB,KAAK,IAAI,aAAa,CAGxB,SAAS,QAAQ,OAAgB,IAA4B,CAC3D,IAAM,QAAU,UAAU,IAAI,OAAO,CACrC,GAAI,CAAC,QAAS,OACd,IAAM,KAAO,QAAQ,IAAI,IAAI,CACxB,QACL,IAAK,IAAM,UAAU,KACnB,QAAQ,CAsBZ,SAAgB,IAAO,aAAyB,CAC9C,IAAM,YAAc,IAAI,IAClB,QAAU,CAAE,OAAQ,aAAc,CAExC,MAAO,CACL,IAAI,OAAW,CAEb,OADA,MAAM,QAAS,SAAS,CACjB,QAAQ,QAEjB,IAAI,MAAM,SAAa,CACrB,IAAM,SAAW,QAAQ,OACrB,WAAO,GAAG,SAAU,SAAS,CAEjC,CADA,QAAQ,OAAS,SACjB,QAAQ,QAAS,SAAS,CAC1B,IAAK,IAAM,MAAM,YACf,GAAG,SAAU,SAAS,GAG1B,UAAU,GAAoD,CAE5D,OADA,YAAY,IAAI,GAAG,KACN,YAAY,OAAO,GAAG,EAEtC,CAqBH,SAAgB,SAAY,OAAiC,CAC3D,IAAI,OACA,MAAQ,GACN,QAAU,CAAE,OAAQ,IAAA,GAAgB,CAEpC,WAAuB,CAC3B,MAAQ,GACR,QAAQ,QAAS,SAAS,EAG5B,MAAO,CACL,IAAI,OAAW,CAEb,GADA,MAAM,QAAS,SAAS,CACpB,MAAO,CACT,IAAM,KAAO,aACb,aAAe,OACf,GAAI,CACF,OAAS,QAAQ,QACT,CACR,aAAe,KAEjB,QAAQ,OAAS,OACjB,MAAQ,GAEV,OAAO,QAEV,CA0BH,SAAgB,MACd,OACA,SACA,QACY,CACZ,IAAI,SACA,QAAU,GAER,OAAS,OAAO,QAAW,WAAa,WAAe,OAAO,MAE9D,QAAoB,CACxB,GAAI,QAAS,OACb,IAAM,SAAW,QAAQ,CACpB,OAAO,GAAG,SAAU,SAAS,GAChC,SAAS,SAAU,SAAS,CAC5B,SAAW,WAKT,KAAO,aACb,aAAe,IACf,GAAI,CACF,SAAW,QAAQ,QACX,CACR,aAAe,KAOjB,OAJI,SAAS,WACX,SAAS,SAAU,IAAA,GAAe,KAGvB,CACX,QAAU,IAqBd,SAAgB,SAAwC,OAAc,CACpE,OAAO,IAAI,MAAM,OAAQ,CACvB,IAAI,IAAK,IAAK,SAAU,CACtB,IAAM,MAAQ,QAAQ,IAAI,IAAK,IAAK,SAAS,CAO7C,OANI,OAAO,KAAQ,SAAiB,OACpC,MAAM,IAAK,IAAI,CAEO,OAAO,OAAU,UAAnC,OAA+C,CAAC,MAAM,QAAQ,MAAM,CAC/D,SAAS,MAAM,CAEjB,QAET,IAAI,IAAK,IAAK,MAAO,SAAU,CAC7B,IAAM,SAAW,QAAQ,IAAI,IAAK,IAAK,SAAS,CAC1C,OAAS,QAAQ,IAAI,IAAK,IAAK,MAAO,SAAS,CAIrD,MAHI,CAAC,OAAO,GAAG,SAAU,MAAM,EAAI,OAAO,KAAQ,UAChD,QAAQ,IAAK,IAAI,CAEZ,QAEV,CAAC,CAMJ,SAAgB,MAAM,MAA0B,CAC9C,OAAyB,OAAO,OAAU,YAAnC,OAA+C,cAAe,OAAS,UAAW,MAI3F,SAAgB,MAAS,MAAsB,CAC7C,OAAO,MAAM,MAAM,CAAG,MAAM,MAAQ,MAItC,SAAgB,OAAsC,IAAuC,CAC3F,IAAM,OAAS,EAAE,CACjB,IAAK,IAAM,OAAO,IAChB,OAAO,KAAO,IAAI,IAAI,KAAK,CAE7B,OAAO"}
1
+ {"version":3,"file":"reactivity.mjs","names":[],"sources":["../../src/core/reactivity.ts"],"sourcesContent":["/**\n * Lightweight reactivity system inspired by Vue 3's composition API.\n * Provides ref(), computed(), watch(), and reactive() for observable\n * backend state — config, metrics, health, circuit breakers.\n */\n\n// ── Dependency Tracking ─────────────────────────────────────────────────\n\ntype Effect = () => void\nlet activeEffect: Effect | null = null\nconst targetMap = new WeakMap<object, Map<string | symbol, Set<Effect>>>()\n\nfunction track(target: object, key: string | symbol): void {\n if (!activeEffect) return\n let depsMap = targetMap.get(target)\n if (!depsMap) {\n depsMap = new Map()\n targetMap.set(target, depsMap)\n }\n let deps = depsMap.get(key)\n if (!deps) {\n deps = new Set()\n depsMap.set(key, deps)\n }\n deps.add(activeEffect)\n}\n\nfunction trigger(target: object, key: string | symbol): void {\n const depsMap = targetMap.get(target)\n if (!depsMap) return\n const deps = depsMap.get(key)\n if (!deps) return\n for (const effect of deps) {\n effect()\n }\n}\n\n// ── ref() ────────────────────────────────────────────────────────────────\n\nexport interface Ref<T = any> {\n value: T\n /** Subscribe to changes. Returns unsubscribe function. */\n subscribe(fn: (newValue: T, oldValue: T) => void): () => void\n}\n\n/**\n * Create a reactive reference. Reading `.value` tracks the dependency,\n * writing `.value` triggers watchers and computed recalculations.\n *\n * @example\n * ```ts\n * const count = ref(0)\n * count.value++ // triggers watchers\n * ```\n */\nexport function ref<T>(initialValue: T): Ref<T> {\n const subscribers = new Set<(newValue: T, oldValue: T) => void>()\n const wrapper = { _value: initialValue }\n\n return {\n get value(): T {\n track(wrapper, '_value')\n return wrapper._value\n },\n set value(newValue: T) {\n const oldValue = wrapper._value\n if (Object.is(oldValue, newValue)) return\n wrapper._value = newValue\n trigger(wrapper, '_value')\n for (const fn of subscribers) {\n fn(newValue, oldValue)\n }\n },\n subscribe(fn: (newValue: T, oldValue: T) => void): () => void {\n subscribers.add(fn)\n return () => subscribers.delete(fn)\n },\n }\n}\n\n// ── computed() ───────────────────────────────────────────────────────────\n\nexport interface ComputedRef<T = any> {\n readonly value: T\n}\n\n/**\n * Create a computed value that auto-recalculates when its reactive\n * dependencies change. Cached until a dependency triggers.\n *\n * @example\n * ```ts\n * const count = ref(0)\n * const doubled = computed(() => count.value * 2)\n * count.value = 5\n * console.log(doubled.value) // 10\n * ```\n */\nexport function computed<T>(getter: () => T): ComputedRef<T> {\n let cached: T\n let dirty = true\n const wrapper = { _value: undefined as T }\n\n const effect: Effect = () => {\n dirty = true\n trigger(wrapper, '_value')\n }\n\n return {\n get value(): T {\n track(wrapper, '_value')\n if (dirty) {\n const prev = activeEffect\n activeEffect = effect\n try {\n cached = getter()\n } finally {\n activeEffect = prev\n }\n wrapper._value = cached\n dirty = false\n }\n return cached\n },\n }\n}\n\n// ── watch() ──────────────────────────────────────────────────────────────\n\nexport interface WatchOptions {\n /** Run the callback immediately with the current value (default: false) */\n immediate?: boolean\n}\n\ntype WatchSource<T> = Ref<T> | ComputedRef<T> | (() => T)\n\n/**\n * Watch a reactive source and run a callback when it changes.\n * Returns a stop function to unsubscribe.\n *\n * @example\n * ```ts\n * const count = ref(0)\n * const stop = watch(count, (newVal, oldVal) => {\n * console.log(`Changed from ${oldVal} to ${newVal}`)\n * })\n * count.value = 1 // logs: \"Changed from 0 to 1\"\n * stop() // no more callbacks\n * ```\n */\nexport function watch<T>(\n source: WatchSource<T>,\n callback: (newValue: T, oldValue: T) => void,\n options?: WatchOptions,\n): () => void {\n let oldValue: T\n let stopped = false\n\n const getter = typeof source === 'function' ? source : () => source.value\n\n const job: Effect = () => {\n if (stopped) return\n const newValue = getter()\n if (!Object.is(newValue, oldValue)) {\n callback(newValue, oldValue)\n oldValue = newValue\n }\n }\n\n // Initial run to establish tracking\n const prev = activeEffect\n activeEffect = job\n try {\n oldValue = getter()\n } finally {\n activeEffect = prev\n }\n\n if (options?.immediate) {\n callback(oldValue, undefined as T)\n }\n\n return () => {\n stopped = true\n }\n}\n\n// ── reactive() ───────────────────────────────────────────────────────────\n\n/**\n * Create a deeply reactive proxy around a plain object. Property reads\n * are tracked, property writes trigger watchers and computed recalculations.\n *\n * @example\n * ```ts\n * const state = reactive({ users: 0, errors: 0 })\n * const errorRate = computed(() =>\n * state.users > 0 ? state.errors / state.users : 0\n * )\n * state.users = 100\n * state.errors = 5\n * console.log(errorRate.value) // 0.05\n * ```\n */\nexport function reactive<T extends Record<string, any>>(target: T): T {\n return new Proxy(target, {\n get(obj, key, receiver) {\n const value = Reflect.get(obj, key, receiver)\n if (typeof key === 'symbol') return value\n track(obj, key)\n // Deep reactivity for nested objects\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return reactive(value)\n }\n return value\n },\n set(obj, key, value, receiver) {\n const oldValue = Reflect.get(obj, key, receiver)\n const result = Reflect.set(obj, key, value, receiver)\n if (!Object.is(oldValue, value) && typeof key !== 'symbol') {\n trigger(obj, key)\n }\n return result\n },\n })\n}\n\n// ── Utility ──────────────────────────────────────────────────────────────\n\n/** Check if a value is a Ref */\nexport function isRef(value: any): value is Ref {\n return value !== null && typeof value === 'object' && 'subscribe' in value && 'value' in value\n}\n\n/** Unwrap a ref or return the value as-is */\nexport function unref<T>(value: Ref<T> | T): T {\n return isRef(value) ? value.value : value\n}\n\n/** Convert all properties of an object to refs */\nexport function toRefs<T extends Record<string, any>>(obj: T): { [K in keyof T]: Ref<T[K]> } {\n const result = {} as any\n for (const key in obj) {\n result[key] = ref(obj[key])\n }\n return result\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.7.1
2
+ * @forinda/kickjs v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,6 +8,6 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import"./container-jPCvIZH2.mjs";import{METADATA}from"./core/interfaces.mjs";import"./core/logger.mjs";import{c as pushClassMeta,l as pushMethodMeta}from"./metadata-Chvfoj23.mjs";import"./core/decorators.mjs";import"./core/cron.mjs";import"./core/cache.mjs";import"reflect-metadata";const mergeConfig$2=(defaults={},overrides={})=>({...defaults,...overrides}),composeName$2=(base,scope)=>`${base}:${scope}`;function defineModule(options){if(typeof options!=`object`||!options)throw TypeError(`defineModule: options must be an object literal. See architecture.md §21 for the spec shape.`);if(typeof options.name!=`string`||options.name.length===0){let got=typeof options.name==`string`?`""`:typeof options.name;throw TypeError(`defineModule: options.name must be a non-empty string (got ${got}). Module names appear in diagnostics and \`.scoped()\` namespacing — anonymous modules make cycle / missing-dep errors hard to localize.`)}if(typeof options.build!=`function`)throw TypeError(`defineModule(${options.name}): options.build is required and must be a function (got ${typeof options.build}). The build function returns the AppModule shape — register() / routes() / contributors() — wired with the resolved config.`);let buildSync=(instanceName,scoped,overrides)=>{let config=mergeConfig$2(options.defaults,overrides),built=options.build(config,{name:instanceName,scoped});return Object.defineProperty(built,`__moduleName`,{value:instanceName,enumerable:!1,writable:!1,configurable:!1}),built},factory=(config=>buildSync(options.name,!1,config));return factory.scoped=(scopeName,config)=>buildSync(composeName$2(options.name,scopeName),!0,config),Object.defineProperty(factory,`definition`,{value:Object.freeze({...options}),writable:!1,enumerable:!0,configurable:!1}),factory}var ModuleList=class extends Array{mount(module){return this.push(module),this}};function defineModules(...initial){let list=new ModuleList;for(let entry of initial)list.push(entry);return list}var MutableModuleRegistry=class{entries=[];mount(module){this.entries.push(module)}},CircuitOpenError=class extends Error{constructor(breakerName){super(`Circuit breaker "${breakerName}" is open — request rejected`),this.breakerName=breakerName,this.name=`CircuitOpenError`}},CircuitBreaker=class{state=`closed`;failures=0;successes=0;halfOpenAttempts=0;lastFailure;openedAt;failureThreshold;resetTimeout;halfOpenMax;constructor(name,options){this.name=name,this.failureThreshold=options.failureThreshold,this.resetTimeout=options.resetTimeout,this.halfOpenMax=options.halfOpenMax??1}async execute(fn){if(this.maybeTransitionToHalfOpen(),this.state===`open`||this.state===`half_open`&&this.halfOpenAttempts>=this.halfOpenMax)throw new CircuitOpenError(this.name);this.state===`half_open`&&this.halfOpenAttempts++;try{let result=await fn();return this.onSuccess(),result}catch(error){throw this.onFailure(),error}}getState(){return this.maybeTransitionToHalfOpen(),this.state}getStats(){return this.maybeTransitionToHalfOpen(),{failures:this.failures,successes:this.successes,state:this.state,...this.lastFailure?{lastFailure:this.lastFailure}:{}}}reset(){this.state=`closed`,this.failures=0,this.successes=0,this.halfOpenAttempts=0,this.lastFailure=void 0,this.openedAt=void 0}onSuccess(){this.state===`half_open`&&(this.state=`closed`,this.failures=0,this.halfOpenAttempts=0,this.openedAt=void 0),this.successes++}onFailure(){this.failures++,this.lastFailure=new Date,this.state===`half_open`?(this.state=`open`,this.openedAt=Date.now(),this.halfOpenAttempts=0):this.state===`closed`&&this.failures>=this.failureThreshold&&(this.state=`open`,this.openedAt=Date.now())}maybeTransitionToHalfOpen(){this.state===`open`&&this.openedAt!=null&&Date.now()-this.openedAt>=this.resetTimeout&&(this.state=`half_open`,this.halfOpenAttempts=0)}};function defineContextDecorator(spec){if(typeof spec!=`object`||!spec)throw TypeError(`defineContextDecorator: spec must be an object literal. See architecture.md §20.4 for the spec shape.`);if(typeof spec.key!=`string`||spec.key.length===0){let got=typeof spec.key==`string`?`""`:typeof spec.key;throw TypeError(`defineContextDecorator: spec.key must be a non-empty string (got ${got}). Pick a name that matches a key declared on \`ContextMeta\` (or one of the framework keys).`)}if(typeof spec.resolve!=`function`)throw TypeError(`defineContextDecorator(${spec.key}): spec.resolve is required and must be a function (got ${typeof spec.resolve}). Each contributor needs a resolver that produces the value to write into ctx.set(${JSON.stringify(spec.key)}, …).`);if(spec.onError!==void 0&&typeof spec.onError!=`function`)throw TypeError(`defineContextDecorator(${spec.key}): spec.onError must be a function when provided (got ${typeof spec.onError}).`);if(spec.dependsOn!==void 0&&!Array.isArray(spec.dependsOn))throw TypeError(`defineContextDecorator(${spec.key}): spec.dependsOn must be an array when provided (got ${typeof spec.dependsOn}).`);if(Array.isArray(spec.dependsOn)&&spec.dependsOn.some(dep=>typeof dep!=`string`||dep.length===0))throw TypeError(`defineContextDecorator(${spec.key}): spec.dependsOn entries must be non-empty strings.`);let definedAt=Error().stack,defaults=Object.freeze({...spec.paramDefaults??{}}),sharedDeps=Object.freeze({...spec.deps??{}}),sharedDependsOn=Object.freeze([...spec.dependsOn??[]]),sharedOptional=spec.optional??!1,buildRegistration=params=>{let frozenParams=Object.freeze({...params}),onError=spec.onError?(err,ctx)=>spec.onError(err,ctx,frozenParams):void 0;return Object.freeze({key:spec.key,deps:sharedDeps,dependsOn:sharedDependsOn,optional:sharedOptional,onError,resolve:(ctx,deps)=>spec.resolve(ctx,deps,frozenParams),definedAt})},defaultRegistration=buildRegistration({...defaults}),isDecoratorCall=args=>args.length===0?!1:args.length>=2||typeof args[0]==`function`,applyAsDecorator=(registration,target,propertyKey)=>{if(propertyKey===void 0)pushClassMeta(METADATA.CLASS_CONTRIBUTORS,target,registration);else{let constructor=target.constructor;pushMethodMeta(METADATA.METHOD_CONTRIBUTORS,constructor,String(propertyKey),registration)}},isPlainObject=value=>{let proto=Object.getPrototypeOf(value);return proto===Object.prototype||proto===null},mergeParams=override=>{if(override===void 0)return{...defaults};if(typeof override!=`object`||!override||Array.isArray(override)||!isPlainObject(override)){let got=override===null?`null`:Array.isArray(override)?`array`:typeof override==`object`?`instance of ${override.constructor?.name??`unknown class`}`:typeof override;throw TypeError(`defineContextDecorator(${spec.key}): factory call requires a plain object literal, got ${got}. Class instances and built-ins (Map, Date, etc) silently spread to empty objects — call the decorator with a spread object literal instead, e.g. \`MyDecorator({ ...someInstance })\`.`)}return{...defaults,...override}};function decoratorOrFactory(...args){if(isDecoratorCall(args)){let[target,propertyKey]=args;applyAsDecorator(defaultRegistration,target,propertyKey);return}let registration=buildRegistration(mergeParams(args[0]));return(target,propertyKey)=>{applyAsDecorator(registration,target,propertyKey)}}Object.defineProperty(decoratorOrFactory,`name`,{value:`ContextDecorator(${spec.key})`,writable:!1,enumerable:!1,configurable:!0});let decorator=Object.assign(decoratorOrFactory,{registration:defaultRegistration,with:params=>({registration:buildRegistration(mergeParams(params))})});return Object.freeze(decorator)}var MissingContributorError=class extends Error{key;dependent;route;dependentDefinedAt;constructor(key,dependent,route,dependentDefinedAt){let where=route?` on route ${route}`:``,declaredAt=formatDeclaredAt(dependentDefinedAt);super(`Missing context contributor '${key}' required by '${dependent}'${where}${declaredAt}`),this.name=`MissingContributorError`,this.key=key,this.dependent=dependent,this.route=route,this.dependentDefinedAt=dependentDefinedAt}};function formatDeclaredAt(stack){if(!stack)return``;let lines=stack.split(`
11
+ import"./container-BvRsVif5.mjs";import{METADATA}from"./core/interfaces.mjs";import"./core/logger.mjs";import{c as pushClassMeta,l as pushMethodMeta}from"./metadata-DN0sBHmY.mjs";import"./core/decorators.mjs";import"./core/cron.mjs";import"./core/cache.mjs";import"reflect-metadata";const mergeConfig$2=(defaults={},overrides={})=>({...defaults,...overrides}),composeName$2=(base,scope)=>`${base}:${scope}`;function defineModule(options){if(typeof options!=`object`||!options)throw TypeError(`defineModule: options must be an object literal. See architecture.md §21 for the spec shape.`);if(typeof options.name!=`string`||options.name.length===0){let got=typeof options.name==`string`?`""`:typeof options.name;throw TypeError(`defineModule: options.name must be a non-empty string (got ${got}). Module names appear in diagnostics and \`.scoped()\` namespacing — anonymous modules make cycle / missing-dep errors hard to localize.`)}if(typeof options.build!=`function`)throw TypeError(`defineModule(${options.name}): options.build is required and must be a function (got ${typeof options.build}). The build function returns the AppModule shape — register() / routes() / contributors() — wired with the resolved config.`);let buildSync=(instanceName,scoped,overrides)=>{let config=mergeConfig$2(options.defaults,overrides),built=options.build(config,{name:instanceName,scoped});return Object.defineProperty(built,`__moduleName`,{value:instanceName,enumerable:!1,writable:!1,configurable:!1}),built},factory=(config=>buildSync(options.name,!1,config));return factory.scoped=(scopeName,config)=>buildSync(composeName$2(options.name,scopeName),!0,config),Object.defineProperty(factory,`definition`,{value:Object.freeze({...options}),writable:!1,enumerable:!0,configurable:!1}),factory}var ModuleList=class extends Array{mount(module){return this.push(module),this}};function defineModules(...initial){let list=new ModuleList;for(let entry of initial)list.push(entry);return list}var MutableModuleRegistry=class{entries=[];mount(module){this.entries.push(module)}},CircuitOpenError=class extends Error{breakerName;constructor(breakerName){super(`Circuit breaker "${breakerName}" is open — request rejected`),this.breakerName=breakerName,this.name=`CircuitOpenError`}},CircuitBreaker=class{name;state=`closed`;failures=0;successes=0;halfOpenAttempts=0;lastFailure;openedAt;failureThreshold;resetTimeout;halfOpenMax;constructor(name,options){this.name=name,this.failureThreshold=options.failureThreshold,this.resetTimeout=options.resetTimeout,this.halfOpenMax=options.halfOpenMax??1}async execute(fn){if(this.maybeTransitionToHalfOpen(),this.state===`open`||this.state===`half_open`&&this.halfOpenAttempts>=this.halfOpenMax)throw new CircuitOpenError(this.name);this.state===`half_open`&&this.halfOpenAttempts++;try{let result=await fn();return this.onSuccess(),result}catch(error){throw this.onFailure(),error}}getState(){return this.maybeTransitionToHalfOpen(),this.state}getStats(){return this.maybeTransitionToHalfOpen(),{failures:this.failures,successes:this.successes,state:this.state,...this.lastFailure?{lastFailure:this.lastFailure}:{}}}reset(){this.state=`closed`,this.failures=0,this.successes=0,this.halfOpenAttempts=0,this.lastFailure=void 0,this.openedAt=void 0}onSuccess(){this.state===`half_open`&&(this.state=`closed`,this.failures=0,this.halfOpenAttempts=0,this.openedAt=void 0),this.successes++}onFailure(){this.failures++,this.lastFailure=new Date,this.state===`half_open`?(this.state=`open`,this.openedAt=Date.now(),this.halfOpenAttempts=0):this.state===`closed`&&this.failures>=this.failureThreshold&&(this.state=`open`,this.openedAt=Date.now())}maybeTransitionToHalfOpen(){this.state===`open`&&this.openedAt!=null&&Date.now()-this.openedAt>=this.resetTimeout&&(this.state=`half_open`,this.halfOpenAttempts=0)}};function defineContextDecorator(spec){if(typeof spec!=`object`||!spec)throw TypeError(`defineContextDecorator: spec must be an object literal. See architecture.md §20.4 for the spec shape.`);if(typeof spec.key!=`string`||spec.key.length===0){let got=typeof spec.key==`string`?`""`:typeof spec.key;throw TypeError(`defineContextDecorator: spec.key must be a non-empty string (got ${got}). Pick a name that matches a key declared on \`ContextMeta\` (or one of the framework keys).`)}if(typeof spec.resolve!=`function`)throw TypeError(`defineContextDecorator(${spec.key}): spec.resolve is required and must be a function (got ${typeof spec.resolve}). Each contributor needs a resolver that produces the value to write into ctx.set(${JSON.stringify(spec.key)}, …).`);if(spec.onError!==void 0&&typeof spec.onError!=`function`)throw TypeError(`defineContextDecorator(${spec.key}): spec.onError must be a function when provided (got ${typeof spec.onError}).`);if(spec.dependsOn!==void 0&&!Array.isArray(spec.dependsOn))throw TypeError(`defineContextDecorator(${spec.key}): spec.dependsOn must be an array when provided (got ${typeof spec.dependsOn}).`);if(Array.isArray(spec.dependsOn)&&spec.dependsOn.some(dep=>typeof dep!=`string`||dep.length===0))throw TypeError(`defineContextDecorator(${spec.key}): spec.dependsOn entries must be non-empty strings.`);let definedAt=Error().stack,defaults=Object.freeze({...spec.paramDefaults??{}}),sharedDeps=Object.freeze({...spec.deps??{}}),sharedDependsOn=Object.freeze([...spec.dependsOn??[]]),sharedOptional=spec.optional??!1,buildRegistration=params=>{let frozenParams=Object.freeze({...params}),onError=spec.onError?(err,ctx)=>spec.onError(err,ctx,frozenParams):void 0;return Object.freeze({key:spec.key,deps:sharedDeps,dependsOn:sharedDependsOn,optional:sharedOptional,onError,resolve:(ctx,deps)=>spec.resolve(ctx,deps,frozenParams),definedAt})},defaultRegistration=buildRegistration({...defaults}),isDecoratorCall=args=>args.length===0?!1:args.length>=2||typeof args[0]==`function`,applyAsDecorator=(registration,target,propertyKey)=>{if(propertyKey===void 0)pushClassMeta(METADATA.CLASS_CONTRIBUTORS,target,registration);else{let constructor=target.constructor;pushMethodMeta(METADATA.METHOD_CONTRIBUTORS,constructor,String(propertyKey),registration)}},isPlainObject=value=>{let proto=Object.getPrototypeOf(value);return proto===Object.prototype||proto===null},mergeParams=override=>{if(override===void 0)return{...defaults};if(typeof override!=`object`||!override||Array.isArray(override)||!isPlainObject(override)){let got=override===null?`null`:Array.isArray(override)?`array`:typeof override==`object`?`instance of ${override.constructor?.name??`unknown class`}`:typeof override;throw TypeError(`defineContextDecorator(${spec.key}): factory call requires a plain object literal, got ${got}. Class instances and built-ins (Map, Date, etc) silently spread to empty objects — call the decorator with a spread object literal instead, e.g. \`MyDecorator({ ...someInstance })\`.`)}return{...defaults,...override}};function decoratorOrFactory(...args){if(isDecoratorCall(args)){let[target,propertyKey]=args;applyAsDecorator(defaultRegistration,target,propertyKey);return}let registration=buildRegistration(mergeParams(args[0]));return(target,propertyKey)=>{applyAsDecorator(registration,target,propertyKey)}}Object.defineProperty(decoratorOrFactory,`name`,{value:`ContextDecorator(${spec.key})`,writable:!1,enumerable:!1,configurable:!0});let decorator=Object.assign(decoratorOrFactory,{registration:defaultRegistration,with:params=>({registration:buildRegistration(mergeParams(params))})});return Object.freeze(decorator)}var MissingContributorError=class extends Error{key;dependent;route;dependentDefinedAt;constructor(key,dependent,route,dependentDefinedAt){let where=route?` on route ${route}`:``,declaredAt=formatDeclaredAt(dependentDefinedAt);super(`Missing context contributor '${key}' required by '${dependent}'${where}${declaredAt}`),this.name=`MissingContributorError`,this.key=key,this.dependent=dependent,this.route=route,this.dependentDefinedAt=dependentDefinedAt}};function formatDeclaredAt(stack){if(!stack)return``;let lines=stack.split(`
12
12
  `);for(let line of lines){let trimmed=line.trim();if(trimmed.startsWith(`at `)&&!trimmed.includes(`context-decorator.`)&&!trimmed.includes(`context-errors.`))return`\n declared at ${trimmed.replace(/^at /,``)}`}return``}var ContributorCycleError=class extends Error{cycle;route;constructor(cycle,route){let where=route?` on route ${route}`:``;super(`Cycle in context contributors${where}: ${cycle.join(` → `)}`),this.name=`ContributorCycleError`,this.cycle=Object.freeze([...cycle]),this.route=route}},DuplicateContributorError=class extends Error{key;sources;constructor(key,sources){super(`Duplicate context contributor for key '${key}' at the same precedence level. Sources: ${sources.join(`, `)}`),this.name=`DuplicateContributorError`,this.key=key,this.sources=Object.freeze([...sources])}};const PRECEDENCE_ORDER=[`method`,`class`,`module`,`adapter`,`global`];function buildPipeline(sources,options={}){let route=options.route,bySource=new Map;for(let src of PRECEDENCE_ORDER)bySource.set(src,[]);for(let entry of sources)bySource.get(entry.source).push(entry);let winners=new Map;for(let src of PRECEDENCE_ORDER){let rows=bySource.get(src),keysAtThisLevel=new Map;for(let row of rows){let key=row.registration.key,existing=keysAtThisLevel.get(key)??[];existing.push(row),keysAtThisLevel.set(key,existing)}for(let[key,rowsForKey]of keysAtThisLevel){if(rowsForKey.length>1)throw new DuplicateContributorError(key,rowsForKey.map((r,i)=>r.label??`${src}#${i}`));winners.has(key)||winners.set(key,rowsForKey[0])}}let survivors=[...winners.values()].map(r=>r.registration),allKeys=new Set(survivors.map(r=>r.key));for(let reg of survivors)for(let dep of reg.dependsOn)if(!allKeys.has(dep))throw new MissingContributorError(dep,reg.key,route,reg.definedAt);let sorted=topoSort(survivors,route);return Object.freeze({contributors:Object.freeze(sorted),keys:allKeys})}function topoSort(registrations,route){let indegree=new Map,dependents=new Map,byKey=new Map;for(let reg of registrations)indegree.set(reg.key,reg.dependsOn.length),byKey.set(reg.key,reg);for(let reg of registrations)for(let dep of reg.dependsOn){let list=dependents.get(dep)??[];list.push(reg),dependents.set(dep,list)}let queue=[];for(let reg of registrations)indegree.get(reg.key)===0&&queue.push(reg);let sorted=[];for(;queue.length>0;){let node=queue.shift();sorted.push(node);for(let dependent of dependents.get(node.key)??[]){let next=(indegree.get(dependent.key)??0)-1;indegree.set(dependent.key,next),next===0&&queue.push(dependent)}}if(sorted.length!==registrations.length)throw new ContributorCycleError(reconstructCycle$1(registrations.filter(r=>(indegree.get(r.key)??0)>0),byKey),route);return sorted}function reconstructCycle$1(residual,byKey){let residualKeys=new Set(residual.map(r=>r.key)),start=residual[0].key,path=[start],seen=new Set([start]),cursor=start;for(;;){let nextDep=byKey.get(cursor).dependsOn.find(d=>residualKeys.has(d));if(nextDep===void 0)break;if(seen.has(nextDep)){let cycleStart=path.indexOf(nextDep);return[...path.slice(cycleStart),nextDep]}path.push(nextDep),seen.add(nextDep),cursor=nextDep}return path}async function runContributors(options){let{pipeline,ctx,container}=options;for(let reg of pipeline.contributors)await runOne(reg,ctx,container)}async function runOne(reg,ctx,container){let value;try{let deps=resolveDeps(reg,container);value=await reg.resolve(ctx,deps)}catch(err){if(reg.optional)return;if(reg.onError){let replacement=await reg.onError(err,ctx);if(replacement===void 0)return;ctx.set(reg.key,replacement);return}throw err}ctx.set(reg.key,value)}function resolveDeps(reg,container){let out={};for(let[key,token]of Object.entries(reg.deps))out[key]=container.resolve(token);return out}var DuplicateMountNameError=class extends Error{kind;mountName;constructor(kind,mountName){super(`Duplicate ${kind} name '${mountName}' — every ${kind} must declare a unique name`),this.name=`DuplicateMountNameError`,this.kind=kind,this.mountName=mountName}},MissingMountDepError=class extends Error{kind;missing;dependent;constructor(kind,missing,dependent){super(`Missing ${kind} dependency '${missing}' required by '${dependent}' — is the ${kind} installed and named correctly?`),this.name=`MissingMountDepError`,this.kind=kind,this.missing=missing,this.dependent=dependent}},MountCycleError=class extends Error{kind;cycle;constructor(kind,cycle){super(`Cycle in ${kind} dependsOn declarations: ${cycle.join(` → `)}`),this.name=`MountCycleError`,this.kind=kind,this.cycle=Object.freeze([...cycle])}};function mountSort(items,kind){let byName=new Map;for(let item of items){if(byName.has(item.name))throw new DuplicateMountNameError(kind,item.name);byName.set(item.name,item)}let indegree=new Map,dependents=new Map;for(let item of items)indegree.set(item.name,item.dependsOn?.length??0);for(let item of items)for(let dep of item.dependsOn??[]){if(!byName.has(dep))throw new MissingMountDepError(kind,dep,item.name);let list=dependents.get(dep)??[];list.push(item),dependents.set(dep,list)}let queue=[];for(let item of items)indegree.get(item.name)===0&&queue.push(item);let sorted=[];for(;queue.length>0;){let node=queue.shift();sorted.push(node);for(let dependent of dependents.get(node.name)??[]){let next=(indegree.get(dependent.name)??0)-1;indegree.set(dependent.name,next),next===0&&queue.push(dependent)}}if(sorted.length!==items.length)throw new MountCycleError(kind,reconstructCycle(items.filter(it=>(indegree.get(it.name)??0)>0),byName));return sorted}function reconstructCycle(residual,byName){let residualNames=new Set(residual.map(r=>r.name)),start=residual[0].name,path=[start],seen=new Set([start]),cursor=start;for(;;){let nextDep=byName.get(cursor).dependsOn?.find(d=>residualNames.has(d));if(nextDep===void 0)break;if(seen.has(nextDep)){let cycleStart=path.indexOf(nextDep);return[...path.slice(cycleStart),nextDep]}path.push(nextDep),seen.add(nextDep),cursor=nextDep}return path}const mergeConfig$1=(defaults={},overrides={})=>({...defaults,...overrides}),composeName$1=(base,scope)=>`${base}:${scope}`;function definePlugin(options){let buildSync=(instanceName,scoped,overrides)=>{let config=mergeConfig$1(options.defaults,overrides),built=options.build(config,{name:instanceName,scoped});return built.name=instanceName,built},buildAsync=(instanceName,opts)=>{let inner,ensureInner=async container=>{if(inner)return inner;let deps=(opts.inject??[]).map(tok=>container.resolve(tok));return inner=buildSync(instanceName,!1,await opts.useFactory(...deps)),inner};return{name:instanceName,async onReady(container){let built=await ensureInner(container);built.register?.(container),await built.onReady?.(container)},async shutdown(){await inner?.shutdown?.()}}},factory=(config=>buildSync(options.name,!1,config));return factory.scoped=(scopeName,config)=>buildSync(composeName$1(options.name,scopeName),!0,config),factory.async=opts=>buildAsync(options.name,opts),Object.defineProperty(factory,`definition`,{value:Object.freeze({...options})}),factory}const mergeConfig=(defaults={},overrides={})=>({...defaults,...overrides}),composeName=(base,scope)=>`${base}:${scope}`;function defineAdapter(options){let buildSync=(instanceName,scoped,overrides)=>{let config=mergeConfig(options.defaults,overrides),built=options.build(config,{name:instanceName,scoped});return built.name=instanceName,built},buildAsync=(instanceName,opts)=>{let inner;return{name:instanceName,async beforeStart(ctx){let deps=(opts.inject??[]).map(tok=>ctx.container.resolve(tok));inner=buildSync(instanceName,!1,await opts.useFactory(...deps)),await inner.beforeStart?.(ctx)},async afterStart(ctx){await inner?.afterStart?.(ctx)},async shutdown(){await inner?.shutdown?.()},async onHealthCheck(){return await inner?.onHealthCheck?.()??{name:instanceName,status:`up`}}}},factory=(config=>buildSync(options.name,!1,config));return factory.scoped=(scopeName,config)=>buildSync(composeName(options.name,scopeName),!0,config),factory.async=opts=>buildAsync(options.name,opts),Object.defineProperty(factory,`definition`,{value:Object.freeze({...options})}),factory}function defineAugmentation(name,meta){}export{ModuleList as _,MissingMountDepError as a,runContributors as c,DuplicateContributorError as d,MissingContributorError as f,MutableModuleRegistry as g,CircuitOpenError as h,DuplicateMountNameError as i,buildPipeline as l,CircuitBreaker as m,defineAdapter as n,MountCycleError as o,defineContextDecorator as p,definePlugin as r,mountSort as s,defineAugmentation as t,ContributorCycleError as u,defineModules as v,defineModule as y};
13
- //# sourceMappingURL=core-DR36jGxB.mjs.map
13
+ //# sourceMappingURL=core-BQHQsimv.mjs.map