@porulle/core 0.63.0 → 0.65.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 (463) hide show
  1. package/dist/adapters/email-render.d.ts +18 -0
  2. package/dist/adapters/email-render.d.ts.map +1 -0
  3. package/dist/adapters/email-render.js +37 -0
  4. package/dist/auth/actor.d.ts.map +1 -1
  5. package/dist/auth/actor.js +11 -0
  6. package/dist/auth/auth-failure.d.ts +0 -2
  7. package/dist/auth/auth-failure.d.ts.map +1 -1
  8. package/dist/auth/auth-failure.js +0 -4
  9. package/dist/auth/middleware.d.ts +0 -1
  10. package/dist/auth/middleware.d.ts.map +1 -1
  11. package/dist/auth/middleware.js +7 -6
  12. package/dist/auth/permissions.d.ts +2 -0
  13. package/dist/auth/permissions.d.ts.map +1 -1
  14. package/dist/auth/permissions.js +8 -6
  15. package/dist/auth/role-authority.d.ts +0 -1
  16. package/dist/auth/role-authority.d.ts.map +1 -1
  17. package/dist/auth/role-authority.js +1 -8
  18. package/dist/auth/setup.d.ts.map +1 -1
  19. package/dist/auth/setup.js +8 -0
  20. package/dist/auth/strict-org-resolution.d.ts +8 -1
  21. package/dist/auth/strict-org-resolution.d.ts.map +1 -1
  22. package/dist/auth/strict-org-resolution.js +9 -19
  23. package/dist/auth/system-actor.d.ts +3 -2
  24. package/dist/auth/system-actor.d.ts.map +1 -1
  25. package/dist/auth/system-actor.js +3 -3
  26. package/dist/config/defaults.d.ts.map +1 -1
  27. package/dist/config/defaults.js +3 -20
  28. package/dist/config/define-config.d.ts +2 -2
  29. package/dist/config/define-config.d.ts.map +1 -1
  30. package/dist/config/define-config.js +3 -2
  31. package/dist/config/types.d.ts +13 -3
  32. package/dist/config/types.d.ts.map +1 -1
  33. package/dist/hooks/checkout.d.ts +2 -15
  34. package/dist/hooks/checkout.d.ts.map +1 -1
  35. package/dist/hooks/checkout.js +2 -51
  36. package/dist/index.d.ts +11 -19
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +11 -12
  39. package/dist/interfaces/rest/router.js +3 -3
  40. package/dist/interfaces/rest/routes/admin/compensation-failures.d.ts.map +1 -1
  41. package/dist/interfaces/rest/routes/admin/compensation-failures.js +5 -5
  42. package/dist/interfaces/rest/routes/admin/entity-field-definitions.js +5 -5
  43. package/dist/interfaces/rest/routes/admin/staff.d.ts.map +1 -1
  44. package/dist/interfaces/rest/routes/admin/staff.js +2 -3
  45. package/dist/interfaces/rest/routes/analytics.d.ts.map +1 -1
  46. package/dist/interfaces/rest/routes/analytics.js +2 -2
  47. package/dist/interfaces/rest/routes/carts.d.ts.map +1 -1
  48. package/dist/interfaces/rest/routes/carts.js +12 -12
  49. package/dist/interfaces/rest/routes/catalog.js +37 -37
  50. package/dist/interfaces/rest/routes/checkout.d.ts.map +1 -1
  51. package/dist/interfaces/rest/routes/checkout.js +9 -10
  52. package/dist/interfaces/rest/routes/customers.d.ts.map +1 -1
  53. package/dist/interfaces/rest/routes/customers.js +12 -12
  54. package/dist/interfaces/rest/routes/documents.d.ts.map +1 -1
  55. package/dist/interfaces/rest/routes/documents.js +9 -9
  56. package/dist/interfaces/rest/routes/inventory.d.ts.map +1 -1
  57. package/dist/interfaces/rest/routes/inventory.js +8 -8
  58. package/dist/interfaces/rest/routes/media.d.ts.map +1 -1
  59. package/dist/interfaces/rest/routes/media.js +5 -5
  60. package/dist/interfaces/rest/routes/orders.d.ts.map +1 -1
  61. package/dist/interfaces/rest/routes/orders.js +32 -32
  62. package/dist/interfaces/rest/routes/payments.d.ts.map +1 -1
  63. package/dist/interfaces/rest/routes/payments.js +2 -2
  64. package/dist/interfaces/rest/routes/pricing.d.ts.map +1 -1
  65. package/dist/interfaces/rest/routes/pricing.js +8 -8
  66. package/dist/interfaces/rest/routes/promotions.d.ts.map +1 -1
  67. package/dist/interfaces/rest/routes/promotions.js +7 -7
  68. package/dist/interfaces/rest/routes/search.d.ts.map +1 -1
  69. package/dist/interfaces/rest/routes/search.js +3 -3
  70. package/dist/interfaces/rest/routes/settings.d.ts.map +1 -1
  71. package/dist/interfaces/rest/routes/settings.js +4 -4
  72. package/dist/interfaces/rest/routes/shipping.d.ts.map +1 -1
  73. package/dist/interfaces/rest/routes/shipping.js +9 -9
  74. package/dist/interfaces/rest/routes/tax.d.ts.map +1 -1
  75. package/dist/interfaces/rest/routes/tax.js +9 -9
  76. package/dist/interfaces/rest/routes/webhooks.d.ts.map +1 -1
  77. package/dist/interfaces/rest/routes/webhooks.js +4 -4
  78. package/dist/interfaces/rest/utils.d.ts +1 -1
  79. package/dist/interfaces/rest/utils.d.ts.map +1 -1
  80. package/dist/interfaces/rest/utils.js +4 -13
  81. package/dist/jobs.d.ts +1 -0
  82. package/dist/jobs.d.ts.map +1 -1
  83. package/dist/jobs.js +1 -0
  84. package/dist/kernel/database/adapter.d.ts +9 -0
  85. package/dist/kernel/database/adapter.d.ts.map +1 -1
  86. package/dist/kernel/database/adapter.js +1 -1
  87. package/dist/kernel/database/migrate.d.ts +0 -4
  88. package/dist/kernel/database/migrate.d.ts.map +1 -1
  89. package/dist/kernel/database/migrate.js +2 -14
  90. package/dist/kernel/database/pglite-transaction.d.ts +28 -0
  91. package/dist/kernel/database/pglite-transaction.d.ts.map +1 -0
  92. package/dist/kernel/database/pglite-transaction.js +52 -0
  93. package/dist/kernel/database/tx-context.d.ts +0 -1
  94. package/dist/kernel/database/tx-context.d.ts.map +1 -1
  95. package/dist/kernel/database/tx-context.js +2 -14
  96. package/dist/kernel/database/unique-violation.d.ts +3 -0
  97. package/dist/kernel/database/unique-violation.d.ts.map +1 -0
  98. package/dist/kernel/database/unique-violation.js +9 -0
  99. package/dist/kernel/error-mapper.d.ts.map +1 -1
  100. package/dist/kernel/error-mapper.js +1 -0
  101. package/dist/kernel/errors.d.ts +12 -0
  102. package/dist/kernel/errors.d.ts.map +1 -1
  103. package/dist/kernel/errors.js +16 -0
  104. package/dist/kernel/hooks/create-context.d.ts +18 -9
  105. package/dist/kernel/hooks/create-context.d.ts.map +1 -1
  106. package/dist/kernel/hooks/create-context.js +24 -3
  107. package/dist/kernel/hooks/registry.d.ts +0 -19
  108. package/dist/kernel/hooks/registry.d.ts.map +1 -1
  109. package/dist/kernel/hooks/registry.js +0 -32
  110. package/dist/kernel/jobs/drizzle-adapter.d.ts.map +1 -1
  111. package/dist/kernel/jobs/drizzle-adapter.js +3 -10
  112. package/dist/kernel/jobs/prepare-enqueue.d.ts +20 -0
  113. package/dist/kernel/jobs/prepare-enqueue.d.ts.map +1 -0
  114. package/dist/kernel/jobs/prepare-enqueue.js +24 -0
  115. package/dist/kernel/jobs/types.d.ts +0 -4
  116. package/dist/kernel/jobs/types.d.ts.map +1 -1
  117. package/dist/kernel/jobs/types.js +0 -4
  118. package/dist/kernel/local-api.d.ts +0 -33
  119. package/dist/kernel/local-api.d.ts.map +1 -1
  120. package/dist/kernel/local-api.js +0 -36
  121. package/dist/kernel/plugin/manifest.d.ts +3 -5
  122. package/dist/kernel/plugin/manifest.d.ts.map +1 -1
  123. package/dist/modules/analytics/service.d.ts +0 -6
  124. package/dist/modules/analytics/service.d.ts.map +1 -1
  125. package/dist/modules/analytics/service.js +0 -32
  126. package/dist/modules/cart/service.d.ts.map +1 -1
  127. package/dist/modules/cart/service.js +5 -17
  128. package/dist/modules/catalog/entity-service.d.ts.map +1 -1
  129. package/dist/modules/catalog/entity-service.js +9 -17
  130. package/dist/modules/catalog/import-service.d.ts.map +1 -1
  131. package/dist/modules/catalog/import-service.js +4 -13
  132. package/dist/modules/catalog/service.d.ts +1 -81
  133. package/dist/modules/catalog/service.d.ts.map +1 -1
  134. package/dist/modules/catalog/service.js +1 -8
  135. package/dist/modules/customers/service.d.ts.map +1 -1
  136. package/dist/modules/customers/service.js +5 -17
  137. package/dist/modules/documents/render.d.ts +0 -3
  138. package/dist/modules/documents/render.d.ts.map +1 -1
  139. package/dist/modules/documents/render.js +2 -17
  140. package/dist/modules/fulfillment/service.d.ts.map +1 -1
  141. package/dist/modules/fulfillment/service.js +8 -26
  142. package/dist/modules/inventory/service.d.ts.map +1 -1
  143. package/dist/modules/inventory/service.js +3 -20
  144. package/dist/modules/media/service.d.ts.map +1 -1
  145. package/dist/modules/media/service.js +2 -10
  146. package/dist/modules/orders/quote.d.ts.map +1 -1
  147. package/dist/modules/orders/quote.js +1 -2
  148. package/dist/modules/orders/service.d.ts.map +1 -1
  149. package/dist/modules/orders/service.js +4 -17
  150. package/dist/modules/pricing/service.d.ts.map +1 -1
  151. package/dist/modules/pricing/service.js +7 -18
  152. package/dist/modules/promotions/service.d.ts.map +1 -1
  153. package/dist/modules/promotions/service.js +4 -16
  154. package/dist/modules/tax/service.d.ts +1 -3
  155. package/dist/modules/tax/service.d.ts.map +1 -1
  156. package/dist/modules/tax/service.js +16 -52
  157. package/dist/modules/webhooks/hook.d.ts.map +1 -1
  158. package/dist/modules/webhooks/hook.js +3 -2
  159. package/dist/modules/webhooks/service.d.ts.map +1 -1
  160. package/dist/modules/webhooks/service.js +1 -50
  161. package/dist/runtime/commerce.d.ts.map +1 -1
  162. package/dist/runtime/commerce.js +4 -11
  163. package/dist/runtime/kernel-modules.d.ts +38 -1799
  164. package/dist/runtime/kernel-modules.d.ts.map +1 -1
  165. package/dist/runtime/kernel-modules.js +160 -66
  166. package/dist/runtime/kernel-types.d.ts +3 -15
  167. package/dist/runtime/kernel-types.d.ts.map +1 -1
  168. package/dist/runtime/kernel-types.js +0 -10
  169. package/dist/runtime/kernel.d.ts +2 -3
  170. package/dist/runtime/kernel.d.ts.map +1 -1
  171. package/dist/runtime/kernel.js +10 -51
  172. package/dist/runtime/server.d.ts +1 -1
  173. package/dist/runtime/server.d.ts.map +1 -1
  174. package/dist/test-utils/create-pglite-adapter.d.ts.map +1 -1
  175. package/dist/test-utils/create-pglite-adapter.js +5 -62
  176. package/dist/test-utils/create-plugin-test-app.d.ts.map +1 -1
  177. package/dist/test-utils/create-plugin-test-app.js +13 -32
  178. package/dist/test-utils/rest-api-test-utils.d.ts +0 -12
  179. package/dist/test-utils/rest-api-test-utils.d.ts.map +1 -1
  180. package/dist/test-utils/rest-api-test-utils.js +3 -70
  181. package/dist/test-utils/test-actors.d.ts +9 -0
  182. package/dist/test-utils/test-actors.d.ts.map +1 -1
  183. package/dist/test-utils/test-actors.js +62 -0
  184. package/dist/testing.d.ts +1 -4
  185. package/dist/testing.d.ts.map +1 -1
  186. package/dist/testing.js +1 -4
  187. package/dist/utils/escape-html.d.ts +3 -0
  188. package/dist/utils/escape-html.d.ts.map +1 -0
  189. package/dist/utils/escape-html.js +9 -0
  190. package/dist/utils/id.d.ts +0 -1
  191. package/dist/utils/id.d.ts.map +1 -1
  192. package/dist/utils/id.js +0 -3
  193. package/dist/utils/logger.d.ts +1 -1
  194. package/dist/utils/logger.d.ts.map +1 -1
  195. package/dist/utils/logger.js +1 -1
  196. package/dist/utils/money.d.ts +13 -0
  197. package/dist/utils/money.d.ts.map +1 -0
  198. package/dist/utils/money.js +58 -0
  199. package/package.json +5 -6
  200. package/src/adapters/email-render.ts +63 -0
  201. package/src/auth/actor.ts +14 -0
  202. package/src/auth/auth-failure.ts +0 -5
  203. package/src/auth/middleware.ts +7 -6
  204. package/src/auth/permissions.ts +12 -6
  205. package/src/auth/role-authority.ts +1 -10
  206. package/src/auth/setup.ts +11 -0
  207. package/src/auth/strict-org-resolution.ts +9 -16
  208. package/src/auth/system-actor.ts +3 -3
  209. package/src/config/defaults.ts +3 -20
  210. package/src/config/define-config.ts +5 -4
  211. package/src/config/types.ts +13 -2
  212. package/src/hooks/checkout.ts +2 -86
  213. package/src/index.ts +9 -36
  214. package/src/interfaces/rest/router.ts +3 -3
  215. package/src/interfaces/rest/routes/admin/compensation-failures.ts +5 -5
  216. package/src/interfaces/rest/routes/admin/entity-field-definitions.ts +5 -5
  217. package/src/interfaces/rest/routes/admin/staff.ts +2 -3
  218. package/src/interfaces/rest/routes/analytics.ts +2 -2
  219. package/src/interfaces/rest/routes/carts.ts +12 -12
  220. package/src/interfaces/rest/routes/catalog.ts +37 -37
  221. package/src/interfaces/rest/routes/checkout.ts +8 -10
  222. package/src/interfaces/rest/routes/customers.ts +12 -12
  223. package/src/interfaces/rest/routes/documents.ts +9 -9
  224. package/src/interfaces/rest/routes/inventory.ts +8 -8
  225. package/src/interfaces/rest/routes/media.ts +5 -5
  226. package/src/interfaces/rest/routes/orders.ts +32 -32
  227. package/src/interfaces/rest/routes/payments.ts +2 -2
  228. package/src/interfaces/rest/routes/pricing.ts +8 -8
  229. package/src/interfaces/rest/routes/promotions.ts +7 -7
  230. package/src/interfaces/rest/routes/search.ts +3 -3
  231. package/src/interfaces/rest/routes/settings.ts +4 -4
  232. package/src/interfaces/rest/routes/shipping.ts +9 -9
  233. package/src/interfaces/rest/routes/tax.ts +9 -9
  234. package/src/interfaces/rest/routes/webhooks.ts +4 -4
  235. package/src/interfaces/rest/utils.ts +4 -14
  236. package/src/jobs.ts +2 -1
  237. package/src/kernel/database/adapter.ts +1 -1
  238. package/src/kernel/database/migrate.ts +2 -17
  239. package/src/kernel/database/pglite-transaction.ts +61 -0
  240. package/src/kernel/database/tx-context.ts +2 -20
  241. package/src/kernel/database/unique-violation.ts +7 -0
  242. package/src/kernel/error-mapper.ts +1 -0
  243. package/src/kernel/errors.ts +18 -0
  244. package/src/kernel/hooks/create-context.ts +38 -8
  245. package/src/kernel/hooks/registry.ts +0 -37
  246. package/src/kernel/jobs/drizzle-adapter.ts +4 -15
  247. package/src/kernel/jobs/prepare-enqueue.ts +42 -0
  248. package/src/kernel/jobs/types.ts +0 -5
  249. package/src/kernel/local-api.ts +0 -44
  250. package/src/kernel/plugin/manifest.ts +3 -5
  251. package/src/modules/analytics/service.ts +0 -36
  252. package/src/modules/cart/service.ts +6 -29
  253. package/src/modules/catalog/entity-service.ts +9 -19
  254. package/src/modules/catalog/import-service.ts +4 -11
  255. package/src/modules/catalog/service.ts +2 -286
  256. package/src/modules/customers/service.ts +6 -27
  257. package/src/modules/documents/render.ts +2 -19
  258. package/src/modules/fulfillment/service.ts +8 -27
  259. package/src/modules/inventory/service.ts +3 -21
  260. package/src/modules/media/service.ts +2 -8
  261. package/src/modules/orders/quote.ts +1 -2
  262. package/src/modules/orders/service.ts +5 -30
  263. package/src/modules/pricing/service.ts +12 -30
  264. package/src/modules/promotions/service.ts +5 -28
  265. package/src/modules/tax/service.ts +20 -48
  266. package/src/modules/webhooks/hook.ts +3 -2
  267. package/src/modules/webhooks/service.ts +1 -42
  268. package/src/runtime/commerce.ts +4 -11
  269. package/src/runtime/kernel-modules.ts +191 -67
  270. package/src/runtime/kernel-types.ts +3 -26
  271. package/src/runtime/kernel.ts +11 -66
  272. package/src/runtime/server.ts +1 -3
  273. package/src/test-utils/create-pglite-adapter.ts +5 -67
  274. package/src/test-utils/create-plugin-test-app.ts +13 -52
  275. package/src/test-utils/rest-api-test-utils.ts +3 -70
  276. package/src/test-utils/test-actors.ts +66 -0
  277. package/src/testing.ts +1 -3
  278. package/src/utils/escape-html.ts +9 -0
  279. package/src/utils/id.ts +0 -4
  280. package/src/utils/logger.ts +1 -1
  281. package/src/utils/money.ts +62 -0
  282. package/dist/auth/access.d.ts +0 -101
  283. package/dist/auth/access.d.ts.map +0 -1
  284. package/dist/auth/access.js +0 -128
  285. package/dist/generated/plugin-manifest.d.ts +0 -51
  286. package/dist/generated/plugin-manifest.d.ts.map +0 -1
  287. package/dist/generated/plugin-manifest.js +0 -21
  288. package/dist/kernel/factory/repository-factory.d.ts +0 -71
  289. package/dist/kernel/factory/repository-factory.d.ts.map +0 -1
  290. package/dist/kernel/factory/repository-factory.js +0 -138
  291. package/dist/kernel/http-error.d.ts +0 -30
  292. package/dist/kernel/http-error.d.ts.map +0 -1
  293. package/dist/kernel/http-error.js +0 -35
  294. package/dist/kernel/jobs/builtin-job-tasks.d.ts +0 -3
  295. package/dist/kernel/jobs/builtin-job-tasks.d.ts.map +0 -1
  296. package/dist/kernel/jobs/builtin-job-tasks.js +0 -6
  297. package/dist/kernel/module/define.d.ts +0 -21
  298. package/dist/kernel/module/define.d.ts.map +0 -1
  299. package/dist/kernel/module/define.js +0 -3
  300. package/dist/kernel/module/index.d.ts +0 -4
  301. package/dist/kernel/module/index.d.ts.map +0 -1
  302. package/dist/kernel/module/index.js +0 -2
  303. package/dist/kernel/module/topo-sort.d.ts +0 -7
  304. package/dist/kernel/module/topo-sort.d.ts.map +0 -1
  305. package/dist/kernel/module/topo-sort.js +0 -89
  306. package/dist/kernel/query/executor.d.ts +0 -21
  307. package/dist/kernel/query/executor.d.ts.map +0 -1
  308. package/dist/kernel/query/executor.js +0 -128
  309. package/dist/kernel/query/registry.d.ts +0 -33
  310. package/dist/kernel/query/registry.d.ts.map +0 -1
  311. package/dist/kernel/query/registry.js +0 -20
  312. package/dist/kernel/service-registry.d.ts +0 -109
  313. package/dist/kernel/service-registry.d.ts.map +0 -1
  314. package/dist/kernel/service-registry.js +0 -26
  315. package/dist/modules/analytics/hooks.d.ts +0 -13
  316. package/dist/modules/analytics/hooks.d.ts.map +0 -1
  317. package/dist/modules/analytics/hooks.js +0 -12
  318. package/dist/modules/analytics/module.d.ts +0 -3
  319. package/dist/modules/analytics/module.d.ts.map +0 -1
  320. package/dist/modules/analytics/module.js +0 -24
  321. package/dist/modules/analytics/repository/index.d.ts +0 -5
  322. package/dist/modules/analytics/repository/index.d.ts.map +0 -1
  323. package/dist/modules/analytics/repository/index.js +0 -1
  324. package/dist/modules/audit/index.d.ts +0 -2
  325. package/dist/modules/audit/index.d.ts.map +0 -1
  326. package/dist/modules/audit/index.js +0 -1
  327. package/dist/modules/audit/module.d.ts +0 -180
  328. package/dist/modules/audit/module.d.ts.map +0 -1
  329. package/dist/modules/audit/module.js +0 -8
  330. package/dist/modules/cart/access.d.ts +0 -11
  331. package/dist/modules/cart/access.d.ts.map +0 -1
  332. package/dist/modules/cart/access.js +0 -18
  333. package/dist/modules/cart/module.d.ts +0 -14
  334. package/dist/modules/cart/module.d.ts.map +0 -1
  335. package/dist/modules/cart/module.js +0 -17
  336. package/dist/modules/catalog/module.d.ts +0 -26
  337. package/dist/modules/catalog/module.d.ts.map +0 -1
  338. package/dist/modules/catalog/module.js +0 -33
  339. package/dist/modules/customers/index.d.ts +0 -2
  340. package/dist/modules/customers/index.d.ts.map +0 -1
  341. package/dist/modules/customers/index.js +0 -1
  342. package/dist/modules/customers/module.d.ts +0 -563
  343. package/dist/modules/customers/module.d.ts.map +0 -1
  344. package/dist/modules/customers/module.js +0 -20
  345. package/dist/modules/documents/module.d.ts +0 -7
  346. package/dist/modules/documents/module.d.ts.map +0 -1
  347. package/dist/modules/documents/module.js +0 -13
  348. package/dist/modules/fulfillment/module.d.ts +0 -13
  349. package/dist/modules/fulfillment/module.d.ts.map +0 -1
  350. package/dist/modules/fulfillment/module.js +0 -23
  351. package/dist/modules/inventory/module.d.ts +0 -13
  352. package/dist/modules/inventory/module.d.ts.map +0 -1
  353. package/dist/modules/inventory/module.js +0 -20
  354. package/dist/modules/media/index.d.ts +0 -2
  355. package/dist/modules/media/index.d.ts.map +0 -1
  356. package/dist/modules/media/index.js +0 -1
  357. package/dist/modules/media/module.d.ts +0 -360
  358. package/dist/modules/media/module.d.ts.map +0 -1
  359. package/dist/modules/media/module.js +0 -24
  360. package/dist/modules/orders/module.d.ts +0 -25
  361. package/dist/modules/orders/module.d.ts.map +0 -1
  362. package/dist/modules/orders/module.js +0 -33
  363. package/dist/modules/organization/index.d.ts +0 -2
  364. package/dist/modules/organization/index.d.ts.map +0 -1
  365. package/dist/modules/organization/index.js +0 -1
  366. package/dist/modules/organization/module.d.ts +0 -205
  367. package/dist/modules/organization/module.d.ts.map +0 -1
  368. package/dist/modules/organization/module.js +0 -8
  369. package/dist/modules/payments/module.d.ts +0 -3
  370. package/dist/modules/payments/module.d.ts.map +0 -1
  371. package/dist/modules/payments/module.js +0 -7
  372. package/dist/modules/payments/repository/index.d.ts +0 -5
  373. package/dist/modules/payments/repository/index.d.ts.map +0 -1
  374. package/dist/modules/payments/repository/index.js +0 -1
  375. package/dist/modules/pricing/index.d.ts +0 -2
  376. package/dist/modules/pricing/index.d.ts.map +0 -1
  377. package/dist/modules/pricing/index.js +0 -1
  378. package/dist/modules/pricing/module.d.ts +0 -14
  379. package/dist/modules/pricing/module.d.ts.map +0 -1
  380. package/dist/modules/pricing/module.js +0 -17
  381. package/dist/modules/promotions/module.d.ts +0 -14
  382. package/dist/modules/promotions/module.d.ts.map +0 -1
  383. package/dist/modules/promotions/module.js +0 -19
  384. package/dist/modules/search/module.d.ts +0 -8
  385. package/dist/modules/search/module.d.ts.map +0 -1
  386. package/dist/modules/search/module.js +0 -22
  387. package/dist/modules/search/repository/index.d.ts +0 -5
  388. package/dist/modules/search/repository/index.d.ts.map +0 -1
  389. package/dist/modules/search/repository/index.js +0 -1
  390. package/dist/modules/settings/module.d.ts +0 -6
  391. package/dist/modules/settings/module.d.ts.map +0 -1
  392. package/dist/modules/settings/module.js +0 -12
  393. package/dist/modules/shipping/module.d.ts +0 -12
  394. package/dist/modules/shipping/module.d.ts.map +0 -1
  395. package/dist/modules/shipping/module.js +0 -14
  396. package/dist/modules/tax/module.d.ts +0 -7
  397. package/dist/modules/tax/module.d.ts.map +0 -1
  398. package/dist/modules/tax/module.js +0 -13
  399. package/dist/modules/webhooks/index.d.ts +0 -2
  400. package/dist/modules/webhooks/index.d.ts.map +0 -1
  401. package/dist/modules/webhooks/index.js +0 -1
  402. package/dist/modules/webhooks/module.d.ts +0 -403
  403. package/dist/modules/webhooks/module.d.ts.map +0 -1
  404. package/dist/modules/webhooks/module.js +0 -16
  405. package/dist/test-utils/create-repository-test-harness.d.ts +0 -8
  406. package/dist/test-utils/create-repository-test-harness.d.ts.map +0 -1
  407. package/dist/test-utils/create-repository-test-harness.js +0 -7
  408. package/dist/test-utils/create-test-plugin-context.d.ts +0 -38
  409. package/dist/test-utils/create-test-plugin-context.d.ts.map +0 -1
  410. package/dist/test-utils/create-test-plugin-context.js +0 -39
  411. package/dist/test-utils/typed-hooks.d.ts +0 -44
  412. package/dist/test-utils/typed-hooks.d.ts.map +0 -1
  413. package/dist/test-utils/typed-hooks.js +0 -36
  414. package/dist/types/commerce-types.d.ts +0 -34
  415. package/dist/types/commerce-types.d.ts.map +0 -1
  416. package/dist/types/commerce-types.js +0 -1
  417. package/src/auth/access.ts +0 -187
  418. package/src/generated/plugin-capabilities.d.ts +0 -21
  419. package/src/generated/plugin-manifest.ts +0 -24
  420. package/src/generated/plugin-repositories.d.ts +0 -21
  421. package/src/kernel/factory/repository-factory.ts +0 -244
  422. package/src/kernel/http-error.ts +0 -44
  423. package/src/kernel/jobs/builtin-job-tasks.ts +0 -17
  424. package/src/kernel/module/define.ts +0 -36
  425. package/src/kernel/module/index.ts +0 -3
  426. package/src/kernel/module/topo-sort.ts +0 -99
  427. package/src/kernel/query/executor.ts +0 -184
  428. package/src/kernel/query/registry.ts +0 -46
  429. package/src/kernel/service-registry.ts +0 -76
  430. package/src/modules/analytics/hooks.ts +0 -11
  431. package/src/modules/analytics/module.ts +0 -35
  432. package/src/modules/analytics/repository/index.ts +0 -5
  433. package/src/modules/audit/index.ts +0 -1
  434. package/src/modules/audit/module.ts +0 -11
  435. package/src/modules/cart/access.ts +0 -27
  436. package/src/modules/cart/module.ts +0 -32
  437. package/src/modules/catalog/module.ts +0 -80
  438. package/src/modules/customers/index.ts +0 -1
  439. package/src/modules/customers/module.ts +0 -29
  440. package/src/modules/documents/module.ts +0 -21
  441. package/src/modules/fulfillment/module.ts +0 -44
  442. package/src/modules/inventory/module.ts +0 -37
  443. package/src/modules/media/index.ts +0 -1
  444. package/src/modules/media/module.ts +0 -27
  445. package/src/modules/orders/module.ts +0 -67
  446. package/src/modules/organization/index.ts +0 -1
  447. package/src/modules/organization/module.ts +0 -11
  448. package/src/modules/payments/module.ts +0 -14
  449. package/src/modules/payments/repository/index.ts +0 -5
  450. package/src/modules/pricing/index.ts +0 -1
  451. package/src/modules/pricing/module.ts +0 -32
  452. package/src/modules/promotions/module.ts +0 -34
  453. package/src/modules/search/module.ts +0 -32
  454. package/src/modules/search/repository/index.ts +0 -5
  455. package/src/modules/settings/module.ts +0 -20
  456. package/src/modules/shipping/module.ts +0 -27
  457. package/src/modules/tax/module.ts +0 -21
  458. package/src/modules/webhooks/index.ts +0 -1
  459. package/src/modules/webhooks/module.ts +0 -24
  460. package/src/test-utils/create-repository-test-harness.ts +0 -16
  461. package/src/test-utils/create-test-plugin-context.ts +0 -66
  462. package/src/test-utils/typed-hooks.ts +0 -55
  463. package/src/types/commerce-types.ts +0 -34
