@forinda/kickjs 6.4.0 → 6.5.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 (127) hide show
  1. package/dist/{adapter-BjxEv8oW.d.mts → adapter-CEt1MEdF.d.mts} +120 -10
  2. package/dist/adapter-CEt1MEdF.d.mts.map +1 -0
  3. package/dist/{app-module-BwYtACD6.d.mts → app-module-BSpHKlhE.d.mts} +149 -28
  4. package/dist/app-module-BSpHKlhE.d.mts.map +1 -0
  5. package/dist/{application-Bo3jSfmL.d.mts → application-Bzdzl5wP.d.mts} +3 -3
  6. package/dist/{application-Bo3jSfmL.d.mts.map → application-Bzdzl5wP.d.mts.map} +1 -1
  7. package/dist/{application-TiHVcGRL.mjs → application-C-r79XqD.mjs} +3 -3
  8. package/dist/{application-TiHVcGRL.mjs.map → application-C-r79XqD.mjs.map} +1 -1
  9. package/dist/{bootstrap-DW2yzKh6.mjs → bootstrap-C1VGQQVF.mjs} +3 -3
  10. package/dist/{bootstrap-DW2yzKh6.mjs.map → bootstrap-C1VGQQVF.mjs.map} +1 -1
  11. package/dist/{bootstrap-DUUxZXvF.d.mts → bootstrap-DYexY169.d.mts} +2 -2
  12. package/dist/{bootstrap-DUUxZXvF.d.mts.map → bootstrap-DYexY169.d.mts.map} +1 -1
  13. package/dist/config/index.mjs +2 -2
  14. package/dist/{config-BTDTXaeZ.mjs → config-BeIZJBXA.mjs} +3 -3
  15. package/dist/{config-BTDTXaeZ.mjs.map → config-BeIZJBXA.mjs.map} +1 -1
  16. package/dist/{container-Da9BLMHy.mjs → container-CBaL5lus.mjs} +3 -3
  17. package/dist/{container-Da9BLMHy.mjs.map → container-CBaL5lus.mjs.map} +1 -1
  18. package/dist/context-BS5o1IuU.mjs +12 -0
  19. package/dist/context-BS5o1IuU.mjs.map +1 -0
  20. package/dist/context-errors-CwD27Vbj.mjs +13 -0
  21. package/dist/context-errors-CwD27Vbj.mjs.map +1 -0
  22. package/dist/contributor-runner-Cu13cDQp.mjs +12 -0
  23. package/dist/contributor-runner-Cu13cDQp.mjs.map +1 -0
  24. package/dist/core/adapter.d.mts +1 -1
  25. package/dist/core/adapter.mjs +1 -1
  26. package/dist/core/app-module.d.mts +1 -1
  27. package/dist/core/app-module.mjs +1 -1
  28. package/dist/core/cache.mjs +1 -1
  29. package/dist/core/container.mjs +2 -2
  30. package/dist/core/cron.mjs +2 -2
  31. package/dist/core/decorators.mjs +2 -2
  32. package/dist/core/errors.mjs +1 -1
  33. package/dist/core/interfaces.mjs +1 -1
  34. package/dist/core/logger.d.mts +2 -2
  35. package/dist/core/logger.mjs +2 -2
  36. package/dist/core/logger.mjs.map +1 -1
  37. package/dist/core/path.mjs +1 -1
  38. package/dist/core/plugin.d.mts +1 -1
  39. package/dist/core/plugin.mjs +1 -1
  40. package/dist/core/reactivity.mjs +1 -1
  41. package/dist/core-TDR0XGzO.mjs +12 -0
  42. package/dist/core-TDR0XGzO.mjs.map +1 -0
  43. package/dist/{csrf-Dlo-P8Il.mjs → csrf-DNh_7aOk.mjs} +2 -2
  44. package/dist/{csrf-Dlo-P8Il.mjs.map → csrf-DNh_7aOk.mjs.map} +1 -1
  45. package/dist/{disposables-rPSyh69r.mjs → disposables-mnjJuaVx.mjs} +2 -2
  46. package/dist/{disposables-rPSyh69r.mjs.map → disposables-mnjJuaVx.mjs.map} +1 -1
  47. package/dist/{env-Ce-aYRxQ.mjs → env-Dgtjncd5.mjs} +3 -3
  48. package/dist/{env-Ce-aYRxQ.mjs.map → env-Dgtjncd5.mjs.map} +1 -1
  49. package/dist/{error-handler-3ih4E-QZ.d.mts → error-handler-DR01K_rI.d.mts} +5 -1
  50. package/dist/error-handler-DR01K_rI.d.mts.map +1 -0
  51. package/dist/handler-UvmjQGYc.mjs +13 -0
  52. package/dist/handler-UvmjQGYc.mjs.map +1 -0
  53. package/dist/http/application.d.mts +1 -1
  54. package/dist/http/application.mjs +2 -2
  55. package/dist/http/bootstrap.d.mts +1 -1
  56. package/dist/http/bootstrap.mjs +2 -2
  57. package/dist/http/context.d.mts +2 -2
  58. package/dist/http/context.mjs +2 -2
  59. package/dist/http/middleware/cors.mjs +1 -1
  60. package/dist/http/middleware/csrf.mjs +2 -2
  61. package/dist/http/middleware/error-handler.d.mts +1 -1
  62. package/dist/http/middleware/error-handler.mjs +3 -2
  63. package/dist/http/middleware/error-handler.mjs.map +1 -1
  64. package/dist/http/middleware/helmet.mjs +1 -1
  65. package/dist/http/middleware/rate-limit.mjs +2 -2
  66. package/dist/http/middleware/request-id.mjs +1 -1
  67. package/dist/http/middleware/request-logger.mjs +2 -2
  68. package/dist/http/middleware/session.mjs +2 -2
  69. package/dist/http/middleware/spa.d.mts +1 -1
  70. package/dist/http/middleware/spa.mjs +2 -2
  71. package/dist/http/middleware/upload.mjs +2 -2
  72. package/dist/http/middleware/validate.mjs +1 -1
  73. package/dist/http/middleware/views.d.mts +1 -1
  74. package/dist/http/middleware/views.mjs +2 -2
  75. package/dist/http/query/index.mjs +2 -2
  76. package/dist/http/router-builder.d.mts +1 -1
  77. package/dist/http/router-builder.mjs +2 -2
  78. package/dist/http/runtimes/fastify.d.mts +1 -1
  79. package/dist/http/runtimes/fastify.mjs +2 -2
  80. package/dist/http/runtimes/h3-web.d.mts +1 -1
  81. package/dist/http/runtimes/h3-web.d.mts.map +1 -1
  82. package/dist/http/runtimes/h3-web.mjs +2 -2
  83. package/dist/http/runtimes/h3-web.mjs.map +1 -1
  84. package/dist/http/runtimes/h3.d.mts +1 -1
  85. package/dist/http/runtimes/h3.mjs +2 -2
  86. package/dist/index.d.mts +11 -11
  87. package/dist/index.mjs +2 -2
  88. package/dist/index.mjs.map +1 -1
  89. package/dist/{kv-stores-CAYc5VKm.mjs → kv-stores-O8HUSwpv.mjs} +2 -2
  90. package/dist/{kv-stores-CAYc5VKm.mjs.map → kv-stores-O8HUSwpv.mjs.map} +1 -1
  91. package/dist/{kv-stores-gQrfH0KQ.d.mts → kv-stores-duYHIEr1.d.mts} +2 -2
  92. package/dist/{kv-stores-gQrfH0KQ.d.mts.map → kv-stores-duYHIEr1.d.mts.map} +1 -1
  93. package/dist/{logger-COlEkn_C.d.mts → logger-DA43DvNY.d.mts} +18 -3
  94. package/dist/logger-DA43DvNY.d.mts.map +1 -0
  95. package/dist/{metadata-BhKXlN2F.mjs → metadata-CUDfhy4e.mjs} +2 -2
  96. package/dist/{metadata-BhKXlN2F.mjs.map → metadata-CUDfhy4e.mjs.map} +1 -1
  97. package/dist/{module-registry-CvP9mee-.mjs → module-registry-Mv5FqVlq.mjs} +2 -2
  98. package/dist/{module-registry-CvP9mee-.mjs.map → module-registry-Mv5FqVlq.mjs.map} +1 -1
  99. package/dist/{query-Cs_Llg77.mjs → query-gMAVXzx2.mjs} +2 -2
  100. package/dist/{query-Cs_Llg77.mjs.map → query-gMAVXzx2.mjs.map} +1 -1
  101. package/dist/{reply-edT8RGBB.mjs → reply-BMBvs-FB.mjs} +3 -3
  102. package/dist/{reply-edT8RGBB.mjs.map → reply-BMBvs-FB.mjs.map} +1 -1
  103. package/dist/{rolldown-runtime-Bzotz84Y.mjs → rolldown-runtime-CuwksmWW.mjs} +1 -1
  104. package/dist/{router-builder-CiS2ASTJ.d.mts → router-builder-GWgxoOdC.d.mts} +2 -2
  105. package/dist/{router-builder-CiS2ASTJ.d.mts.map → router-builder-GWgxoOdC.d.mts.map} +1 -1
  106. package/dist/{spa-Dp9onKJt.d.mts → spa-DWzSWAzx.d.mts} +2 -2
  107. package/dist/{spa-Dp9onKJt.d.mts.map → spa-DWzSWAzx.d.mts.map} +1 -1
  108. package/dist/{upload-config-C3MSF7RF.mjs → upload-config-CFfHvoHF.mjs} +2 -2
  109. package/dist/{upload-config-C3MSF7RF.mjs.map → upload-config-CFfHvoHF.mjs.map} +1 -1
  110. package/dist/{views-DjgUXRdu.d.mts → views-Kp8Z3AO1.d.mts} +4 -4
  111. package/dist/{views-DjgUXRdu.d.mts.map → views-Kp8Z3AO1.d.mts.map} +1 -1
  112. package/dist/web.d.mts +3 -3
  113. package/dist/web.d.mts.map +1 -1
  114. package/dist/web.mjs +2 -2
  115. package/package.json +1 -1
  116. package/dist/adapter-BjxEv8oW.d.mts.map +0 -1
  117. package/dist/app-module-BwYtACD6.d.mts.map +0 -1
  118. package/dist/context-Cs0939u1.mjs +0 -12
  119. package/dist/context-Cs0939u1.mjs.map +0 -1
  120. package/dist/contributor-runner-B3Z3Q7J5.mjs +0 -13
  121. package/dist/contributor-runner-B3Z3Q7J5.mjs.map +0 -1
  122. package/dist/core-CQ6u5kOq.mjs +0 -12
  123. package/dist/core-CQ6u5kOq.mjs.map +0 -1
  124. package/dist/error-handler-3ih4E-QZ.d.mts.map +0 -1
  125. package/dist/handler-D8Zyie-B.mjs +0 -12
  126. package/dist/handler-D8Zyie-B.mjs.map +0 -1
  127. package/dist/logger-COlEkn_C.d.mts.map +0 -1
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @forinda/kickjs v6.5.0
3
+ *
4
+ * Copyright (c) Felix Orinda
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import{i as MissingContributorError,n as DuplicateContributorError,t as ContributorCycleError}from"./context-errors-CwD27Vbj.mjs";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(registrations.filter(r=>(indegree.get(r.key)??0)>0),byKey),route);return sorted}function reconstructCycle(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}export{buildPipeline as n,runContributors as t};
12
+ //# sourceMappingURL=contributor-runner-Cu13cDQp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contributor-runner-Cu13cDQp.mjs","names":[],"sources":["../src/core/contributor-pipeline.ts","../src/core/contributor-runner.ts"],"sourcesContent":["import type { AnyContributorRegistration } from './context-decorator'\nimport {\n ContributorCycleError,\n DuplicateContributorError,\n MissingContributorError,\n} from './context-errors'\n\n/**\n * Where a contributor was registered, ordered by precedence\n * (lower index wins). Mirrors `architecture.md` §20.4.\n *\n * Levels (highest → lowest precedence):\n * - `'method'` — `@LoadX` on a controller method.\n * - `'class'` — `@LoadX` on a controller class.\n * - `'module'` — returned by `AppModule.contributors?()`. Per-module scope.\n * - `'adapter'` — returned by `AppAdapter.contributors?()`. Cross-cutting, applies\n * to every module's routes.\n * - `'global'` — `ApplicationOptions.contributors`. App-wide default.\n */\nexport type ContributorSource = 'method' | 'class' | 'module' | 'adapter' | 'global'\n\n/** Precedence-ranked source list. Index = precedence; method (0) wins ties. */\nconst PRECEDENCE_ORDER: readonly ContributorSource[] = [\n 'method',\n 'class',\n 'module',\n 'adapter',\n 'global',\n]\n\n/**\n * Input row to {@link buildPipeline}. Pairs a registration with its origin\n * so dedup can apply the precedence rule and diagnostic errors can name\n * the offending site.\n *\n * `registration` is the type-erased {@link AnyContributorRegistration}\n * — the runner doesn't care about each registration's narrow `D` /\n * `Ctx` shape, and adopters frequently mix HTTP / transport-agnostic\n * contributors in the same `externalSources` / `contributors()`\n * array. The narrow generics from `defineContextDecorator` survive\n * at the *definition* site (where `resolve` is typed); they're erased\n * here so collections compose without `as any` casts.\n */\nexport interface SourcedRegistration {\n registration: AnyContributorRegistration\n source: ContributorSource\n /** Human label surfaced in DuplicateContributorError messages. */\n label?: string\n}\n\n/**\n * Resolved, validated, topo-sorted pipeline ready for execution.\n *\n * `contributors` is in execution order — every entry's `dependsOn`\n * keys appear earlier. `keys` is the set of all keys this pipeline\n * produces; the runner uses it for fast existence checks and the\n * builder uses it for missing-dep validation.\n */\nexport interface ContributorPipeline {\n readonly contributors: readonly AnyContributorRegistration[]\n readonly keys: ReadonlySet<string>\n}\n\nexport interface BuildPipelineOptions {\n /** Optional route identifier surfaced in diagnostic errors (e.g., 'GET /projects/:id'). */\n route?: string\n}\n\n/**\n * Build, validate, and topo-sort a contributor pipeline.\n *\n * Pipeline:\n *\n * 1. Group sources by precedence (method > class > module > adapter > global).\n * 2. Within each precedence level, two contributors with the same `key`\n * raise {@link DuplicateContributorError}.\n * 3. Across levels, the highest-precedence contributor wins each key\n * (lower-precedence duplicates are silently dropped — that is the\n * documented override mechanism, not an error).\n * 4. Every key referenced by `dependsOn` must be produced by the\n * surviving set, otherwise {@link MissingContributorError}.\n * 5. Kahn's algorithm topo-sorts the survivors. Any nodes left after\n * the queue drains form a cycle → {@link ContributorCycleError}\n * with a reconstructed path.\n *\n * Pure function — no DI, no I/O. Safe to call once at startup per\n * route and cache the result.\n */\nexport function buildPipeline(\n sources: readonly SourcedRegistration[],\n options: BuildPipelineOptions = {},\n): ContributorPipeline {\n const route = options.route\n\n // Step 1: group by source.\n const bySource = new Map<ContributorSource, SourcedRegistration[]>()\n for (const src of PRECEDENCE_ORDER) bySource.set(src, [])\n for (const entry of sources) bySource.get(entry.source)!.push(entry)\n\n // Step 2 + 3: dedup with precedence. We walk highest precedence first,\n // claim its keys, and drop lower-precedence rows that conflict.\n const winners = new Map<string, SourcedRegistration>()\n for (const src of PRECEDENCE_ORDER) {\n const rows = bySource.get(src)!\n const keysAtThisLevel = new Map<string, SourcedRegistration[]>()\n for (const row of rows) {\n const key = row.registration.key\n const existing = keysAtThisLevel.get(key) ?? []\n existing.push(row)\n keysAtThisLevel.set(key, existing)\n }\n for (const [key, rowsForKey] of keysAtThisLevel) {\n if (rowsForKey.length > 1) {\n const labels = rowsForKey.map((r, i) => r.label ?? `${src}#${i}`)\n throw new DuplicateContributorError(key, labels)\n }\n if (!winners.has(key)) winners.set(key, rowsForKey[0])\n }\n }\n\n const survivors = [...winners.values()].map((r) => r.registration)\n const allKeys = new Set(survivors.map((r) => r.key))\n\n // Step 4: dependsOn validation.\n for (const reg of survivors) {\n for (const dep of reg.dependsOn) {\n if (!allKeys.has(dep)) {\n throw new MissingContributorError(dep, reg.key, route, reg.definedAt)\n }\n }\n }\n\n // Step 5: Kahn topo-sort.\n const sorted = topoSort(survivors, route)\n\n return Object.freeze({\n contributors: Object.freeze(sorted),\n keys: allKeys,\n })\n}\n\n/**\n * Kahn's algorithm with deterministic ordering on ties.\n *\n * Nodes with no remaining incoming edges enter the queue in input\n * order. Cycles surface as nodes still present after the queue\n * drains; we reconstruct one cycle path for diagnostics.\n */\nfunction topoSort(\n registrations: readonly AnyContributorRegistration[],\n route: string | undefined,\n): AnyContributorRegistration[] {\n // indegree[key] = number of unresolved dependsOn entries for key\n const indegree = new Map<string, number>()\n // dependents[depKey] = list of registrations that depend on depKey\n const dependents = new Map<string, AnyContributorRegistration[]>()\n const byKey = new Map<string, AnyContributorRegistration>()\n\n for (const reg of registrations) {\n indegree.set(reg.key, reg.dependsOn.length)\n byKey.set(reg.key, reg)\n }\n for (const reg of registrations) {\n for (const dep of reg.dependsOn) {\n const list = dependents.get(dep) ?? []\n list.push(reg)\n dependents.set(dep, list)\n }\n }\n\n // Initial queue: registrations with zero indegree, preserving input order.\n const queue: AnyContributorRegistration[] = []\n for (const reg of registrations) {\n if (indegree.get(reg.key) === 0) queue.push(reg)\n }\n\n const sorted: AnyContributorRegistration[] = []\n while (queue.length > 0) {\n const node = queue.shift()!\n sorted.push(node)\n for (const dependent of dependents.get(node.key) ?? []) {\n const next = (indegree.get(dependent.key) ?? 0) - 1\n indegree.set(dependent.key, next)\n if (next === 0) queue.push(dependent)\n }\n }\n\n if (sorted.length !== registrations.length) {\n const remaining = registrations.filter((r) => (indegree.get(r.key) ?? 0) > 0)\n throw new ContributorCycleError(reconstructCycle(remaining, byKey), route)\n }\n\n return sorted\n}\n\n/**\n * Reconstruct one cycle path from the residual graph.\n *\n * Walks from any remaining node, following its first dependency that's\n * still in the residual set, until we revisit a node. The path returned\n * starts and ends with the same key so the message reads naturally:\n * `tenant → project → tenant`.\n */\nfunction reconstructCycle(\n residual: readonly AnyContributorRegistration[],\n byKey: ReadonlyMap<string, AnyContributorRegistration>,\n): string[] {\n const residualKeys = new Set(residual.map((r) => r.key))\n const start = residual[0].key\n const path: string[] = [start]\n const seen = new Set<string>([start])\n let cursor: string = start\n\n while (true) {\n const reg = byKey.get(cursor)!\n const nextDep = reg.dependsOn.find((d) => residualKeys.has(d))\n if (nextDep === undefined) break\n if (seen.has(nextDep)) {\n // Trim the prefix that isn't part of the cycle.\n const cycleStart = path.indexOf(nextDep)\n return [...path.slice(cycleStart), nextDep]\n }\n path.push(nextDep)\n seen.add(nextDep)\n cursor = nextDep\n }\n\n // Fallback — couldn't reconstruct a strict cycle, return what we walked.\n return path\n}\n","import type { Container } from './container'\nimport type { ContributorRegistration } from './context-decorator'\nimport type { ExecutionContext } from './execution-context'\nimport type { ContributorPipeline } from './contributor-pipeline'\n\nexport interface RunContributorsOptions {\n /** Pre-built, validated, topo-sorted pipeline. */\n pipeline: ContributorPipeline\n /** The execution context contributors read from and write into. */\n ctx: ExecutionContext\n /** DI container used to resolve declared `deps`. */\n container: Container\n}\n\n/**\n * Execute a built {@link ContributorPipeline} against an {@link ExecutionContext}.\n *\n * Sequential — one contributor at a time, in the topo order chosen at\n * pipeline-build time. Per `architecture.md` §20.10, V1 does not run\n * contributors in parallel even within the same topo level; that is a\n * V2 follow-up gated on profiling.\n *\n * ## Error matrix (architecture.md §20.9)\n *\n * | resolve outcome | optional | onError defined | runner behaviour |\n * |-----------------|----------|-----------------|--------------------------------------------------|\n * | throws | true | — | skip; `ctx.get(key)` remains undefined |\n * | throws | false | yes | call hook; returned value (if any) stored |\n * | throws | false | no | propagate the original error |\n * | hook throws | — | yes | propagate the new error |\n * | hook returns | — | yes | undefined/void → skip; value → `ctx.set(key, v)` |\n * | resolves | — | — | `ctx.set(key, value)` |\n *\n * Container.resolve() throwing while building `deps` is treated as a\n * resolve-side throw and flows through the same matrix — adopters who\n * need different behaviour for missing-DI vs. data-lookup failures can\n * wrap the container access inside their own `resolve()`.\n */\nexport async function runContributors(options: RunContributorsOptions): Promise<void> {\n const { pipeline, ctx, container } = options\n\n for (const reg of pipeline.contributors) {\n await runOne(reg, ctx, container)\n }\n}\n\nasync function runOne(\n reg: ContributorRegistration,\n ctx: ExecutionContext,\n container: Container,\n): Promise<void> {\n let value: unknown\n try {\n const deps = resolveDeps(reg, container)\n value = await reg.resolve(ctx, deps)\n } catch (err) {\n if (reg.optional) return\n if (reg.onError) {\n // Hook throws are unconditionally propagated — there is no\n // second-chance hook. Returning undefined/void from the hook\n // means \"skip\"; returning a value means \"use this instead\".\n const replacement = await reg.onError(err, ctx)\n if (replacement === undefined) return\n ctx.set(reg.key, replacement as never)\n return\n }\n throw err\n }\n ctx.set(reg.key, value as never)\n}\n\n/**\n * Resolve a contributor's declared dependencies through the container,\n * preserving the property names from the spec so `resolve(ctx, deps)`\n * receives exactly the shape the user wrote.\n *\n * Empty `deps` produces an empty object — `resolve()` always sees an\n * object, never `undefined`.\n */\nfunction resolveDeps(reg: ContributorRegistration, container: Container): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [key, token] of Object.entries(reg.deps)) {\n out[key] = container.resolve(token as never)\n }\n return out\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
 
