payment-kit 1.27.2 → 1.28.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 (184) hide show
  1. package/__blocklet__.js +37 -0
  2. package/api/ocap-1.30-subpath-shims.d.ts +35 -0
  3. package/api/src/crons/index.ts +10 -0
  4. package/api/src/crons/metering-subscription-detection.ts +12 -14
  5. package/api/src/crons/overdue-detection.ts +51 -74
  6. package/api/src/integrations/arcblock/nft.ts +6 -2
  7. package/api/src/integrations/arcblock/stake.ts +3 -2
  8. package/api/src/integrations/arcblock/token.ts +4 -4
  9. package/api/src/integrations/blocklet/notification.ts +1 -1
  10. package/api/src/integrations/ethereum/tx.ts +29 -0
  11. package/api/src/integrations/stripe/handlers/invoice.ts +70 -53
  12. package/api/src/integrations/stripe/handlers/payment-intent.ts +8 -1
  13. package/api/src/integrations/stripe/resource.ts +8 -0
  14. package/api/src/libs/audit.ts +32 -16
  15. package/api/src/libs/auth.ts +49 -2
  16. package/api/src/libs/chain-error.ts +31 -0
  17. package/api/src/libs/error.ts +15 -0
  18. package/api/src/libs/event.ts +42 -1
  19. package/api/src/libs/invoice.ts +69 -34
  20. package/api/src/libs/notification/template/customer-auto-recharge-daily-limit-exceeded.ts +1 -3
  21. package/api/src/libs/notification/template/customer-auto-recharge-failed.ts +1 -3
  22. package/api/src/libs/notification/template/customer-credit-grant-granted.ts +1 -3
  23. package/api/src/libs/notification/template/customer-credit-insufficient.ts +1 -3
  24. package/api/src/libs/notification/template/customer-credit-low-balance.ts +1 -3
  25. package/api/src/libs/notification/template/customer-revenue-succeeded.ts +1 -3
  26. package/api/src/libs/notification/template/customer-reward-succeeded.ts +1 -3
  27. package/api/src/libs/notification/template/one-time-payment-refund-succeeded.ts +1 -3
  28. package/api/src/libs/notification/template/one-time-payment-succeeded.ts +1 -3
  29. package/api/src/libs/notification/template/subscription-renew-failed.ts +1 -3
  30. package/api/src/libs/notification/template/subscription-slippage-exceeded.ts +1 -3
  31. package/api/src/libs/notification/template/subscription-slippage-warning.ts +1 -3
  32. package/api/src/libs/notification/template/subscription-succeeded.ts +1 -1
  33. package/api/src/libs/pagination.ts +14 -9
  34. package/api/src/libs/payment.ts +25 -10
  35. package/api/src/libs/session.ts +1 -1
  36. package/api/src/libs/timing.ts +35 -0
  37. package/api/src/libs/util.ts +16 -15
  38. package/api/src/libs/wallet-migration.ts +72 -53
  39. package/api/src/queues/auto-recharge.ts +1 -1
  40. package/api/src/queues/credit-consume.ts +94 -12
  41. package/api/src/queues/credit-grant.ts +4 -0
  42. package/api/src/queues/event.ts +14 -2
  43. package/api/src/queues/invoice.ts +1 -0
  44. package/api/src/queues/payment.ts +83 -15
  45. package/api/src/queues/refund.ts +84 -71
  46. package/api/src/queues/subscription.ts +1 -0
  47. package/api/src/routes/checkout-sessions.ts +82 -43
  48. package/api/src/routes/connect/change-payment.ts +2 -0
  49. package/api/src/routes/connect/change-plan.ts +2 -0
  50. package/api/src/routes/connect/pay.ts +12 -3
  51. package/api/src/routes/connect/setup.ts +3 -1
  52. package/api/src/routes/connect/shared.ts +52 -39
  53. package/api/src/routes/connect/subscribe.ts +4 -1
  54. package/api/src/routes/credit-grants.ts +25 -17
  55. package/api/src/routes/donations.ts +2 -2
  56. package/api/src/routes/meter-events.ts +16 -6
  57. package/api/src/routes/payment-links.ts +1 -1
  58. package/api/src/routes/payment-methods.ts +1 -1
  59. package/api/src/routes/settings.ts +1 -1
  60. package/api/src/routes/tax-rates.ts +1 -1
  61. package/api/src/store/models/customer.ts +23 -1
  62. package/api/src/store/models/payment-method.ts +4 -0
  63. package/api/src/store/models/price.ts +23 -14
  64. package/api/tests/libs/wallet-migration.spec.ts +4 -4
  65. package/api/tests/queues/credit-consume-batch.spec.ts +5 -2
  66. package/api/tests/queues/credit-consume.spec.ts +8 -4
  67. package/api/tests/routes/credit-grants.spec.ts +1 -0
  68. package/blocklet.yml +1 -1
  69. package/cloudflare/MIGRATION-CHALLENGES.md +676 -0
  70. package/cloudflare/MIGRATION-RUNBOOK.md +777 -0
  71. package/cloudflare/README.md +499 -0
  72. package/cloudflare/STAGING-MIGRATION-GUIDE.md +602 -0
  73. package/cloudflare/build.ts +151 -0
  74. package/cloudflare/did-connect-auth.ts +527 -0
  75. package/cloudflare/docs/2026-04-22-sdk-1.30.9-upgrade-retro.md +324 -0
  76. package/cloudflare/docs/2026-04-24-queue-ops-followup.md +218 -0
  77. package/cloudflare/docs/cf-queues-ops-alert-analysis.md +663 -0
  78. package/cloudflare/docs/cf-workers-local-dev-and-fixes.md +284 -0
  79. package/cloudflare/docs/cleanup-tasks-2026-05.md +62 -0
  80. package/cloudflare/docs/payment-kit-platform-analysis-2026-04-20.md +354 -0
  81. package/cloudflare/frontend-shims/buffer-polyfill.ts +9 -0
  82. package/cloudflare/frontend-shims/js-sdk.ts +43 -0
  83. package/cloudflare/frontend-shims/mime-types.ts +46 -0
  84. package/cloudflare/frontend-shims/session.ts +24 -0
  85. package/cloudflare/frontend-shims/vite-plugin-noop.ts +6 -0
  86. package/cloudflare/index.html +40 -0
  87. package/cloudflare/migrate-to-d1.js +252 -0
  88. package/cloudflare/migrations/0001_initial_schema.sql +82 -0
  89. package/cloudflare/migrations/0002_indexes.sql +75 -0
  90. package/cloudflare/migrations/0003_locks_and_constraints.sql +18 -0
  91. package/cloudflare/run-build.js +390 -0
  92. package/cloudflare/scripts/test-decrypt.js +102 -0
  93. package/cloudflare/shims/arcblock-ws.ts +20 -0
  94. package/cloudflare/shims/axios-http-adapter.ts +4 -0
  95. package/cloudflare/shims/axios-lite.ts +117 -0
  96. package/cloudflare/shims/blocklet-sdk/auth-service.ts +33 -0
  97. package/cloudflare/shims/blocklet-sdk/cdn.ts +3 -0
  98. package/cloudflare/shims/blocklet-sdk/component-api.ts +35 -0
  99. package/cloudflare/shims/blocklet-sdk/component.ts +18 -0
  100. package/cloudflare/shims/blocklet-sdk/config.ts +8 -0
  101. package/cloudflare/shims/blocklet-sdk/did.ts +14 -0
  102. package/cloudflare/shims/blocklet-sdk/env.ts +12 -0
  103. package/cloudflare/shims/blocklet-sdk/eventbus.ts +3 -0
  104. package/cloudflare/shims/blocklet-sdk/fallback.ts +3 -0
  105. package/cloudflare/shims/blocklet-sdk/index.ts +11 -0
  106. package/cloudflare/shims/blocklet-sdk/logger.ts +11 -0
  107. package/cloudflare/shims/blocklet-sdk/middlewares.ts +15 -0
  108. package/cloudflare/shims/blocklet-sdk/notification.ts +11 -0
  109. package/cloudflare/shims/blocklet-sdk/security.ts +53 -0
  110. package/cloudflare/shims/blocklet-sdk/session.ts +8 -0
  111. package/cloudflare/shims/blocklet-sdk/verify-sign.ts +38 -0
  112. package/cloudflare/shims/blocklet-sdk/wallet-authenticator.ts +3 -0
  113. package/cloudflare/shims/blocklet-sdk/wallet-handler.ts +6 -0
  114. package/cloudflare/shims/blocklet-sdk/wallet.ts +103 -0
  115. package/cloudflare/shims/cookie-parser.ts +3 -0
  116. package/cloudflare/shims/cors.ts +21 -0
  117. package/cloudflare/shims/cron.ts +189 -0
  118. package/cloudflare/shims/crypto-js-warn.ts +7 -0
  119. package/cloudflare/shims/did-space-js.ts +17 -0
  120. package/cloudflare/shims/did-space.ts +11 -0
  121. package/cloudflare/shims/error.ts +18 -0
  122. package/cloudflare/shims/express-compat/index.ts +80 -0
  123. package/cloudflare/shims/express-compat/types.ts +41 -0
  124. package/cloudflare/shims/fastq.ts +105 -0
  125. package/cloudflare/shims/lock.ts +115 -0
  126. package/cloudflare/shims/mime-types.ts +56 -0
  127. package/cloudflare/shims/nedb-storage.ts +9 -0
  128. package/cloudflare/shims/node-child-process.ts +9 -0
  129. package/cloudflare/shims/node-fs.ts +20 -0
  130. package/cloudflare/shims/node-http.ts +13 -0
  131. package/cloudflare/shims/node-https.ts +4 -0
  132. package/cloudflare/shims/node-misc.ts +15 -0
  133. package/cloudflare/shims/node-net.ts +8 -0
  134. package/cloudflare/shims/node-os.ts +14 -0
  135. package/cloudflare/shims/node-tty.ts +8 -0
  136. package/cloudflare/shims/node-zlib.ts +17 -0
  137. package/cloudflare/shims/noop.ts +26 -0
  138. package/cloudflare/shims/payment-vendor.ts +14 -0
  139. package/cloudflare/shims/querystring.ts +12 -0
  140. package/cloudflare/shims/queue.ts +585 -0
  141. package/cloudflare/shims/rolldown-runtime.ts +43 -0
  142. package/cloudflare/shims/sequelize-d1/datatypes.ts +24 -0
  143. package/cloudflare/shims/sequelize-d1/helpers.ts +46 -0
  144. package/cloudflare/shims/sequelize-d1/index.ts +34 -0
  145. package/cloudflare/shims/sequelize-d1/model.ts +1157 -0
  146. package/cloudflare/shims/sequelize-d1/operators.ts +293 -0
  147. package/cloudflare/shims/sequelize-d1/retry.ts +85 -0
  148. package/cloudflare/shims/sequelize-d1/sequelize-class.ts +119 -0
  149. package/cloudflare/shims/sequelize-d1/timing.ts +81 -0
  150. package/cloudflare/shims/sequelize-d1/types.ts +35 -0
  151. package/cloudflare/shims/stripe-cf.ts +29 -0
  152. package/cloudflare/shims/ws-lite.ts +103 -0
  153. package/cloudflare/shims/xss.ts +3 -0
  154. package/cloudflare/tests/shims/cron.spec.ts +210 -0
  155. package/cloudflare/tests/shims/queue-scheduled.spec.ts +186 -0
  156. package/cloudflare/vite.config.ts +162 -0
  157. package/cloudflare/worker.ts +1553 -0
  158. package/cloudflare/wrangler.json +63 -0
  159. package/cloudflare/wrangler.jsonc +69 -0
  160. package/cloudflare/wrangler.staging.json +66 -0
  161. package/cloudflare/wrangler.toml +28 -0
  162. package/jest.config.js +4 -12
  163. package/package.json +26 -22
  164. package/src/app.tsx +62 -4
  165. package/src/components/customer/link.tsx +9 -13
  166. package/src/components/customer/notification-preference.tsx +3 -2
  167. package/src/components/filter-toolbar.tsx +4 -0
  168. package/src/components/invoice/list.tsx +9 -1
  169. package/src/components/invoice-pdf/utils.ts +2 -1
  170. package/src/components/layout/admin.tsx +39 -5
  171. package/src/components/layout/user-cf.tsx +77 -0
  172. package/src/components/payment-intent/actions.tsx +23 -3
  173. package/src/components/safe-did-address.tsx +75 -0
  174. package/src/libs/patch-user-card.ts +25 -0
  175. package/src/libs/util.ts +5 -7
  176. package/src/pages/admin/billing/meter-events/index.tsx +4 -0
  177. package/src/pages/admin/customers/customers/detail.tsx +2 -2
  178. package/src/pages/admin/customers/customers/index.tsx +2 -2
  179. package/src/pages/admin/overview.tsx +3 -1
  180. package/src/pages/customer/subscription/detail.tsx +4 -4
  181. package/tsconfig.api.json +1 -6
  182. package/tsconfig.json +3 -4
  183. package/tsconfig.types.json +2 -1
  184. package/vite.config.ts +6 -1