@@ -1,7 +1,7 @@
1
1
  import { OpenAPIHono } from "@hono/zod-openapi";
2
2
  import type { Kernel } from "../../../runtime/kernel.js";
3
3
  import { createWebhookEndpointRoute, listWebhookEndpointsRoute, deleteWebhookEndpointRoute } from "../schemas/webhooks.js";
4
- import { type AppEnv, mapErrorToResponse, mapErrorToStatus, requirePerm } from "../utils.js";
4
+ import { type AppEnv, errorBody, mapErrorToStatus, requirePerm } from "../utils.js";
5
5
 
6
6
  export function webhookRoutes(kernel: Kernel) {
7
7
  const router = new OpenAPIHono<AppEnv>();
@@ -18,7 +18,7 @@ export function webhookRoutes(kernel: Kernel) {
18
18
  const actor = c.get("actor");
19
19
  const result = await kernel.services.webhooks.createEndpoint(body, actor);
20
20
  if (!result.ok) {
21
- return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
21
+ return c.json(errorBody(result.error), mapErrorToStatus(result.error));
22
22
  }
23
23
  return c.json({ data: result.value }, 201);
24
24
  });
@@ -27,7 +27,7 @@ export function webhookRoutes(kernel: Kernel) {
27
27
  router.openapi(listWebhookEndpointsRoute, async (c) => {
28
28
  const result = await kernel.services.webhooks.listEndpoints(c.get("actor"));
29
29
  if (!result.ok) {
30
- return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
30
+ return c.json(errorBody(result.error), mapErrorToStatus(result.error));
31
31
  }
32
32
  const sanitized = result.value.map(({ secret: _secret, ...rest }) => rest);
33
33
  return c.json({ data: sanitized });
@@ -40,7 +40,7 @@ export function webhookRoutes(kernel: Kernel) {
40
40
  c.get("actor"),
41
41
  );
42
42
  if (!result.ok) {
43
- return c.json(mapErrorToResponse(result.error), mapErrorToStatus(result.error));
43
+ return c.json(errorBody(result.error), mapErrorToStatus(result.error));
44
44
  }
45
45
  return c.json({ data: { deleted: true } });
46
46
  });
@@ -5,6 +5,7 @@ import type { Actor } from "../../auth/types.js";
5
5
  import {
6
6
  AUTHENTICATION_REQUIRED_MESSAGE,
7
7
  isUnauthenticatedActor,
8
+ hasPermissionFromList,
8
9
  } from "../../auth/permissions.js";
9
10
 
10
11
  export const ROUTE_PERMISSION_GUARD = Symbol("porulle.routePermissionGuard");
@@ -72,7 +73,7 @@ export function parseInclude(value?: string): Set<string> {
72
73
  * Map an error to a safe client response. Internal errors are sanitized
73
74
  * to prevent leaking SQL, schema, or stack trace details.
74
75
  */
75
- export function mapErrorToResponse(error: unknown): { error: { code: string; message: string } } {
76
+ export function errorBody(error: unknown): { error: { code: string; message: string } } {
76
77
  const ce = toCommerceError(error);
77
78
  if (ce.code === "INTERNAL_ERROR") {
78
79
  // Sanitize internal errors -- do not expose raw messages to clients
@@ -91,14 +92,7 @@ export { mapErrorToStatus };
91
92
  export function requirePerm(permission: string) {
92
93
  const middleware = async (c: PermissionContext, next: () => Promise<void>) => {
93
94
  const actor = c.get("actor");
94
- const perms = actor?.permissions ?? [];
95
- if (perms.includes(permission) || perms.includes("*:*")) {
96
- await next();
97
- return;
98
- }
99
- // Check resource-level wildcard (e.g., "catalog:*" matches "catalog:create")
100
- const [resource] = permission.split(":");
101
- if (resource && perms.includes(`${resource}:*`)) {
95
+ if (hasPermissionFromList(actor?.permissions ?? [], permission)) {
102
96
  await next();
103
97
  return;
104
98
  }
@@ -114,11 +108,7 @@ export function requireAnyPerm(permissions: readonly string[]) {
114
108
  const middleware = async (c: PermissionContext, next: () => Promise<void>) => {
115
109
  const actor = c.get("actor");
116
110
  const granted = actor?.permissions ?? [];
117
- const allowed = permissions.some((permission) =>
118
- granted.includes(permission) ||
119
- granted.includes("*:*") ||
120
- granted.includes(`${permission.split(":")[0]}:*`),
121
- );
111
+ const allowed = permissions.some((permission) => hasPermissionFromList(granted, permission));
122
112
  if (allowed) {
123
113
  await next();
124
114
  return;
package/src/jobs.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Leaf entry for execution engines that run outside Node (Cloudflare Workers):
2
- // only the job types and the two runtime helpers, none of the server runtime.
2
+ // only the job types and the runtime helpers engines share, none of the server runtime.
3
3
  export type {
4
4
  JobInstanceStatus,
5
5
  TaskContext,
@@ -10,6 +10,7 @@ export type {
10
10
  } from "./kernel/jobs/types.js";
11
11
  export { TaskNonRetryableError } from "./kernel/jobs/types.js";
12
12
  export { createPassThroughTaskStep } from "./kernel/jobs/step.js";
13
+ export { prepareEnqueue, type PreparedEnqueue } from "./kernel/jobs/prepare-enqueue.js";
13
14
  export type {
14
15
  EnqueueOptions,
15
16
  ExecutionEngine,
@@ -54,7 +54,7 @@ export function unwrapDb<T>(db: T): T {
54
54
  * on the `{ rows }` drivers. We intercept only `execute`; every other method
55
55
  * is bound to the real driver instance so its internals are untouched.
56
56
  */
57
- function normalizeExecuteShape<T extends object>(db: T): T {
57
+ export function normalizeExecuteShape<T extends object>(db: T): T {
58
58
  return new Proxy(db, {
59
59
  get(target, prop, receiver) {
60
60
  if (prop === RAW_DB) return target;
@@ -64,19 +64,6 @@ export function buildSchema(config?: CommerceConfig): Record<string, unknown> {
64
64
  return merged;
65
65
  }
66
66
 
67
- /**
68
- * Returns a list of all schema table names defined by the commerce engine.
69
- */
70
- export function getTableNames(): string[] {
71
- return Object.entries(schema)
72
- .filter(
73
- ([_, value]) =>
74
- value != null &&
75
- typeof value === "object" &&
76
- "getSQL" in (value as object),
77
- )
78
- .map(([key]) => key);
79
- }
80
67
 
81
68
  /**
82
69
  * Returns the absolute filesystem path(s) of the combined schema module for
@@ -121,10 +108,8 @@ export async function pushSchema(
121
108
  "pushSchema() requires `drizzle-kit` to be installed. Add it to your project: bun add -d drizzle-kit",
122
109
  );
123
110
  }
124
- // With a config, push the merged core + plugin schema so plugin-declared
125
- // tables are created too; without one, push core only (backward compatible).
126
- const schemaToApply = config ? buildSchema(config) : getSchema();
111
+ // Core plus any plugin-declared tables in `config.customSchemas`.
127
112
  // drizzle-kit needs the native driver result shape; unwrap a normalized db.
128
- const { apply } = await drizzleKit.pushSchema(schemaToApply, unwrapDb(drizzleInstance));
113
+ const { apply } = await drizzleKit.pushSchema(buildSchema(config), unwrapDb(drizzleInstance));
129
114
  await apply();
130
115
  }
@@ -0,0 +1,61 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+
3
+ /** The one PGlite capability a transaction needs: run a statement on the connection. */
4
+ export interface PGliteExec {
5
+ exec(statement: string): Promise<unknown>;
6
+ }
7
+
8
+ /**
9
+ * `DatabaseAdapter.transaction` for a PGlite instance.
10
+ *
11
+ * Drizzle's own `transaction()` can hang on PGlite, so this drives
12
+ * BEGIN/COMMIT/ROLLBACK directly and hands the body the same `db` handle.
13
+ *
14
+ * PGlite is a single connection, so two bodies awaiting concurrently would
15
+ * otherwise interleave their statements between one BEGIN and one COMMIT —
16
+ * the second BEGIN is a no-op Postgres only warns about — and share a snapshot,
17
+ * each other's row locks and each other's rollback. Bodies are queued instead,
18
+ * which is what a connection pool does to two transactions competing for the
19
+ * same rows.
20
+ *
21
+ * Only a call made from INSIDE a running body joins it (without savepoints that
22
+ * is the only sound reading of a nested call). "Inside" is decided by the async
23
+ * context the call runs in, never by whether some transaction happens to be
24
+ * open: an unrelated request that arrives mid-body queues behind it.
25
+ */
26
+ export function createPGliteTransaction(pg: PGliteExec, db: unknown): {
27
+ transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T>;
28
+ /** Whether a transaction body is executing right now. */
29
+ inTransaction(): boolean;
30
+ } {
31
+ // Each transaction gets its own token; a call joins only when it runs inside
32
+ // the body of the transaction that is open right now (work a body started
33
+ // but did not await may outlive it, and must not join a closed transaction).
34
+ const body = new AsyncLocalStorage<object>();
35
+ let queue: Promise<unknown> = Promise.resolve();
36
+ let current: object | null = null;
37
+
38
+ async function transaction<T>(fn: (tx: unknown) => Promise<T>): Promise<T> {
39
+ const caller = body.getStore();
40
+ if (caller !== undefined && caller === current) return fn(db);
41
+ const run = queue.then(async () => {
42
+ await pg.exec("BEGIN");
43
+ const token = {};
44
+ current = token;
45
+ try {
46
+ const result = await body.run(token, () => fn(db));
47
+ await pg.exec("COMMIT");
48
+ return result;
49
+ } catch (error) {
50
+ await pg.exec("ROLLBACK");
51
+ throw error;
52
+ } finally {
53
+ current = null;
54
+ }
55
+ });
56
+ queue = run.catch(() => undefined);
57
+ return run;
58
+ }
59
+
60
+ return { transaction, inTransaction: () => current !== null };
61
+ }
@@ -43,29 +43,11 @@ export async function withTransaction<TDb, TTx, TResult>(
43
43
  });
44
44
  }
45
45
 
46
- export function reuseOrCreateTxContext<TTx>(
47
- tx: TTx,
48
- options: WithTransactionOptions,
49
- existing?: TxContext<TTx> | null,
50
- ): TxContext<TTx> {
51
- if (existing) {
52
- return existing;
53
- }
54
- return createTxContext(tx, options);
55
- }
56
-
57
- function hookContextFromWriteContext(ctx?: CatalogWriteContext): Record<string, unknown> | undefined {
58
- return ctx?.hookContext;
59
- }
60
-
61
- function isTransactionalWriteContext<TTx>(ctx: CatalogWriteContext<TTx>): ctx is TxContext<TTx> {
62
- return "tx" in ctx && ctx.tx != null;
63
- }
64
46
 
65
47
  export function resolveWriteContextHookContext(ctx?: CatalogWriteContext): Record<string, unknown> | undefined {
66
- return hookContextFromWriteContext(ctx);
48
+ return ctx?.hookContext;
67
49
  }
68
50
 
69
51
  export function isWriteContextTransactional<TTx>(ctx?: CatalogWriteContext<TTx>): ctx is TxContext<TTx> {
70
- return ctx != null && isTransactionalWriteContext(ctx);
52
+ return ctx != null && "tx" in ctx && ctx.tx != null;
71
53
  }
@@ -0,0 +1,7 @@
1
+ /** Whether a database error (or any error it wraps) is a Postgres unique violation (23505). */
2
+ export function isUniqueViolation(error: unknown): boolean {
3
+ if (error == null || typeof error !== "object") return false;
4
+ const value = error as { code?: unknown; cause?: unknown };
5
+ if (value.code === "23505") return true;
6
+ return isUniqueViolation(value.cause);
7
+ }
@@ -9,6 +9,7 @@ const statusByCode: Record<string, ContentfulStatusCode> = {
9
9
  FORBIDDEN: 403,
10
10
  UNAUTHORIZED: 401,
11
11
  REAUTH_REQUIRED: 401,
12
+ TWO_FACTOR_REQUIRED: 403,
12
13
  CSRF_ORIGIN_REJECTED: 403,
13
14
  CONFLICT: 409,
14
15
  INVALID_TRANSITION: 422,
@@ -70,6 +70,24 @@ export class CommerceReauthRequiredError extends Error implements CommerceError
70
70
  }
71
71
  }
72
72
 
73
+ /**
74
+ * Raised for a signed-in member whose role is listed in
75
+ * `auth.twoFactor.requiredForRoles` but who has not enabled two-factor
76
+ * authentication. The client discriminates on `code === "TWO_FACTOR_REQUIRED"`
77
+ * to send the member to enrolment (`/api/auth/two-factor/enable`) rather than
78
+ * treating it as a plain refusal.
79
+ */
80
+ export class CommerceTwoFactorRequiredError extends Error implements CommerceError {
81
+ code = "TWO_FACTOR_REQUIRED" as const;
82
+ constructor(
83
+ message: string,
84
+ public details?: unknown,
85
+ ) {
86
+ super(message);
87
+ this.name = "CommerceTwoFactorRequiredError";
88
+ }
89
+ }
90
+
73
91
  export class CommerceForbiddenError extends Error implements CommerceError {
74
92
  code = "FORBIDDEN" as const;
75
93
  constructor(
@@ -5,6 +5,7 @@ import type { JobsAdapter } from "../jobs/adapter.js";
5
5
  import { NullJobsAdapter } from "../jobs/adapter.js";
6
6
  import type { PluginDb } from "../database/plugin-types.js";
7
7
  import type { HookContext, HookOrigin, Logger, ServiceContainer } from "./types.js";
8
+ import { createConsoleLogger } from "../../utils/logger.js";
8
9
 
9
10
  export interface CreateHookContextArgs {
10
11
  actor: Actor | null;
@@ -16,12 +17,7 @@ export interface CreateHookContextArgs {
16
17
  origin?: HookOrigin;
17
18
  jobs?: JobsAdapter;
18
19
  db?: PluginDb;
19
- /** Prefer this over {@link CreateHookContextArgs.kernel}. */
20
20
  database?: { db: PluginDb };
21
- /**
22
- * @deprecated Pass {@link CreateHookContextArgs.database} or {@link CreateHookContextArgs.db} instead.
23
- */
24
- kernel?: { database: { db: PluginDb } };
25
21
  commerceConfig?: CommerceConfig | null;
26
22
  }
27
23
 
@@ -32,11 +28,11 @@ const nullJobs = new NullJobsAdapter();
32
28
  */
33
29
  export function createHookContext(args: CreateHookContextArgs): HookContext {
34
30
  const db =
35
- args.db ?? args.database?.db ?? args.kernel?.database?.db ?? null;
31
+ args.db ?? args.database?.db ?? null;
36
32
 
37
33
  if (db == null) {
38
34
  throw new Error(
39
- "createHookContext requires a database: pass `db`, `database: { db }`, or `kernel: { database: { db } }`.",
35
+ "createHookContext requires a database: pass `db` or `database: { db }`.",
40
36
  );
41
37
  }
42
38
 
@@ -48,8 +44,42 @@ export function createHookContext(args: CreateHookContextArgs): HookContext {
48
44
  context: args.context ?? {},
49
45
  requestId: args.requestId ?? randomUUID(),
50
46
  origin: args.origin ?? "rest",
51
- jobs: args.jobs ?? nullJobs,
47
+ // The kernel installs its engine as `services.jobs` before any module is
48
+ // built, so a context that names no engine still enqueues for real. The
49
+ // null adapter is for a context with no kernel behind it at all.
50
+ jobs: args.jobs ?? (args.services.jobs as JobsAdapter | undefined) ?? nullJobs,
52
51
  db,
53
52
  ...(args.commerceConfig !== undefined ? { commerceConfig: args.commerceConfig } : {}),
54
53
  };
55
54
  }
55
+
56
+ /** What a core module service already holds that its hook context is built from. */
57
+ export interface ModuleHookDeps {
58
+ services: ServiceContainer;
59
+ database: { db: unknown };
60
+ config: CommerceConfig;
61
+ }
62
+
63
+ /**
64
+ * The hook context a core module hands its hooks. Every module builds it the
65
+ * same way — its name as `context.moduleName` (which webhook event names are
66
+ * derived from), a logger scoped to it, the kernel's services (and through them
67
+ * the jobs engine), the database and the config — so none can leave a field out.
68
+ */
69
+ export function createModuleHookContext(
70
+ moduleName: string,
71
+ deps: ModuleHookDeps,
72
+ actor: Actor | null,
73
+ tx: unknown = null,
74
+ options: { logScope?: string; context?: Record<string, unknown> } = {},
75
+ ): HookContext {
76
+ return createHookContext({
77
+ actor,
78
+ tx,
79
+ logger: createConsoleLogger(options.logScope ?? moduleName),
80
+ services: deps.services,
81
+ context: { moduleName, ...options.context },
82
+ database: { db: deps.database.db as PluginDb },
83
+ commerceConfig: deps.config,
84
+ });
85
+ }
@@ -33,7 +33,6 @@ type HookEntry = {
33
33
  export class HookRegistry {
34
34
  private registry = new Map<string, HookEntry>();
35
35
  private inTransactionHandlers = new WeakSet<HookHandler>();
36
- private logger?: { error: (obj: Record<string, unknown>, msg: string) => void };
37
36
 
38
37
  registerConfigHooks(hookName: string, handlers: HookHandler[]): void {
39
38
  this.ensureEntry(hookName);
@@ -55,11 +54,6 @@ export class HookRegistry {
55
54
  this.registry.get(hookName)!.prepended.push(handler);
56
55
  }
57
56
 
58
- prependInTransaction(hookName: string, handler: HookHandler): void {
59
- this.inTransactionHandlers.add(handler);
60
- this.prepend(hookName, handler);
61
- }
62
-
63
57
  runsInTransaction(handler: HookHandler): boolean {
64
58
  return this.inTransactionHandlers.has(handler);
65
59
  }
@@ -70,37 +64,6 @@ export class HookRegistry {
70
64
  return [...entry.prepended, ...entry.configured, ...entry.appended];
71
65
  }
72
66
 
73
- /**
74
- * Emit a plugin event to all registered listeners.
75
- *
76
- * Unlike the before/after hook pattern (which transforms data through
77
- * a pipeline), emit is fire-and-forget notification. Errors in handlers
78
- * are caught and logged but do not propagate to the emitter.
79
- *
80
- * Usage:
81
- * kernel.hooks.emit("production.afterComplete", { orderId, quantity });
82
- *
83
- * Any plugin can listen:
84
- * hooks: () => [{ key: "production.afterComplete", handler: async (payload) => { ... } }]
85
- */
86
- setLogger(logger: { error: (obj: Record<string, unknown>, msg: string) => void }): void {
87
- this.logger = logger;
88
- }
89
-
90
- async emit(key: string, payload: unknown): Promise<void> {
91
- const handlers = this.resolve(key);
92
- for (const handler of handlers) {
93
- try {
94
- await (handler as (payload: unknown) => unknown)(payload);
95
- } catch (err) {
96
- this.logger?.error(
97
- { err, hookKey: key },
98
- `Event handler failed for "${key}"`,
99
- );
100
- }
101
- }
102
- }
103
-
104
67
  private ensureEntry(hookName: string): void {
105
68
  if (!this.registry.has(hookName)) {
106
69
  this.registry.set(hookName, {
@@ -7,8 +7,9 @@ import type {
7
7
  ExecutionEngineSetup,
8
8
  RunJobsOptions,
9
9
  } from "./adapter.js";
10
- import { OrgResolutionError, CommerceNotFoundError } from "../errors.js";
10
+ import { CommerceNotFoundError } from "../errors.js";
11
11
  import { commerceJobs } from "./schema.js";
12
+ import { prepareEnqueue } from "./prepare-enqueue.js";
12
13
  import { runPendingJobs } from "./runner.js";
13
14
  import {
14
15
  getJobReapThresholdMs,
@@ -79,17 +80,8 @@ export class DrizzleJobsAdapter implements ExecutionEngine {
79
80
  input: Record<string, unknown>,
80
81
  options: EnqueueOptions,
81
82
  ): Promise<string> {
82
- const organizationId = options.organizationId.trim();
83
- if (!organizationId) {
84
- throw new OrgResolutionError(
85
- "Jobs enqueue requires a non-empty organizationId.",
86
- );
87
- }
88
-
89
- const task = this.tasks.get(taskSlug);
90
- const concurrencyKey =
91
- options.concurrencyKey ?? task?.concurrency?.key(input);
92
- const supersedes = options.supersedes ?? task?.concurrency?.supersedes;
83
+ const { organizationId, concurrencyKey, supersedes, maxAttempts } =
84
+ prepareEnqueue(this.tasks, taskSlug, input, options);
93
85
 
94
86
  // If supersedes is set, delete existing pending jobs with the same concurrency key
95
87
  if (concurrencyKey && supersedes) {
@@ -105,9 +97,6 @@ export class DrizzleJobsAdapter implements ExecutionEngine {
105
97
  );
106
98
  }
107
99
 
108
- // Look up task definition for default retry config
109
- const maxAttempts = options.maxAttempts ?? task?.retries?.attempts ?? 1;
110
-
111
100
  const rows = await this.db
112
101
  .insert(commerceJobs)
113
102
  .values({
@@ -0,0 +1,42 @@
1
+ import { OrgResolutionError } from "../errors.js";
2
+ import type { EnqueueOptions } from "./adapter.js";
3
+ import type { TaskDefinition } from "./types.js";
4
+
5
+ export interface PreparedEnqueue {
6
+ task: TaskDefinition;
7
+ organizationId: string;
8
+ concurrencyKey: string | undefined;
9
+ /** At most one running job per concurrency key. */
10
+ exclusive: boolean;
11
+ /** A newer enqueue replaces a pending one with the same concurrency key. */
12
+ supersedes: boolean;
13
+ maxAttempts: number;
14
+ }
15
+
16
+ /**
17
+ * The validation and defaulting every execution engine applies before it hands
18
+ * a job to its backend: the task must be registered, the organization must be
19
+ * non-blank, and concurrency/retry settings come from the task unless the
20
+ * enqueue call overrides them.
21
+ */
22
+ export function prepareEnqueue(
23
+ tasks: ReadonlyMap<string, TaskDefinition>,
24
+ taskSlug: string,
25
+ input: Record<string, unknown>,
26
+ options: EnqueueOptions,
27
+ ): PreparedEnqueue {
28
+ const task = tasks.get(taskSlug);
29
+ if (!task) throw new Error(`Unknown task slug: ${taskSlug}`);
30
+ const organizationId = options.organizationId.trim();
31
+ if (!organizationId) {
32
+ throw new OrgResolutionError("Jobs enqueue requires a non-empty organizationId.");
33
+ }
34
+ return {
35
+ task,
36
+ organizationId,
37
+ concurrencyKey: options.concurrencyKey ?? task.concurrency?.key(input),
38
+ exclusive: Boolean(task.concurrency && task.concurrency.exclusive !== false),
39
+ supersedes: Boolean(options.supersedes ?? task.concurrency?.supersedes),
40
+ maxAttempts: options.maxAttempts ?? task.retries?.attempts ?? 1,
41
+ };
42
+ }
@@ -1,11 +1,6 @@
1
1
  import type { Logger, ServiceContainer } from "../hooks/types.js";
2
2
  import type { DrizzleDatabase } from "../database/drizzle-db.js";
3
3
 
4
- export const BUILTIN_JOB_TASK_SLUGS = {
5
- webhookDeliver: "webhooks/deliver",
6
- staleJobReaper: "jobs/reap-stale",
7
- } as const;
8
-
9
4
  export interface TaskContext {
10
5
  logger: Logger;
11
6
  db: DrizzleDatabase;
@@ -142,47 +142,3 @@ export function createLocalAPI(
142
142
  },
143
143
  });
144
144
  }
145
-
146
- // ─── Legacy Class API (backward compat) ─────────────────────────────────────
147
-
148
- /**
149
- * @deprecated Use `createLocalAPI(kernel, { actor, tx })` instead.
150
- * Kept for backward compatibility with existing hook code.
151
- */
152
- export class LocalAPI {
153
- private _proxy: CommerceLocalAPI;
154
-
155
- constructor(
156
- ctx: { actor: Actor | null; tx: unknown; requestId: string },
157
- kernel: Kernel,
158
- ) {
159
- this._proxy = createLocalAPI(kernel, {
160
- actor: ctx.actor,
161
- tx: ctx.tx,
162
- requestId: ctx.requestId,
163
- });
164
- }
165
-
166
- get orders() { return this._proxy.orders; }
167
- get catalog() { return this._proxy.catalog; }
168
- get cart() { return this._proxy.cart; }
169
- get inventory() { return this._proxy.inventory; }
170
- get customers() { return this._proxy.customers; }
171
- get pricing() { return this._proxy.pricing; }
172
- get promotions() { return this._proxy.promotions; }
173
- get media() { return this._proxy.media; }
174
- get shipping() { return this._proxy.shipping; }
175
- get search() { return this._proxy.search; }
176
- get webhooks() { return this._proxy.webhooks; }
177
- get fulfillment() { return this._proxy.fulfillment; }
178
- get payments() { return this._proxy.payments; }
179
- get analytics() { return this._proxy.analytics; }
180
- get tax() { return this._proxy.tax; }
181
- get audit() { return this._proxy.audit; }
182
- get organization() { return this._proxy.organization; }
183
-
184
- /** Resolve a service by name from `kernel.services`. */
185
- service(name: string) {
186
- return (this._proxy as Record<string, unknown>)[name];
187
- }
188
- }
@@ -18,14 +18,12 @@ import type {
18
18
  PluginPermission,
19
19
  } from "../../config/types.js";
20
20
  import type { TaskDefinition } from "../jobs/types.js";
21
+ import type { Logger } from "../hooks/types.js";
21
22
 
22
23
  // ─── Plugin Logger ────────────────────────────────────────────────────
23
24
 
24
- export interface PluginLogger {
25
- info(message: string, data?: unknown): void;
26
- warn(message: string, data?: unknown): void;
27
- error(message: string, data?: unknown): void;
28
- }
25
+ /** The logger a plugin receives — the same shape every hook and job gets. */
26
+ export type PluginLogger = Logger;
29
27
 
30
28
  // ─── Plugin Registration Types ────────────────────────────────────────
31
29
 
@@ -93,33 +93,6 @@ export class AnalyticsService {
93
93
  return this.deps.adapter.query(params, scope);
94
94
  }
95
95
 
96
- async getDashboard(name: string, scope: AnalyticsScope): Promise<Result<AnalyticsQueryResult>> {
97
- const normalized = name.trim().toLowerCase();
98
-
99
- if (normalized === "revenue" || normalized === "revenue-overview") {
100
- return this.query({
101
- measures: ["Orders.revenue", "Orders.count"],
102
- timeDimensions: [{
103
- dimension: "Orders.placedAt",
104
- granularity: "month",
105
- dateRange: "this month",
106
- }],
107
- order: { "Orders.placedAt": "asc" },
108
- }, scope);
109
- }
110
-
111
- if (normalized === "inventory" || normalized === "inventory-health") {
112
- return this.query({
113
- measures: ["Inventory.totalAvailable", "Inventory.lowStockCount"],
114
- dimensions: ["Inventory.warehouseId"],
115
- order: { "Inventory.totalAvailable": "desc" },
116
- }, scope);
117
- }
118
-
119
- return Err(
120
- new CommerceValidationError(`Unknown analytics dashboard: ${name}`),
121
- );
122
- }
123
96
 
124
97
  /** The canned retail reports pack (issue #48). */
125
98
  listReports(): Array<{ name: string; description: string }> {
@@ -161,15 +134,6 @@ export class AnalyticsService {
161
134
  });
162
135
  }
163
136
 
164
- async meta(): Promise<Result<{ measures: string[]; dimensions: string[]; segments: string[] }>> {
165
- const meta = await this.getMeta();
166
- if (!meta.ok) return meta;
167
- return Ok({
168
- measures: meta.value.measures,
169
- dimensions: meta.value.dimensions,
170
- segments: meta.value.segments,
171
- });
172
- }
173
137
 
174
138
  // ─── Private ─────────────────────────────────────────────────────────────
175
139