payment-kit 1.29.1 → 1.29.2

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 (310) hide show
  1. package/api/dev.ts +41 -2
  2. package/api/hono.d.ts +42 -0
  3. package/api/node-sqlite.d.ts +12 -0
  4. package/api/src/bootstrap.ts +36 -0
  5. package/api/src/crons/base.ts +3 -3
  6. package/api/src/crons/currency.ts +1 -1
  7. package/api/src/crons/index.ts +27 -24
  8. package/api/src/crons/metering-subscription-detection.ts +1 -1
  9. package/api/src/crons/overdue-detection.ts +2 -2
  10. package/api/src/crons/retry-pending-events.ts +6 -0
  11. package/api/src/index.ts +22 -161
  12. package/api/src/integrations/app-store/client.ts +3 -4
  13. package/api/src/integrations/app-store/handlers/subscription.ts +7 -7
  14. package/api/src/integrations/app-store/signed-data-verifier.ts +3 -2
  15. package/api/src/integrations/arcblock/token.ts +21 -7
  16. package/api/src/integrations/google-play/handlers/subscription.ts +6 -6
  17. package/api/src/integrations/google-play/handlers/voided.ts +2 -2
  18. package/api/src/integrations/google-play/verify.ts +3 -2
  19. package/api/src/integrations/iap-reconcile.ts +3 -5
  20. package/api/src/integrations/stripe/handlers/invoice.ts +2 -2
  21. package/api/src/integrations/stripe/handlers/subscription.ts +3 -3
  22. package/api/src/libs/archive/query.ts +19 -0
  23. package/api/src/libs/audit.ts +61 -4
  24. package/api/src/libs/auth.ts +99 -38
  25. package/api/src/libs/context.ts +78 -1
  26. package/api/src/libs/currency.ts +2 -2
  27. package/api/src/libs/dayjs.ts +8 -2
  28. package/api/src/libs/drivers/auth-storage.ts +118 -0
  29. package/api/src/libs/drivers/cron.ts +264 -0
  30. package/api/src/libs/drivers/db.ts +170 -0
  31. package/api/src/libs/drivers/identity.ts +81 -0
  32. package/api/src/libs/drivers/index.ts +40 -0
  33. package/api/src/libs/drivers/locks.ts +226 -0
  34. package/api/src/libs/drivers/migrate-runner.ts +70 -0
  35. package/api/src/libs/drivers/queue.ts +104 -0
  36. package/api/src/libs/drivers/secrets.ts +194 -0
  37. package/api/src/libs/env.ts +170 -54
  38. package/api/src/libs/exchange-rate/service.ts +7 -6
  39. package/api/src/libs/http-fetch-adapter.ts +50 -0
  40. package/api/src/libs/invoice.ts +1 -1
  41. package/api/src/libs/lock.ts +51 -47
  42. package/api/src/libs/logger.ts +48 -8
  43. package/api/src/libs/notification/index.ts +1 -1
  44. package/api/src/libs/notification/template/customer-credit-low-balance.ts +2 -1
  45. package/api/src/libs/notification/template/customer-revenue-succeeded.ts +1 -1
  46. package/api/src/libs/notification/template/customer-reward-succeeded.ts +1 -1
  47. package/api/src/libs/overdraft-protection.ts +1 -1
  48. package/api/src/libs/payout.ts +1 -1
  49. package/api/src/libs/queue/index.ts +259 -52
  50. package/api/src/libs/queue/runtime.ts +175 -0
  51. package/api/src/libs/resource.ts +3 -3
  52. package/api/src/libs/secrets.ts +38 -0
  53. package/api/src/libs/session.ts +3 -2
  54. package/api/src/libs/subscription.ts +5 -5
  55. package/api/src/libs/tenant.ts +92 -0
  56. package/api/src/libs/url.ts +3 -3
  57. package/api/src/libs/util.ts +21 -13
  58. package/api/src/middlewares/hono/cdn.ts +63 -0
  59. package/api/src/middlewares/hono/context.ts +73 -0
  60. package/api/src/middlewares/hono/csrf.ts +72 -0
  61. package/api/src/middlewares/hono/fallback.ts +194 -0
  62. package/api/src/middlewares/hono/pipeline.ts +73 -0
  63. package/api/src/middlewares/hono/resource-mount.ts +42 -0
  64. package/api/src/middlewares/hono/resource.ts +63 -0
  65. package/api/src/middlewares/hono/security.ts +214 -0
  66. package/api/src/middlewares/hono/session.ts +114 -0
  67. package/api/src/middlewares/hono/xss.ts +61 -0
  68. package/api/src/queues/auto-recharge.ts +12 -10
  69. package/api/src/queues/checkout-session.ts +17 -12
  70. package/api/src/queues/credit-consume.ts +40 -36
  71. package/api/src/queues/credit-grant.ts +25 -18
  72. package/api/src/queues/credit-reconciliation.ts +7 -5
  73. package/api/src/queues/discount-status.ts +9 -6
  74. package/api/src/queues/event.ts +12 -4
  75. package/api/src/queues/exchange-rate-health.ts +49 -30
  76. package/api/src/queues/invoice.ts +18 -15
  77. package/api/src/queues/notification.ts +14 -7
  78. package/api/src/queues/payment.ts +41 -28
  79. package/api/src/queues/payout.ts +9 -5
  80. package/api/src/queues/refund.ts +18 -12
  81. package/api/src/queues/subscription.ts +83 -53
  82. package/api/src/queues/token-transfer.ts +15 -10
  83. package/api/src/queues/usage-record.ts +8 -5
  84. package/api/src/queues/vendors/commission.ts +7 -5
  85. package/api/src/queues/vendors/fulfillment-coordinator.ts +17 -13
  86. package/api/src/queues/vendors/fulfillment.ts +4 -2
  87. package/api/src/queues/vendors/return-processor.ts +5 -3
  88. package/api/src/queues/vendors/return-scanner.ts +5 -4
  89. package/api/src/queues/vendors/status-check.ts +10 -7
  90. package/api/src/queues/webhook.ts +60 -32
  91. package/api/src/routes/connect/shared.ts +1 -2
  92. package/api/src/routes/connect/subscribe.ts +3 -3
  93. package/api/src/routes/{archive.ts → hono/archive.ts} +69 -64
  94. package/api/src/routes/{auto-recharge-configs.ts → hono/auto-recharge-configs.ts} +39 -28
  95. package/api/src/routes/{checkout-sessions.ts → hono/checkout-sessions.ts} +790 -923
  96. package/api/src/routes/{coupons.ts → hono/coupons.ts} +93 -76
  97. package/api/src/routes/{credit-grants.ts → hono/credit-grants.ts} +140 -126
  98. package/api/src/routes/hono/credit-tokens.ts +43 -0
  99. package/api/src/routes/{credit-transactions.ts → hono/credit-transactions.ts} +37 -29
  100. package/api/src/routes/{customers.ts → hono/customers.ts} +193 -223
  101. package/api/src/routes/{donations.ts → hono/donations.ts} +41 -32
  102. package/api/src/routes/{entitlements.ts → hono/entitlements.ts} +28 -25
  103. package/api/src/routes/{events.ts → hono/events.ts} +107 -71
  104. package/api/src/routes/{exchange-rate-providers.ts → hono/exchange-rate-providers.ts} +138 -126
  105. package/api/src/routes/hono/exchange-rates.ts +77 -0
  106. package/api/src/routes/hono/index.ts +115 -0
  107. package/api/src/routes/{integrations → hono/integrations}/app-store.ts +68 -48
  108. package/api/src/routes/{integrations → hono/integrations}/google-play.ts +78 -58
  109. package/api/src/routes/hono/integrations/stripe.ts +74 -0
  110. package/api/src/routes/{invoices.ts → hono/invoices.ts} +253 -244
  111. package/api/src/routes/{meter-events.ts → hono/meter-events.ts} +120 -110
  112. package/api/src/routes/hono/meters.ts +288 -0
  113. package/api/src/routes/hono/passports.ts +73 -0
  114. package/api/src/routes/{payment-currencies.ts → hono/payment-currencies.ts} +219 -197
  115. package/api/src/routes/{payment-intents.ts → hono/payment-intents.ts} +136 -132
  116. package/api/src/routes/{payment-links.ts → hono/payment-links.ts} +145 -128
  117. package/api/src/routes/{payment-methods.ts → hono/payment-methods.ts} +125 -93
  118. package/api/src/routes/{payment-stats.ts → hono/payment-stats.ts} +30 -25
  119. package/api/src/routes/{payouts.ts → hono/payouts.ts} +55 -47
  120. package/api/src/routes/{prices.ts → hono/prices.ts} +265 -242
  121. package/api/src/routes/{pricing-table.ts → hono/pricing-table.ts} +94 -87
  122. package/api/src/routes/{products.ts → hono/products.ts} +172 -159
  123. package/api/src/routes/{promotion-codes.ts → hono/promotion-codes.ts} +207 -185
  124. package/api/src/routes/hono/redirect.ts +24 -0
  125. package/api/src/routes/{refunds.ts → hono/refunds.ts} +96 -80
  126. package/api/src/routes/{settings.ts → hono/settings.ts} +64 -55
  127. package/api/src/routes/{subscription-items.ts → hono/subscription-items.ts} +64 -57
  128. package/api/src/routes/{subscriptions.ts → hono/subscriptions.ts} +475 -528
  129. package/api/src/routes/{tax-rates.ts → hono/tax-rates.ts} +71 -70
  130. package/api/src/routes/hono/tool.ts +69 -0
  131. package/api/src/routes/{usage-records.ts → hono/usage-records.ts} +47 -42
  132. package/api/src/routes/{vendor.ts → hono/vendor.ts} +315 -167
  133. package/api/src/routes/{webhook-attempts.ts → hono/webhook-attempts.ts} +17 -13
  134. package/api/src/routes/hono/webhook-endpoints.ts +126 -0
  135. package/api/src/service.ts +667 -0
  136. package/api/src/store/migrations/20230911-seeding.ts +2 -1
  137. package/api/src/store/migrations/20260609-remove-did-space-jobs.ts +23 -0
  138. package/api/src/store/migrations/20260610-tenant-columns.ts +40 -0
  139. package/api/src/store/migrations/20260611-tenant-backfill.ts +33 -0
  140. package/api/src/store/models/auto-recharge-config.ts +22 -10
  141. package/api/src/store/models/checkout-session.ts +15 -14
  142. package/api/src/store/models/coupon.ts +29 -20
  143. package/api/src/store/models/credit-grant.ts +38 -29
  144. package/api/src/store/models/credit-transaction.ts +32 -21
  145. package/api/src/store/models/customer.ts +19 -17
  146. package/api/src/store/models/discount.ts +11 -2
  147. package/api/src/store/models/entitlement-grant.ts +21 -9
  148. package/api/src/store/models/entitlement-product.ts +21 -9
  149. package/api/src/store/models/entitlement.ts +19 -10
  150. package/api/src/store/models/event.ts +18 -9
  151. package/api/src/store/models/exchange-rate-provider.ts +17 -4
  152. package/api/src/store/models/invoice-item.ts +18 -9
  153. package/api/src/store/models/invoice.ts +16 -8
  154. package/api/src/store/models/meter-event.ts +27 -9
  155. package/api/src/store/models/meter.ts +31 -22
  156. package/api/src/store/models/payment-currency.ts +25 -8
  157. package/api/src/store/models/payment-intent.ts +15 -6
  158. package/api/src/store/models/payment-link.ts +15 -6
  159. package/api/src/store/models/payment-method.ts +38 -22
  160. package/api/src/store/models/payment-stat.ts +18 -9
  161. package/api/src/store/models/payout.ts +15 -6
  162. package/api/src/store/models/price-quote.ts +17 -8
  163. package/api/src/store/models/price.ts +24 -12
  164. package/api/src/store/models/pricing-table.ts +29 -20
  165. package/api/src/store/models/product-vendor.ts +20 -10
  166. package/api/src/store/models/product.ts +15 -6
  167. package/api/src/store/models/promotion-code.ts +14 -6
  168. package/api/src/store/models/refund.ts +15 -6
  169. package/api/src/store/models/revenue-snapshot.ts +21 -9
  170. package/api/src/store/models/setting.ts +18 -9
  171. package/api/src/store/models/setup-intent.ts +36 -27
  172. package/api/src/store/models/subscription-item.ts +21 -9
  173. package/api/src/store/models/subscription-schedule.ts +21 -9
  174. package/api/src/store/models/subscription.ts +21 -10
  175. package/api/src/store/models/tax-rate.ts +29 -21
  176. package/api/src/store/models/usage-record.ts +11 -2
  177. package/api/src/store/models/webhook-attempt.ts +18 -9
  178. package/api/src/store/models/webhook-endpoint.ts +18 -9
  179. package/api/src/store/scoped-core.ts +55 -0
  180. package/api/src/store/scoped.ts +247 -0
  181. package/api/src/store/sequelize.ts +66 -22
  182. package/api/src/store/sql-migrations.ts +20 -0
  183. package/api/src/store/tenant-backfill.ts +260 -0
  184. package/api/src/store/tenant-model.ts +124 -0
  185. package/api/src/store/tenant-tables.ts +50 -0
  186. package/api/tests/embedded/embedded-multi-mode-d3.spec.ts +257 -0
  187. package/api/tests/fixtures/bare-query-violation.ts +13 -0
  188. package/api/tests/fixtures/core-env-violation.ts +10 -0
  189. package/api/tests/fixtures/host-read-violation.ts +19 -0
  190. package/api/tests/fixtures/tenants.ts +4 -0
  191. package/api/tests/integrations/iap-tenant.spec.ts +284 -0
  192. package/api/tests/libs/archive-query.spec.ts +26 -0
  193. package/api/tests/libs/audit-tenant.spec.ts +153 -0
  194. package/api/tests/libs/context.spec.ts +204 -0
  195. package/api/tests/libs/core-config.spec.ts +115 -0
  196. package/api/tests/libs/cron-driver-d2.spec.ts +237 -0
  197. package/api/tests/libs/crons-conservation-d2.spec.ts +52 -0
  198. package/api/tests/libs/lock-tenant.spec.ts +66 -0
  199. package/api/tests/libs/scoped.spec.ts +222 -0
  200. package/api/tests/libs/secrets-facade.spec.ts +52 -0
  201. package/api/tests/libs/tenancy-slot-authority.spec.ts +209 -0
  202. package/api/tests/libs/tenant-middleware.spec.ts +42 -0
  203. package/api/tests/libs/tenant-scanner.spec.ts +120 -0
  204. package/api/tests/middlewares/hono/cdn.spec.ts +70 -0
  205. package/api/tests/middlewares/hono/context.spec.ts +113 -0
  206. package/api/tests/middlewares/hono/csrf.spec.ts +136 -0
  207. package/api/tests/middlewares/hono/fallback.spec.ts +67 -0
  208. package/api/tests/middlewares/hono/pipeline.spec.ts +47 -0
  209. package/api/tests/middlewares/hono/security.spec.ts +181 -0
  210. package/api/tests/middlewares/hono/session.spec.ts +42 -0
  211. package/api/tests/middlewares/hono/xss.spec.ts +81 -0
  212. package/api/tests/models/tenant-backfill.spec.ts +287 -0
  213. package/api/tests/models/tenant-columns-model.spec.ts +46 -0
  214. package/api/tests/models/tenant-columns.spec.ts +161 -0
  215. package/api/tests/queues/credit-consume-batch.spec.ts +8 -1
  216. package/api/tests/queues/credit-consume.spec.ts +8 -1
  217. package/api/tests/queues/event-tenant.spec.ts +236 -0
  218. package/api/tests/queues/exchange-rate-health-tenant-d6.spec.ts +62 -0
  219. package/api/tests/queues/queue-parity.spec.ts +249 -0
  220. package/api/tests/queues/queue-runtime-surface.spec.ts +277 -0
  221. package/api/tests/queues/queue-teardown-d2.spec.ts +127 -0
  222. package/api/tests/queues/tenant-matrix-a.spec.ts +245 -0
  223. package/api/tests/queues/tenant-matrix-b.spec.ts +168 -0
  224. package/api/tests/routes/connect/hono-attach.spec.ts +107 -0
  225. package/api/tests/service/collapse.spec.ts +96 -0
  226. package/api/tests/store/tenant-crosscut.spec.ts +202 -0
  227. package/api/tests/store/tenant-model-spike.spec.ts +177 -0
  228. package/api/tests/store/tenant-model.spec.ts +162 -0
  229. package/api/tests/store/tenant-residual.spec.ts +196 -0
  230. package/api/third.d.ts +4 -0
  231. package/blocklet.yml +1 -1
  232. package/cloudflare/README.md +26 -6
  233. package/cloudflare/build.ts +28 -13
  234. package/cloudflare/did-connect-auth.ts +0 -217
  235. package/cloudflare/migrations/0006_tenant_columns.sql +46 -0
  236. package/cloudflare/migrations/0007_tenant_backfill_indexes.sql +65 -0
  237. package/cloudflare/migrations/0008_schema_parity.sql +16 -0
  238. package/cloudflare/migrations/0009_remove_did_space_jobs.sql +5 -0
  239. package/cloudflare/queue-runtime-mode.ts +13 -0
  240. package/cloudflare/run-build.js +10 -56
  241. package/cloudflare/shims/blocklet-sdk/asset-host-transformer.ts +20 -0
  242. package/cloudflare/shims/blocklet-sdk/config.ts +8 -1
  243. package/cloudflare/shims/blocklet-sdk/login.ts +12 -0
  244. package/cloudflare/shims/blocklet-sdk/service-api.ts +14 -0
  245. package/cloudflare/shims/blocklet-sdk/session.ts +4 -2
  246. package/cloudflare/shims/blocklet-sdk/util-constants.ts +8 -0
  247. package/cloudflare/shims/blocklet-sdk/util-csrf.ts +13 -0
  248. package/cloudflare/shims/blocklet-sdk/util-wallet.ts +8 -0
  249. package/cloudflare/shims/cron.ts +38 -158
  250. package/cloudflare/shims/events.ts +124 -0
  251. package/cloudflare/shims/fastq.ts +15 -1
  252. package/cloudflare/shims/nedb-storage.ts +16 -8
  253. package/cloudflare/shims/xss.ts +8 -0
  254. package/cloudflare/tenant-middleware.ts +36 -0
  255. package/cloudflare/tests/tenant-middleware.spec.ts +160 -0
  256. package/cloudflare/tests/worker-handler-gate.spec.ts +44 -0
  257. package/cloudflare/worker.ts +204 -433
  258. package/cloudflare/wrangler.local-e2e.jsonc +26 -0
  259. package/jest.config.js +3 -1
  260. package/package.json +33 -38
  261. package/scripts/core-env-whitelist.json +1 -0
  262. package/scripts/e2e-12b-runtime.ts +149 -0
  263. package/scripts/e2e-core-config.ts +125 -0
  264. package/scripts/e2e-d1-tenancy.ts +116 -0
  265. package/scripts/e2e-d2-cron-queue.ts +139 -0
  266. package/scripts/e2e-d3-embedded-multi.ts +171 -0
  267. package/scripts/e2e-hono-s2.ts +125 -0
  268. package/scripts/e2e-hono-s3e.ts +135 -0
  269. package/scripts/e2e-hono-s4.ts +114 -0
  270. package/scripts/e2e-migration-contract.ts +100 -0
  271. package/scripts/e2e-s0.ts +61 -0
  272. package/scripts/e2e-s1.ts +107 -0
  273. package/scripts/e2e-s2.ts +178 -0
  274. package/scripts/e2e-s3.ts +110 -0
  275. package/scripts/e2e-s4.ts +191 -0
  276. package/scripts/e2e-s5.ts +139 -0
  277. package/scripts/e2e-s6.ts +127 -0
  278. package/scripts/e2e-tenant-model.ts +119 -0
  279. package/scripts/e2e-tenant-worker.ts +199 -0
  280. package/scripts/gen-sql-migrations.js +46 -0
  281. package/scripts/phase8-codemod.js +219 -0
  282. package/scripts/phase9a-env-getters-codemod.js +82 -0
  283. package/scripts/scan-core-env.js +109 -0
  284. package/scripts/scan-tenant-queries.js +235 -0
  285. package/scripts/schema-drift-guard.ts +210 -0
  286. package/scripts/tenant-scan-whitelist.json +1 -0
  287. package/src/env.d.ts +13 -1
  288. package/tsconfig.json +1 -1
  289. package/api/src/libs/did-space.ts +0 -235
  290. package/api/src/libs/middleware.ts +0 -50
  291. package/api/src/libs/security.ts +0 -192
  292. package/api/src/queues/space.ts +0 -662
  293. package/api/src/routes/credit-tokens.ts +0 -38
  294. package/api/src/routes/exchange-rates.ts +0 -87
  295. package/api/src/routes/index.ts +0 -142
  296. package/api/src/routes/integrations/stripe.ts +0 -61
  297. package/api/src/routes/meters.ts +0 -274
  298. package/api/src/routes/passports.ts +0 -68
  299. package/api/src/routes/redirect.ts +0 -20
  300. package/api/src/routes/tool.ts +0 -65
  301. package/api/src/routes/webhook-endpoints.ts +0 -126
  302. package/api/tests/routes/credit-grants.spec.ts +0 -1261
  303. package/cloudflare/shims/did-space-js.ts +0 -17
  304. package/cloudflare/shims/did-space.ts +0 -11
  305. package/cloudflare/shims/express-compat/index.ts +0 -80
  306. package/cloudflare/shims/express-compat/types.ts +0 -41
  307. package/cloudflare/shims/lock.ts +0 -115
  308. package/cloudflare/shims/queue.ts +0 -611
  309. package/cloudflare/tests/shims/queue-delayed-persist.spec.ts +0 -87
  310. package/cloudflare/tests/shims/queue-scheduled.spec.ts +0 -186