2
- import { a as MiddlewarePath, i as AppAdapterClass, n as AdapterMiddleware, o as MiddlewarePhase, r as AppAdapter, t as AdapterContext } from "../adapter-BjxEv8oW.mjs";
2
+ import { a as MiddlewarePath, i as AppAdapterClass, n as AdapterMiddleware, o as MiddlewarePhase, r as AppAdapter, t as AdapterContext } from "../adapter-CEt1MEdF.mjs";
3
3
  export { AdapterContext, AdapterMiddleware, AppAdapter, AppAdapterClass, MiddlewarePath, MiddlewarePhase };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,3 +1,3 @@
1
1
 
2
- import { i as ModuleRoutes, n as AppModuleClass, r as AppModuleEntry, t as AppModule } from "../app-module-BwYtACD6.mjs";
2
+ import { i as ModuleRoutes, n as AppModuleClass, r as AppModuleEntry, t as AppModule } from "../app-module-BSpHKlhE.mjs";
3
3
  export { AppModule, AppModuleClass, AppModuleEntry, ModuleRoutes };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.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-Da9BLMHy.mjs";export{Container,tokenName};
11
+ import{n as tokenName,t as Container}from"../container-CBaL5lus.mjs";export{Container,tokenName};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.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-BhKXlN2F.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-CUDfhy4e.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,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.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{METADATA}from"./interfaces.mjs";import{t as Container}from"../container-Da9BLMHy.mjs";import{c as pushClassMeta,d as setInMetaMap,f as setInMetaRecord,l as pushMethodMeta,p as setMethodMeta,u as setClassMeta}from"../metadata-BhKXlN2F.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 PreDestroy(){return(target,propertyKey)=>{setClassMeta(METADATA.PRE_DESTROY,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,PreDestroy,Put,Repository,Service,Value,normalizeApiQueryParamsConfig,withBuilder};
11
+ import{METADATA}from"./interfaces.mjs";import{t as Container}from"../container-CBaL5lus.mjs";import{c as pushClassMeta,d as setInMetaMap,f as setInMetaRecord,l as pushMethodMeta,p as setMethodMeta,u as setClassMeta}from"../metadata-CUDfhy4e.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 PreDestroy(){return(target,propertyKey)=>{setClassMeta(METADATA.PRE_DESTROY,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,PreDestroy,Put,Repository,Service,Value,normalizeApiQueryParamsConfig,withBuilder};
12
12
  //# sourceMappingURL=decorators.mjs.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,3 +1,3 @@