@@ -0,0 +1,390 @@
1
+ const { build } = require("esbuild");
2
+ const path = require("path");
3
+ const cfDir = __dirname;
4
+ const s = (f) => path.resolve(cfDir, f);
5
+
6
+ // Resolve the absolute path of the original queue module so we can intercept it
7
+ const queueModulePath = path.resolve(cfDir, "../api/src/libs/queue/index.ts");
8
+ const queueShimPath = s("shims/queue.ts");
9
+
10
+ // Resolve the absolute path of the original lock module so we can intercept it
11
+ const lockModulePath = path.resolve(cfDir, "../api/src/libs/lock.ts");
12
+ const lockShimPath = s("shims/lock.ts");
13
+
14
+ // Plugin to redirect libs/queue to our CF Workers shim
15
+ const queueNormalizedTarget = queueModulePath.replace(/\/index\.ts$/, '').replace(/\/index$/, '');
16
+ const queueShimPlugin = {
17
+ name: 'queue-shim',
18
+ setup(build) {
19
+ // Intercept any import that resolves to the original queue module
20
+ build.onResolve({ filter: /libs\/queue/ }, (args) => {
21
+ const resolveDir = args.resolveDir;
22
+ if (!resolveDir) return undefined;
23
+
24
+ // Resolve the relative import to an absolute path
25
+ const resolved = path.resolve(resolveDir, args.path).replace(/\/index(\.ts)?$/, '');
26
+ const match = resolved === queueNormalizedTarget;
27
+ if (args.path.includes('queue')) {
28
+ console.log(`[queue-shim] ${match ? 'MATCH' : 'skip'}: ${args.path} -> ${resolved} (target: ${queueNormalizedTarget})`);
29
+ }
30
+ if (match) {
31
+ return { path: queueShimPath };
32
+ }
33
+ return undefined;
34
+ });
35
+ },
36
+ };
37
+
38
+ // Plugin to redirect libs/lock to our CF Workers D1-based lock shim
39
+ const lockNormalizedTarget = lockModulePath.replace(/\.ts$/, '');
40
+ const lockShimPlugin = {
41
+ name: 'lock-shim',
42
+ setup(build) {
43
+ build.onResolve({ filter: /libs\/lock/ }, (args) => {
44
+ const resolveDir = args.resolveDir;
45
+ if (!resolveDir) return undefined;
46
+
47
+ const resolved = path.resolve(resolveDir, args.path).replace(/\.ts$/, '');
48
+ const match = resolved === lockNormalizedTarget;
49
+ if (args.path.includes('lock')) {
50
+ console.log(`[lock-shim] ${match ? 'MATCH' : 'skip'}: ${args.path} -> ${resolved} (target: ${lockNormalizedTarget})`);
51
+ }
52
+ if (match) {
53
+ return { path: lockShimPath };
54
+ }
55
+ return undefined;
56
+ });
57
+ },
58
+ };
59
+
60
+ // Plugin to neutralize rolldown-generated `__require(import.meta.url)` helpers
61
+ // that ship inside npm packages built with rolldown (e.g. @ocap/message,
62
+ // @arcblock/did-connect-js). These helpers use `createRequire(import.meta.url)`
63
+ // at module init to pull in CJS deps like `google-protobuf`, `debug`, etc. —
64
+ // which neither resolve nor work in the CF Workers runtime.
65
+ //
66
+ // The downstream patches/shims that use these require calls are all either:
67
+ // - monkey-patches for edge cases Payment Kit doesn't exercise, or
68
+ // - debug()/logger() factories that Payment Kit doesn't need on CF.
69
+ //
70
+ // Replace every `_virtual/rolldown_runtime.mjs` with a stub whose `__require`
71
+ // returns a Proxy that swallows further property accesses + function calls,
72
+ // and whose `__commonJSMin` returns an empty-module factory. This lets the
73
+ // importing modules finish loading without crashing the worker at startup.
74
+ const rolldownRuntimeStub = `
75
+ // After the Phase 2 CBOR switch (payment-method.ts + did-connect-auth.ts
76
+ // moved off @ocap/client/legacy), no codepath in the worker calls
77
+ // __require('google-protobuf') at runtime. The CBOR-only @ocap/client
78
+ // default entry + @ocap/client/encode use plain ESM imports for their
79
+ // deps. Any remaining __require calls in Rolldown-compiled packages
80
+ // (debug, @arcblock/event-hub, etc.) are handled by the __noop Proxy
81
+ // below — they don't need real modules for payment-kit's flows.
82
+ const __requireMap = {};
83
+ const __noopTarget = function(){};
84
+ const __noopHandler = {
85
+ get(t, p) {
86
+ if (p === Symbol.toPrimitive || p === 'toString') return () => '';
87
+ if (p === 'default') return new Proxy(__noopTarget, __noopHandler);
88
+ return new Proxy(__noopTarget, __noopHandler);
89
+ },
90
+ apply() { return new Proxy(__noopTarget, __noopHandler); },
91
+ construct() { return new Proxy(__noopTarget, __noopHandler); },
92
+ };
93
+ const __noop = new Proxy(__noopTarget, __noopHandler);
94
+ export const __commonJSMin = function(cb){
95
+ return function(){
96
+ var m = { exports: {} };
97
+ try { cb(m.exports, m); } catch (_) {}
98
+ return m.exports;
99
+ };
100
+ };
101
+ export const __require = function(id){
102
+ if (__requireMap[id]) return __requireMap[id];
103
+ return __noop;
104
+ };
105
+ export const __exportAll = function(target, source){
106
+ if (source) {
107
+ try {
108
+ for (var key in source) {
109
+ if (key !== 'default' && !Object.prototype.hasOwnProperty.call(target, key)) {
110
+ Object.defineProperty(target, key, {
111
+ get: function() { return source[key]; },
112
+ enumerable: true,
113
+ configurable: true,
114
+ });
115
+ }
116
+ }
117
+ } catch (_) {}
118
+ }
119
+ return target;
120
+ };
121
+ export const __toESM = function(mod){ return mod && mod.__esModule ? mod : { default: mod }; };
122
+ export const __toCommonJS = function(mod){ return mod; };
123
+ export const __copyProps = function(target){ return target; };
124
+ export default { __commonJSMin, __require, __exportAll, __toESM, __toCommonJS, __copyProps };
125
+ `;
126
+ const rolldownRuntimeNoopPlugin = {
127
+ name: 'rolldown-runtime-noop',
128
+ setup(build) {
129
+ // Catch any import that resolves to a `_virtual/rolldown_runtime.mjs`
130
+ // file, regardless of which package it comes from.
131
+ build.onResolve({ filter: /_virtual\/rolldown_runtime\.mjs$/ }, (args) => {
132
+ return { path: args.path, namespace: 'rolldown-runtime-noop' };
133
+ });
134
+ build.onLoad({ filter: /.*/, namespace: 'rolldown-runtime-noop' }, () => ({
135
+ contents: rolldownRuntimeStub,
136
+ loader: 'js',
137
+ // Need a resolveDir so the virtual stub's `import "google-protobuf"` resolves
138
+ // against the workspace's node_modules. Pointing at cfDir is sufficient since
139
+ // pnpm hoists google-protobuf up to the repo root node_modules.
140
+ resolveDir: cfDir,
141
+ }));
142
+ },
143
+ };
144
+
145
+ // Plugin: fix lodash sub-path CJS/ESM interop
146
+ // The "lodash" → "lodash-es" alias also redirects require('lodash/camelCase')
147
+ // to lodash-es/camelCase (ESM). CJS consumers get { __esModule, default: fn }
148
+ // instead of the function itself, causing "_m is not a function" at runtime.
149
+ // Fix: intercept lodash-es sub-path imports from CJS contexts and generate a
150
+ // virtual wrapper that re-exports the default as module.exports.
151
+ const lodashSubpathPlugin = {
152
+ name: 'lodash-subpath-interop',
153
+ setup(build) {
154
+ // Intercept resolved lodash-es sub-path imports that come from require() calls
155
+ // Intercept CJS require('lodash/xxx') — the alias hasn't applied yet at this stage
156
+ build.onResolve({ filter: /^lodash\/.+/ }, (args) => {
157
+ if (args.kind === 'require-call') {
158
+ // Convert lodash/xxx → lodash-es/xxx and wrap for CJS compat
159
+ const esPath = args.path.replace(/^lodash\//, 'lodash-es/');
160
+ return {
161
+ path: esPath,
162
+ namespace: 'lodash-cjs-compat',
163
+ };
164
+ }
165
+ });
166
+ build.onLoad({ filter: /.*/, namespace: 'lodash-cjs-compat' }, (args) => {
167
+ // Resolve the actual file path, then read and re-export as CJS.
168
+ // By loading the original ESM source as 'js' with CJS-style wrapping,
169
+ // esbuild treats the result as CJS, avoiding the __toModule interop.
170
+ const subPath = args.path.replace('lodash-es/', '');
171
+ const filePath = require.resolve(`lodash-es/${subPath}`);
172
+ const source = require('fs').readFileSync(filePath, 'utf8');
173
+ // Transform: replace ESM export default with module.exports
174
+ // lodash-es modules all follow: import deps... ; function fn(...){...}; export default fn;
175
+ const transformed = source
176
+ .replace(/^export default /m, 'module.exports = ')
177
+ .replace(/^export\s*\{[^}]*\}\s*;?\s*$/m, '');
178
+ return {
179
+ contents: transformed,
180
+ loader: 'js',
181
+ resolveDir: require('path').dirname(filePath),
182
+ };
183
+ });
184
+ },
185
+ };
186
+
187
+ // Plugin: redirect bare `@arcblock/did-util` and `@ocap/message` imports to their
188
+ // CBOR-only subpath entries, and noop `@arcblock/did-util/protobuf`. This strips
189
+ // the protobuf runtime (`@ocap/proto/runtime`, `google-protobuf`, `*_pb.js`) out
190
+ // of the CF Workers bundle. Only matches EXACT bare specifiers — subpath imports
191
+ // (e.g. `@arcblock/did-util/cbor`) pass through untouched.
192
+ const cborOnlyPlugin = {
193
+ name: 'cbor-only-redirect',
194
+ setup(build) {
195
+ build.onResolve({ filter: /^@arcblock\/did-util$/ }, () => ({
196
+ path: path.resolve(__dirname, '../../..', 'node_modules/@arcblock/did-util/esm/cbor.mjs'),
197
+ }));
198
+ build.onResolve({ filter: /^@ocap\/message$/ }, () => ({
199
+ path: path.resolve(__dirname, '../../..', 'node_modules/@ocap/message/esm/cbor.mjs'),
200
+ }));
201
+ build.onResolve({ filter: /^@arcblock\/did-util\/protobuf$/ }, () => ({
202
+ path: s('shims/noop.ts'),
203
+ }));
204
+ },
205
+ };
206
+
207
+ // Plugin: noop entire package trees that have sub-path imports (alias alone
208
+ // doesn't work because esbuild treats "axon" alias as prefix, breaking
209
+ // "axon/lib/plugins/queue"). This plugin intercepts bare + sub-path imports.
210
+ const noopPackagesPlugin = {
211
+ name: 'noop-packages',
212
+ setup(build) {
213
+ const packages = ['axon', '@arcblock/ws', '@arcblock/event-hub', 'graphql', 'follow-redirects', 'proxy-from-env'];
214
+ const filter = new RegExp('^(' + packages.join('|') + ')(\\/|$)');
215
+ build.onResolve({ filter }, () => ({ path: s('shims/noop.ts') }));
216
+ },
217
+ };
218
+
219
+ build({
220
+ entryPoints: [s("worker.ts")],
221
+ bundle: true, format: "esm", platform: "node", target: "esnext",
222
+ outdir: s("dist"), minify: true, sourcemap: true, metafile: true,
223
+ mainFields: ["module", "main"],
224
+ plugins: [
225
+ noopPackagesPlugin, queueShimPlugin, lockShimPlugin, rolldownRuntimeNoopPlugin, lodashSubpathPlugin,
226
+ ],
227
+ external: ["cloudflare:*", "__STATIC_CONTENT_MANIFEST"],
228
+ // Give import.meta.url a stable fallback so bundled deps that call
229
+ // createRequire(import.meta.url) at module init don't throw at worker
230
+ // startup. The polyfill in banner handles any legitimate require() lookups.
231
+ define: {
232
+ "import.meta.url": '"file:///worker.js"',
233
+ },
234
+ banner: {
235
+ js: [
236
+ '// Polyfill require() for CJS modules that dynamically require Node builtins',
237
+ 'import __nodeCrypto from "node:crypto";',
238
+ 'import __nodeBuffer from "node:buffer";',
239
+ 'import __nodeEvents from "node:events";',
240
+ 'import __nodeStream from "node:stream";',
241
+ 'import __nodeUtil from "node:util";',
242
+ 'import __nodeAssert from "node:assert";',
243
+ 'import __nodePath from "node:path";',
244
+ 'import __nodeUrl from "node:url";',
245
+ 'import __nodeProcess from "node:process";',
246
+ 'const __qsShim = { stringify: function(o) { return new URLSearchParams(o).toString(); }, parse: function(s) { return Object.fromEntries(new URLSearchParams(s).entries()); } };',
247
+ 'const __nodeModules = { crypto: __nodeCrypto, buffer: __nodeBuffer, events: __nodeEvents, stream: __nodeStream, util: __nodeUtil, assert: __nodeAssert, path: __nodePath, url: __nodeUrl, process: __nodeProcess, querystring: __qsShim };',
248
+ '// Accept both "xxx" and "node:xxx" specifier forms; return empty stub for unknown modules',
249
+ '// (some deps tree-shake to nothing but still call require() at init — a hard throw crashes the worker).',
250
+ 'globalThis.require = globalThis.require || function(m) { var key = typeof m === "string" && m.indexOf("node:") === 0 ? m.slice(5) : m; if (__nodeModules[key]) return __nodeModules[key]; console.warn("[require shim] unknown module: " + m); return {}; };',
251
+ '// Ensure process.stderr.fd exists for debug/supports-color',
252
+ 'if (typeof process !== "undefined") { if (!process.stderr) process.stderr = { fd: 2, write: function(){} }; else if (process.stderr.fd === undefined) process.stderr.fd = 2; if (!process.stdout) process.stdout = { fd: 1, write: function(){} }; else if (process.stdout.fd === undefined) process.stdout.fd = 1; }',
253
+ '// Polyfill process.on/process.exit for modules that use them at init',
254
+ 'if (typeof process !== "undefined" && !process.on) { process.on = function(){}; process.once = function(){}; process.off = function(){}; process.removeListener = function(){}; process.emit = function(){}; process.exit = function(){}; }',
255
+ '// CF Workers: defer timers called during global scope init until first request',
256
+ 'var __deferredTimers = []; var __timersReady = false;',
257
+ 'globalThis.__flushDeferredTimers = function() { if (__timersReady) return; __timersReady = true; var q = __deferredTimers; __deferredTimers = []; q.forEach(function(entry) { try { entry.fn.apply(null, entry.args); } catch(e) { console.error("deferred timer error:", e); } }); };',
258
+ 'var _origSetTimeout = globalThis.setTimeout; globalThis.setTimeout = function() { if (!__timersReady) { var args = arguments; var fn = args[0]; __deferredTimers.push({fn: function(){ _origSetTimeout.apply(globalThis, args); }, args: []}); return { unref: function(){}, ref: function(){}, [Symbol.toPrimitive]: function(){ return 0; } }; } var id = _origSetTimeout.apply(this, arguments); if (typeof id === "number") { return { unref: function(){}, ref: function(){}, [Symbol.toPrimitive]: function(){ return id; } }; } if (id && !id.unref) id.unref = function(){}; return id; };',
259
+ 'var _origSetInterval = globalThis.setInterval; globalThis.setInterval = function() { if (!__timersReady) { var args = arguments; __deferredTimers.push({fn: function(){ _origSetInterval.apply(globalThis, args); }, args: []}); return { unref: function(){}, ref: function(){}, [Symbol.toPrimitive]: function(){ return 0; } }; } var id = _origSetInterval.apply(this, arguments); if (typeof id === "number") { return { unref: function(){}, ref: function(){}, [Symbol.toPrimitive]: function(){ return id; } }; } if (id && !id.unref) id.unref = function(){}; return id; };',
260
+ 'var _origSetImmediate = globalThis.setImmediate; if (_origSetImmediate) { globalThis.setImmediate = function() { if (!__timersReady) { var args = arguments; __deferredTimers.push({fn: function(){ _origSetImmediate.apply(globalThis, args); }, args: []}); return { unref: function(){}, ref: function(){} }; } return _origSetImmediate.apply(this, arguments); }; } else { globalThis.setImmediate = function(fn) { if (!__timersReady) { __deferredTimers.push({fn: function(){ _origSetTimeout(fn, 0); }, args: []}); return { unref: function(){}, ref: function(){} }; } return _origSetTimeout(fn, 0); }; }',
261
+ 'if (typeof process !== "undefined") { var _origNextTick = process.nextTick; if (_origNextTick) { process.nextTick = function() { if (!__timersReady) { var args = Array.prototype.slice.call(arguments); var fn = args.shift(); __deferredTimers.push({fn: function(){ _origNextTick.apply(process, [fn].concat(args)); }, args: []}); return; } return _origNextTick.apply(process, arguments); }; } else { process.nextTick = function(fn) { if (!__timersReady) { __deferredTimers.push({fn: function(){ _origSetTimeout(fn, 0); }, args: []}); return; } _origSetTimeout(fn, 0); }; } }',
262
+ ].join('\n'),
263
+ },
264
+ alias: {
265
+ // axios → lightweight fetch-based shim (115KB → ~2KB)
266
+ "axios": s("shims/axios-lite.ts"),
267
+
268
+ // Stripe — wrap constructor to use fetch HTTP client in CF Workers
269
+ "stripe": s("shims/stripe-cf.ts"),
270
+ "__real_stripe__": require.resolve("stripe"),
271
+
272
+ // @ocap/message ships a patch.mjs that monkey-patches google-protobuf at
273
+ // module init. google-protobuf isn't available in CF Workers (no filesystem
274
+ // for createRequire to resolve), and Payment Kit doesn't use the features
275
+ // that patch touches. Replace with a noop so the import chain stays alive
276
+ // but the patch is skipped. Same for the rolldown_runtime helper that
277
+ // relies on createRequire(import.meta.url).
278
+ "@ocap/message/esm/patch.mjs": s("shims/noop.ts"),
279
+ "@ocap/message/esm/_virtual/rolldown_runtime.mjs": s("shims/noop.ts"),
280
+
281
+ "sequelize": s("shims/sequelize-d1/index.ts"),
282
+ "sqlite3": s("shims/noop.ts"),
283
+ "cls-hooked": s("shims/noop.ts"),
284
+ "express-async-errors": s("shims/noop.ts"),
285
+ "express": s("shims/express-compat/index.ts"),
286
+ "cors": s("shims/cors.ts"),
287
+ "cookie-parser": s("shims/cookie-parser.ts"),
288
+ "@blocklet/sdk/lib/middlewares/fallback": s("shims/blocklet-sdk/fallback.ts"),
289
+ "@blocklet/sdk/lib/middlewares/cdn": s("shims/blocklet-sdk/cdn.ts"),
290
+ "@blocklet/sdk/lib/middlewares/session": s("shims/blocklet-sdk/session.ts"),
291
+ "@blocklet/sdk/lib/middlewares": s("shims/blocklet-sdk/middlewares.ts"),
292
+ "@blocklet/sdk/lib/env": s("shims/blocklet-sdk/env.ts"),
293
+ "@blocklet/sdk/lib/config": s("shims/blocklet-sdk/config.ts"),
294
+ "@blocklet/sdk/lib/component": s("shims/blocklet-sdk/component.ts"),
295
+ "@blocklet/sdk/lib/wallet": s("shims/blocklet-sdk/wallet.ts"),
296
+ "@blocklet/sdk/lib/wallet-authenticator": s("shims/blocklet-sdk/wallet-authenticator.ts"),
297
+ "@blocklet/sdk/lib/wallet-handler": s("shims/blocklet-sdk/wallet-handler.ts"),
298
+ "@blocklet/sdk/lib/security": s("shims/blocklet-sdk/security.ts"),
299
+ "@blocklet/sdk/lib/util/verify-sign": s("shims/blocklet-sdk/verify-sign.ts"),
300
+ "@blocklet/sdk/lib/util/component-api": s("shims/blocklet-sdk/component-api.ts"),
301
+ "@blocklet/sdk/lib/error-handler": s("shims/noop.ts"),
302
+ "@blocklet/sdk/lib/did": s("shims/blocklet-sdk/did.ts"),
303
+ "@blocklet/sdk/lib/types/notification": s("shims/noop.ts"),
304
+ "@blocklet/sdk/service/notification": s("shims/blocklet-sdk/notification.ts"),
305
+ "@blocklet/sdk/service/eventbus": s("shims/blocklet-sdk/eventbus.ts"),
306
+ "@blocklet/sdk/service/auth": s("shims/blocklet-sdk/auth-service.ts"),
307
+ "@blocklet/sdk/service/blocklet": s("shims/blocklet-sdk/auth-service.ts"),
308
+ "@blocklet/sdk": s("shims/blocklet-sdk/index.ts"),
309
+ "@blocklet/xss": s("shims/xss.ts"),
310
+ "@blocklet/error": s("shims/error.ts"),
311
+ "@blocklet/logger": s("shims/blocklet-sdk/logger.ts"),
312
+ "@blocklet/did-space-js": s("shims/did-space.ts"),
313
+ "@blocklet/payment-vendor": s("shims/payment-vendor.ts"),
314
+ "@arcblock/did-connect-storage-nedb": s("shims/nedb-storage.ts"),
315
+ "@abtnode/cron": s("shims/cron.ts"),
316
+ "dotenv-flow": s("shims/noop.ts"),
317
+ "fastq": s("shims/fastq.ts"),
318
+
319
+ // Bundle size optimizations — lodash base import aliased to lodash-es for tree-shaking.
320
+ // Sub-path imports (lodash/camelCase etc.) handled by lodashSubpathPlugin below.
321
+ "lodash": "lodash-es", // 357KB CJS → tree-shakeable ESM
322
+ "esprima": s("shims/noop.ts"), // 215KB — only used by @ocap/contract, not called in payment-kit
323
+ "mustache": s("shims/noop.ts"), // 16KB — template engine, not used in payment-kit
324
+ "mime-types": s("shims/mime-types.ts"), // 150KB — lightweight shim with common MIME types
325
+ "mime-db": s("shims/noop.ts"),
326
+ "ws": s("shims/ws-lite.ts"), // 66KB — native WebSocket wrapper for CF Workers
327
+ "crypto-js": s("shims/crypto-js-warn.ts"), // 115KB — AES legacy not used, warns if called
328
+ "crypto-js/aes": s("shims/crypto-js-warn.ts"),
329
+ "crypto-js/enc-base64": s("shims/noop.ts"),
330
+ "crypto-js/enc-hex": s("shims/noop.ts"),
331
+ "crypto-js/enc-latin1": s("shims/noop.ts"),
332
+ "crypto-js/enc-utf8": s("shims/noop.ts"),
333
+ "crypto-js/enc-utf16": s("shims/noop.ts"),
334
+
335
+ // Force ESM-only to avoid CJS+ESM double-bundling
336
+ "valibot": path.resolve(__dirname, "../../..", "node_modules/valibot/dist/index.mjs"), // 396KB → ~200KB
337
+ // CF Workers: noop modules not useful in Workers environment
338
+ "phoenix": s("shims/noop.ts"), // 36KB — Phoenix channels, only used by @arcblock/ws
339
+ "numbro": s("shims/noop.ts"), // 49KB — number formatting, replaced inline in util.ts
340
+
341
+ // Node built-in shims (not fully supported in CF Workers nodejs_compat)
342
+ "os": s("shims/node-os.ts"),
343
+ "node:os": s("shims/node-os.ts"),
344
+ "tty": s("shims/node-tty.ts"),
345
+ "node:tty": s("shims/node-tty.ts"),
346
+ "http": s("shims/node-http.ts"),
347
+ "node:http": s("shims/node-http.ts"),
348
+ "https": s("shims/node-https.ts"),
349
+ "node:https": s("shims/node-https.ts"),
350
+ "http2": s("shims/node-http.ts"),
351
+ "node:http2": s("shims/node-http.ts"),
352
+ "net": s("shims/node-net.ts"),
353
+ "node:net": s("shims/node-net.ts"),
354
+ "tls": s("shims/node-misc.ts"),
355
+ "node:tls": s("shims/node-misc.ts"),
356
+ "fs": s("shims/node-fs.ts"),
357
+ "node:fs": s("shims/node-fs.ts"),
358
+ "cluster": s("shims/node-misc.ts"),
359
+ "node:cluster": s("shims/node-misc.ts"),
360
+ "zlib": s("shims/node-zlib.ts"),
361
+ "node:zlib": s("shims/node-zlib.ts"),
362
+ "child_process": s("shims/node-child-process.ts"),
363
+ "node:child_process": s("shims/node-child-process.ts"),
364
+ "bufferutil": s("shims/noop.ts"),
365
+ "utf-8-validate": s("shims/noop.ts"),
366
+ "dns": s("shims/noop.ts"),
367
+ "node:dns": s("shims/noop.ts"),
368
+ "pg": s("shims/noop.ts"),
369
+ "postgres": s("shims/noop.ts"),
370
+ },
371
+ logLevel: "warning",
372
+ }).then(result => {
373
+ require('fs').writeFileSync(s('dist/meta.json'), JSON.stringify(result.metafile));
374
+ Object.entries(result.metafile.outputs).forEach(function(entry) {
375
+ var k = entry[0], v = entry[1];
376
+ if (k.indexOf(".map") === -1) {
377
+ console.log(k + ": " + (v.bytes / 1024).toFixed(1) + "KB");
378
+ }
379
+ });
380
+ console.log("BUILD SUCCESS");
381
+ }).catch(err => {
382
+ console.error("BUILD FAILED: " + (err.errors ? err.errors.length + " errors" : err.message));
383
+ if (err.errors) {
384
+ err.errors.slice(0, 20).forEach(function(e) {
385
+ var loc = e.location ? " at " + e.location.file + ":" + e.location.line : "";
386
+ console.error(" " + e.text + loc);
387
+ });
388
+ if (err.errors.length > 20) console.error(" ... and " + (err.errors.length - 20) + " more");
389
+ }
390
+ });
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Test script: Verify we can decrypt Stripe keys from D1 using APP_SK + BLOCKLET_DID (COMPONENT_DID).
4
+ *
5
+ * Usage:
6
+ * 1. First, get the encrypted value from D1:
7
+ * wrangler d1 execute payment-kit-prod --remote \
8
+ * --command "SELECT settings FROM payment_methods WHERE type='stripe'" --json
9
+ *
10
+ * 2. Run this script with the encrypted value and keys:
11
+ * APP_SK=<hex> BLOCKLET_DID=<did> ENCRYPTED=<base64> node test-decrypt.js
12
+ *
13
+ * The decryption chain:
14
+ * passphrase = PBKDF2(APP_SK, BLOCKLET_DID, 256 iterations, 32 bytes, sha512).toString('hex')
15
+ * plaintext = CryptoJS.AES.decrypt(encrypted, passphrase)
16
+ *
17
+ * CryptoJS.AES with a string passphrase uses OpenSSL's EvpKDF internally:
18
+ * - Input: "Salted__" + 8-byte salt + ciphertext (Base64 decoded)
19
+ * - EvpKDF derives key (32 bytes) + IV (16 bytes) from passphrase + salt using MD5
20
+ * - AES-256-CBC decryption
21
+ */
22
+
23
+ const crypto = require('crypto');
24
+
25
+ const APP_SK = process.env.APP_SK;
26
+ const BLOCKLET_DID = process.env.BLOCKLET_DID;
27
+ const ENCRYPTED = process.env.ENCRYPTED;
28
+
29
+ if (!APP_SK || !BLOCKLET_DID || !ENCRYPTED) {
30
+ console.log('Usage: APP_SK=<hex> BLOCKLET_DID=<did> ENCRYPTED=<base64> node test-decrypt.js');
31
+ console.log('\nTo get ENCRYPTED value:');
32
+ console.log(' wrangler d1 execute payment-kit-prod --remote \\');
33
+ console.log(' --command "SELECT settings FROM payment_methods WHERE type=\'stripe\'" --json');
34
+ process.exit(1);
35
+ }
36
+
37
+ // Step 1: Derive passphrase via PBKDF2 (same as @blocklet/sdk/lib/security)
38
+ const passphrase = crypto.pbkdf2Sync(APP_SK, BLOCKLET_DID, 256, 32, 'sha512').toString('hex');
39
+ console.log('Derived passphrase (first 16 chars):', passphrase.substring(0, 16) + '...');
40
+
41
+ // Step 2: Decode CryptoJS OpenSSL format
42
+ const rawCipher = Buffer.from(ENCRYPTED, 'base64');
43
+ const prefix = rawCipher.slice(0, 8).toString('utf8'); // Should be "Salted__"
44
+ if (prefix !== 'Salted__') {
45
+ console.error('ERROR: Not a CryptoJS OpenSSL encrypted value (missing Salted__ prefix)');
46
+ console.log('Raw prefix bytes:', rawCipher.slice(0, 8));
47
+ process.exit(1);
48
+ }
49
+ console.log('Format: CryptoJS OpenSSL (Salted__)');
50
+
51
+ const salt = rawCipher.slice(8, 16);
52
+ const ciphertext = rawCipher.slice(16);
53
+ console.log('Salt (hex):', salt.toString('hex'));
54
+ console.log('Ciphertext length:', ciphertext.length, 'bytes');
55
+
56
+ // Step 3: EvpKDF — CryptoJS uses MD5-based key derivation (OpenSSL EVP_BytesToKey)
57
+ function evpKDF(password, salt, keySize, ivSize) {
58
+ const passBuffer = Buffer.from(password, 'utf8');
59
+ const totalSize = keySize + ivSize;
60
+ const derived = [];
61
+ let block = Buffer.alloc(0);
62
+
63
+ while (Buffer.concat(derived).length < totalSize) {
64
+ const hasher = crypto.createHash('md5');
65
+ hasher.update(block);
66
+ hasher.update(passBuffer);
67
+ hasher.update(salt);
68
+ block = hasher.digest();
69
+ derived.push(block);
70
+ }
71
+
72
+ const all = Buffer.concat(derived);
73
+ return {
74
+ key: all.slice(0, keySize),
75
+ iv: all.slice(keySize, keySize + ivSize),
76
+ };
77
+ }
78
+
79
+ const { key, iv } = evpKDF(passphrase, salt, 32, 16);
80
+ console.log('AES key (hex, first 16 chars):', key.toString('hex').substring(0, 16) + '...');
81
+ console.log('AES IV (hex):', iv.toString('hex'));
82
+
83
+ // Step 4: AES-256-CBC decrypt
84
+ try {
85
+ const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
86
+ let decrypted = decipher.update(ciphertext, undefined, 'utf8');
87
+ decrypted += decipher.final('utf8');
88
+ console.log('\n✅ DECRYPTED:', decrypted);
89
+
90
+ // Mask sensitive output
91
+ if (decrypted.startsWith('sk_')) {
92
+ console.log('(Stripe secret key detected — first 12 chars: ' + decrypted.substring(0, 12) + '...)');
93
+ } else if (decrypted.startsWith('whsec_')) {
94
+ console.log('(Stripe webhook secret detected — first 10 chars: ' + decrypted.substring(0, 10) + '...)');
95
+ }
96
+ } catch (err) {
97
+ console.error('\n❌ DECRYPTION FAILED:', err.message);
98
+ console.log('\nPossible causes:');
99
+ console.log(' 1. Wrong APP_SK — verify it matches the Blocklet Server environment');
100
+ console.log(' 2. Wrong BLOCKLET_DID — should be COMPONENT_DID (z2qa...), not APP_PID');
101
+ console.log(' 3. Data was encrypted with a different key');
102
+ }
@@ -0,0 +1,20 @@
1
+ // Shim for @arcblock/ws — WebSocket client/server not needed in CF Workers
2
+ // @ocap/client imports this but only uses HTTP, not WebSocket subscriptions
3
+
4
+ export class WsClient {
5
+ constructor(..._args: any[]) {}
6
+ connect() {}
7
+ disconnect() {}
8
+ onOpen(_cb: any) {}
9
+ onClose(_cb: any) {}
10
+ onError(_cb: any) {}
11
+ onMessage(_cb: any) {}
12
+ }
13
+
14
+ export class WsServer {
15
+ constructor(..._args: any[]) {}
16
+ attach() {}
17
+ broadcast() {}
18
+ }
19
+
20
+ export default { WsClient, WsServer };
@@ -0,0 +1,4 @@
1
+ // Shim: redirect axios HTTP adapter → fetch adapter for CF Workers
2
+ // axios's default Node.js adapter uses node:http which is shimmed to a noop in CF Workers,
3
+ // causing all HTTP requests to hang forever. This shim re-exports the fetch-based adapter instead.
4
+ export { default, getFetch } from 'axios/lib/adapters/fetch.js';
@@ -0,0 +1,117 @@
1
+ // Lightweight axios shim (~2KB) for CF Workers — replaces full axios (115KB).
2
+ // Only implements the API surface actually used by payment-kit:
3
+ // axios.get(url, config)
4
+ // axios.create(defaults) → instance with .get()
5
+ // AxiosError with .response
6
+
7
+ export class AxiosError extends Error {
8
+ response?: { status: number; data: any; headers: Record<string, string> };
9
+ config?: any;
10
+ code?: string;
11
+ isAxiosError = true;
12
+
13
+ constructor(message: string, code?: string, config?: any, response?: AxiosError['response']) {
14
+ super(message);
15
+ this.name = 'AxiosError';
16
+ this.code = code;
17
+ this.config = config;
18
+ this.response = response;
19
+ }
20
+ }
21
+
22
+ interface AxiosConfig {
23
+ params?: Record<string, any>;
24
+ timeout?: number;
25
+ headers?: Record<string, string>;
26
+ baseURL?: string;
27
+ }
28
+
29
+ interface AxiosResponse<T = any> {
30
+ data: T;
31
+ status: number;
32
+ statusText: string;
33
+ headers: Record<string, string>;
34
+ }
35
+
36
+ async function request<T = any>(url: string, config: AxiosConfig = {}): Promise<AxiosResponse<T>> {
37
+ const { params, timeout, headers = {}, baseURL } = config;
38
+
39
+ let fullUrl = baseURL ? `${baseURL.replace(/\/$/, '')}/${url.replace(/^\//, '')}` : url;
40
+
41
+ if (params) {
42
+ const qs = new URLSearchParams();
43
+ for (const [k, v] of Object.entries(params)) {
44
+ if (v !== undefined && v !== null) qs.append(k, String(v));
45
+ }
46
+ const sep = fullUrl.includes('?') ? '&' : '?';
47
+ fullUrl = `${fullUrl}${sep}${qs.toString()}`;
48
+ }
49
+
50
+ const controller = new AbortController();
51
+ const timeoutMs = timeout || 30000;
52
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
53
+
54
+ let res: Response;
55
+ try {
56
+ res = await fetch(fullUrl, { headers, signal: controller.signal });
57
+ } catch (err: any) {
58
+ clearTimeout(timer);
59
+ const code = err?.name === 'AbortError' ? 'ECONNABORTED' : 'ERR_NETWORK';
60
+ throw new AxiosError(err?.message || 'Network Error', code, config);
61
+ } finally {
62
+ clearTimeout(timer);
63
+ }
64
+
65
+ const responseHeaders: Record<string, string> = {};
66
+ res.headers.forEach((v, k) => { responseHeaders[k] = v; });
67
+
68
+ const ct = res.headers.get('content-type') || '';
69
+ const data = ct.includes('application/json') ? await res.json() : await res.text();
70
+
71
+ const response: AxiosResponse<T> = {
72
+ data: data as T,
73
+ status: res.status,
74
+ statusText: res.statusText,
75
+ headers: responseHeaders,
76
+ };
77
+
78
+ if (!res.ok) {
79
+ throw new AxiosError(
80
+ `Request failed with status code ${res.status}`,
81
+ 'ERR_BAD_RESPONSE',
82
+ config,
83
+ { status: res.status, data, headers: responseHeaders },
84
+ );
85
+ }
86
+
87
+ return response;
88
+ }
89
+
90
+ function createInstance(defaults: AxiosConfig = {}) {
91
+ const instance = {
92
+ defaults,
93
+ get<T = any>(url: string, config: AxiosConfig = {}): Promise<AxiosResponse<T>> {
94
+ return request<T>(url, { ...defaults, ...config, headers: { ...defaults.headers, ...config.headers } });
95
+ },
96
+ post<T = any>(url: string, _body?: any, config: AxiosConfig = {}): Promise<AxiosResponse<T>> {
97
+ return request<T>(url, { ...defaults, ...config, headers: { ...defaults.headers, ...config.headers } });
98
+ },
99
+ request<T = any>(config: AxiosConfig & { url: string }): Promise<AxiosResponse<T>> {
100
+ const { url, ...rest } = config;
101
+ return request<T>(url, { ...defaults, ...rest, headers: { ...defaults.headers, ...rest.headers } });
102
+ },
103
+ };
104
+ return instance;
105
+ }
106
+
107
+ const axios = {
108
+ get: <T = any>(url: string, config?: AxiosConfig) => request<T>(url, config),
109
+ post: <T = any>(url: string, _body?: any, config?: AxiosConfig) => request<T>(url, config),
110
+ create: (defaults?: AxiosConfig) => createInstance(defaults),
111
+ isAxiosError: (err: any): err is AxiosError => err?.isAxiosError === true,
112
+ AxiosError,
113
+ };
114
+
115
+ export default axios;
116
+ export { axios, AxiosError as default_AxiosError };
117
+ export type { AxiosConfig, AxiosResponse };