@@ -1,18 +1,22 @@
1
- import { Router } from 'express';
1
+ // Phase 3 (express→hono) hono fork of routes/archive.ts. Sub-app with
2
+ // routes relative to /api/archive (mounted via mountResourceGroup). The
3
+ // business logic is unchanged; only the express plumbing becomes hono:
4
+ // req.body → c.get('sanitizedBody'); res.status(n).json(x) → c.json(x, n).
5
+ import { Hono } from 'hono';
2
6
  import Joi from 'joi';
3
7
 
4
- import dayjs from '../libs/dayjs';
5
- import { authenticate } from '../libs/security';
6
- import logger from '../libs/logger';
7
- import { createFlexibleEvent } from '../libs/audit';
8
- import { getRetentionConfig } from '../libs/archive/config';
9
- import { previewArchive } from '../libs/archive/executor';
10
- import { queryArchive } from '../libs/archive/query';
11
- import { enqueueArchiveJob } from '../queues/archive';
12
- import { ArchiveMetadata } from '../store/models/archive-metadata';
13
- import { listArchiveFiles, getFileSize } from '../libs/archive/store';
14
-
15
- const router = Router();
8
+ import dayjs from '../../libs/dayjs';
9
+ import { authenticate } from '../../middlewares/hono/security';
10
+ import logger from '../../libs/logger';
11
+ import { createFlexibleEvent } from '../../libs/audit';
12
+ import { getRetentionConfig } from '../../libs/archive/config';
13
+ import { previewArchive } from '../../libs/archive/executor';
14
+ import { queryArchive } from '../../libs/archive/query';
15
+ import { enqueueArchiveJob } from '../../queues/archive';
16
+ import { ArchiveMetadata } from '../../store/models/archive-metadata';
17
+ import { listArchiveFiles, getFileSize } from '../../libs/archive/store';
18
+
19
+ const app = new Hono();
16
20
  const authAdmin = authenticate({ component: true, roles: ['owner', 'admin'] });