1
1
 
2
- import { i as createLogger, n as Logger, r as LoggerProvider, t as ConsoleLoggerProvider } from "../logger-COlEkn_C.mjs";
3
- export { ConsoleLoggerProvider, Logger, LoggerProvider, createLogger };
2
+ import { a as describeError, i as createLogger, n as Logger, r as LoggerProvider, t as ConsoleLoggerProvider } from "../logger-DA43DvNY.mjs";
3
+ export { ConsoleLoggerProvider, Logger, LoggerProvider, createLogger, describeError };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.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 LEVEL_RANK={trace:10,debug:20,info:30,warn:40,error:50,fatal:60,silent:100};function thresholdRank(){let level=(process.env.LOG_LEVEL??`info`).toLowerCase();return LEVEL_RANK[level]??LEVEL_RANK.info}var ConsoleLoggerProvider=class ConsoleLoggerProvider{prefix;useColor;constructor(prefix){this.prefix=prefix??``,this.useColor=typeof process<`u`&&process.stdout?.isTTY===!0&&!process.env.NO_COLOR}fmt(level,color,msg){let tag=this.prefix?`[${this.prefix}]`:``;return this.useColor?`${color}${level}\x1b[0m ${tag?`\x1b[36m${tag}\x1b[0m `:``}${msg}`:`${level} ${tag?`${tag} `:``}${msg}`}enabled(rank){return rank>=thresholdRank()}info(msg,...args){this.enabled(LEVEL_RANK.info)&&console.log(this.fmt(`INFO`,`\x1B[32m`,msg),...args)}warn(msg,...args){this.enabled(LEVEL_RANK.warn)&&console.warn(this.fmt(`WARN`,`\x1B[33m`,msg),...args)}error(msg,...args){this.enabled(LEVEL_RANK.error)&&console.error(this.fmt(`ERROR`,`\x1B[31m`,msg),...args)}debug(msg,...args){this.enabled(LEVEL_RANK.debug)&&console.debug(this.fmt(`DEBUG`,`\x1B[90m`,msg),...args)}trace(msg,...args){this.enabled(LEVEL_RANK.trace)&&console.trace(this.fmt(`TRACE`,`\x1B[90m`,msg),...args)}fatal(msg,...args){this.enabled(LEVEL_RANK.fatal)&&console.error(this.fmt(`FATAL`,`\x1B[1m\x1B[31m`,msg),...args)}child(bindings){return new ConsoleLoggerProvider(bindings.component)}};let activeProvider=new ConsoleLoggerProvider;const loggerCache=new Map;var Logger=class Logger{_provider;_providerVersion;_name;static _providerVersion=0;constructor(name){this._name=name,this._providerVersion=Logger._providerVersion,this._provider=name?activeProvider.child({component:name}):activeProvider}get provider(){return this._providerVersion!==Logger._providerVersion&&(this._providerVersion=Logger._providerVersion,this._provider=this._name?activeProvider.child({component:this._name}):activeProvider),this._provider}static setProvider(provider){activeProvider=provider,Logger._providerVersion++,loggerCache.clear()}static getProvider(){return activeProvider}static resetProvider(){activeProvider=new ConsoleLoggerProvider,Logger._providerVersion++,loggerCache.clear()}static for(name){let cached=loggerCache.get(name);return cached||(cached=new Logger(name),loggerCache.set(name,cached)),cached}child(name){return new Logger(name)}info(msg,...args){this.provider.info(msg,...args)}warn(msg,...args){this.provider.warn(msg,...args)}error(msgOrObj,msg,...args){typeof msgOrObj==`string`?this.provider.error(msgOrObj):msg?this.provider.error(msg,...args):this.provider.error(String(msgOrObj))}debug(msg,...args){this.provider.debug(msg,...args)}trace(msg,...args){this.provider.trace?this.provider.trace(msg,...args):this.provider.debug(msg,...args)}fatal(msg,...args){this.provider.fatal?this.provider.fatal(msg,...args):this.provider.error(msg,...args)}};function createLogger(name){return Logger.for(name)}export{ConsoleLoggerProvider,Logger,createLogger};
11
+ const LEVEL_RANK={trace:10,debug:20,info:30,warn:40,error:50,fatal:60,silent:100};function thresholdRank(){let level=((typeof process<`u`?process.env?.LOG_LEVEL:void 0)??`info`).toLowerCase();return LEVEL_RANK[level]??LEVEL_RANK.info}var ConsoleLoggerProvider=class ConsoleLoggerProvider{prefix;useColor;constructor(prefix){this.prefix=prefix??``,this.useColor=typeof process<`u`&&process.stdout?.isTTY===!0&&!process.env.NO_COLOR}fmt(level,color,msg){let tag=this.prefix?`[${this.prefix}]`:``;return this.useColor?`${color}${level}\x1b[0m ${tag?`\x1b[36m${tag}\x1b[0m `:``}${msg}`:`${level} ${tag?`${tag} `:``}${msg}`}enabled(rank){return rank>=thresholdRank()}info(msg,...args){this.enabled(LEVEL_RANK.info)&&console.log(this.fmt(`INFO`,`\x1B[32m`,msg),...args)}warn(msg,...args){this.enabled(LEVEL_RANK.warn)&&console.warn(this.fmt(`WARN`,`\x1B[33m`,msg),...args)}error(msg,...args){this.enabled(LEVEL_RANK.error)&&console.error(this.fmt(`ERROR`,`\x1B[31m`,msg),...args)}debug(msg,...args){this.enabled(LEVEL_RANK.debug)&&console.debug(this.fmt(`DEBUG`,`\x1B[90m`,msg),...args)}trace(msg,...args){this.enabled(LEVEL_RANK.trace)&&console.trace(this.fmt(`TRACE`,`\x1B[90m`,msg),...args)}fatal(msg,...args){this.enabled(LEVEL_RANK.fatal)&&console.error(this.fmt(`FATAL`,`\x1B[1m\x1B[31m`,msg),...args)}child(bindings){return new ConsoleLoggerProvider(bindings.component)}};let activeProvider=new ConsoleLoggerProvider;const loggerCache=new Map;var Logger=class Logger{_provider;_providerVersion;_name;static _providerVersion=0;constructor(name){this._name=name,this._providerVersion=Logger._providerVersion,this._provider=name?activeProvider.child({component:name}):activeProvider}get provider(){return this._providerVersion!==Logger._providerVersion&&(this._providerVersion=Logger._providerVersion,this._provider=this._name?activeProvider.child({component:this._name}):activeProvider),this._provider}static setProvider(provider){activeProvider=provider,Logger._providerVersion++,loggerCache.clear()}static getProvider(){return activeProvider}static resetProvider(){activeProvider=new ConsoleLoggerProvider,Logger._providerVersion++,loggerCache.clear()}static for(name){let cached=loggerCache.get(name);return cached||(cached=new Logger(name),loggerCache.set(name,cached)),cached}child(name){return new Logger(name)}info(msg,...args){this.provider.info(msg,...args)}warn(msg,...args){this.provider.warn(msg,...args)}error(msgOrErr,...rest){if(typeof msgOrErr==`string`){this.provider.error(msgOrErr,...rest);return}let[maybeMsg,...extra]=rest;typeof maybeMsg==`string`?this.provider.error(maybeMsg,msgOrErr,...extra):this.provider.error(describeError(msgOrErr),msgOrErr,...rest)}debug(msg,...args){this.provider.debug(msg,...args)}trace(msg,...args){this.provider.trace?this.provider.trace(msg,...args):this.provider.debug(msg,...args)}fatal(msg,...args){this.provider.fatal?this.provider.fatal(msg,...args):this.provider.error(msg,...args)}};function describeError(err,maxDepth=4){let parts=[],seen=new Set,current=err;for(let depth=0;current!=null&&depth<maxDepth;depth++){if(seen.has(current)){parts.push(`[circular cause]`);break}if(seen.add(current),current instanceof Error)parts.push(current.name?`${current.name}: ${current.message}`:current.message),current=current.cause;else{parts.push(typeof current==`string`?current:safeStringify(current));break}}return parts.length>0?parts.join(` ← caused by `):`Unknown error`}function safeStringify(value){try{return JSON.stringify(value)??String(value)}catch{return String(value)}}function createLogger(name){return Logger.for(name)}export{ConsoleLoggerProvider,Logger,createLogger,describeError};
12
12
  //# sourceMappingURL=logger.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.mjs","names":[],"sources":["../../src/core/logger.ts"],"sourcesContent":["// ── LoggerProvider interface ───────────────────────────────────────────\n\n/**\n * Pluggable logger backend.\n *\n * Implement this interface to plug in any logging library (pino,\n * winston, bunyan, console, etc.). The framework only ever calls the\n * methods declared here — it doesn't know or care which logger is\n * underneath.\n *\n * Default: `ConsoleLoggerProvider` (zero runtime deps).\n *\n * @example\n * ```ts\n * import pino from 'pino'\n * import { Logger, type LoggerProvider } from '@forinda/kickjs'\n *\n * class PinoProvider implements LoggerProvider {\n * constructor(private p = pino()) {}\n * info(msg, ...args) { this.p.info(msg, ...args) }\n * warn(msg, ...args) { this.p.warn(msg, ...args) }\n * error(msg, ...args) { this.p.error(msg, ...args) }\n * debug(msg, ...args) { this.p.debug(msg, ...args) }\n * child({ component }) { return new PinoProvider(this.p.child({ component })) }\n * }\n *\n * Logger.setProvider(new PinoProvider())\n * ```\n *\n * See `docs/guide/logging.md` for Pino, Winston, and silent-logger recipes.\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// ── Log levels ─────────────────────────────────────────────────────────\n\n/** Severity ordering — a message prints only when its rank ≥ the threshold. */\nconst LEVEL_RANK: Record<string, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n silent: 100,\n}\n\n/**\n * Resolve the active threshold rank from `LOG_LEVEL` (default `info`).\n * Read per-call so a late `process.env.LOG_LEVEL` assignment still\n * takes effect. An unrecognised value falls back to `info`.\n */\nfunction thresholdRank(): number {\n const level = (process.env.LOG_LEVEL ?? 'info').toLowerCase()\n return LEVEL_RANK[level] ?? LEVEL_RANK.info\n}\n\n// ── ConsoleLoggerProvider (default) ────────────────────────────────────\n\n/**\n * Default provider — emits through `console.*` methods. Zero deps.\n *\n * Respects the `LOG_LEVEL` env var (default `info`): messages below the\n * threshold are dropped, so the verbose startup detail (the route table,\n * DI wiring, HMR ticks — all `debug`) stays quiet by default and only\n * appears with `LOG_LEVEL=debug`. `error`/`fatal` always print unless\n * `LOG_LEVEL=silent`.\n *\n * Swap it for pino, winston, bunyan, or anything else by implementing\n * the `LoggerProvider` interface and calling `Logger.setProvider()`\n * before `bootstrap()`.\n */\nexport class ConsoleLoggerProvider implements LoggerProvider {\n private prefix: string\n private useColor: boolean\n\n constructor(prefix?: string) {\n this.prefix = prefix ?? ''\n this.useColor =\n typeof process !== 'undefined' && process.stdout?.isTTY === true && !process.env.NO_COLOR\n }\n\n private fmt(level: string, color: string, msg: string): string {\n const tag = this.prefix ? `[${this.prefix}]` : ''\n if (this.useColor) {\n return `${color}${level}\\x1b[0m ${tag ? `\\x1b[36m${tag}\\x1b[0m ` : ''}${msg}`\n }\n return `${level} ${tag ? `${tag} ` : ''}${msg}`\n }\n\n /** Should a message at `rank` print under the current `LOG_LEVEL`? */\n private enabled(rank: number): boolean {\n return rank >= thresholdRank()\n }\n\n info(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.info)) console.log(this.fmt('INFO', '\\x1b[32m', msg), ...args)\n }\n warn(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.warn)) console.warn(this.fmt('WARN', '\\x1b[33m', msg), ...args)\n }\n error(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.error)) console.error(this.fmt('ERROR', '\\x1b[31m', msg), ...args)\n }\n debug(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.debug)) console.debug(this.fmt('DEBUG', '\\x1b[90m', msg), ...args)\n }\n trace(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.trace)) console.trace(this.fmt('TRACE', '\\x1b[90m', msg), ...args)\n }\n fatal(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.fatal))\n console.error(this.fmt('FATAL', '\\x1b[1m\\x1b[31m', 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 ConsoleLoggerProvider()\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 — see docs/guide/logging.md\n * Logger.setProvider(new MyCustomProvider())\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 /** 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 MyWinstonProvider())\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 `ConsoleLoggerProvider`.\n * Primarily intended for test teardown.\n */\n static resetProvider(): void {\n activeProvider = new ConsoleLoggerProvider()\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 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":["// ── LoggerProvider interface ───────────────────────────────────────────\n\n/**\n * Pluggable logger backend.\n *\n * Implement this interface to plug in any logging library (pino,\n * winston, bunyan, console, etc.). The framework only ever calls the\n * methods declared here — it doesn't know or care which logger is\n * underneath.\n *\n * Default: `ConsoleLoggerProvider` (zero runtime deps).\n *\n * @example\n * ```ts\n * import pino from 'pino'\n * import { Logger, type LoggerProvider } from '@forinda/kickjs'\n *\n * class PinoProvider implements LoggerProvider {\n * constructor(private p = pino()) {}\n * info(msg, ...args) { this.p.info(msg, ...args) }\n * warn(msg, ...args) { this.p.warn(msg, ...args) }\n * error(msg, ...args) { this.p.error(msg, ...args) }\n * debug(msg, ...args) { this.p.debug(msg, ...args) }\n * child({ component }) { return new PinoProvider(this.p.child({ component })) }\n * }\n *\n * Logger.setProvider(new PinoProvider())\n * ```\n *\n * See `docs/guide/logging.md` for Pino, Winston, and silent-logger recipes.\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// ── Log levels ─────────────────────────────────────────────────────────\n\n/** Severity ordering — a message prints only when its rank ≥ the threshold. */\nconst LEVEL_RANK: Record<string, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n silent: 100,\n}\n\n/**\n * Resolve the active threshold rank from `LOG_LEVEL` (default `info`).\n * Read per-call so a late `process.env.LOG_LEVEL` assignment still\n * takes effect. An unrecognised value falls back to `info`.\n */\nfunction thresholdRank(): number {\n // `process` is guarded because this module is reachable from the\n // edge-safe web pipeline (`@forinda/kickjs/web`), where strict runtimes\n // expose no `process` global at all. The colour probe below already\n // guarded; this one did not, so merely importing the logger could throw\n // on such a runtime.\n const level = (\n (typeof process !== 'undefined' ? process.env?.LOG_LEVEL : undefined) ?? 'info'\n ).toLowerCase()\n return LEVEL_RANK[level] ?? LEVEL_RANK.info\n}\n\n// ── ConsoleLoggerProvider (default) ────────────────────────────────────\n\n/**\n * Default provider — emits through `console.*` methods. Zero deps.\n *\n * Respects the `LOG_LEVEL` env var (default `info`): messages below the\n * threshold are dropped, so the verbose startup detail (the route table,\n * DI wiring, HMR ticks — all `debug`) stays quiet by default and only\n * appears with `LOG_LEVEL=debug`. `error`/`fatal` always print unless\n * `LOG_LEVEL=silent`.\n *\n * Swap it for pino, winston, bunyan, or anything else by implementing\n * the `LoggerProvider` interface and calling `Logger.setProvider()`\n * before `bootstrap()`.\n */\nexport class ConsoleLoggerProvider implements LoggerProvider {\n private prefix: string\n private useColor: boolean\n\n constructor(prefix?: string) {\n this.prefix = prefix ?? ''\n this.useColor =\n typeof process !== 'undefined' && process.stdout?.isTTY === true && !process.env.NO_COLOR\n }\n\n private fmt(level: string, color: string, msg: string): string {\n const tag = this.prefix ? `[${this.prefix}]` : ''\n if (this.useColor) {\n return `${color}${level}\\x1b[0m ${tag ? `\\x1b[36m${tag}\\x1b[0m ` : ''}${msg}`\n }\n return `${level} ${tag ? `${tag} ` : ''}${msg}`\n }\n\n /** Should a message at `rank` print under the current `LOG_LEVEL`? */\n private enabled(rank: number): boolean {\n return rank >= thresholdRank()\n }\n\n info(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.info)) console.log(this.fmt('INFO', '\\x1b[32m', msg), ...args)\n }\n warn(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.warn)) console.warn(this.fmt('WARN', '\\x1b[33m', msg), ...args)\n }\n error(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.error)) console.error(this.fmt('ERROR', '\\x1b[31m', msg), ...args)\n }\n debug(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.debug)) console.debug(this.fmt('DEBUG', '\\x1b[90m', msg), ...args)\n }\n trace(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.trace)) console.trace(this.fmt('TRACE', '\\x1b[90m', msg), ...args)\n }\n fatal(msg: string, ...args: any[]) {\n if (this.enabled(LEVEL_RANK.fatal))\n console.error(this.fmt('FATAL', '\\x1b[1m\\x1b[31m', 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 ConsoleLoggerProvider()\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 — see docs/guide/logging.md\n * Logger.setProvider(new MyCustomProvider())\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 /** 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 MyWinstonProvider())\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 `ConsoleLoggerProvider`.\n * Primarily intended for test teardown.\n */\n static resetProvider(): void {\n activeProvider = new ConsoleLoggerProvider()\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 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 /** Pino-style error-first form — `log.error(err, 'what failed')`. */\n error(err: unknown, msg: string, ...args: any[]): void\n /** Message-first form — `log.error('what failed', detail)`. */\n error(msg: string, ...args: any[]): void\n /** Error alone — `log.error(err)`. */\n error(err: unknown): void\n error(msgOrErr: any, ...rest: any[]): void {\n if (typeof msgOrErr === 'string') {\n // Message-first. `rest` used to be dropped on the floor, so\n // `log.error('save failed', { id })` logged only the string.\n this.provider.error(msgOrErr, ...rest)\n return\n }\n\n // Error-first (the framework's own idiom at ~16 call sites). The\n // error object used to be discarded entirely — `provider.error(msg)`\n // with the error nowhere in the call — so every `log.error(err, msg)`\n // in the codebase logged a bare sentence with NO stack, no error\n // name, and no `cause` chain. That is what made an unexpected 500\n // undiagnosable from the logs: you got the message and nothing else.\n //\n // The error is now forwarded as a trailing argument, which is what\n // the msg-first `LoggerProvider` contract can carry. `console.error`\n // renders the full stack from it; a pino/winston adapter receives it\n // as structured extra.\n const [maybeMsg, ...extra] = rest\n if (typeof maybeMsg === 'string') {\n this.provider.error(maybeMsg, msgOrErr, ...extra)\n } else {\n // No message supplied — use the error's own summary as the line so\n // the log stays readable, and still pass the object for the stack.\n this.provider.error(describeError(msgOrErr), msgOrErr, ...rest)\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/**\n * One-line summary of an unknown thrown value, including the error name\n * and — when present — the `cause` chain. ORM and driver errors routinely\n * wrap the useful detail in `cause`, so dropping it is how a 500 ends up\n * saying nothing actionable.\n *\n * Depth-capped and cycle-guarded: `cause` is attacker-influenced in some\n * stacks and self-referential chains do occur.\n */\nexport function describeError(err: unknown, maxDepth = 4): string {\n const parts: string[] = []\n const seen = new Set<unknown>()\n let current: unknown = err\n for (let depth = 0; current !== undefined && current !== null && depth < maxDepth; depth++) {\n if (seen.has(current)) {\n parts.push('[circular cause]')\n break\n }\n seen.add(current)\n if (current instanceof Error) {\n parts.push(current.name ? `${current.name}: ${current.message}` : current.message)\n current = (current as { cause?: unknown }).cause\n } else {\n parts.push(typeof current === 'string' ? current : safeStringify(current))\n break\n }\n }\n return parts.length > 0 ? parts.join(' ← caused by ') : 'Unknown error'\n}\n\n/** `JSON.stringify` that never throws on circular / exotic values. */\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value) ?? String(value)\n } catch {\n return String(value)\n }\n}\n\n/** Shorthand for Logger.for(name) */\nexport function createLogger(name: string): Logger {\n return Logger.for(name)\n}\n"],"mappings":";;;;;;;;;;AA6CA,MAAM,WAAqC,CACzC,MAAO,GACP,MAAO,GACP,KAAM,GACN,KAAM,GACN,MAAO,GACP,MAAO,GACP,OAAQ,GACV,EAOA,SAAS,eAAwB,CAM/B,IAAM,QACH,OAAO,QAAY,IAAc,QAAQ,KAAK,UAAY,IAAA,KAAc,OAAA,CACzE,YAAY,EACd,OAAO,WAAW,QAAU,WAAW,IACzC,CAiBA,IAAa,sBAAb,MAAa,qBAAgD,CAC3D,OACA,SAEA,YAAY,OAAiB,CAC3B,KAAK,OAAS,QAAU,GACxB,KAAK,SACH,OAAO,QAAY,KAAe,QAAQ,QAAQ,QAAU,IAAQ,CAAC,QAAQ,IAAI,QACrF,CAEA,IAAY,MAAe,MAAe,IAAqB,CAC7D,IAAM,IAAM,KAAK,OAAS,IAAI,KAAK,OAAO,GAAK,GAI/C,OAHI,KAAK,SACA,GAAG,QAAQ,MAAM,UAAU,IAAM,WAAW,IAAI,UAAY,KAAK,MAEnE,GAAG,MAAM,GAAG,IAAM,GAAG,IAAI,GAAK,KAAK,KAC5C,CAGA,QAAgB,KAAuB,CACrC,OAAO,MAAQ,cAAc,CAC/B,CAEA,KAAK,IAAa,GAAG,KAAa,CAC5B,KAAK,QAAQ,WAAW,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI,OAAQ,WAAY,GAAG,EAAG,GAAG,IAAI,CAC3F,CACA,KAAK,IAAa,GAAG,KAAa,CAC5B,KAAK,QAAQ,WAAW,IAAI,GAAG,QAAQ,KAAK,KAAK,IAAI,OAAQ,WAAY,GAAG,EAAG,GAAG,IAAI,CAC5F,CACA,MAAM,IAAa,GAAG,KAAa,CAC7B,KAAK,QAAQ,WAAW,KAAK,GAAG,QAAQ,MAAM,KAAK,IAAI,QAAS,WAAY,GAAG,EAAG,GAAG,IAAI,CAC/F,CACA,MAAM,IAAa,GAAG,KAAa,CAC7B,KAAK,QAAQ,WAAW,KAAK,GAAG,QAAQ,MAAM,KAAK,IAAI,QAAS,WAAY,GAAG,EAAG,GAAG,IAAI,CAC/F,CACA,MAAM,IAAa,GAAG,KAAa,CAC7B,KAAK,QAAQ,WAAW,KAAK,GAAG,QAAQ,MAAM,KAAK,IAAI,QAAS,WAAY,GAAG,EAAG,GAAG,IAAI,CAC/F,CACA,MAAM,IAAa,GAAG,KAAa,CAC7B,KAAK,QAAQ,WAAW,KAAK,GAC/B,QAAQ,MAAM,KAAK,IAAI,QAAS,kBAAmB,GAAG,EAAG,GAAG,IAAI,CACpE,CACA,MAAM,SAAiD,CACrD,OAAO,IAAI,sBAAsB,SAAS,SAAS,CACrD,CACF,EAIA,IAAI,eAAiC,IAAI,sBAGzC,MAAM,YAAc,IAAI,IA0BxB,IAAa,OAAb,MAAa,MAAO,CAClB,UACA,iBACA,MAGA,OAAe,iBAAmB,EAElC,YAAY,KAAe,CACzB,KAAK,MAAQ,KACb,KAAK,iBAAmB,OAAO,iBAC/B,KAAK,UAAY,KAAO,eAAe,MAAM,CAAE,UAAW,IAAK,CAAC,EAAI,cACtE,CAGA,IAAY,UAA2B,CAKrC,OAJI,KAAK,mBAAqB,OAAO,mBACnC,KAAK,iBAAmB,OAAO,iBAC/B,KAAK,UAAY,KAAK,MAAQ,eAAe,MAAM,CAAE,UAAW,KAAK,KAAM,CAAC,EAAI,gBAE3E,KAAK,SACd,CAYA,OAAO,YAAY,SAAgC,CACjD,eAAiB,SACjB,OAAO,mBACP,YAAY,MAAM,CACpB,CAGA,OAAO,aAA8B,CACnC,OAAO,cACT,CAMA,OAAO,eAAsB,CAC3B,eAAiB,IAAI,sBACrB,OAAO,mBACP,YAAY,MAAM,CACpB,CAGA,OAAO,IAAI,KAAsB,CAC/B,IAAI,OAAS,YAAY,IAAI,IAAI,EAKjC,OAJK,SACH,OAAS,IAAI,OAAO,IAAI,EACxB,YAAY,IAAI,KAAM,MAAM,GAEvB,MACT,CAGA,MAAM,KAAsB,CAC1B,OAAO,IAAI,OAAO,IAAI,CACxB,CAEA,KAAK,IAAa,GAAG,KAAa,CAChC,KAAK,SAAS,KAAK,IAAK,GAAG,IAAI,CACjC,CAEA,KAAK,IAAa,GAAG,KAAa,CAChC,KAAK,SAAS,KAAK,IAAK,GAAG,IAAI,CACjC,CAQA,MAAM,SAAe,GAAG,KAAmB,CACzC,GAAI,OAAO,UAAa,SAAU,CAGhC,KAAK,SAAS,MAAM,SAAU,GAAG,IAAI,EACrC,MACF,CAaA,GAAM,CAAC,SAAU,GAAG,OAAS,KACzB,OAAO,UAAa,SACtB,KAAK,SAAS,MAAM,SAAU,SAAU,GAAG,KAAK,EAIhD,KAAK,SAAS,MAAM,cAAc,QAAQ,EAAG,SAAU,GAAG,IAAI,CAElE,CAEA,MAAM,IAAa,GAAG,KAAa,CACjC,KAAK,SAAS,MAAM,IAAK,GAAG,IAAI,CAClC,CAEA,MAAM,IAAa,GAAG,KAAa,CAC7B,KAAK,SAAS,MAAO,KAAK,SAAS,MAAM,IAAK,GAAG,IAAI,EACpD,KAAK,SAAS,MAAM,IAAK,GAAG,IAAI,CACvC,CAEA,MAAM,IAAa,GAAG,KAAa,CAC7B,KAAK,SAAS,MAAO,KAAK,SAAS,MAAM,IAAK,GAAG,IAAI,EACpD,KAAK,SAAS,MAAM,IAAK,GAAG,IAAI,CACvC,CACF,EAWA,SAAgB,cAAc,IAAc,SAAW,EAAW,CAChE,IAAM,MAAkB,CAAC,EACnB,KAAO,IAAI,IACb,QAAmB,IACvB,IAAK,IAAI,MAAQ,EAAG,SAAqC,MAAQ,MAAQ,SAAU,QAAS,CAC1F,GAAI,KAAK,IAAI,OAAO,EAAG,CACrB,MAAM,KAAK,kBAAkB,EAC7B,KACF,CAEA,GADA,KAAK,IAAI,OAAO,EACZ,mBAAmB,MACrB,MAAM,KAAK,QAAQ,KAAO,GAAG,QAAQ,KAAK,IAAI,QAAQ,UAAY,QAAQ,OAAO,EACjF,QAAW,QAAgC,UACtC,CACL,MAAM,KAAK,OAAO,SAAY,SAAW,QAAU,cAAc,OAAO,CAAC,EACzE,KACF,CACF,CACA,OAAO,MAAM,OAAS,EAAI,MAAM,KAAK,eAAe,EAAI,eAC1D,CAGA,SAAS,cAAc,MAAwB,CAC7C,GAAI,CACF,OAAO,KAAK,UAAU,KAAK,GAAK,OAAO,KAAK,CAC9C,MAAQ,CACN,OAAO,OAAO,KAAK,CACrB,CACF,CAGA,SAAgB,aAAa,KAAsB,CACjD,OAAO,OAAO,IAAI,IAAI,CACxB"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,3 +1,3 @@
1
1
 
2
- import { Ft as KickPlugin } from "../adapter-BjxEv8oW.mjs";
2
+ import { It as KickPlugin } from "../adapter-CEt1MEdF.mjs";
3
3
  export { KickPlugin };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v6.4.0
2
+ * @forinda/kickjs v6.5.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @forinda/kickjs v6.5.0
3
+ *
4
+ * Copyright (c) Felix Orinda
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import{t as __require}from"./rolldown-runtime-CuwksmWW.mjs";import{METADATA}from"./core/interfaces.mjs";import{i as createToken,u as _setAssetResolver}from"./container-CBaL5lus.mjs";import"./core/logger.mjs";import{c as pushClassMeta,l as pushMethodMeta}from"./metadata-CUDfhy4e.mjs";import"./core/decorators.mjs";import"./core/cron.mjs";import"./core/cache.mjs";import"reflect-metadata";import{existsSync,readFileSync,readdirSync}from"node:fs";import{isAbsolute,join,resolve,sep}from"node:path";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 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 defineContextDecoratorImpl(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(spec.requiredParams!==void 0&&!Array.isArray(spec.requiredParams))throw TypeError(`defineContextDecorator(${spec.key}): spec.requiredParams must be an array when provided (got ${typeof spec.requiredParams}).`);if(Array.isArray(spec.requiredParams)&&spec.requiredParams.some(p=>typeof p!=`string`||p.length===0))throw TypeError(`defineContextDecorator(${spec.key}): spec.requiredParams entries must be non-empty strings.`);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}},sharedRequiredParams=Object.freeze([...spec.requiredParams??[]]),assertRequiredParams=(params,usage)=>{if(sharedRequiredParams.length===0)return;let missing=sharedRequiredParams.filter(name=>params[name]===void 0);if(missing.length!==0)throw TypeError(`defineContextDecorator(${spec.key}): ${usage} is missing required param(s) ${missing.map(m=>`'${m}'`).join(`, `)}. Supply them at the call site — e.g. \`@${spec.key}({ ${missing[0]}: … })\` — or add a default in \`paramDefaults\` if one is genuinely correct for every route.`)};function decoratorOrFactory(...args){if(isDecoratorCall(args)){let[target,propertyKey]=args;assertRequiredParams({...defaults},"bare `@decorator` usage"),applyAsDecorator(defaultRegistration,target,propertyKey);return}let params=mergeParams(args[0]);assertRequiredParams(params,`factory call`);let registration=buildRegistration(params);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,{with:params=>{let merged=mergeParams(params);return assertRequiredParams(merged,"`.with()`"),{registration:buildRegistration(merged)}}});return Object.defineProperty(decorator,"registration",{get(){return assertRequiredParams({...defaults},"`.registration`"),defaultRegistration},enumerable:!0,configurable:!1}),Object.freeze(decorator)}const defineContextDecorator=Object.freeze(Object.assign(defineContextDecoratorImpl,{withParams:()=>spec=>defineContextDecoratorImpl(spec)}));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)),config=await opts.useFactory(...deps);return inner=buildSync(instanceName,!1,config),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)),config=await opts.useFactory(...deps);inner=buildSync(instanceName,!1,config),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){}function groupAssetKeys(namespace,paths,opts={}){let strategy=opts.strategy??`auto`;if(strategy===`with-extension`)return{pairs:paths.map(rel=>({rel,key:`${namespace}/${rel}`})),collisionGroupsResolved:0};if(strategy===`strip`)return{pairs:paths.map(rel=>({rel,key:`${namespace}/${stripExt(rel)}`})),collisionGroupsResolved:0};let groups=new Map;for(let rel of paths){let strippedKey=`${namespace}/${stripExt(rel)}`,arr=groups.get(strippedKey);arr?arr.push(rel):groups.set(strippedKey,[rel])}let collisionGroupsResolved=0,keyByRel=new Map;for(let[strippedKey,rels]of groups)if(rels.length===1)keyByRel.set(rels[0],strippedKey);else{collisionGroupsResolved+=1;for(let rel of rels)keyByRel.set(rel,`${namespace}/${rel}`)}return{pairs:paths.map(rel=>({rel,key:keyByRel.get(rel)??`${namespace}/${rel}`})),collisionGroupsResolved}}function stripExt(path){let lastSlash=path.lastIndexOf(`/`),filename=lastSlash>=0?path.slice(lastSlash+1):path,lastDot=filename.lastIndexOf(`.`);return lastDot<=0?path:(lastSlash>=0?path.slice(0,lastSlash+1):``)+filename.slice(0,lastDot)}const ASSET_MANIFEST_VERSION=1,ASSETS=createToken(`kick/assets/Map`);var UnknownAssetError=class extends Error{namespace;key;constructor(namespace,key){super(`Unknown asset '${namespace}/${key}'. Make sure the namespace exists in kick.config.ts assetMap and that the file is present in the source directory.`),this.name=`UnknownAssetError`,this.namespace=namespace,this.key=key}};let manifestCache;function toPosixPath(p){return p.replaceAll(`\\`,`/`)}function resolveAsset(namespace,key){let resolved=loadManifest();if(!resolved)throw new UnknownAssetError(namespace,key);let entry=resolved.manifest.entries[`${namespace}/${key}`];if(!entry)throw new UnknownAssetError(namespace,key);return toPosixPath(isAbsolute(entry)?entry:resolve(resolved.root,entry))}function clearAssetCache(){manifestCache=void 0}function loadManifest(){return process.env.NODE_ENV===`production`?(manifestCache===void 0&&(manifestCache=discoverManifest()),manifestCache):discoverManifest()}function discoverManifest(){let envRoot=process.env.KICK_ASSETS_ROOT;if(envRoot){let fromEnv=readBuiltManifest(envRoot);if(fromEnv)return fromEnv}let cwd=process.cwd(),config=loadConfigSync(cwd);if(process.env.NODE_ENV!==`production`){let fresh=synthesiseDevManifest(cwd,config);if(fresh)return fresh}let configOutDir=config?.build?.outDir;if(configOutDir&&!STANDARD_OUT_DIRS.includes(configOutDir)){let found=readBuiltManifest(resolve(cwd,configOutDir));if(found)return found}for(let candidate of STANDARD_OUT_DIRS){let found=readBuiltManifest(join(cwd,candidate));if(found)return found}return synthesiseDevManifest(cwd,config)}const STANDARD_OUT_DIRS=[`dist`,`build`,`out`];function readBuiltManifest(dir){let path=join(dir,`.kickjs-assets.json`);if(!existsSync(path))return null;try{let raw=readFileSync(path,`utf-8`),parsed=JSON.parse(raw);return parsed.version!==1||!parsed.entries||typeof parsed.entries!=`object`?null:{manifest:parsed,root:resolve(dir)}}catch{return null}}function synthesiseDevManifest(cwd,preloadedConfig){let config=preloadedConfig===void 0?loadConfigSync(cwd):preloadedConfig;if(!config?.assetMap)return null;let entries={};for(let[namespace,entry]of Object.entries(config.assetMap)){if(!entry||typeof entry.src!=`string`)continue;let srcAbs=resolve(cwd,entry.src);if(!existsSync(srcAbs))continue;let collected=[];walkSync(srcAbs,srcAbs,(relPath,absPath)=>{entry.glob&&!matchesGlobLite(relPath,entry.glob,namespace)||collected.push({rel:relPath,abs:absPath})}),collected.sort((a,b)=>a.rel.localeCompare(b.rel));let{pairs,collisionGroupsResolved}=groupAssetKeys(namespace,collected.map(c=>c.rel),{strategy:entry.keys??`auto`}),absByRel=new Map(collected.map(c=>[c.rel,c.abs]));for(let{rel,key}of pairs){let abs=absByRel.get(rel);abs&&(entries[key]=abs)}collisionGroupsResolved>0&&process.env.NODE_ENV!==`production`&&console.log(`[kickjs/assets] '${namespace}': ${collisionGroupsResolved} basename collision(s) auto-resolved by keeping extensions (set assetMap.${namespace}.keys to 'strip' or 'with-extension' to override).`)}return{manifest:{version:1,entries},root:cwd}}const warnedGlobs=new Set;function matchesGlobLite(relPath,pattern,namespace){if(pattern===`**/*`||pattern===`**`)return!0;let singleExt=/^\*\*\/\*\.(\w+)$/.exec(pattern);if(singleExt)return relPath.endsWith(`.${singleExt[1]}`);let braceExt=/^\*\*\/\*\.\{([^}]+)\}$/.exec(pattern);if(braceExt)return braceExt[1].split(`,`).map(e=>e.trim()).some(ext=>relPath.endsWith(`.${ext}`));let tag=`${namespace}::${pattern}`;return warnedGlobs.has(tag)||(warnedGlobs.add(tag),console.warn(`[kickjs/assets] Dev-mode glob '${pattern}' on '${namespace}' isn't recognised by the lite matcher. Falling back to '**/*'. Run 'kick build:assets' to use the full glob engine.`)),!0}function walkSync(root,dir,onFile){let entries;try{entries=readdirSync(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){if(entry.name===`node_modules`||entry.name.startsWith(`.`))continue;let full=join(dir,entry.name);entry.isDirectory()?walkSync(root,full,onFile):entry.isFile()&&onFile(full.slice(root.length+1).split(sep).join(`/`),full)}}function loadConfigSync(cwd){let jsonPath=join(cwd,`kick.config.json`);if(existsSync(jsonPath))try{return JSON.parse(readFileSync(jsonPath,`utf-8`))}catch{return null}for(let filename of[`kick.config.cjs`,`kick.config.js`]){let path=join(cwd,filename);if(existsSync(path))try{let{createRequire}=__require(`node:module`),mod=createRequire(join(cwd,`package.json`))(path);return mod.default??mod??null}catch{continue}}let snapshotPath=join(cwd,`.kickjs`,`kick.config.json`);if(existsSync(snapshotPath))try{return JSON.parse(readFileSync(snapshotPath,`utf-8`))}catch{return null}return null}const PROMISE_DETECTION_KEYS=new Set([`then`]),PASSTHROUGH_KEYS=new Set([`toString`,`valueOf`,`constructor`,`prototype`,`name`,`length`,`asymmetricMatch`,`nodeType`,Symbol.toPrimitive,Symbol.toStringTag,Symbol.iterator,Symbol.asyncIterator]);function createNamespaceProxy(parts){return new Proxy(function(){},{apply(){if(parts.length<2)throw new UnknownAssetError(parts[0]??``,``);let[namespace,...rest]=parts;return resolveAsset(namespace,rest.join(`/`))},get(t,prop){if(!PROMISE_DETECTION_KEYS.has(prop)){if(PASSTHROUGH_KEYS.has(prop))return Reflect.get(t,prop);if(typeof prop!=`symbol`)return createNamespaceProxy([...parts,prop])}}})}function createAssetProxy(){return new Proxy({},{get(t,prop){if(!PROMISE_DETECTION_KEYS.has(prop)){if(PASSTHROUGH_KEYS.has(prop))return Reflect.get(t,prop);if(typeof prop!=`symbol`)return createNamespaceProxy([prop])}}})}const assets=createAssetProxy();function useAssets(){return assets}_setAssetResolver(resolveAsset);export{defineModule as S,defineContextDecorator as _,clearAssetCache as a,ModuleList as b,groupAssetKeys as c,defineAdapter as d,definePlugin as f,mountSort as g,MountCycleError as h,assets as i,stripExt as l,MissingMountDepError as m,ASSET_MANIFEST_VERSION as n,resolveAsset as o,DuplicateMountNameError as p,UnknownAssetError as r,useAssets as s,ASSETS as t,defineAugmentation as u,CircuitBreaker as v,defineModules as x,CircuitOpenError as y};
12
+ //# sourceMappingURL=core-TDR0XGzO.mjs.map