17
21
 
18
22
  const querySchema = Joi.object({
@@ -24,7 +28,12 @@ const querySchema = Joi.object({
24
28
  limit: Joi.number().integer().min(1).max(100).default(20),
25
29
  });
26
30
 
27
- router.get('/status', authAdmin, async (_req, res) => {
31
+ const runSchema = Joi.object({
32
+ tables: Joi.array().items(Joi.string()).optional(),
33
+ dryRun: Joi.boolean().optional(),
34
+ });
35
+
36
+ app.get('/status', authAdmin, async (c) => {
28
37
  try {
29
38
  const config = getRetentionConfig();
30
39
  const lastRun = await ArchiveMetadata.findOne({ order: [['created_at', 'DESC']] });
@@ -39,7 +48,7 @@ router.get('/status', authAdmin, async (_req, res) => {
39
48
  nextRun = nextRun.add(1, 'week');
40
49
  }
41
50
 
42
- res.json({
51
+ return c.json({
43
52
  enabled: config.enabled,
44
53
  config,
45
54
  lastRun: lastRun
@@ -66,32 +75,63 @@ router.get('/status', authAdmin, async (_req, res) => {
66
75
  });
67
76
  } catch (error: any) {
68
77
  logger.error('archive status error', error);
69
- res.status(500).json({ error: error.message });
78
+ return c.json({ error: error.message }, 500);
79
+ }
80
+ });
81
+
82
+ app.post('/run', authAdmin, async (c) => {
83
+ try {
84
+ const config = getRetentionConfig();
85
+ if (!config.enabled) {
86
+ return c.json({ error: 'Archive is disabled' }, 400);
87
+ }
88
+
89
+ const body = c.get('sanitizedBody') ?? {};
90
+ const { value, error } = runSchema.validate(body, { stripUnknown: true });
91
+ if (error) {
92
+ return c.json({ error: error.message }, 400);
93
+ }
94
+
95
+ if (value?.dryRun) {
96
+ const preview = await previewArchive({ tables: value.tables });
97
+ return c.json({ status: 'dry_run_complete', preview });
98
+ }
99
+
100
+ const jobId = enqueueArchiveJob({
101
+ tables: value.tables,
102
+ triggeredBy: 'manual',
103
+ triggeredByUserId: c.get('user')?.did,
104
+ });
105
+
106
+ return c.json({ status: 'started', jobId });
107
+ } catch (error: any) {
108
+ logger.error('archive run error', error);
109
+ return c.json({ error: error.message }, 500);
70
110
  }
71
111
  });
72
112
 
73
- router.get('/:table', authAdmin, async (req, res) => {
113
+ app.get('/:table', authAdmin, async (c) => {
74
114
  try {
75
115
  const config = getRetentionConfig();
76
116
  if (!config.enabled) {
77
- return res.status(400).json({ error: 'Archive is disabled' });
117
+ return c.json({ error: 'Archive is disabled' }, 400);
78
118
  }
79
119
 
80
- const { value, error } = querySchema.validate(req.query, { stripUnknown: true, convert: true });
120
+ const { value, error } = querySchema.validate(c.req.query(), { stripUnknown: true, convert: true });
81
121
  if (error) {
82
- return res.status(400).json({ error: error.message });
122
+ return c.json({ error: error.message }, 400);
83
123
  }
84
124
 
85
- const { table } = req.params;
125
+ const table = c.req.param('table');
86
126
  if (!table) {
87
- return res.status(400).json({ error: 'table is required' });
127
+ return c.json({ error: 'table is required' }, 400);
88
128
  }
89
129
  if (!Object.prototype.hasOwnProperty.call(config.tables, table)) {
90
- return res.status(400).json({ error: `Unsupported table: ${table}` });
130
+ return c.json({ error: `Unsupported table: ${table}` }, 400);
91
131
  }
92
132
 
93
133
  if (value.from === undefined) {
94
- return res.status(400).json({ error: 'from is required' });
134
+ return c.json({ error: 'from is required' }, 400);
95
135
  }
96
136
 
97
137
  const result = await queryArchive(
@@ -104,7 +144,7 @@ router.get('/:table', authAdmin, async (req, res) => {
104
144
  page: value.page,
105
145
  limit: value.limit,
106
146
  },
107
- req.user?.did
147
+ c.get('user')?.did
108
148
  );
109
149
 
110
150
  await createFlexibleEvent(
@@ -117,10 +157,10 @@ router.get('/:table', authAdmin, async (req, res) => {
117
157
  result_count: result.data.length,
118
158
  archive_files: result.archiveFiles,
119
159
  },
120
- { requestedBy: req.user?.did }
160
+ { requestedBy: c.get('user')?.did }
121
161
  );
122
162
 
123
- return res.json({
163
+ return c.json({
124
164
  data: result.data,
125
165
  pagination: {
126
166
  page: value.page,
@@ -134,43 +174,8 @@ router.get('/:table', authAdmin, async (req, res) => {
134
174
  });
135
175
  } catch (error: any) {
136
176
  logger.error('archive query error', error);
137
- return res.status(500).json({ error: error.message });
138
- }
139
- });
140
-
141
- const runSchema = Joi.object({
142
- tables: Joi.array().items(Joi.string()).optional(),
143
- dryRun: Joi.boolean().optional(),
144
- });
145
-
146
- router.post('/run', authAdmin, async (req, res) => {
147
- try {
148
- const config = getRetentionConfig();
149
- if (!config.enabled) {
150
- return res.status(400).json({ error: 'Archive is disabled' });
151
- }
152
-
153
- const { value, error } = runSchema.validate(req.body, { stripUnknown: true });
154
- if (error) {
155
- return res.status(400).json({ error: error.message });
156
- }
157
-
158
- if (value?.dryRun) {
159
- const preview = await previewArchive({ tables: value.tables });
160
- return res.json({ status: 'dry_run_complete', preview });
161
- }
162
-
163
- const jobId = enqueueArchiveJob({
164
- tables: value.tables,
165
- triggeredBy: 'manual',
166
- triggeredByUserId: req.user?.did,
167
- });
168
-
169
- return res.json({ status: 'started', jobId });
170
- } catch (error: any) {
171
- logger.error('archive run error', error);
172
- return res.status(500).json({ error: error.message });
177
+ return c.json({ error: error.message }, 500);
173
178
  }
174
179
  });
175
180
 
176
- export default router;
181
+ export default app;
@@ -1,12 +1,15 @@
1
- import { Router } from 'express';
1
+ // Phase 3 (express→hono) hono fork of routes/auto-recharge-configs.ts. Sub-app with
2
+ // routes relative to /api/auto-recharge-configs (mounted via mountResourceGroup). The
3
+ // business logic is unchanged; only the express plumbing becomes hono:
4
+ // req.body → c.get('sanitizedBody') ?? {}; res.status(n).json(x) → c.json(x, n).
5
+ import { Hono } from 'hono';
2
6
  import Joi from 'joi';
3
7
 
4
8
  import { CustomError } from '@blocklet/error';
5
9
  import { Op } from 'sequelize';
6
- import { sessionMiddleware } from '@blocklet/sdk/lib/middlewares/session';
7
10
  import { BN, fromTokenToUnit, fromUnitToToken } from '@ocap/util';
8
- import { trimDecimals } from '../libs/math-utils';
9
- import { applySlippageToAmount } from '../libs/slippage';
11
+ import { trimDecimals } from '../../libs/math-utils';
12
+ import { applySlippageToAmount } from '../../libs/slippage';
10
13
  import {
11
14
  AutoRechargeConfig,
12
15
  Customer,
@@ -17,14 +20,19 @@ import {
17
20
  Price,
18
21
  Product,
19
22
  TPriceExpanded,
20
- } from '../store/models';
21
- import { isDelegationSufficientForPayment } from '../libs/payment';
22
- import { validateStripePaymentAmounts } from '../libs/session';
23
- import { getPriceUintAmountByCurrency } from '../libs/price';
24
- import { ensureStripeSetupIntentForAutoRecharge } from '../integrations/stripe/resource';
25
- import logger from '../libs/logger';
23
+ } from '../../store/models';
24
+ import { isDelegationSufficientForPayment } from '../../libs/payment';
25
+ import { validateStripePaymentAmounts } from '../../libs/session';
26
+ import { getPriceUintAmountByCurrency } from '../../libs/price';
27
+ import { ensureStripeSetupIntentForAutoRecharge } from '../../integrations/stripe/resource';
28
+ import logger from '../../libs/logger';
29
+ import { sessionMiddleware } from '../../middlewares/hono/session';
26
30
 
27
- const router = Router();
31
+ const app = new Hono();
32
+
33
+ // faithful fork of the express `sessionMiddleware({ accessKey: true })` — populates
34
+ // c.get('user') from a login token OR access key, and does NOT gate (next() either way).
35
+ const user = sessionMiddleware({ accessKey: true });
28
36
 
29
37
  const slippageConfigSchema = Joi.object({
30
38
  mode: Joi.string().valid('percent', 'rate').optional(),
@@ -161,27 +169,28 @@ async function applyBalanceCheckResults(
161
169
  }
162
170
 
163
171
  // Get auto-recharge configuration for a customer
164
- router.get('/customer/:customerId', sessionMiddleware({ accessKey: true }), async (req, res) => {
165
- const { error, value } = getConfigSchema.validate(req.query, {
172
+ // Static segment registered before /:id variants
173
+ app.get('/customer/:customerId', user, async (c) => {
174
+ const { error, value } = getConfigSchema.validate(c.req.query(), {
166
175
  stripUnknown: true,
167
176
  });
168
177
  if (error) {
169
178
  throw new CustomError(400, error.message || 'Validation error');
170
179
  }
171
180
 
172
- if (!req.user) {
181
+ if (!c.get('user')) {
173
182
  throw new CustomError(403, 'Please login to continue');
174
183
  }
175
184
 
176
- let { customerId } = req.params;
185
+ let customerId = c.req.param('customerId');
177
186
  if (!customerId) {
178
- customerId = req.user?.did;
187
+ customerId = c.get('user')?.did;
179
188
  }
180
189
 
181
190
  const { currency_id: currencyId } = value;
182
191
  const customer = await ensureCustomerExists(customerId);
183
192
 
184
- if (customer.did !== req.user?.did && !['admin', 'owner'].includes(req.user?.role)) {
193
+ if (customer.did !== c.get('user')?.did && !['admin', 'owner'].includes(c.get('user')?.role)) {
185
194
  throw new CustomError(403, 'You are not allowed to access this resource');
186
195
  }
187
196
 
@@ -229,7 +238,7 @@ router.get('/customer/:customerId', sessionMiddleware({ accessKey: true }), asyn
229
238
  quantity: 1,
230
239
  recharge_currency_id: price.currency_id,
231
240
  });
232
- return res.json({
241
+ return c.json({
233
242
  ...newConfig.toJSON(),
234
243
  currency,
235
244
  price: {
@@ -250,7 +259,7 @@ router.get('/customer/:customerId', sessionMiddleware({ accessKey: true }), asyn
250
259
  const configThreshold = new BN(config.threshold || '0').lt(new BN(minimumThreshold))
251
260
  ? minimumThreshold
252
261
  : config.threshold;
253
- return res.json({
262
+ return c.json({
254
263
  ...config.toJSON(),
255
264
  daily_limits: {
256
265
  max_attempts: config.daily_limits?.max_attempts || 0,
@@ -267,8 +276,9 @@ router.get('/customer/:customerId', sessionMiddleware({ accessKey: true }), asyn
267
276
  });
268
277
 
269
278
  // Retrieve specific auto-recharge configuration by ID
270
- router.get('/retrieve/:id', sessionMiddleware({ accessKey: true }), async (req, res) => {
271
- const config = await AutoRechargeConfig.findByPk(req.params.id);
279
+ // Static segment registered before plain /:id
280
+ app.get('/retrieve/:id', user, async (c) => {
281
+ const config = await AutoRechargeConfig.findByPk(c.req.param('id'));
272
282
  if (!config) {
273
283
  throw new CustomError(404, 'Auto recharge config not found');
274
284
  }
@@ -276,7 +286,7 @@ router.get('/retrieve/:id', sessionMiddleware({ accessKey: true }), async (req,
276
286
  if (!paymentMethod) {
277
287
  throw new CustomError(404, 'Payment method not found');
278
288
  }
279
- return res.json({
289
+ return c.json({
280
290
  ...config.toJSON(),
281
291
  paymentMethod,
282
292
  });
@@ -376,8 +386,9 @@ async function checkSufficientBalance({
376
386
  }
377
387
 
378
388
  // Submit auto-recharge configuration
379
- router.post('/submit', async (req, res) => {
380
- const { error, value } = createConfigSchema.validate(req.body, {
389
+ app.post('/submit', async (c) => {
390
+ const body = c.get('sanitizedBody') ?? {};
391
+ const { error, value } = createConfigSchema.validate(body, {
381
392
  stripUnknown: true,
382
393
  });
383
394
  if (error) {
@@ -471,7 +482,7 @@ router.post('/submit', async (req, res) => {
471
482
  await existingConfig.update({
472
483
  enabled: false,
473
484
  });
474
- return res.json({
485
+ return c.json({
475
486
  ...existingConfig.toJSON(),
476
487
  paymentMethod,
477
488
  customer,
@@ -510,7 +521,7 @@ router.post('/submit', async (req, res) => {
510
521
  });
511
522
  // Update payment details and settings based on balance check result
512
523
  await applyBalanceCheckResults(existingConfig, balanceResult, paymentMethod);
513
- return res.json({
524
+ return c.json({
514
525
  ...existingConfig.toJSON(),
515
526
  balanceResult,
516
527
  paymentMethod,
@@ -550,7 +561,7 @@ router.post('/submit', async (req, res) => {
550
561
 
551
562
  // Update payment details and settings based on balance check result
552
563
  await applyBalanceCheckResults(config, balanceResult, paymentMethod, true);
553
- return res.json({
564
+ return c.json({
554
565
  ...config.toJSON(),
555
566
  balanceResult,
556
567
  paymentMethod,
@@ -558,4 +569,4 @@ router.post('/submit', async (req, res) => {
558
569
  });
559
570
  });
560
571
 
561
- export default router;
572
+ export default app;