@dodopayments/nextjs 0.3.0 → 0.3.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.
- package/dist/index.cjs +2244 -1908
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2244 -1908
- package/dist/index.js.map +1 -1
- package/package.json +12 -8
package/dist/index.js
CHANGED
|
@@ -24,10 +24,9 @@ var detectDomainLocale = {};
|
|
|
24
24
|
detectedLocale = detectedLocale.toLowerCase();
|
|
25
25
|
}
|
|
26
26
|
for (const item of domainItems){
|
|
27
|
-
var _item_domain, _item_locales;
|
|
28
27
|
// remove port if present
|
|
29
|
-
const domainHostname =
|
|
30
|
-
if (hostname === domainHostname || detectedLocale === item.defaultLocale.toLowerCase() ||
|
|
28
|
+
const domainHostname = item.domain?.split(':', 1)[0].toLowerCase();
|
|
29
|
+
if (hostname === domainHostname || detectedLocale === item.defaultLocale.toLowerCase() || item.locales?.some((locale)=>locale.toLowerCase() === detectedLocale)) {
|
|
31
30
|
return item;
|
|
32
31
|
}
|
|
33
32
|
}
|
|
@@ -122,7 +121,7 @@ var parsePath = {};
|
|
|
122
121
|
return path;
|
|
123
122
|
}
|
|
124
123
|
const { pathname, query, hash } = (0, _parsepath.parsePath)(path);
|
|
125
|
-
return
|
|
124
|
+
return `${prefix}${pathname}${query}${hash}`;
|
|
126
125
|
}
|
|
127
126
|
|
|
128
127
|
|
|
@@ -146,7 +145,7 @@ var addPathSuffix = {};
|
|
|
146
145
|
return path;
|
|
147
146
|
}
|
|
148
147
|
const { pathname, query, hash } = (0, _parsepath.parsePath)(path);
|
|
149
|
-
return
|
|
148
|
+
return `${pathname}${suffix}${query}${hash}`;
|
|
150
149
|
}
|
|
151
150
|
|
|
152
151
|
|
|
@@ -199,10 +198,10 @@ var pathHasPrefix = {};
|
|
|
199
198
|
// don't need to prefix the path.
|
|
200
199
|
if (!ignorePrefix) {
|
|
201
200
|
if ((0, _pathhasprefix.pathHasPrefix)(lower, '/api')) return path;
|
|
202
|
-
if ((0, _pathhasprefix.pathHasPrefix)(lower,
|
|
201
|
+
if ((0, _pathhasprefix.pathHasPrefix)(lower, `/${locale.toLowerCase()}`)) return path;
|
|
203
202
|
}
|
|
204
203
|
// Add the locale prefix to the path.
|
|
205
|
-
return (0, _addpathprefix.addPathPrefix)(path,
|
|
204
|
+
return (0, _addpathprefix.addPathPrefix)(path, `/${locale}`);
|
|
206
205
|
}
|
|
207
206
|
|
|
208
207
|
|
|
@@ -228,7 +227,7 @@ var pathHasPrefix = {};
|
|
|
228
227
|
pathname = (0, _removetrailingslash.removeTrailingSlash)(pathname);
|
|
229
228
|
}
|
|
230
229
|
if (info.buildId) {
|
|
231
|
-
pathname = (0, _addpathsuffix.addPathSuffix)((0, _addpathprefix.addPathPrefix)(pathname,
|
|
230
|
+
pathname = (0, _addpathsuffix.addPathSuffix)((0, _addpathprefix.addPathPrefix)(pathname, `/_next/data/${info.buildId}`), info.pathname === '/' ? 'index.json' : '.json');
|
|
232
231
|
}
|
|
233
232
|
pathname = (0, _addpathprefix.addPathPrefix)(pathname, info.basePath);
|
|
234
233
|
return !info.buildId && info.trailingSlash ? !pathname.endsWith('/') ? (0, _addpathsuffix.addPathSuffix)(pathname, '/') : pathname : (0, _removetrailingslash.removeTrailingSlash)(pathname);
|
|
@@ -253,7 +252,7 @@ var getHostname = {};
|
|
|
253
252
|
// Get the hostname from the headers if it exists, otherwise use the parsed
|
|
254
253
|
// hostname.
|
|
255
254
|
let hostname;
|
|
256
|
-
if (
|
|
255
|
+
if (headers?.host && !Array.isArray(headers.host)) {
|
|
257
256
|
hostname = headers.host.toString().split(':', 1)[0];
|
|
258
257
|
} else if (parsed.hostname) {
|
|
259
258
|
hostname = parsed.hostname;
|
|
@@ -361,7 +360,7 @@ var removePathPrefix = {};
|
|
|
361
360
|
}
|
|
362
361
|
// If the path without the prefix doesn't start with a `/` we need to add it
|
|
363
362
|
// back to the path to make sure it's a valid path.
|
|
364
|
-
return
|
|
363
|
+
return `/${withoutPrefix}`;
|
|
365
364
|
}
|
|
366
365
|
|
|
367
366
|
|
|
@@ -381,8 +380,7 @@ var removePathPrefix = {};
|
|
|
381
380
|
const _removepathprefix = removePathPrefix;
|
|
382
381
|
const _pathhasprefix = pathHasPrefix;
|
|
383
382
|
function getNextPathnameInfo(pathname, options) {
|
|
384
|
-
|
|
385
|
-
const { basePath, i18n, trailingSlash } = (_options_nextConfig = options.nextConfig) != null ? _options_nextConfig : {};
|
|
383
|
+
const { basePath, i18n, trailingSlash } = options.nextConfig ?? {};
|
|
386
384
|
const info = {
|
|
387
385
|
pathname,
|
|
388
386
|
trailingSlash: pathname !== '/' ? pathname.endsWith('/') : trailingSlash
|
|
@@ -396,7 +394,7 @@ var removePathPrefix = {};
|
|
|
396
394
|
const paths = info.pathname.replace(/^\/_next\/data\//, '').replace(/\.json$/, '').split('/');
|
|
397
395
|
const buildId = paths[0];
|
|
398
396
|
info.buildId = buildId;
|
|
399
|
-
pathnameNoDataPrefix = paths[1] !== 'index' ?
|
|
397
|
+
pathnameNoDataPrefix = paths[1] !== 'index' ? `/${paths.slice(1).join('/')}` : '/';
|
|
400
398
|
// update pathname with normalized if enabled although
|
|
401
399
|
// we use normalized to populate locale info still
|
|
402
400
|
if (options.parseData === true) {
|
|
@@ -408,8 +406,7 @@ var removePathPrefix = {};
|
|
|
408
406
|
if (i18n) {
|
|
409
407
|
let result = options.i18nProvider ? options.i18nProvider.analyze(info.pathname) : (0, _normalizelocalepath.normalizeLocalePath)(info.pathname, i18n.locales);
|
|
410
408
|
info.locale = result.detectedLocale;
|
|
411
|
-
|
|
412
|
-
info.pathname = (_result_pathname = result.pathname) != null ? _result_pathname : info.pathname;
|
|
409
|
+
info.pathname = result.pathname ?? info.pathname;
|
|
413
410
|
if (!result.detectedLocale && info.buildId) {
|
|
414
411
|
result = options.i18nProvider ? options.i18nProvider.analyze(pathnameNoDataPrefix) : (0, _normalizelocalepath.normalizeLocalePath)(pathnameNoDataPrefix, i18n.locales);
|
|
415
412
|
if (result.detectedLocale) {
|
|
@@ -659,12 +656,18 @@ var constants = {};
|
|
|
659
656
|
GSSP_NO_RETURNED_VALUE: function() {
|
|
660
657
|
return GSSP_NO_RETURNED_VALUE;
|
|
661
658
|
},
|
|
659
|
+
HTML_CONTENT_TYPE_HEADER: function() {
|
|
660
|
+
return HTML_CONTENT_TYPE_HEADER;
|
|
661
|
+
},
|
|
662
662
|
INFINITE_CACHE: function() {
|
|
663
663
|
return INFINITE_CACHE;
|
|
664
664
|
},
|
|
665
665
|
INSTRUMENTATION_HOOK_FILENAME: function() {
|
|
666
666
|
return INSTRUMENTATION_HOOK_FILENAME;
|
|
667
667
|
},
|
|
668
|
+
JSON_CONTENT_TYPE_HEADER: function() {
|
|
669
|
+
return JSON_CONTENT_TYPE_HEADER;
|
|
670
|
+
},
|
|
668
671
|
MATCHED_PATH_HEADER: function() {
|
|
669
672
|
return MATCHED_PATH_HEADER;
|
|
670
673
|
},
|
|
@@ -725,6 +728,12 @@ var constants = {};
|
|
|
725
728
|
PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER: function() {
|
|
726
729
|
return PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER;
|
|
727
730
|
},
|
|
731
|
+
PROXY_FILENAME: function() {
|
|
732
|
+
return PROXY_FILENAME;
|
|
733
|
+
},
|
|
734
|
+
PROXY_LOCATION_REGEXP: function() {
|
|
735
|
+
return PROXY_LOCATION_REGEXP;
|
|
736
|
+
},
|
|
728
737
|
PUBLIC_DIR_MIDDLEWARE_CONFLICT: function() {
|
|
729
738
|
return PUBLIC_DIR_MIDDLEWARE_CONFLICT;
|
|
730
739
|
},
|
|
@@ -785,6 +794,9 @@ var constants = {};
|
|
|
785
794
|
STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR: function() {
|
|
786
795
|
return STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR;
|
|
787
796
|
},
|
|
797
|
+
TEXT_PLAIN_CONTENT_TYPE_HEADER: function() {
|
|
798
|
+
return TEXT_PLAIN_CONTENT_TYPE_HEADER;
|
|
799
|
+
},
|
|
788
800
|
UNSTABLE_REVALIDATE_RENAME_ERROR: function() {
|
|
789
801
|
return UNSTABLE_REVALIDATE_RENAME_ERROR;
|
|
790
802
|
},
|
|
@@ -793,8 +805,14 @@ var constants = {};
|
|
|
793
805
|
},
|
|
794
806
|
WEBPACK_RESOURCE_QUERIES: function() {
|
|
795
807
|
return WEBPACK_RESOURCE_QUERIES;
|
|
808
|
+
},
|
|
809
|
+
WEB_SOCKET_MAX_RECONNECTIONS: function() {
|
|
810
|
+
return WEB_SOCKET_MAX_RECONNECTIONS;
|
|
796
811
|
}
|
|
797
812
|
});
|
|
813
|
+
const TEXT_PLAIN_CONTENT_TYPE_HEADER = 'text/plain';
|
|
814
|
+
const HTML_CONTENT_TYPE_HEADER = 'text/html; charset=utf-8';
|
|
815
|
+
const JSON_CONTENT_TYPE_HEADER = 'application/json; charset=utf-8';
|
|
798
816
|
const NEXT_QUERY_PARAM_PREFIX = 'nxtP';
|
|
799
817
|
const NEXT_INTERCEPTION_MARKER_PREFIX = 'nxtI';
|
|
800
818
|
const MATCHED_PATH_HEADER = 'x-matched-path';
|
|
@@ -820,6 +838,8 @@ var constants = {};
|
|
|
820
838
|
const INFINITE_CACHE = 0xfffffffe;
|
|
821
839
|
const MIDDLEWARE_FILENAME = 'middleware';
|
|
822
840
|
const MIDDLEWARE_LOCATION_REGEXP = `(?:src/)?${MIDDLEWARE_FILENAME}`;
|
|
841
|
+
const PROXY_FILENAME = 'proxy';
|
|
842
|
+
const PROXY_LOCATION_REGEXP = `(?:src/)?${PROXY_FILENAME}`;
|
|
823
843
|
const INSTRUMENTATION_HOOK_FILENAME = 'instrumentation';
|
|
824
844
|
const PAGES_DIR_ALIAS = 'private-next-pages';
|
|
825
845
|
const DOT_NEXT_ALIAS = 'private-dot-next';
|
|
@@ -856,6 +876,7 @@ var constants = {};
|
|
|
856
876
|
experimentalEdge: 'experimental-edge',
|
|
857
877
|
nodejs: 'nodejs'
|
|
858
878
|
};
|
|
879
|
+
const WEB_SOCKET_MAX_RECONNECTIONS = 12;
|
|
859
880
|
/**
|
|
860
881
|
* The names of the webpack layers. These layers are the primitives for the
|
|
861
882
|
* webpack chunks.
|
|
@@ -1941,7 +1962,8 @@ var asyncLocalStorage = {};
|
|
|
1941
1962
|
}
|
|
1942
1963
|
return new FakeAsyncLocalStorage();
|
|
1943
1964
|
}
|
|
1944
|
-
function bindSnapshot(
|
|
1965
|
+
function bindSnapshot(// WARNING: Don't pass a named function to this argument! See: https://github.com/facebook/react/pull/34911
|
|
1966
|
+
fn) {
|
|
1945
1967
|
if (maybeGlobalAsyncLocalStorage) {
|
|
1946
1968
|
return maybeGlobalAsyncLocalStorage.bind(fn);
|
|
1947
1969
|
}
|
|
@@ -2093,9 +2115,15 @@ var appRouterHeaders = {exports: {}};
|
|
|
2093
2115
|
NEXT_HMR_REFRESH_HEADER: function() {
|
|
2094
2116
|
return NEXT_HMR_REFRESH_HEADER;
|
|
2095
2117
|
},
|
|
2118
|
+
NEXT_HTML_REQUEST_ID_HEADER: function() {
|
|
2119
|
+
return NEXT_HTML_REQUEST_ID_HEADER;
|
|
2120
|
+
},
|
|
2096
2121
|
NEXT_IS_PRERENDER_HEADER: function() {
|
|
2097
2122
|
return NEXT_IS_PRERENDER_HEADER;
|
|
2098
2123
|
},
|
|
2124
|
+
NEXT_REQUEST_ID_HEADER: function() {
|
|
2125
|
+
return NEXT_REQUEST_ID_HEADER;
|
|
2126
|
+
},
|
|
2099
2127
|
NEXT_REWRITTEN_PATH_HEADER: function() {
|
|
2100
2128
|
return NEXT_REWRITTEN_PATH_HEADER;
|
|
2101
2129
|
},
|
|
@@ -2127,14 +2155,14 @@ var appRouterHeaders = {exports: {}};
|
|
|
2127
2155
|
return RSC_HEADER;
|
|
2128
2156
|
}
|
|
2129
2157
|
});
|
|
2130
|
-
const RSC_HEADER = '
|
|
2131
|
-
const ACTION_HEADER = '
|
|
2132
|
-
const NEXT_ROUTER_STATE_TREE_HEADER = '
|
|
2133
|
-
const NEXT_ROUTER_PREFETCH_HEADER = '
|
|
2134
|
-
const NEXT_ROUTER_SEGMENT_PREFETCH_HEADER = '
|
|
2135
|
-
const NEXT_HMR_REFRESH_HEADER = '
|
|
2158
|
+
const RSC_HEADER = 'rsc';
|
|
2159
|
+
const ACTION_HEADER = 'next-action';
|
|
2160
|
+
const NEXT_ROUTER_STATE_TREE_HEADER = 'next-router-state-tree';
|
|
2161
|
+
const NEXT_ROUTER_PREFETCH_HEADER = 'next-router-prefetch';
|
|
2162
|
+
const NEXT_ROUTER_SEGMENT_PREFETCH_HEADER = 'next-router-segment-prefetch';
|
|
2163
|
+
const NEXT_HMR_REFRESH_HEADER = 'next-hmr-refresh';
|
|
2136
2164
|
const NEXT_HMR_REFRESH_HASH_COOKIE = '__next_hmr_refresh_hash__';
|
|
2137
|
-
const NEXT_URL = '
|
|
2165
|
+
const NEXT_URL = 'next-url';
|
|
2138
2166
|
const RSC_CONTENT_TYPE_HEADER = 'text/x-component';
|
|
2139
2167
|
const FLIGHT_HEADERS = [
|
|
2140
2168
|
RSC_HEADER,
|
|
@@ -2150,6 +2178,8 @@ var appRouterHeaders = {exports: {}};
|
|
|
2150
2178
|
const NEXT_REWRITTEN_QUERY_HEADER = 'x-nextjs-rewritten-query';
|
|
2151
2179
|
const NEXT_IS_PRERENDER_HEADER = 'x-nextjs-prerender';
|
|
2152
2180
|
const NEXT_ACTION_NOT_FOUND_HEADER = 'x-nextjs-action-not-found';
|
|
2181
|
+
const NEXT_REQUEST_ID_HEADER = 'x-nextjs-request-id';
|
|
2182
|
+
const NEXT_HTML_REQUEST_ID_HEADER = 'x-nextjs-html-request-id';
|
|
2153
2183
|
|
|
2154
2184
|
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
|
|
2155
2185
|
Object.defineProperty(exports.default, '__esModule', { value: true });
|
|
@@ -2162,6 +2192,28 @@ var appRouterHeaders = {exports: {}};
|
|
|
2162
2192
|
|
|
2163
2193
|
var appRouterHeadersExports = appRouterHeaders.exports;
|
|
2164
2194
|
|
|
2195
|
+
var invariantError = {};
|
|
2196
|
+
|
|
2197
|
+
(function (exports) {
|
|
2198
|
+
Object.defineProperty(exports, "__esModule", {
|
|
2199
|
+
value: true
|
|
2200
|
+
});
|
|
2201
|
+
Object.defineProperty(exports, "InvariantError", {
|
|
2202
|
+
enumerable: true,
|
|
2203
|
+
get: function() {
|
|
2204
|
+
return InvariantError;
|
|
2205
|
+
}
|
|
2206
|
+
});
|
|
2207
|
+
class InvariantError extends Error {
|
|
2208
|
+
constructor(message, options){
|
|
2209
|
+
super(`Invariant: ${message.endsWith('.') ? message : message + '.'} This is a bug in Next.js.`, options);
|
|
2210
|
+
this.name = 'InvariantError';
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
|
|
2215
|
+
} (invariantError));
|
|
2216
|
+
|
|
2165
2217
|
(function (exports) {
|
|
2166
2218
|
Object.defineProperty(exports, "__esModule", {
|
|
2167
2219
|
value: true
|
|
@@ -2173,12 +2225,12 @@ var appRouterHeadersExports = appRouterHeaders.exports;
|
|
|
2173
2225
|
});
|
|
2174
2226
|
}
|
|
2175
2227
|
_export(exports, {
|
|
2228
|
+
getCacheSignal: function() {
|
|
2229
|
+
return getCacheSignal;
|
|
2230
|
+
},
|
|
2176
2231
|
getDraftModeProviderForCacheScope: function() {
|
|
2177
2232
|
return getDraftModeProviderForCacheScope;
|
|
2178
2233
|
},
|
|
2179
|
-
getExpectedRequestStore: function() {
|
|
2180
|
-
return getExpectedRequestStore;
|
|
2181
|
-
},
|
|
2182
2234
|
getHmrRefreshHash: function() {
|
|
2183
2235
|
return getHmrRefreshHash;
|
|
2184
2236
|
},
|
|
@@ -2188,50 +2240,28 @@ var appRouterHeadersExports = appRouterHeaders.exports;
|
|
|
2188
2240
|
getRenderResumeDataCache: function() {
|
|
2189
2241
|
return getRenderResumeDataCache;
|
|
2190
2242
|
},
|
|
2243
|
+
getRuntimeStagePromise: function() {
|
|
2244
|
+
return getRuntimeStagePromise;
|
|
2245
|
+
},
|
|
2246
|
+
getServerComponentsHmrCache: function() {
|
|
2247
|
+
return getServerComponentsHmrCache;
|
|
2248
|
+
},
|
|
2249
|
+
isHmrRefresh: function() {
|
|
2250
|
+
return isHmrRefresh;
|
|
2251
|
+
},
|
|
2191
2252
|
throwForMissingRequestStore: function() {
|
|
2192
2253
|
return throwForMissingRequestStore;
|
|
2193
2254
|
},
|
|
2255
|
+
throwInvariantForMissingStore: function() {
|
|
2256
|
+
return throwInvariantForMissingStore;
|
|
2257
|
+
},
|
|
2194
2258
|
workUnitAsyncStorage: function() {
|
|
2195
2259
|
return _workunitasyncstorageinstance.workUnitAsyncStorageInstance;
|
|
2196
2260
|
}
|
|
2197
2261
|
});
|
|
2198
2262
|
const _workunitasyncstorageinstance = workUnitAsyncStorageInstance;
|
|
2199
2263
|
const _approuterheaders = appRouterHeadersExports;
|
|
2200
|
-
|
|
2201
|
-
const workUnitStore = _workunitasyncstorageinstance.workUnitAsyncStorageInstance.getStore();
|
|
2202
|
-
if (!workUnitStore) {
|
|
2203
|
-
throwForMissingRequestStore(callingExpression);
|
|
2204
|
-
}
|
|
2205
|
-
switch(workUnitStore.type){
|
|
2206
|
-
case 'request':
|
|
2207
|
-
return workUnitStore;
|
|
2208
|
-
case 'prerender':
|
|
2209
|
-
case 'prerender-client':
|
|
2210
|
-
case 'prerender-ppr':
|
|
2211
|
-
case 'prerender-legacy':
|
|
2212
|
-
// This should not happen because we should have checked it already.
|
|
2213
|
-
throw Object.defineProperty(new Error(`\`${callingExpression}\` cannot be called inside a prerender. This is a bug in Next.js.`), "__NEXT_ERROR_CODE", {
|
|
2214
|
-
value: "E401",
|
|
2215
|
-
enumerable: false,
|
|
2216
|
-
configurable: true
|
|
2217
|
-
});
|
|
2218
|
-
case 'cache':
|
|
2219
|
-
throw Object.defineProperty(new Error(`\`${callingExpression}\` cannot be called inside "use cache". Call it outside and pass an argument instead. Read more: https://nextjs.org/docs/messages/next-request-in-use-cache`), "__NEXT_ERROR_CODE", {
|
|
2220
|
-
value: "E37",
|
|
2221
|
-
enumerable: false,
|
|
2222
|
-
configurable: true
|
|
2223
|
-
});
|
|
2224
|
-
case 'unstable-cache':
|
|
2225
|
-
throw Object.defineProperty(new Error(`\`${callingExpression}\` cannot be called inside unstable_cache. Call it outside and pass an argument instead. Read more: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`), "__NEXT_ERROR_CODE", {
|
|
2226
|
-
value: "E69",
|
|
2227
|
-
enumerable: false,
|
|
2228
|
-
configurable: true
|
|
2229
|
-
});
|
|
2230
|
-
default:
|
|
2231
|
-
const _exhaustiveCheck = workUnitStore;
|
|
2232
|
-
return _exhaustiveCheck;
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2264
|
+
const _invarianterror = invariantError;
|
|
2235
2265
|
function throwForMissingRequestStore(callingExpression) {
|
|
2236
2266
|
throw Object.defineProperty(new Error(`\`${callingExpression}\` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context`), "__NEXT_ERROR_CODE", {
|
|
2237
2267
|
value: "E251",
|
|
@@ -2239,18 +2269,45 @@ var appRouterHeadersExports = appRouterHeaders.exports;
|
|
|
2239
2269
|
configurable: true
|
|
2240
2270
|
});
|
|
2241
2271
|
}
|
|
2272
|
+
function throwInvariantForMissingStore() {
|
|
2273
|
+
throw Object.defineProperty(new _invarianterror.InvariantError('Expected workUnitAsyncStorage to have a store.'), "__NEXT_ERROR_CODE", {
|
|
2274
|
+
value: "E696",
|
|
2275
|
+
enumerable: false,
|
|
2276
|
+
configurable: true
|
|
2277
|
+
});
|
|
2278
|
+
}
|
|
2242
2279
|
function getPrerenderResumeDataCache(workUnitStore) {
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2280
|
+
switch(workUnitStore.type){
|
|
2281
|
+
case 'prerender':
|
|
2282
|
+
case 'prerender-runtime':
|
|
2283
|
+
case 'prerender-ppr':
|
|
2284
|
+
return workUnitStore.prerenderResumeDataCache;
|
|
2285
|
+
case 'prerender-client':
|
|
2286
|
+
// TODO eliminate fetch caching in client scope and stop exposing this data
|
|
2287
|
+
// cache during SSR.
|
|
2288
|
+
return workUnitStore.prerenderResumeDataCache;
|
|
2289
|
+
case 'request':
|
|
2290
|
+
{
|
|
2291
|
+
// In dev, we might fill caches even during a dynamic request.
|
|
2292
|
+
if (workUnitStore.prerenderResumeDataCache) {
|
|
2293
|
+
return workUnitStore.prerenderResumeDataCache;
|
|
2294
|
+
}
|
|
2295
|
+
// fallthrough
|
|
2296
|
+
}
|
|
2297
|
+
case 'prerender-legacy':
|
|
2298
|
+
case 'cache':
|
|
2299
|
+
case 'private-cache':
|
|
2300
|
+
case 'unstable-cache':
|
|
2301
|
+
return null;
|
|
2302
|
+
default:
|
|
2303
|
+
return workUnitStore;
|
|
2246
2304
|
}
|
|
2247
|
-
return null;
|
|
2248
2305
|
}
|
|
2249
2306
|
function getRenderResumeDataCache(workUnitStore) {
|
|
2250
2307
|
switch(workUnitStore.type){
|
|
2251
2308
|
case 'request':
|
|
2252
|
-
return workUnitStore.renderResumeDataCache;
|
|
2253
2309
|
case 'prerender':
|
|
2310
|
+
case 'prerender-runtime':
|
|
2254
2311
|
case 'prerender-client':
|
|
2255
2312
|
if (workUnitStore.renderResumeDataCache) {
|
|
2256
2313
|
// If we are in a prerender, we might have a render resume data cache
|
|
@@ -2261,31 +2318,107 @@ var appRouterHeadersExports = appRouterHeaders.exports;
|
|
|
2261
2318
|
case 'prerender-ppr':
|
|
2262
2319
|
// Otherwise we return the mutable resume data cache here as an immutable
|
|
2263
2320
|
// version of the cache as it can also be used for reading.
|
|
2264
|
-
return workUnitStore.prerenderResumeDataCache;
|
|
2265
|
-
|
|
2321
|
+
return workUnitStore.prerenderResumeDataCache ?? null;
|
|
2322
|
+
case 'cache':
|
|
2323
|
+
case 'private-cache':
|
|
2324
|
+
case 'unstable-cache':
|
|
2325
|
+
case 'prerender-legacy':
|
|
2266
2326
|
return null;
|
|
2327
|
+
default:
|
|
2328
|
+
return workUnitStore;
|
|
2267
2329
|
}
|
|
2268
2330
|
}
|
|
2269
2331
|
function getHmrRefreshHash(workStore, workUnitStore) {
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2332
|
+
if (workStore.dev) {
|
|
2333
|
+
switch(workUnitStore.type){
|
|
2334
|
+
case 'cache':
|
|
2335
|
+
case 'private-cache':
|
|
2336
|
+
case 'prerender':
|
|
2337
|
+
case 'prerender-runtime':
|
|
2338
|
+
return workUnitStore.hmrRefreshHash;
|
|
2339
|
+
case 'request':
|
|
2340
|
+
var _workUnitStore_cookies_get;
|
|
2341
|
+
return (_workUnitStore_cookies_get = workUnitStore.cookies.get(_approuterheaders.NEXT_HMR_REFRESH_HASH_COOKIE)) == null ? void 0 : _workUnitStore_cookies_get.value;
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
return undefined;
|
|
2345
|
+
}
|
|
2346
|
+
function isHmrRefresh(workStore, workUnitStore) {
|
|
2347
|
+
if (workStore.dev) {
|
|
2348
|
+
switch(workUnitStore.type){
|
|
2349
|
+
case 'cache':
|
|
2350
|
+
case 'private-cache':
|
|
2351
|
+
case 'request':
|
|
2352
|
+
return workUnitStore.isHmrRefresh ?? false;
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
return false;
|
|
2356
|
+
}
|
|
2357
|
+
function getServerComponentsHmrCache(workStore, workUnitStore) {
|
|
2358
|
+
if (workStore.dev) {
|
|
2359
|
+
switch(workUnitStore.type){
|
|
2360
|
+
case 'cache':
|
|
2361
|
+
case 'private-cache':
|
|
2362
|
+
case 'request':
|
|
2363
|
+
return workUnitStore.serverComponentsHmrCache;
|
|
2364
|
+
}
|
|
2273
2365
|
}
|
|
2274
|
-
return
|
|
2366
|
+
return undefined;
|
|
2275
2367
|
}
|
|
2276
2368
|
function getDraftModeProviderForCacheScope(workStore, workUnitStore) {
|
|
2277
2369
|
if (workStore.isDraftMode) {
|
|
2278
2370
|
switch(workUnitStore.type){
|
|
2279
2371
|
case 'cache':
|
|
2372
|
+
case 'private-cache':
|
|
2280
2373
|
case 'unstable-cache':
|
|
2374
|
+
case 'prerender-runtime':
|
|
2281
2375
|
case 'request':
|
|
2282
2376
|
return workUnitStore.draftMode;
|
|
2283
|
-
default:
|
|
2284
|
-
return undefined;
|
|
2285
2377
|
}
|
|
2286
2378
|
}
|
|
2287
2379
|
return undefined;
|
|
2288
2380
|
}
|
|
2381
|
+
function getCacheSignal(workUnitStore) {
|
|
2382
|
+
switch(workUnitStore.type){
|
|
2383
|
+
case 'prerender':
|
|
2384
|
+
case 'prerender-client':
|
|
2385
|
+
case 'prerender-runtime':
|
|
2386
|
+
return workUnitStore.cacheSignal;
|
|
2387
|
+
case 'request':
|
|
2388
|
+
{
|
|
2389
|
+
// In dev, we might fill caches even during a dynamic request.
|
|
2390
|
+
if (workUnitStore.cacheSignal) {
|
|
2391
|
+
return workUnitStore.cacheSignal;
|
|
2392
|
+
}
|
|
2393
|
+
// fallthrough
|
|
2394
|
+
}
|
|
2395
|
+
case 'prerender-ppr':
|
|
2396
|
+
case 'prerender-legacy':
|
|
2397
|
+
case 'cache':
|
|
2398
|
+
case 'private-cache':
|
|
2399
|
+
case 'unstable-cache':
|
|
2400
|
+
return null;
|
|
2401
|
+
default:
|
|
2402
|
+
return workUnitStore;
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
function getRuntimeStagePromise(workUnitStore) {
|
|
2406
|
+
switch(workUnitStore.type){
|
|
2407
|
+
case 'prerender-runtime':
|
|
2408
|
+
case 'private-cache':
|
|
2409
|
+
return workUnitStore.runtimeStagePromise;
|
|
2410
|
+
case 'prerender':
|
|
2411
|
+
case 'prerender-client':
|
|
2412
|
+
case 'prerender-ppr':
|
|
2413
|
+
case 'prerender-legacy':
|
|
2414
|
+
case 'request':
|
|
2415
|
+
case 'cache':
|
|
2416
|
+
case 'unstable-cache':
|
|
2417
|
+
return null;
|
|
2418
|
+
default:
|
|
2419
|
+
return workUnitStore;
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2289
2422
|
|
|
2290
2423
|
|
|
2291
2424
|
} (workUnitAsyncStorage_external));
|
|
@@ -4172,7 +4305,7 @@ var hooksServerContext = {exports: {}};
|
|
|
4172
4305
|
const DYNAMIC_ERROR_CODE = 'DYNAMIC_SERVER_USAGE';
|
|
4173
4306
|
class DynamicServerError extends Error {
|
|
4174
4307
|
constructor(description){
|
|
4175
|
-
super(
|
|
4308
|
+
super(`Dynamic server usage: ${description}`), this.description = description, this.digest = DYNAMIC_ERROR_CODE;
|
|
4176
4309
|
}
|
|
4177
4310
|
}
|
|
4178
4311
|
function isDynamicServerError(err) {
|
|
@@ -4253,6 +4386,9 @@ var dynamicRenderingUtils = {};
|
|
|
4253
4386
|
isHangingPromiseRejectionError: function() {
|
|
4254
4387
|
return isHangingPromiseRejectionError;
|
|
4255
4388
|
},
|
|
4389
|
+
makeDevtoolsIOAwarePromise: function() {
|
|
4390
|
+
return makeDevtoolsIOAwarePromise;
|
|
4391
|
+
},
|
|
4256
4392
|
makeHangingPromise: function() {
|
|
4257
4393
|
return makeHangingPromise;
|
|
4258
4394
|
}
|
|
@@ -4265,17 +4401,17 @@ var dynamicRenderingUtils = {};
|
|
|
4265
4401
|
}
|
|
4266
4402
|
const HANGING_PROMISE_REJECTION = 'HANGING_PROMISE_REJECTION';
|
|
4267
4403
|
class HangingPromiseRejectionError extends Error {
|
|
4268
|
-
constructor(expression){
|
|
4269
|
-
super(`During prerendering, ${expression} rejects when the prerender is complete. Typically these errors are handled by React but if you move ${expression} to a different context by using \`setTimeout\`, \`after\`, or similar functions you may observe this error and you should handle it in that context.`), this.expression = expression, this.digest = HANGING_PROMISE_REJECTION;
|
|
4404
|
+
constructor(route, expression){
|
|
4405
|
+
super(`During prerendering, ${expression} rejects when the prerender is complete. Typically these errors are handled by React but if you move ${expression} to a different context by using \`setTimeout\`, \`after\`, or similar functions you may observe this error and you should handle it in that context. This occurred at route "${route}".`), this.route = route, this.expression = expression, this.digest = HANGING_PROMISE_REJECTION;
|
|
4270
4406
|
}
|
|
4271
4407
|
}
|
|
4272
4408
|
const abortListenersBySignal = new WeakMap();
|
|
4273
|
-
function makeHangingPromise(signal, expression) {
|
|
4409
|
+
function makeHangingPromise(signal, route, expression) {
|
|
4274
4410
|
if (signal.aborted) {
|
|
4275
|
-
return Promise.reject(new HangingPromiseRejectionError(expression));
|
|
4411
|
+
return Promise.reject(new HangingPromiseRejectionError(route, expression));
|
|
4276
4412
|
} else {
|
|
4277
4413
|
const hangingPromise = new Promise((_, reject)=>{
|
|
4278
|
-
const boundRejection = reject.bind(null, new HangingPromiseRejectionError(expression));
|
|
4414
|
+
const boundRejection = reject.bind(null, new HangingPromiseRejectionError(route, expression));
|
|
4279
4415
|
let currentListeners = abortListenersBySignal.get(signal);
|
|
4280
4416
|
if (currentListeners) {
|
|
4281
4417
|
currentListeners.push(boundRejection);
|
|
@@ -4301,11 +4437,25 @@ var dynamicRenderingUtils = {};
|
|
|
4301
4437
|
}
|
|
4302
4438
|
}
|
|
4303
4439
|
function ignoreReject() {}
|
|
4440
|
+
function makeDevtoolsIOAwarePromise(underlying, requestStore, stage) {
|
|
4441
|
+
if (requestStore.stagedRendering) {
|
|
4442
|
+
// We resolve each stage in a timeout, so React DevTools will pick this up as IO.
|
|
4443
|
+
return requestStore.stagedRendering.delayUntilStage(stage, undefined, underlying);
|
|
4444
|
+
}
|
|
4445
|
+
// in React DevTools if we resolve in a setTimeout we will observe
|
|
4446
|
+
// the promise resolution as something that can suspend a boundary or root.
|
|
4447
|
+
return new Promise((resolve)=>{
|
|
4448
|
+
// Must use setTimeout to be considered IO React DevTools. setImmediate will not work.
|
|
4449
|
+
setTimeout(()=>{
|
|
4450
|
+
resolve(underlying);
|
|
4451
|
+
}, 0);
|
|
4452
|
+
});
|
|
4453
|
+
}
|
|
4304
4454
|
|
|
4305
4455
|
|
|
4306
4456
|
} (dynamicRenderingUtils));
|
|
4307
4457
|
|
|
4308
|
-
var
|
|
4458
|
+
var boundaryConstants = {};
|
|
4309
4459
|
|
|
4310
4460
|
(function (exports) {
|
|
4311
4461
|
Object.defineProperty(exports, "__esModule", {
|
|
@@ -4324,6 +4474,9 @@ var metadataConstants = {};
|
|
|
4324
4474
|
OUTLET_BOUNDARY_NAME: function() {
|
|
4325
4475
|
return OUTLET_BOUNDARY_NAME;
|
|
4326
4476
|
},
|
|
4477
|
+
ROOT_LAYOUT_BOUNDARY_NAME: function() {
|
|
4478
|
+
return ROOT_LAYOUT_BOUNDARY_NAME;
|
|
4479
|
+
},
|
|
4327
4480
|
VIEWPORT_BOUNDARY_NAME: function() {
|
|
4328
4481
|
return VIEWPORT_BOUNDARY_NAME;
|
|
4329
4482
|
}
|
|
@@ -4331,9 +4484,10 @@ var metadataConstants = {};
|
|
|
4331
4484
|
const METADATA_BOUNDARY_NAME = '__next_metadata_boundary__';
|
|
4332
4485
|
const VIEWPORT_BOUNDARY_NAME = '__next_viewport_boundary__';
|
|
4333
4486
|
const OUTLET_BOUNDARY_NAME = '__next_outlet_boundary__';
|
|
4487
|
+
const ROOT_LAYOUT_BOUNDARY_NAME = '__next_root_layout_boundary__';
|
|
4334
4488
|
|
|
4335
4489
|
|
|
4336
|
-
} (
|
|
4490
|
+
} (boundaryConstants));
|
|
4337
4491
|
|
|
4338
4492
|
var scheduler = {};
|
|
4339
4493
|
|
|
@@ -4397,6 +4551,198 @@ var scheduler = {};
|
|
|
4397
4551
|
|
|
4398
4552
|
} (scheduler));
|
|
4399
4553
|
|
|
4554
|
+
var bailoutToCsr = {};
|
|
4555
|
+
|
|
4556
|
+
(function (exports) {
|
|
4557
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4558
|
+
value: true
|
|
4559
|
+
});
|
|
4560
|
+
function _export(target, all) {
|
|
4561
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
4562
|
+
enumerable: true,
|
|
4563
|
+
get: all[name]
|
|
4564
|
+
});
|
|
4565
|
+
}
|
|
4566
|
+
_export(exports, {
|
|
4567
|
+
BailoutToCSRError: function() {
|
|
4568
|
+
return BailoutToCSRError;
|
|
4569
|
+
},
|
|
4570
|
+
isBailoutToCSRError: function() {
|
|
4571
|
+
return isBailoutToCSRError;
|
|
4572
|
+
}
|
|
4573
|
+
});
|
|
4574
|
+
const BAILOUT_TO_CSR = 'BAILOUT_TO_CLIENT_SIDE_RENDERING';
|
|
4575
|
+
class BailoutToCSRError extends Error {
|
|
4576
|
+
constructor(reason){
|
|
4577
|
+
super(`Bail out to client-side rendering: ${reason}`), this.reason = reason, this.digest = BAILOUT_TO_CSR;
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
function isBailoutToCSRError(err) {
|
|
4581
|
+
if (typeof err !== 'object' || err === null || !('digest' in err)) {
|
|
4582
|
+
return false;
|
|
4583
|
+
}
|
|
4584
|
+
return err.digest === BAILOUT_TO_CSR;
|
|
4585
|
+
}
|
|
4586
|
+
|
|
4587
|
+
|
|
4588
|
+
} (bailoutToCsr));
|
|
4589
|
+
|
|
4590
|
+
var stagedRendering = {};
|
|
4591
|
+
|
|
4592
|
+
var promiseWithResolvers = {};
|
|
4593
|
+
|
|
4594
|
+
(function (exports) {
|
|
4595
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4596
|
+
value: true
|
|
4597
|
+
});
|
|
4598
|
+
Object.defineProperty(exports, "createPromiseWithResolvers", {
|
|
4599
|
+
enumerable: true,
|
|
4600
|
+
get: function() {
|
|
4601
|
+
return createPromiseWithResolvers;
|
|
4602
|
+
}
|
|
4603
|
+
});
|
|
4604
|
+
function createPromiseWithResolvers() {
|
|
4605
|
+
// Shim of Stage 4 Promise.withResolvers proposal
|
|
4606
|
+
let resolve;
|
|
4607
|
+
let reject;
|
|
4608
|
+
const promise = new Promise((res, rej)=>{
|
|
4609
|
+
resolve = res;
|
|
4610
|
+
reject = rej;
|
|
4611
|
+
});
|
|
4612
|
+
return {
|
|
4613
|
+
resolve: resolve,
|
|
4614
|
+
reject: reject,
|
|
4615
|
+
promise
|
|
4616
|
+
};
|
|
4617
|
+
}
|
|
4618
|
+
|
|
4619
|
+
|
|
4620
|
+
} (promiseWithResolvers));
|
|
4621
|
+
|
|
4622
|
+
(function (exports) {
|
|
4623
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4624
|
+
value: true
|
|
4625
|
+
});
|
|
4626
|
+
function _export(target, all) {
|
|
4627
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
4628
|
+
enumerable: true,
|
|
4629
|
+
get: all[name]
|
|
4630
|
+
});
|
|
4631
|
+
}
|
|
4632
|
+
_export(exports, {
|
|
4633
|
+
RenderStage: function() {
|
|
4634
|
+
return RenderStage;
|
|
4635
|
+
},
|
|
4636
|
+
StagedRenderingController: function() {
|
|
4637
|
+
return StagedRenderingController;
|
|
4638
|
+
}
|
|
4639
|
+
});
|
|
4640
|
+
const _invarianterror = invariantError;
|
|
4641
|
+
const _promisewithresolvers = promiseWithResolvers;
|
|
4642
|
+
var RenderStage = /*#__PURE__*/ function(RenderStage) {
|
|
4643
|
+
RenderStage[RenderStage["Static"] = 1] = "Static";
|
|
4644
|
+
RenderStage[RenderStage["Runtime"] = 2] = "Runtime";
|
|
4645
|
+
RenderStage[RenderStage["Dynamic"] = 3] = "Dynamic";
|
|
4646
|
+
return RenderStage;
|
|
4647
|
+
}({});
|
|
4648
|
+
class StagedRenderingController {
|
|
4649
|
+
constructor(abortSignal = null){
|
|
4650
|
+
this.abortSignal = abortSignal;
|
|
4651
|
+
this.currentStage = 1;
|
|
4652
|
+
this.runtimeStagePromise = (0, _promisewithresolvers.createPromiseWithResolvers)();
|
|
4653
|
+
this.dynamicStagePromise = (0, _promisewithresolvers.createPromiseWithResolvers)();
|
|
4654
|
+
if (abortSignal) {
|
|
4655
|
+
abortSignal.addEventListener('abort', ()=>{
|
|
4656
|
+
const { reason } = abortSignal;
|
|
4657
|
+
if (this.currentStage < 2) {
|
|
4658
|
+
this.runtimeStagePromise.promise.catch(ignoreReject) // avoid unhandled rejections
|
|
4659
|
+
;
|
|
4660
|
+
this.runtimeStagePromise.reject(reason);
|
|
4661
|
+
}
|
|
4662
|
+
if (this.currentStage < 3) {
|
|
4663
|
+
this.dynamicStagePromise.promise.catch(ignoreReject) // avoid unhandled rejections
|
|
4664
|
+
;
|
|
4665
|
+
this.dynamicStagePromise.reject(reason);
|
|
4666
|
+
}
|
|
4667
|
+
}, {
|
|
4668
|
+
once: true
|
|
4669
|
+
});
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4672
|
+
advanceStage(stage) {
|
|
4673
|
+
// If we're already at the target stage or beyond, do nothing.
|
|
4674
|
+
// (this can happen e.g. if sync IO advanced us to the dynamic stage)
|
|
4675
|
+
if (this.currentStage >= stage) {
|
|
4676
|
+
return;
|
|
4677
|
+
}
|
|
4678
|
+
this.currentStage = stage;
|
|
4679
|
+
// Note that we might be going directly from Static to Dynamic,
|
|
4680
|
+
// so we need to resolve the runtime stage as well.
|
|
4681
|
+
if (stage >= 2) {
|
|
4682
|
+
this.runtimeStagePromise.resolve();
|
|
4683
|
+
}
|
|
4684
|
+
if (stage >= 3) {
|
|
4685
|
+
this.dynamicStagePromise.resolve();
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
getStagePromise(stage) {
|
|
4689
|
+
switch(stage){
|
|
4690
|
+
case 2:
|
|
4691
|
+
{
|
|
4692
|
+
return this.runtimeStagePromise.promise;
|
|
4693
|
+
}
|
|
4694
|
+
case 3:
|
|
4695
|
+
{
|
|
4696
|
+
return this.dynamicStagePromise.promise;
|
|
4697
|
+
}
|
|
4698
|
+
default:
|
|
4699
|
+
{
|
|
4700
|
+
throw Object.defineProperty(new _invarianterror.InvariantError(`Invalid render stage: ${stage}`), "__NEXT_ERROR_CODE", {
|
|
4701
|
+
value: "E881",
|
|
4702
|
+
enumerable: false,
|
|
4703
|
+
configurable: true
|
|
4704
|
+
});
|
|
4705
|
+
}
|
|
4706
|
+
}
|
|
4707
|
+
}
|
|
4708
|
+
waitForStage(stage) {
|
|
4709
|
+
return this.getStagePromise(stage);
|
|
4710
|
+
}
|
|
4711
|
+
delayUntilStage(stage, displayName, resolvedValue) {
|
|
4712
|
+
const ioTriggerPromise = this.getStagePromise(stage);
|
|
4713
|
+
const promise = makeDevtoolsIOPromiseFromIOTrigger(ioTriggerPromise, displayName, resolvedValue);
|
|
4714
|
+
// Analogously to `makeHangingPromise`, we might reject this promise if the signal is invoked.
|
|
4715
|
+
// (e.g. in the case where we don't want want the render to proceed to the dynamic stage and abort it).
|
|
4716
|
+
// We shouldn't consider this an unhandled rejection, so we attach a noop catch handler here to suppress this warning.
|
|
4717
|
+
if (this.abortSignal) {
|
|
4718
|
+
promise.catch(ignoreReject);
|
|
4719
|
+
}
|
|
4720
|
+
return promise;
|
|
4721
|
+
}
|
|
4722
|
+
}
|
|
4723
|
+
function ignoreReject() {}
|
|
4724
|
+
// TODO(restart-on-cache-miss): the layering of `delayUntilStage`,
|
|
4725
|
+
// `makeDevtoolsIOPromiseFromIOTrigger` and and `makeDevtoolsIOAwarePromise`
|
|
4726
|
+
// is confusing, we should clean it up.
|
|
4727
|
+
function makeDevtoolsIOPromiseFromIOTrigger(ioTrigger, displayName, resolvedValue) {
|
|
4728
|
+
// If we create a `new Promise` and give it a displayName
|
|
4729
|
+
// (with no userspace code above us in the stack)
|
|
4730
|
+
// React Devtools will use it as the IO cause when determining "suspended by".
|
|
4731
|
+
// In particular, it should shadow any inner IO that resolved/rejected the promise
|
|
4732
|
+
// (in case of staged rendering, this will be the `setTimeout` that triggers the relevant stage)
|
|
4733
|
+
const promise = new Promise((resolve, reject)=>{
|
|
4734
|
+
ioTrigger.then(resolve.bind(null, resolvedValue), reject);
|
|
4735
|
+
});
|
|
4736
|
+
if (displayName !== undefined) {
|
|
4737
|
+
// @ts-expect-error
|
|
4738
|
+
promise.displayName = displayName;
|
|
4739
|
+
}
|
|
4740
|
+
return promise;
|
|
4741
|
+
}
|
|
4742
|
+
|
|
4743
|
+
|
|
4744
|
+
} (stagedRendering));
|
|
4745
|
+
|
|
4400
4746
|
/**
|
|
4401
4747
|
* The functions provided by this module are used to communicate certain properties
|
|
4402
4748
|
* about the currently running code so that Next.js can make decisions on how to handle
|
|
@@ -4460,8 +4806,11 @@ var scheduler = {};
|
|
|
4460
4806
|
createHangingInputAbortSignal: function() {
|
|
4461
4807
|
return createHangingInputAbortSignal;
|
|
4462
4808
|
},
|
|
4463
|
-
|
|
4464
|
-
return
|
|
4809
|
+
createRenderInBrowserAbortSignal: function() {
|
|
4810
|
+
return createRenderInBrowserAbortSignal;
|
|
4811
|
+
},
|
|
4812
|
+
delayUntilRuntimeStage: function() {
|
|
4813
|
+
return delayUntilRuntimeStage;
|
|
4465
4814
|
},
|
|
4466
4815
|
formatDynamicAPIAccesses: function() {
|
|
4467
4816
|
return formatDynamicAPIAccesses;
|
|
@@ -4475,6 +4824,9 @@ var scheduler = {};
|
|
|
4475
4824
|
isPrerenderInterruptedError: function() {
|
|
4476
4825
|
return isPrerenderInterruptedError;
|
|
4477
4826
|
},
|
|
4827
|
+
logDisallowedDynamicError: function() {
|
|
4828
|
+
return logDisallowedDynamicError;
|
|
4829
|
+
},
|
|
4478
4830
|
markCurrentScopeAsDynamic: function() {
|
|
4479
4831
|
return markCurrentScopeAsDynamic;
|
|
4480
4832
|
},
|
|
@@ -4493,17 +4845,14 @@ var scheduler = {};
|
|
|
4493
4845
|
trackDynamicDataInDynamicRender: function() {
|
|
4494
4846
|
return trackDynamicDataInDynamicRender;
|
|
4495
4847
|
},
|
|
4496
|
-
trackFallbackParamAccessed: function() {
|
|
4497
|
-
return trackFallbackParamAccessed;
|
|
4498
|
-
},
|
|
4499
4848
|
trackSynchronousPlatformIOAccessInDev: function() {
|
|
4500
4849
|
return trackSynchronousPlatformIOAccessInDev;
|
|
4501
4850
|
},
|
|
4502
|
-
trackSynchronousRequestDataAccessInDev: function() {
|
|
4503
|
-
return trackSynchronousRequestDataAccessInDev;
|
|
4504
|
-
},
|
|
4505
4851
|
useDynamicRouteParams: function() {
|
|
4506
4852
|
return useDynamicRouteParams;
|
|
4853
|
+
},
|
|
4854
|
+
useDynamicSearchParams: function() {
|
|
4855
|
+
return useDynamicSearchParams;
|
|
4507
4856
|
}
|
|
4508
4857
|
});
|
|
4509
4858
|
const _react = /*#__PURE__*/ _interop_require_default(reactExports);
|
|
@@ -4512,8 +4861,11 @@ var scheduler = {};
|
|
|
4512
4861
|
const _workunitasyncstorageexternal = workUnitAsyncStorage_external;
|
|
4513
4862
|
const _workasyncstorageexternal = workAsyncStorage_external;
|
|
4514
4863
|
const _dynamicrenderingutils = dynamicRenderingUtils;
|
|
4515
|
-
const
|
|
4864
|
+
const _boundaryconstants = boundaryConstants;
|
|
4516
4865
|
const _scheduler = scheduler;
|
|
4866
|
+
const _bailouttocsr = bailoutToCsr;
|
|
4867
|
+
const _invarianterror = invariantError;
|
|
4868
|
+
const _stagedrendering = stagedRendering;
|
|
4517
4869
|
function _interop_require_default(obj) {
|
|
4518
4870
|
return obj && obj.__esModule ? obj : {
|
|
4519
4871
|
default: obj
|
|
@@ -4542,11 +4894,17 @@ var scheduler = {};
|
|
|
4542
4894
|
}
|
|
4543
4895
|
function markCurrentScopeAsDynamic(store, workUnitStore, expression) {
|
|
4544
4896
|
if (workUnitStore) {
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4897
|
+
switch(workUnitStore.type){
|
|
4898
|
+
case 'cache':
|
|
4899
|
+
case 'unstable-cache':
|
|
4900
|
+
// Inside cache scopes, marking a scope as dynamic has no effect,
|
|
4901
|
+
// because the outer cache scope creates a cache boundary. This is
|
|
4902
|
+
// subtly different from reading a dynamic data source, which is
|
|
4903
|
+
// forbidden inside a cache scope.
|
|
4904
|
+
return;
|
|
4905
|
+
case 'private-cache':
|
|
4906
|
+
// A private cache scope is already dynamic by definition.
|
|
4907
|
+
return;
|
|
4550
4908
|
}
|
|
4551
4909
|
}
|
|
4552
4910
|
// If we're forcing dynamic rendering or we're forcing static rendering, we
|
|
@@ -4561,29 +4919,29 @@ var scheduler = {};
|
|
|
4561
4919
|
});
|
|
4562
4920
|
}
|
|
4563
4921
|
if (workUnitStore) {
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4922
|
+
switch(workUnitStore.type){
|
|
4923
|
+
case 'prerender-ppr':
|
|
4924
|
+
return postponeWithTracking(store.route, expression, workUnitStore.dynamicTracking);
|
|
4925
|
+
case 'prerender-legacy':
|
|
4926
|
+
workUnitStore.revalidate = 0;
|
|
4927
|
+
// We aren't prerendering, but we are generating a static page. We need
|
|
4928
|
+
// to bail out of static generation.
|
|
4929
|
+
const err = Object.defineProperty(new _hooksservercontext.DynamicServerError(`Route ${store.route} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`), "__NEXT_ERROR_CODE", {
|
|
4930
|
+
value: "E550",
|
|
4931
|
+
enumerable: false,
|
|
4932
|
+
configurable: true
|
|
4933
|
+
});
|
|
4934
|
+
store.dynamicUsageDescription = expression;
|
|
4935
|
+
store.dynamicUsageStack = err.stack;
|
|
4936
|
+
throw err;
|
|
4937
|
+
case 'request':
|
|
4938
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4939
|
+
workUnitStore.usedDynamic = true;
|
|
4940
|
+
}
|
|
4941
|
+
break;
|
|
4579
4942
|
}
|
|
4580
4943
|
}
|
|
4581
4944
|
}
|
|
4582
|
-
function trackFallbackParamAccessed(store, expression) {
|
|
4583
|
-
const prerenderStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
4584
|
-
if (!prerenderStore || prerenderStore.type !== 'prerender-ppr') return;
|
|
4585
|
-
postponeWithTracking(store.route, expression, prerenderStore.dynamicTracking);
|
|
4586
|
-
}
|
|
4587
4945
|
function throwToInterruptStaticGeneration(expression, store, prerenderStore) {
|
|
4588
4946
|
// We aren't prerendering but we are generating a static page. We need to bail out of static generation
|
|
4589
4947
|
const err = Object.defineProperty(new _hooksservercontext.DynamicServerError(`Route ${store.route} couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`), "__NEXT_ERROR_CODE", {
|
|
@@ -4596,21 +4954,29 @@ var scheduler = {};
|
|
|
4596
4954
|
store.dynamicUsageStack = err.stack;
|
|
4597
4955
|
throw err;
|
|
4598
4956
|
}
|
|
4599
|
-
function trackDynamicDataInDynamicRender(
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
//
|
|
4957
|
+
function trackDynamicDataInDynamicRender(workUnitStore) {
|
|
4958
|
+
switch(workUnitStore.type){
|
|
4959
|
+
case 'cache':
|
|
4960
|
+
case 'unstable-cache':
|
|
4961
|
+
// Inside cache scopes, marking a scope as dynamic has no effect,
|
|
4962
|
+
// because the outer cache scope creates a cache boundary. This is
|
|
4963
|
+
// subtly different from reading a dynamic data source, which is
|
|
4604
4964
|
// forbidden inside a cache scope.
|
|
4605
4965
|
return;
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4966
|
+
case 'private-cache':
|
|
4967
|
+
// A private cache scope is already dynamic by definition.
|
|
4968
|
+
return;
|
|
4969
|
+
case 'prerender':
|
|
4970
|
+
case 'prerender-runtime':
|
|
4971
|
+
case 'prerender-legacy':
|
|
4972
|
+
case 'prerender-ppr':
|
|
4973
|
+
case 'prerender-client':
|
|
4974
|
+
break;
|
|
4975
|
+
case 'request':
|
|
4976
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
4977
|
+
workUnitStore.usedDynamic = true;
|
|
4978
|
+
}
|
|
4979
|
+
break;
|
|
4614
4980
|
}
|
|
4615
4981
|
}
|
|
4616
4982
|
function abortOnSynchronousDynamicDataAccess(route, expression, prerenderStore) {
|
|
@@ -4642,8 +5008,12 @@ var scheduler = {};
|
|
|
4642
5008
|
}
|
|
4643
5009
|
function trackSynchronousPlatformIOAccessInDev(requestStore) {
|
|
4644
5010
|
// We don't actually have a controller to abort but we do the semantic equivalent by
|
|
4645
|
-
// advancing the request store out of prerender
|
|
4646
|
-
requestStore.
|
|
5011
|
+
// advancing the request store out of the prerender stage
|
|
5012
|
+
if (requestStore.stagedRendering) {
|
|
5013
|
+
// TODO: error for sync IO in the runtime stage
|
|
5014
|
+
// (which is not currently covered by the validation render in `spawnDynamicValidationInDev`)
|
|
5015
|
+
requestStore.stagedRendering.advanceStage(_stagedrendering.RenderStage.Dynamic);
|
|
5016
|
+
}
|
|
4647
5017
|
}
|
|
4648
5018
|
function abortAndThrowOnSynchronousRequestDataAccess(route, expression, errorWithStack, prerenderStore) {
|
|
4649
5019
|
const prerenderSignal = prerenderStore.controller.signal;
|
|
@@ -4667,7 +5037,6 @@ var scheduler = {};
|
|
|
4667
5037
|
}
|
|
4668
5038
|
throw createPrerenderInterruptedError(`Route ${route} needs to bail out of prerendering at this point because it used ${expression}.`);
|
|
4669
5039
|
}
|
|
4670
|
-
const trackSynchronousRequestDataAccessInDev = trackSynchronousPlatformIOAccessInDev;
|
|
4671
5040
|
function Postpone({ reason, route }) {
|
|
4672
5041
|
const prerenderStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
4673
5042
|
const dynamicTracking = prerenderStore && prerenderStore.type === 'prerender-ppr' ? prerenderStore.dynamicTracking : null;
|
|
@@ -4759,35 +5128,57 @@ var scheduler = {};
|
|
|
4759
5128
|
});
|
|
4760
5129
|
}
|
|
4761
5130
|
}
|
|
4762
|
-
function
|
|
4763
|
-
assertPostpone();
|
|
5131
|
+
function createRenderInBrowserAbortSignal() {
|
|
4764
5132
|
const controller = new AbortController();
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
}
|
|
5133
|
+
controller.abort(Object.defineProperty(new _bailouttocsr.BailoutToCSRError('Render in Browser'), "__NEXT_ERROR_CODE", {
|
|
5134
|
+
value: "E721",
|
|
5135
|
+
enumerable: false,
|
|
5136
|
+
configurable: true
|
|
5137
|
+
}));
|
|
4771
5138
|
return controller.signal;
|
|
4772
5139
|
}
|
|
4773
5140
|
function createHangingInputAbortSignal(workUnitStore) {
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
5141
|
+
switch(workUnitStore.type){
|
|
5142
|
+
case 'prerender':
|
|
5143
|
+
case 'prerender-runtime':
|
|
5144
|
+
const controller = new AbortController();
|
|
5145
|
+
if (workUnitStore.cacheSignal) {
|
|
5146
|
+
// If we have a cacheSignal it means we're in a prospective render. If
|
|
5147
|
+
// the input we're waiting on is coming from another cache, we do want
|
|
5148
|
+
// to wait for it so that we can resolve this cache entry too.
|
|
5149
|
+
workUnitStore.cacheSignal.inputReady().then(()=>{
|
|
5150
|
+
controller.abort();
|
|
5151
|
+
});
|
|
5152
|
+
} else {
|
|
5153
|
+
// Otherwise we're in the final render and we should already have all
|
|
5154
|
+
// our caches filled.
|
|
5155
|
+
// If the prerender uses stages, we have wait until the runtime stage,
|
|
5156
|
+
// at which point all runtime inputs will be resolved.
|
|
5157
|
+
// (otherwise, a runtime prerender might consider `cookies()` hanging
|
|
5158
|
+
// even though they'd resolve in the next task.)
|
|
5159
|
+
//
|
|
5160
|
+
// We might still be waiting on some microtasks so we
|
|
5161
|
+
// wait one tick before giving up. When we give up, we still want to
|
|
5162
|
+
// render the content of this cache as deeply as we can so that we can
|
|
5163
|
+
// suspend as deeply as possible in the tree or not at all if we don't
|
|
5164
|
+
// end up waiting for the input.
|
|
5165
|
+
const runtimeStagePromise = (0, _workunitasyncstorageexternal.getRuntimeStagePromise)(workUnitStore);
|
|
5166
|
+
if (runtimeStagePromise) {
|
|
5167
|
+
runtimeStagePromise.then(()=>(0, _scheduler.scheduleOnNextTick)(()=>controller.abort()));
|
|
5168
|
+
} else {
|
|
5169
|
+
(0, _scheduler.scheduleOnNextTick)(()=>controller.abort());
|
|
5170
|
+
}
|
|
5171
|
+
}
|
|
5172
|
+
return controller.signal;
|
|
5173
|
+
case 'prerender-client':
|
|
5174
|
+
case 'prerender-ppr':
|
|
5175
|
+
case 'prerender-legacy':
|
|
5176
|
+
case 'request':
|
|
5177
|
+
case 'cache':
|
|
5178
|
+
case 'private-cache':
|
|
5179
|
+
case 'unstable-cache':
|
|
5180
|
+
return undefined;
|
|
4789
5181
|
}
|
|
4790
|
-
return controller.signal;
|
|
4791
5182
|
}
|
|
4792
5183
|
function annotateDynamicAccess(expression, prerenderStore) {
|
|
4793
5184
|
const dynamicTracking = prerenderStore.dynamicTracking;
|
|
@@ -4800,31 +5191,111 @@ var scheduler = {};
|
|
|
4800
5191
|
}
|
|
4801
5192
|
function useDynamicRouteParams(expression) {
|
|
4802
5193
|
const workStore = _workasyncstorageexternal.workAsyncStorage.getStore();
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
5194
|
+
const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
5195
|
+
if (workStore && workUnitStore) {
|
|
5196
|
+
switch(workUnitStore.type){
|
|
5197
|
+
case 'prerender-client':
|
|
5198
|
+
case 'prerender':
|
|
5199
|
+
{
|
|
5200
|
+
const fallbackParams = workUnitStore.fallbackRouteParams;
|
|
5201
|
+
if (fallbackParams && fallbackParams.size > 0) {
|
|
5202
|
+
// We are in a prerender with cacheComponents semantics. We are going to
|
|
5203
|
+
// hang here and never resolve. This will cause the currently
|
|
5204
|
+
// rendering component to effectively be a dynamic hole.
|
|
5205
|
+
_react.default.use((0, _dynamicrenderingutils.makeHangingPromise)(workUnitStore.renderSignal, workStore.route, expression));
|
|
5206
|
+
}
|
|
5207
|
+
break;
|
|
5208
|
+
}
|
|
5209
|
+
case 'prerender-ppr':
|
|
5210
|
+
{
|
|
5211
|
+
const fallbackParams = workUnitStore.fallbackRouteParams;
|
|
5212
|
+
if (fallbackParams && fallbackParams.size > 0) {
|
|
5213
|
+
return postponeWithTracking(workStore.route, expression, workUnitStore.dynamicTracking);
|
|
5214
|
+
}
|
|
5215
|
+
break;
|
|
5216
|
+
}
|
|
5217
|
+
case 'prerender-runtime':
|
|
5218
|
+
throw Object.defineProperty(new _invarianterror.InvariantError(`\`${expression}\` was called during a runtime prerender. Next.js should be preventing ${expression} from being included in server components statically, but did not in this case.`), "__NEXT_ERROR_CODE", {
|
|
5219
|
+
value: "E771",
|
|
5220
|
+
enumerable: false,
|
|
5221
|
+
configurable: true
|
|
5222
|
+
});
|
|
5223
|
+
case 'cache':
|
|
5224
|
+
case 'private-cache':
|
|
5225
|
+
throw Object.defineProperty(new _invarianterror.InvariantError(`\`${expression}\` was called inside a cache scope. Next.js should be preventing ${expression} from being included in server components statically, but did not in this case.`), "__NEXT_ERROR_CODE", {
|
|
5226
|
+
value: "E745",
|
|
5227
|
+
enumerable: false,
|
|
5228
|
+
configurable: true
|
|
5229
|
+
});
|
|
4820
5230
|
}
|
|
4821
5231
|
}
|
|
4822
5232
|
}
|
|
5233
|
+
function useDynamicSearchParams(expression) {
|
|
5234
|
+
const workStore = _workasyncstorageexternal.workAsyncStorage.getStore();
|
|
5235
|
+
const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
5236
|
+
if (!workStore) {
|
|
5237
|
+
// We assume pages router context and just return
|
|
5238
|
+
return;
|
|
5239
|
+
}
|
|
5240
|
+
if (!workUnitStore) {
|
|
5241
|
+
(0, _workunitasyncstorageexternal.throwForMissingRequestStore)(expression);
|
|
5242
|
+
}
|
|
5243
|
+
switch(workUnitStore.type){
|
|
5244
|
+
case 'prerender-client':
|
|
5245
|
+
{
|
|
5246
|
+
_react.default.use((0, _dynamicrenderingutils.makeHangingPromise)(workUnitStore.renderSignal, workStore.route, expression));
|
|
5247
|
+
break;
|
|
5248
|
+
}
|
|
5249
|
+
case 'prerender-legacy':
|
|
5250
|
+
case 'prerender-ppr':
|
|
5251
|
+
{
|
|
5252
|
+
if (workStore.forceStatic) {
|
|
5253
|
+
return;
|
|
5254
|
+
}
|
|
5255
|
+
throw Object.defineProperty(new _bailouttocsr.BailoutToCSRError(expression), "__NEXT_ERROR_CODE", {
|
|
5256
|
+
value: "E394",
|
|
5257
|
+
enumerable: false,
|
|
5258
|
+
configurable: true
|
|
5259
|
+
});
|
|
5260
|
+
}
|
|
5261
|
+
case 'prerender':
|
|
5262
|
+
case 'prerender-runtime':
|
|
5263
|
+
throw Object.defineProperty(new _invarianterror.InvariantError(`\`${expression}\` was called from a Server Component. Next.js should be preventing ${expression} from being included in server components statically, but did not in this case.`), "__NEXT_ERROR_CODE", {
|
|
5264
|
+
value: "E795",
|
|
5265
|
+
enumerable: false,
|
|
5266
|
+
configurable: true
|
|
5267
|
+
});
|
|
5268
|
+
case 'cache':
|
|
5269
|
+
case 'unstable-cache':
|
|
5270
|
+
case 'private-cache':
|
|
5271
|
+
throw Object.defineProperty(new _invarianterror.InvariantError(`\`${expression}\` was called inside a cache scope. Next.js should be preventing ${expression} from being included in server components statically, but did not in this case.`), "__NEXT_ERROR_CODE", {
|
|
5272
|
+
value: "E745",
|
|
5273
|
+
enumerable: false,
|
|
5274
|
+
configurable: true
|
|
5275
|
+
});
|
|
5276
|
+
case 'request':
|
|
5277
|
+
return;
|
|
5278
|
+
}
|
|
5279
|
+
}
|
|
4823
5280
|
const hasSuspenseRegex = /\n\s+at Suspense \(<anonymous>\)/;
|
|
4824
|
-
|
|
4825
|
-
const
|
|
4826
|
-
|
|
4827
|
-
|
|
5281
|
+
// Common implicit body tags that React will treat as body when placed directly in html
|
|
5282
|
+
const bodyAndImplicitTags = 'body|div|main|section|article|aside|header|footer|nav|form|p|span|h1|h2|h3|h4|h5|h6';
|
|
5283
|
+
// Detects when RootLayoutBoundary (our framework marker component) appears
|
|
5284
|
+
// after Suspense in the component stack, indicating the root layout is wrapped
|
|
5285
|
+
// within a Suspense boundary. Ensures no body/html/implicit-body components are in between.
|
|
5286
|
+
//
|
|
5287
|
+
// Example matches:
|
|
5288
|
+
// at Suspense (<anonymous>)
|
|
5289
|
+
// at __next_root_layout_boundary__ (<anonymous>)
|
|
5290
|
+
//
|
|
5291
|
+
// Or with other components in between (but not body/html/implicit-body):
|
|
5292
|
+
// at Suspense (<anonymous>)
|
|
5293
|
+
// at SomeComponent (<anonymous>)
|
|
5294
|
+
// at __next_root_layout_boundary__ (<anonymous>)
|
|
5295
|
+
const hasSuspenseBeforeRootLayoutWithoutBodyOrImplicitBodyRegex = new RegExp(`\\n\\s+at Suspense \\(<anonymous>\\)(?:(?!\\n\\s+at (?:${bodyAndImplicitTags}) \\(<anonymous>\\))[\\s\\S])*?\\n\\s+at ${_boundaryconstants.ROOT_LAYOUT_BOUNDARY_NAME} \\([^\\n]*\\)`);
|
|
5296
|
+
const hasMetadataRegex = new RegExp(`\\n\\s+at ${_boundaryconstants.METADATA_BOUNDARY_NAME}[\\n\\s]`);
|
|
5297
|
+
const hasViewportRegex = new RegExp(`\\n\\s+at ${_boundaryconstants.VIEWPORT_BOUNDARY_NAME}[\\n\\s]`);
|
|
5298
|
+
const hasOutletRegex = new RegExp(`\\n\\s+at ${_boundaryconstants.OUTLET_BOUNDARY_NAME}[\\n\\s]`);
|
|
4828
5299
|
function trackAllowedDynamicAccess(workStore, componentStack, dynamicValidation, clientDynamic) {
|
|
4829
5300
|
if (hasOutletRegex.test(componentStack)) {
|
|
4830
5301
|
// We don't need to track that this is dynamic. It is only so when something else is also dynamic.
|
|
@@ -4835,9 +5306,10 @@ var scheduler = {};
|
|
|
4835
5306
|
} else if (hasViewportRegex.test(componentStack)) {
|
|
4836
5307
|
dynamicValidation.hasDynamicViewport = true;
|
|
4837
5308
|
return;
|
|
4838
|
-
} else if (
|
|
4839
|
-
//
|
|
4840
|
-
//
|
|
5309
|
+
} else if (hasSuspenseBeforeRootLayoutWithoutBodyOrImplicitBodyRegex.test(componentStack)) {
|
|
5310
|
+
// For Suspense within body, the prelude wouldn't be empty so it wouldn't violate the empty static shells rule.
|
|
5311
|
+
// But if you have Suspense above body, the prelude is empty but we allow that because having Suspense
|
|
5312
|
+
// is an explicit signal from the user that they acknowledge the empty shell and want dynamic rendering.
|
|
4841
5313
|
dynamicValidation.hasAllowedDynamic = true;
|
|
4842
5314
|
dynamicValidation.hasSuspenseAboveBody = true;
|
|
4843
5315
|
return;
|
|
@@ -4851,7 +5323,7 @@ var scheduler = {};
|
|
|
4851
5323
|
dynamicValidation.dynamicErrors.push(clientDynamic.syncDynamicErrorWithStack);
|
|
4852
5324
|
return;
|
|
4853
5325
|
} else {
|
|
4854
|
-
const message = `Route "${workStore.route}":
|
|
5326
|
+
const message = `Route "${workStore.route}": Uncached data was accessed outside of ` + '<Suspense>. This delays the entire page from rendering, resulting in a ' + 'slow user experience. Learn more: ' + 'https://nextjs.org/docs/messages/blocking-route';
|
|
4855
5327
|
const error = createErrorWithComponentOrOwnerStack(message, componentStack);
|
|
4856
5328
|
dynamicValidation.dynamicErrors.push(error);
|
|
4857
5329
|
return;
|
|
@@ -4889,8 +5361,8 @@ var scheduler = {};
|
|
|
4889
5361
|
}
|
|
4890
5362
|
}
|
|
4891
5363
|
function throwIfDisallowedDynamic(workStore, prelude, dynamicValidation, serverDynamic) {
|
|
4892
|
-
if (
|
|
4893
|
-
logDisallowedDynamicError(workStore,
|
|
5364
|
+
if (serverDynamic.syncDynamicErrorWithStack) {
|
|
5365
|
+
logDisallowedDynamicError(workStore, serverDynamic.syncDynamicErrorWithStack);
|
|
4894
5366
|
throw new _staticgenerationbailout.StaticGenBailoutError();
|
|
4895
5367
|
}
|
|
4896
5368
|
if (prelude !== 0) {
|
|
@@ -4900,13 +5372,6 @@ var scheduler = {};
|
|
|
4900
5372
|
// a lack of a shell is not considered disallowed so we simply return
|
|
4901
5373
|
return;
|
|
4902
5374
|
}
|
|
4903
|
-
if (serverDynamic.syncDynamicErrorWithStack) {
|
|
4904
|
-
// There is no shell and the server did something sync dynamic likely
|
|
4905
|
-
// leading to an early termination of the prerender before the shell
|
|
4906
|
-
// could be completed. We terminate the build/validating render.
|
|
4907
|
-
logDisallowedDynamicError(workStore, serverDynamic.syncDynamicErrorWithStack);
|
|
4908
|
-
throw new _staticgenerationbailout.StaticGenBailoutError();
|
|
4909
|
-
}
|
|
4910
5375
|
// We didn't have any sync bailouts but there may be user code which
|
|
4911
5376
|
// blocked the root. We would have captured these during the prerender
|
|
4912
5377
|
// and can log them here and then terminate the build/validating render
|
|
@@ -4939,6 +5404,12 @@ var scheduler = {};
|
|
|
4939
5404
|
}
|
|
4940
5405
|
}
|
|
4941
5406
|
}
|
|
5407
|
+
function delayUntilRuntimeStage(prerenderStore, result) {
|
|
5408
|
+
if (prerenderStore.runtimeStagePromise) {
|
|
5409
|
+
return prerenderStore.runtimeStagePromise.then(()=>result);
|
|
5410
|
+
}
|
|
5411
|
+
return result;
|
|
5412
|
+
}
|
|
4942
5413
|
|
|
4943
5414
|
|
|
4944
5415
|
} (dynamicRendering));
|
|
@@ -4997,22 +5468,12 @@ var afterTaskAsyncStorageInstance = {};
|
|
|
4997
5468
|
throwForSearchParamsAccessInUseCache: function() {
|
|
4998
5469
|
return throwForSearchParamsAccessInUseCache;
|
|
4999
5470
|
},
|
|
5000
|
-
throwWithStaticGenerationBailoutError: function() {
|
|
5001
|
-
return throwWithStaticGenerationBailoutError;
|
|
5002
|
-
},
|
|
5003
5471
|
throwWithStaticGenerationBailoutErrorWithDynamicError: function() {
|
|
5004
5472
|
return throwWithStaticGenerationBailoutErrorWithDynamicError;
|
|
5005
5473
|
}
|
|
5006
5474
|
});
|
|
5007
5475
|
const _staticgenerationbailout = staticGenerationBailoutExports;
|
|
5008
5476
|
const _aftertaskasyncstorageexternal = afterTaskAsyncStorage_external;
|
|
5009
|
-
function throwWithStaticGenerationBailoutError(route, expression) {
|
|
5010
|
-
throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route ${route} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`), "__NEXT_ERROR_CODE", {
|
|
5011
|
-
value: "E576",
|
|
5012
|
-
enumerable: false,
|
|
5013
|
-
configurable: true
|
|
5014
|
-
});
|
|
5015
|
-
}
|
|
5016
5477
|
function throwWithStaticGenerationBailoutErrorWithDynamicError(route, expression) {
|
|
5017
5478
|
throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route ${route} with \`dynamic = "error"\` couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`), "__NEXT_ERROR_CODE", {
|
|
5018
5479
|
value: "E543",
|
|
@@ -5021,8 +5482,8 @@ var afterTaskAsyncStorageInstance = {};
|
|
|
5021
5482
|
});
|
|
5022
5483
|
}
|
|
5023
5484
|
function throwForSearchParamsAccessInUseCache(workStore, constructorOpt) {
|
|
5024
|
-
const error = Object.defineProperty(new Error(`Route ${workStore.route} used
|
|
5025
|
-
value: "
|
|
5485
|
+
const error = Object.defineProperty(new Error(`Route ${workStore.route} used \`searchParams\` inside "use cache". Accessing dynamic request data inside a cache scope is not supported. If you need some search params inside a cached function await \`searchParams\` outside of the cached function and pass only the required search params as arguments to the cached function. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache`), "__NEXT_ERROR_CODE", {
|
|
5486
|
+
value: "E842",
|
|
5026
5487
|
enumerable: false,
|
|
5027
5488
|
configurable: true
|
|
5028
5489
|
});
|
|
@@ -5054,294 +5515,100 @@ var afterTaskAsyncStorageInstance = {};
|
|
|
5054
5515
|
const _staticgenerationbailout = staticGenerationBailoutExports;
|
|
5055
5516
|
const _dynamicrenderingutils = dynamicRenderingUtils;
|
|
5056
5517
|
const _utils = utils;
|
|
5518
|
+
const _stagedrendering = stagedRendering;
|
|
5057
5519
|
function connection() {
|
|
5520
|
+
const callingExpression = 'connection';
|
|
5058
5521
|
const workStore = _workasyncstorageexternal.workAsyncStorage.getStore();
|
|
5059
5522
|
const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
5060
5523
|
if (workStore) {
|
|
5061
5524
|
if (workUnitStore && workUnitStore.phase === 'after' && !(0, _utils.isRequestAPICallableInsideAfter)()) {
|
|
5062
|
-
throw Object.defineProperty(new Error(`Route ${workStore.route} used
|
|
5063
|
-
value: "
|
|
5525
|
+
throw Object.defineProperty(new Error(`Route ${workStore.route} used \`connection()\` inside \`after()\`. The \`connection()\` function is used to indicate the subsequent code must only run when there is an actual Request, but \`after()\` executes after the request, so this function is not allowed in this scope. See more info here: https://nextjs.org/docs/canary/app/api-reference/functions/after`), "__NEXT_ERROR_CODE", {
|
|
5526
|
+
value: "E827",
|
|
5064
5527
|
enumerable: false,
|
|
5065
5528
|
configurable: true
|
|
5066
5529
|
});
|
|
5067
5530
|
}
|
|
5068
5531
|
if (workStore.forceStatic) {
|
|
5069
|
-
// When using forceStatic we override all other logic and always just
|
|
5070
|
-
//
|
|
5532
|
+
// When using forceStatic, we override all other logic and always just
|
|
5533
|
+
// return a resolving promise without tracking.
|
|
5071
5534
|
return Promise.resolve(undefined);
|
|
5072
5535
|
}
|
|
5073
|
-
if (workUnitStore) {
|
|
5074
|
-
if (workUnitStore.type === 'cache') {
|
|
5075
|
-
throw Object.defineProperty(new Error(`Route ${workStore.route} used "connection" inside "use cache". The \`connection()\` function is used to indicate the subsequent code must only run when there is an actual Request, but caches must be able to be produced before a Request so this function is not allowed in this scope. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache`), "__NEXT_ERROR_CODE", {
|
|
5076
|
-
value: "E111",
|
|
5077
|
-
enumerable: false,
|
|
5078
|
-
configurable: true
|
|
5079
|
-
});
|
|
5080
|
-
} else if (workUnitStore.type === 'unstable-cache') {
|
|
5081
|
-
throw Object.defineProperty(new Error(`Route ${workStore.route} used "connection" inside a function cached with "unstable_cache(...)". The \`connection()\` function is used to indicate the subsequent code must only run when there is an actual Request, but caches must be able to be produced before a Request so this function is not allowed in this scope. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`), "__NEXT_ERROR_CODE", {
|
|
5082
|
-
value: "E1",
|
|
5083
|
-
enumerable: false,
|
|
5084
|
-
configurable: true
|
|
5085
|
-
});
|
|
5086
|
-
}
|
|
5087
|
-
}
|
|
5088
5536
|
if (workStore.dynamicShouldError) {
|
|
5089
|
-
throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route ${workStore.route} with \`dynamic = "error"\` couldn't be rendered statically because it used \`connection\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`), "__NEXT_ERROR_CODE", {
|
|
5090
|
-
value: "
|
|
5537
|
+
throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route ${workStore.route} with \`dynamic = "error"\` couldn't be rendered statically because it used \`connection()\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`), "__NEXT_ERROR_CODE", {
|
|
5538
|
+
value: "E847",
|
|
5091
5539
|
enumerable: false,
|
|
5092
5540
|
configurable: true
|
|
5093
5541
|
});
|
|
5094
5542
|
}
|
|
5095
5543
|
if (workUnitStore) {
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
(0, _dynamicrendering.throwToInterruptStaticGeneration)('connection', workStore, workUnitStore);
|
|
5108
|
-
}
|
|
5109
|
-
}
|
|
5110
|
-
// We fall through to the dynamic context below but we still track dynamic access
|
|
5111
|
-
// because in dev we can still error for things like using headers inside a cache context
|
|
5112
|
-
(0, _dynamicrendering.trackDynamicDataInDynamicRender)(workStore, workUnitStore);
|
|
5113
|
-
}
|
|
5114
|
-
return Promise.resolve(undefined);
|
|
5115
|
-
}
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
} (connection));
|
|
5119
|
-
|
|
5120
|
-
var rootParams = {};
|
|
5121
|
-
|
|
5122
|
-
var invariantError = {};
|
|
5123
|
-
|
|
5124
|
-
(function (exports) {
|
|
5125
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5126
|
-
value: true
|
|
5127
|
-
});
|
|
5128
|
-
Object.defineProperty(exports, "InvariantError", {
|
|
5129
|
-
enumerable: true,
|
|
5130
|
-
get: function() {
|
|
5131
|
-
return InvariantError;
|
|
5132
|
-
}
|
|
5133
|
-
});
|
|
5134
|
-
class InvariantError extends Error {
|
|
5135
|
-
constructor(message, options){
|
|
5136
|
-
super("Invariant: " + (message.endsWith('.') ? message : message + '.') + " This is a bug in Next.js.", options);
|
|
5137
|
-
this.name = 'InvariantError';
|
|
5138
|
-
}
|
|
5139
|
-
}
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
} (invariantError));
|
|
5143
|
-
|
|
5144
|
-
var reflectUtils = {};
|
|
5145
|
-
|
|
5146
|
-
(function (exports) {
|
|
5147
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5148
|
-
value: true
|
|
5149
|
-
});
|
|
5150
|
-
function _export(target, all) {
|
|
5151
|
-
for(var name in all)Object.defineProperty(target, name, {
|
|
5152
|
-
enumerable: true,
|
|
5153
|
-
get: all[name]
|
|
5154
|
-
});
|
|
5155
|
-
}
|
|
5156
|
-
_export(exports, {
|
|
5157
|
-
describeHasCheckingStringProperty: function() {
|
|
5158
|
-
return describeHasCheckingStringProperty;
|
|
5159
|
-
},
|
|
5160
|
-
describeStringPropertyAccess: function() {
|
|
5161
|
-
return describeStringPropertyAccess;
|
|
5162
|
-
},
|
|
5163
|
-
wellKnownProperties: function() {
|
|
5164
|
-
return wellKnownProperties;
|
|
5165
|
-
}
|
|
5166
|
-
});
|
|
5167
|
-
const isDefinitelyAValidIdentifier = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
5168
|
-
function describeStringPropertyAccess(target, prop) {
|
|
5169
|
-
if (isDefinitelyAValidIdentifier.test(prop)) {
|
|
5170
|
-
return "`" + target + "." + prop + "`";
|
|
5171
|
-
}
|
|
5172
|
-
return "`" + target + "[" + JSON.stringify(prop) + "]`";
|
|
5173
|
-
}
|
|
5174
|
-
function describeHasCheckingStringProperty(target, prop) {
|
|
5175
|
-
const stringifiedProp = JSON.stringify(prop);
|
|
5176
|
-
return "`Reflect.has(" + target + ", " + stringifiedProp + ")`, `" + stringifiedProp + " in " + target + "`, or similar";
|
|
5177
|
-
}
|
|
5178
|
-
const wellKnownProperties = new Set([
|
|
5179
|
-
'hasOwnProperty',
|
|
5180
|
-
'isPrototypeOf',
|
|
5181
|
-
'propertyIsEnumerable',
|
|
5182
|
-
'toString',
|
|
5183
|
-
'valueOf',
|
|
5184
|
-
'toLocaleString',
|
|
5185
|
-
// Promise prototype
|
|
5186
|
-
// fallthrough
|
|
5187
|
-
'then',
|
|
5188
|
-
'catch',
|
|
5189
|
-
'finally',
|
|
5190
|
-
// React Promise extension
|
|
5191
|
-
// fallthrough
|
|
5192
|
-
'status',
|
|
5193
|
-
// React introspection
|
|
5194
|
-
'displayName',
|
|
5195
|
-
'_debugInfo',
|
|
5196
|
-
// Common tested properties
|
|
5197
|
-
// fallthrough
|
|
5198
|
-
'toJSON',
|
|
5199
|
-
'$$typeof',
|
|
5200
|
-
'__esModule'
|
|
5201
|
-
]);
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
} (reflectUtils));
|
|
5205
|
-
|
|
5206
|
-
(function (exports) {
|
|
5207
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5208
|
-
value: true
|
|
5209
|
-
});
|
|
5210
|
-
Object.defineProperty(exports, "unstable_rootParams", {
|
|
5211
|
-
enumerable: true,
|
|
5212
|
-
get: function() {
|
|
5213
|
-
return unstable_rootParams;
|
|
5214
|
-
}
|
|
5215
|
-
});
|
|
5216
|
-
const _invarianterror = invariantError;
|
|
5217
|
-
const _dynamicrendering = dynamicRendering;
|
|
5218
|
-
const _workasyncstorageexternal = workAsyncStorage_external;
|
|
5219
|
-
const _workunitasyncstorageexternal = workUnitAsyncStorage_external;
|
|
5220
|
-
const _dynamicrenderingutils = dynamicRenderingUtils;
|
|
5221
|
-
const _reflectutils = reflectUtils;
|
|
5222
|
-
const CachedParams = new WeakMap();
|
|
5223
|
-
async function unstable_rootParams() {
|
|
5224
|
-
const workStore = _workasyncstorageexternal.workAsyncStorage.getStore();
|
|
5225
|
-
if (!workStore) {
|
|
5226
|
-
throw Object.defineProperty(new _invarianterror.InvariantError('Missing workStore in unstable_rootParams'), "__NEXT_ERROR_CODE", {
|
|
5227
|
-
value: "E615",
|
|
5228
|
-
enumerable: false,
|
|
5229
|
-
configurable: true
|
|
5230
|
-
});
|
|
5231
|
-
}
|
|
5232
|
-
const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
5233
|
-
if (!workUnitStore) {
|
|
5234
|
-
throw Object.defineProperty(new Error(`Route ${workStore.route} used \`unstable_rootParams()\` in Pages Router. This API is only available within App Router.`), "__NEXT_ERROR_CODE", {
|
|
5235
|
-
value: "E641",
|
|
5236
|
-
enumerable: false,
|
|
5237
|
-
configurable: true
|
|
5238
|
-
});
|
|
5239
|
-
}
|
|
5240
|
-
switch(workUnitStore.type){
|
|
5241
|
-
case 'unstable-cache':
|
|
5242
|
-
case 'cache':
|
|
5243
|
-
{
|
|
5244
|
-
throw Object.defineProperty(new Error(`Route ${workStore.route} used \`unstable_rootParams()\` inside \`"use cache"\` or \`unstable_cache\`. Support for this API inside cache scopes is planned for a future version of Next.js.`), "__NEXT_ERROR_CODE", {
|
|
5245
|
-
value: "E642",
|
|
5246
|
-
enumerable: false,
|
|
5247
|
-
configurable: true
|
|
5248
|
-
});
|
|
5249
|
-
}
|
|
5250
|
-
case 'prerender':
|
|
5251
|
-
case 'prerender-client':
|
|
5252
|
-
case 'prerender-ppr':
|
|
5253
|
-
case 'prerender-legacy':
|
|
5254
|
-
return createPrerenderRootParams(workUnitStore.rootParams, workStore, workUnitStore);
|
|
5255
|
-
default:
|
|
5256
|
-
return Promise.resolve(workUnitStore.rootParams);
|
|
5257
|
-
}
|
|
5258
|
-
}
|
|
5259
|
-
function createPrerenderRootParams(underlyingParams, workStore, prerenderStore) {
|
|
5260
|
-
const fallbackParams = workStore.fallbackRouteParams;
|
|
5261
|
-
if (fallbackParams) {
|
|
5262
|
-
let hasSomeFallbackParams = false;
|
|
5263
|
-
for(const key in underlyingParams){
|
|
5264
|
-
if (fallbackParams.has(key)) {
|
|
5265
|
-
hasSomeFallbackParams = true;
|
|
5266
|
-
break;
|
|
5267
|
-
}
|
|
5268
|
-
}
|
|
5269
|
-
if (hasSomeFallbackParams) {
|
|
5270
|
-
// params need to be treated as dynamic because we have at least one fallback param
|
|
5271
|
-
switch(prerenderStore.type){
|
|
5272
|
-
case 'prerender':
|
|
5273
|
-
// We are in a dynamicIO prerender
|
|
5274
|
-
const cachedParams = CachedParams.get(underlyingParams);
|
|
5275
|
-
if (cachedParams) {
|
|
5276
|
-
return cachedParams;
|
|
5544
|
+
switch(workUnitStore.type){
|
|
5545
|
+
case 'cache':
|
|
5546
|
+
{
|
|
5547
|
+
const error = Object.defineProperty(new Error(`Route ${workStore.route} used \`connection()\` inside "use cache". The \`connection()\` function is used to indicate the subsequent code must only run when there is an actual request, but caches must be able to be produced before a request, so this function is not allowed in this scope. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache`), "__NEXT_ERROR_CODE", {
|
|
5548
|
+
value: "E841",
|
|
5549
|
+
enumerable: false,
|
|
5550
|
+
configurable: true
|
|
5551
|
+
});
|
|
5552
|
+
Error.captureStackTrace(error, connection);
|
|
5553
|
+
workStore.invalidDynamicUsageError ??= error;
|
|
5554
|
+
throw error;
|
|
5277
5555
|
}
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5556
|
+
case 'private-cache':
|
|
5557
|
+
{
|
|
5558
|
+
// It might not be intuitive to throw for private caches as well, but
|
|
5559
|
+
// we don't consider runtime prefetches as "actual requests" (in the
|
|
5560
|
+
// navigation sense), despite allowing them to read cookies.
|
|
5561
|
+
const error = Object.defineProperty(new Error(`Route ${workStore.route} used \`connection()\` inside "use cache: private". The \`connection()\` function is used to indicate the subsequent code must only run when there is an actual navigation request, but caches must be able to be produced before a navigation request, so this function is not allowed in this scope. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache`), "__NEXT_ERROR_CODE", {
|
|
5562
|
+
value: "E837",
|
|
5563
|
+
enumerable: false,
|
|
5564
|
+
configurable: true
|
|
5565
|
+
});
|
|
5566
|
+
Error.captureStackTrace(error, connection);
|
|
5567
|
+
workStore.invalidDynamicUsageError ??= error;
|
|
5568
|
+
throw error;
|
|
5569
|
+
}
|
|
5570
|
+
case 'unstable-cache':
|
|
5571
|
+
throw Object.defineProperty(new Error(`Route ${workStore.route} used \`connection()\` inside a function cached with \`unstable_cache()\`. The \`connection()\` function is used to indicate the subsequent code must only run when there is an actual Request, but caches must be able to be produced before a Request so this function is not allowed in this scope. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`), "__NEXT_ERROR_CODE", {
|
|
5572
|
+
value: "E840",
|
|
5285
5573
|
enumerable: false,
|
|
5286
5574
|
configurable: true
|
|
5287
5575
|
});
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
//
|
|
5292
|
-
//
|
|
5293
|
-
return
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
// instrument the promise with spreadable properties of ReactPromise.
|
|
5311
|
-
const promise = Promise.resolve(augmentedUnderlying);
|
|
5312
|
-
CachedParams.set(underlyingParams, promise);
|
|
5313
|
-
Object.keys(underlyingParams).forEach((prop)=>{
|
|
5314
|
-
if (_reflectutils.wellKnownProperties.has(prop)) ; else {
|
|
5315
|
-
if (fallbackParams.has(prop)) {
|
|
5316
|
-
Object.defineProperty(augmentedUnderlying, prop, {
|
|
5317
|
-
get () {
|
|
5318
|
-
const expression = (0, _reflectutils.describeStringPropertyAccess)('unstable_rootParams', prop);
|
|
5319
|
-
// In most dynamic APIs we also throw if `dynamic = "error"` however
|
|
5320
|
-
// for params is only dynamic when we're generating a fallback shell
|
|
5321
|
-
// and even when `dynamic = "error"` we still support generating dynamic
|
|
5322
|
-
// fallback shells
|
|
5323
|
-
// TODO remove this comment when dynamicIO is the default since there
|
|
5324
|
-
// will be no `dynamic = "error"`
|
|
5325
|
-
if (prerenderStore.type === 'prerender-ppr') {
|
|
5326
|
-
// PPR Prerender (no dynamicIO)
|
|
5327
|
-
(0, _dynamicrendering.postponeWithTracking)(workStore.route, expression, prerenderStore.dynamicTracking);
|
|
5328
|
-
} else {
|
|
5329
|
-
// Legacy Prerender
|
|
5330
|
-
(0, _dynamicrendering.throwToInterruptStaticGeneration)(expression, workStore, prerenderStore);
|
|
5576
|
+
case 'prerender':
|
|
5577
|
+
case 'prerender-client':
|
|
5578
|
+
case 'prerender-runtime':
|
|
5579
|
+
// We return a promise that never resolves to allow the prerender to
|
|
5580
|
+
// stall at this point.
|
|
5581
|
+
return (0, _dynamicrenderingutils.makeHangingPromise)(workUnitStore.renderSignal, workStore.route, '`connection()`');
|
|
5582
|
+
case 'prerender-ppr':
|
|
5583
|
+
// We use React's postpone API to interrupt rendering here to create a
|
|
5584
|
+
// dynamic hole
|
|
5585
|
+
return (0, _dynamicrendering.postponeWithTracking)(workStore.route, 'connection', workUnitStore.dynamicTracking);
|
|
5586
|
+
case 'prerender-legacy':
|
|
5587
|
+
// We throw an error here to interrupt prerendering to mark the route
|
|
5588
|
+
// as dynamic
|
|
5589
|
+
return (0, _dynamicrendering.throwToInterruptStaticGeneration)('connection', workStore, workUnitStore);
|
|
5590
|
+
case 'request':
|
|
5591
|
+
(0, _dynamicrendering.trackDynamicDataInDynamicRender)(workUnitStore);
|
|
5592
|
+
if (process.env.NODE_ENV === 'development') {
|
|
5593
|
+
// Semantically we only need the dev tracking when running in `next dev`
|
|
5594
|
+
// but since you would never use next dev with production NODE_ENV we use this
|
|
5595
|
+
// as a proxy so we can statically exclude this code from production builds.
|
|
5596
|
+
if (workUnitStore.asyncApiPromises) {
|
|
5597
|
+
return workUnitStore.asyncApiPromises.connection;
|
|
5331
5598
|
}
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
promise[prop] = underlyingParams[prop];
|
|
5599
|
+
return (0, _dynamicrenderingutils.makeDevtoolsIOAwarePromise)(undefined, workUnitStore, _stagedrendering.RenderStage.Dynamic);
|
|
5600
|
+
} else {
|
|
5601
|
+
return Promise.resolve(undefined);
|
|
5602
|
+
}
|
|
5337
5603
|
}
|
|
5338
5604
|
}
|
|
5339
|
-
}
|
|
5340
|
-
|
|
5605
|
+
}
|
|
5606
|
+
// If we end up here, there was no work store or work unit store present.
|
|
5607
|
+
(0, _workunitasyncstorageexternal.throwForMissingRequestStore)(callingExpression);
|
|
5341
5608
|
}
|
|
5342
5609
|
|
|
5343
5610
|
|
|
5344
|
-
} (
|
|
5611
|
+
} (connection));
|
|
5345
5612
|
|
|
5346
5613
|
(function (module, exports) {
|
|
5347
5614
|
const serverExports = {
|
|
@@ -5359,8 +5626,6 @@ var reflectUtils = {};
|
|
|
5359
5626
|
.URLPattern,
|
|
5360
5627
|
after: after$1.after,
|
|
5361
5628
|
connection: connection.connection,
|
|
5362
|
-
unstable_rootParams: rootParams
|
|
5363
|
-
.unstable_rootParams,
|
|
5364
5629
|
};
|
|
5365
5630
|
|
|
5366
5631
|
// https://nodejs.org/api/esm.html#commonjs-namespaces
|
|
@@ -5375,8 +5640,7 @@ var reflectUtils = {};
|
|
|
5375
5640
|
exports.userAgent = serverExports.userAgent;
|
|
5376
5641
|
exports.URLPattern = serverExports.URLPattern;
|
|
5377
5642
|
exports.after = serverExports.after;
|
|
5378
|
-
exports.connection = serverExports.connection;
|
|
5379
|
-
exports.unstable_rootParams = serverExports.unstable_rootParams;
|
|
5643
|
+
exports.connection = serverExports.connection;
|
|
5380
5644
|
} (server, server.exports));
|
|
5381
5645
|
|
|
5382
5646
|
var serverExports = server.exports;
|
|
@@ -9342,7 +9606,7 @@ const unknownType = ZodUnknown.create;
|
|
|
9342
9606
|
ZodNever.create;
|
|
9343
9607
|
const arrayType = ZodArray.create;
|
|
9344
9608
|
const objectType = ZodObject.create;
|
|
9345
|
-
ZodUnion.create;
|
|
9609
|
+
const unionType = ZodUnion.create;
|
|
9346
9610
|
const discriminatedUnionType = ZodDiscriminatedUnion.create;
|
|
9347
9611
|
ZodIntersection.create;
|
|
9348
9612
|
ZodTuple.create;
|
|
@@ -9561,7 +9825,7 @@ const safeJSON = (text) => {
|
|
|
9561
9825
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
9562
9826
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
9563
9827
|
|
|
9564
|
-
const VERSION = '2.
|
|
9828
|
+
const VERSION = '2.4.6'; // x-release-please-version
|
|
9565
9829
|
|
|
9566
9830
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
9567
9831
|
/**
|
|
@@ -10311,6 +10575,9 @@ class CheckoutSessions extends APIResource {
|
|
|
10311
10575
|
create(body, options) {
|
|
10312
10576
|
return this._client.post('/checkouts', { body, ...options });
|
|
10313
10577
|
}
|
|
10578
|
+
retrieve(id, options) {
|
|
10579
|
+
return this._client.get(path `/checkouts/${id}`, options);
|
|
10580
|
+
}
|
|
10314
10581
|
}
|
|
10315
10582
|
|
|
10316
10583
|
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
@@ -10989,1398 +11256,323 @@ let Headers$1 = class Headers extends APIResource {
|
|
|
10989
11256
|
}
|
|
10990
11257
|
};
|
|
10991
11258
|
|
|
10992
|
-
|
|
10993
|
-
|
|
10994
|
-
|
|
10995
|
-
|
|
10996
|
-
|
|
11259
|
+
var dist = {};
|
|
11260
|
+
|
|
11261
|
+
var timing_safe_equal = {};
|
|
11262
|
+
|
|
11263
|
+
Object.defineProperty(timing_safe_equal, "__esModule", { value: true });
|
|
11264
|
+
timing_safe_equal.timingSafeEqual = void 0;
|
|
11265
|
+
function assert(expr, msg = "") {
|
|
11266
|
+
if (!expr) {
|
|
11267
|
+
throw new Error(msg);
|
|
10997
11268
|
}
|
|
10998
|
-
|
|
10999
|
-
|
|
11000
|
-
|
|
11001
|
-
|
|
11002
|
-
return this._client.post('/webhooks', { body, ...options });
|
|
11269
|
+
}
|
|
11270
|
+
function timingSafeEqual(a, b) {
|
|
11271
|
+
if (a.byteLength !== b.byteLength) {
|
|
11272
|
+
return false;
|
|
11003
11273
|
}
|
|
11004
|
-
|
|
11005
|
-
|
|
11006
|
-
*/
|
|
11007
|
-
retrieve(webhookID, options) {
|
|
11008
|
-
return this._client.get(path `/webhooks/${webhookID}`, options);
|
|
11274
|
+
if (!(a instanceof DataView)) {
|
|
11275
|
+
a = new DataView(ArrayBuffer.isView(a) ? a.buffer : a);
|
|
11009
11276
|
}
|
|
11010
|
-
|
|
11011
|
-
|
|
11012
|
-
*/
|
|
11013
|
-
update(webhookID, body, options) {
|
|
11014
|
-
return this._client.patch(path `/webhooks/${webhookID}`, { body, ...options });
|
|
11277
|
+
if (!(b instanceof DataView)) {
|
|
11278
|
+
b = new DataView(ArrayBuffer.isView(b) ? b.buffer : b);
|
|
11015
11279
|
}
|
|
11016
|
-
|
|
11017
|
-
|
|
11018
|
-
|
|
11019
|
-
|
|
11020
|
-
|
|
11021
|
-
|
|
11022
|
-
|
|
11023
|
-
* Delete a webhook by id
|
|
11024
|
-
*/
|
|
11025
|
-
delete(webhookID, options) {
|
|
11026
|
-
return this._client.delete(path `/webhooks/${webhookID}`, {
|
|
11027
|
-
...options,
|
|
11028
|
-
headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
|
|
11029
|
-
});
|
|
11030
|
-
}
|
|
11031
|
-
/**
|
|
11032
|
-
* Get webhook secret by id
|
|
11033
|
-
*/
|
|
11034
|
-
retrieveSecret(webhookID, options) {
|
|
11035
|
-
return this._client.get(path `/webhooks/${webhookID}/secret`, options);
|
|
11280
|
+
assert(a instanceof DataView);
|
|
11281
|
+
assert(b instanceof DataView);
|
|
11282
|
+
const length = a.byteLength;
|
|
11283
|
+
let out = 0;
|
|
11284
|
+
let i = -1;
|
|
11285
|
+
while (++i < length) {
|
|
11286
|
+
out |= a.getUint8(i) ^ b.getUint8(i);
|
|
11036
11287
|
}
|
|
11037
|
-
|
|
11038
|
-
|
|
11288
|
+
return out === 0;
|
|
11289
|
+
}
|
|
11290
|
+
timing_safe_equal.timingSafeEqual = timingSafeEqual;
|
|
11039
11291
|
|
|
11040
|
-
|
|
11292
|
+
var base64$1 = {};
|
|
11293
|
+
|
|
11294
|
+
// Copyright (C) 2016 Dmitry Chestnykh
|
|
11295
|
+
// MIT License. See LICENSE file for details.
|
|
11296
|
+
var __extends = (commonjsGlobal && commonjsGlobal.__extends) || (function () {
|
|
11297
|
+
var extendStatics = function (d, b) {
|
|
11298
|
+
extendStatics = Object.setPrototypeOf ||
|
|
11299
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
11300
|
+
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
11301
|
+
return extendStatics(d, b);
|
|
11302
|
+
};
|
|
11303
|
+
return function (d, b) {
|
|
11304
|
+
extendStatics(d, b);
|
|
11305
|
+
function __() { this.constructor = d; }
|
|
11306
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
11307
|
+
};
|
|
11308
|
+
})();
|
|
11309
|
+
Object.defineProperty(base64$1, "__esModule", { value: true });
|
|
11041
11310
|
/**
|
|
11042
|
-
*
|
|
11043
|
-
*
|
|
11044
|
-
* Trims beginning and trailing whitespace.
|
|
11045
|
-
*
|
|
11046
|
-
* Will return undefined if the environment variable doesn't exist or cannot be accessed.
|
|
11311
|
+
* Package base64 implements Base64 encoding and decoding.
|
|
11047
11312
|
*/
|
|
11048
|
-
|
|
11049
|
-
|
|
11050
|
-
|
|
11051
|
-
|
|
11052
|
-
if (typeof globalThis.Deno !== 'undefined') {
|
|
11053
|
-
return globalThis.Deno.env?.get?.(env)?.trim();
|
|
11054
|
-
}
|
|
11055
|
-
return undefined;
|
|
11056
|
-
};
|
|
11057
|
-
|
|
11058
|
-
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
11059
|
-
var _DodoPayments_instances, _a, _DodoPayments_encoder, _DodoPayments_baseURLOverridden;
|
|
11060
|
-
const environments = {
|
|
11061
|
-
live_mode: 'https://live.dodopayments.com',
|
|
11062
|
-
test_mode: 'https://test.dodopayments.com',
|
|
11063
|
-
};
|
|
11313
|
+
// Invalid character used in decoding to indicate
|
|
11314
|
+
// that the character to decode is out of range of
|
|
11315
|
+
// alphabet and cannot be decoded.
|
|
11316
|
+
var INVALID_BYTE = 256;
|
|
11064
11317
|
/**
|
|
11065
|
-
*
|
|
11318
|
+
* Implements standard Base64 encoding.
|
|
11319
|
+
*
|
|
11320
|
+
* Operates in constant time.
|
|
11066
11321
|
*/
|
|
11067
|
-
class
|
|
11068
|
-
|
|
11069
|
-
|
|
11070
|
-
|
|
11071
|
-
|
|
11072
|
-
|
|
11073
|
-
|
|
11074
|
-
|
|
11075
|
-
|
|
11076
|
-
* @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
|
|
11077
|
-
* @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
|
|
11078
|
-
* @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
|
|
11079
|
-
* @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
|
|
11080
|
-
*/
|
|
11081
|
-
constructor({ baseURL = readEnv('DODO_PAYMENTS_BASE_URL'), bearerToken = readEnv('DODO_PAYMENTS_API_KEY'), ...opts } = {}) {
|
|
11082
|
-
_DodoPayments_instances.add(this);
|
|
11083
|
-
_DodoPayments_encoder.set(this, void 0);
|
|
11084
|
-
this.checkoutSessions = new CheckoutSessions(this);
|
|
11085
|
-
this.payments = new Payments(this);
|
|
11086
|
-
this.subscriptions = new Subscriptions(this);
|
|
11087
|
-
this.invoices = new Invoices(this);
|
|
11088
|
-
this.licenses = new Licenses(this);
|
|
11089
|
-
this.licenseKeys = new LicenseKeys(this);
|
|
11090
|
-
this.licenseKeyInstances = new LicenseKeyInstances(this);
|
|
11091
|
-
this.customers = new Customers(this);
|
|
11092
|
-
this.refunds = new Refunds(this);
|
|
11093
|
-
this.disputes = new Disputes(this);
|
|
11094
|
-
this.payouts = new Payouts(this);
|
|
11095
|
-
this.webhookEvents = new WebhookEvents(this);
|
|
11096
|
-
this.products = new Products(this);
|
|
11097
|
-
this.misc = new Misc(this);
|
|
11098
|
-
this.discounts = new Discounts(this);
|
|
11099
|
-
this.addons = new Addons(this);
|
|
11100
|
-
this.brands = new Brands(this);
|
|
11101
|
-
this.webhooks = new Webhooks$1(this);
|
|
11102
|
-
this.usageEvents = new UsageEvents(this);
|
|
11103
|
-
this.meters = new Meters(this);
|
|
11104
|
-
if (bearerToken === undefined) {
|
|
11105
|
-
throw new DodoPaymentsError("The DODO_PAYMENTS_API_KEY environment variable is missing or empty; either provide it, or instantiate the DodoPayments client with an bearerToken option, like new DodoPayments({ bearerToken: 'My Bearer Token' }).");
|
|
11322
|
+
var Coder = /** @class */ (function () {
|
|
11323
|
+
// TODO(dchest): methods to encode chunk-by-chunk.
|
|
11324
|
+
function Coder(_paddingCharacter) {
|
|
11325
|
+
if (_paddingCharacter === void 0) { _paddingCharacter = "="; }
|
|
11326
|
+
this._paddingCharacter = _paddingCharacter;
|
|
11327
|
+
}
|
|
11328
|
+
Coder.prototype.encodedLength = function (length) {
|
|
11329
|
+
if (!this._paddingCharacter) {
|
|
11330
|
+
return (length * 8 + 5) / 6 | 0;
|
|
11106
11331
|
}
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11332
|
+
return (length + 2) / 3 * 4 | 0;
|
|
11333
|
+
};
|
|
11334
|
+
Coder.prototype.encode = function (data) {
|
|
11335
|
+
var out = "";
|
|
11336
|
+
var i = 0;
|
|
11337
|
+
for (; i < data.length - 2; i += 3) {
|
|
11338
|
+
var c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
|
|
11339
|
+
out += this._encodeByte((c >>> 3 * 6) & 63);
|
|
11340
|
+
out += this._encodeByte((c >>> 2 * 6) & 63);
|
|
11341
|
+
out += this._encodeByte((c >>> 1 * 6) & 63);
|
|
11342
|
+
out += this._encodeByte((c >>> 0 * 6) & 63);
|
|
11115
11343
|
}
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
|
|
11119
|
-
|
|
11120
|
-
|
|
11121
|
-
|
|
11122
|
-
|
|
11123
|
-
parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ??
|
|
11124
|
-
parseLogLevel(readEnv('DODO_PAYMENTS_LOG'), "process.env['DODO_PAYMENTS_LOG']", this) ??
|
|
11125
|
-
defaultLogLevel;
|
|
11126
|
-
this.fetchOptions = options.fetchOptions;
|
|
11127
|
-
this.maxRetries = options.maxRetries ?? 2;
|
|
11128
|
-
this.fetch = options.fetch ?? getDefaultFetch();
|
|
11129
|
-
__classPrivateFieldSet(this, _DodoPayments_encoder, FallbackEncoder);
|
|
11130
|
-
this._options = options;
|
|
11131
|
-
this.bearerToken = bearerToken;
|
|
11132
|
-
}
|
|
11133
|
-
/**
|
|
11134
|
-
* Create a new client instance re-using the same options given to the current client with optional overriding.
|
|
11135
|
-
*/
|
|
11136
|
-
withOptions(options) {
|
|
11137
|
-
const client = new this.constructor({
|
|
11138
|
-
...this._options,
|
|
11139
|
-
environment: options.environment ? options.environment : undefined,
|
|
11140
|
-
baseURL: options.environment ? undefined : this.baseURL,
|
|
11141
|
-
maxRetries: this.maxRetries,
|
|
11142
|
-
timeout: this.timeout,
|
|
11143
|
-
logger: this.logger,
|
|
11144
|
-
logLevel: this.logLevel,
|
|
11145
|
-
fetch: this.fetch,
|
|
11146
|
-
fetchOptions: this.fetchOptions,
|
|
11147
|
-
bearerToken: this.bearerToken,
|
|
11148
|
-
...options,
|
|
11149
|
-
});
|
|
11150
|
-
return client;
|
|
11151
|
-
}
|
|
11152
|
-
defaultQuery() {
|
|
11153
|
-
return this._options.defaultQuery;
|
|
11154
|
-
}
|
|
11155
|
-
validateHeaders({ values, nulls }) {
|
|
11156
|
-
return;
|
|
11157
|
-
}
|
|
11158
|
-
async authHeaders(opts) {
|
|
11159
|
-
return buildHeaders([{ Authorization: `Bearer ${this.bearerToken}` }]);
|
|
11160
|
-
}
|
|
11161
|
-
/**
|
|
11162
|
-
* Basic re-implementation of `qs.stringify` for primitive types.
|
|
11163
|
-
*/
|
|
11164
|
-
stringifyQuery(query) {
|
|
11165
|
-
return Object.entries(query)
|
|
11166
|
-
.filter(([_, value]) => typeof value !== 'undefined')
|
|
11167
|
-
.map(([key, value]) => {
|
|
11168
|
-
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
11169
|
-
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
11344
|
+
var left = data.length - i;
|
|
11345
|
+
if (left > 0) {
|
|
11346
|
+
var c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0);
|
|
11347
|
+
out += this._encodeByte((c >>> 3 * 6) & 63);
|
|
11348
|
+
out += this._encodeByte((c >>> 2 * 6) & 63);
|
|
11349
|
+
if (left === 2) {
|
|
11350
|
+
out += this._encodeByte((c >>> 1 * 6) & 63);
|
|
11170
11351
|
}
|
|
11171
|
-
|
|
11172
|
-
|
|
11352
|
+
else {
|
|
11353
|
+
out += this._paddingCharacter || "";
|
|
11173
11354
|
}
|
|
11174
|
-
|
|
11175
|
-
})
|
|
11176
|
-
.join('&');
|
|
11177
|
-
}
|
|
11178
|
-
getUserAgent() {
|
|
11179
|
-
return `${this.constructor.name}/JS ${VERSION}`;
|
|
11180
|
-
}
|
|
11181
|
-
defaultIdempotencyKey() {
|
|
11182
|
-
return `stainless-node-retry-${uuid4()}`;
|
|
11183
|
-
}
|
|
11184
|
-
makeStatusError(status, error, message, headers) {
|
|
11185
|
-
return APIError.generate(status, error, message, headers);
|
|
11186
|
-
}
|
|
11187
|
-
buildURL(path, query, defaultBaseURL) {
|
|
11188
|
-
const baseURL = (!__classPrivateFieldGet(this, _DodoPayments_instances, "m", _DodoPayments_baseURLOverridden).call(this) && defaultBaseURL) || this.baseURL;
|
|
11189
|
-
const url = isAbsoluteURL(path) ?
|
|
11190
|
-
new URL(path)
|
|
11191
|
-
: new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
|
|
11192
|
-
const defaultQuery = this.defaultQuery();
|
|
11193
|
-
if (!isEmptyObj(defaultQuery)) {
|
|
11194
|
-
query = { ...defaultQuery, ...query };
|
|
11355
|
+
out += this._paddingCharacter || "";
|
|
11195
11356
|
}
|
|
11196
|
-
|
|
11197
|
-
|
|
11357
|
+
return out;
|
|
11358
|
+
};
|
|
11359
|
+
Coder.prototype.maxDecodedLength = function (length) {
|
|
11360
|
+
if (!this._paddingCharacter) {
|
|
11361
|
+
return (length * 6 + 7) / 8 | 0;
|
|
11198
11362
|
}
|
|
11199
|
-
return
|
|
11200
|
-
}
|
|
11201
|
-
|
|
11202
|
-
|
|
11203
|
-
|
|
11204
|
-
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
*
|
|
11208
|
-
* This is useful for cases where you want to add certain headers based off of
|
|
11209
|
-
* the request properties, e.g. `method` or `url`.
|
|
11210
|
-
*/
|
|
11211
|
-
async prepareRequest(request, { url, options }) { }
|
|
11212
|
-
get(path, opts) {
|
|
11213
|
-
return this.methodRequest('get', path, opts);
|
|
11214
|
-
}
|
|
11215
|
-
post(path, opts) {
|
|
11216
|
-
return this.methodRequest('post', path, opts);
|
|
11217
|
-
}
|
|
11218
|
-
patch(path, opts) {
|
|
11219
|
-
return this.methodRequest('patch', path, opts);
|
|
11220
|
-
}
|
|
11221
|
-
put(path, opts) {
|
|
11222
|
-
return this.methodRequest('put', path, opts);
|
|
11223
|
-
}
|
|
11224
|
-
delete(path, opts) {
|
|
11225
|
-
return this.methodRequest('delete', path, opts);
|
|
11226
|
-
}
|
|
11227
|
-
methodRequest(method, path, opts) {
|
|
11228
|
-
return this.request(Promise.resolve(opts).then((opts) => {
|
|
11229
|
-
return { method, path, ...opts };
|
|
11230
|
-
}));
|
|
11231
|
-
}
|
|
11232
|
-
request(options, remainingRetries = null) {
|
|
11233
|
-
return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
|
|
11234
|
-
}
|
|
11235
|
-
async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
|
|
11236
|
-
const options = await optionsInput;
|
|
11237
|
-
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
11238
|
-
if (retriesRemaining == null) {
|
|
11239
|
-
retriesRemaining = maxRetries;
|
|
11240
|
-
}
|
|
11241
|
-
await this.prepareOptions(options);
|
|
11242
|
-
const { req, url, timeout } = await this.buildRequest(options, {
|
|
11243
|
-
retryCount: maxRetries - retriesRemaining,
|
|
11244
|
-
});
|
|
11245
|
-
await this.prepareRequest(req, { url, options });
|
|
11246
|
-
/** Not an API request ID, just for correlating local log entries. */
|
|
11247
|
-
const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
|
|
11248
|
-
const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
|
|
11249
|
-
const startTime = Date.now();
|
|
11250
|
-
loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({
|
|
11251
|
-
retryOfRequestLogID,
|
|
11252
|
-
method: options.method,
|
|
11253
|
-
url,
|
|
11254
|
-
options,
|
|
11255
|
-
headers: req.headers,
|
|
11256
|
-
}));
|
|
11257
|
-
if (options.signal?.aborted) {
|
|
11258
|
-
throw new APIUserAbortError();
|
|
11259
|
-
}
|
|
11260
|
-
const controller = new AbortController();
|
|
11261
|
-
const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
|
|
11262
|
-
const headersTime = Date.now();
|
|
11263
|
-
if (response instanceof globalThis.Error) {
|
|
11264
|
-
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
11265
|
-
if (options.signal?.aborted) {
|
|
11266
|
-
throw new APIUserAbortError();
|
|
11267
|
-
}
|
|
11268
|
-
// detect native connection timeout errors
|
|
11269
|
-
// deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
|
|
11270
|
-
// undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
|
|
11271
|
-
// others do not provide enough information to distinguish timeouts from other connection errors
|
|
11272
|
-
const isTimeout = isAbortError(response) ||
|
|
11273
|
-
/timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
|
|
11274
|
-
if (retriesRemaining) {
|
|
11275
|
-
loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`);
|
|
11276
|
-
loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({
|
|
11277
|
-
retryOfRequestLogID,
|
|
11278
|
-
url,
|
|
11279
|
-
durationMs: headersTime - startTime,
|
|
11280
|
-
message: response.message,
|
|
11281
|
-
}));
|
|
11282
|
-
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
|
|
11283
|
-
}
|
|
11284
|
-
loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`);
|
|
11285
|
-
loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({
|
|
11286
|
-
retryOfRequestLogID,
|
|
11287
|
-
url,
|
|
11288
|
-
durationMs: headersTime - startTime,
|
|
11289
|
-
message: response.message,
|
|
11290
|
-
}));
|
|
11291
|
-
if (isTimeout) {
|
|
11292
|
-
throw new APIConnectionTimeoutError();
|
|
11293
|
-
}
|
|
11294
|
-
throw new APIConnectionError({ cause: response });
|
|
11295
|
-
}
|
|
11296
|
-
const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
|
|
11297
|
-
if (!response.ok) {
|
|
11298
|
-
const shouldRetry = await this.shouldRetry(response);
|
|
11299
|
-
if (retriesRemaining && shouldRetry) {
|
|
11300
|
-
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
11301
|
-
// We don't need the body of this response.
|
|
11302
|
-
await CancelReadableStream(response.body);
|
|
11303
|
-
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
11304
|
-
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
|
|
11305
|
-
retryOfRequestLogID,
|
|
11306
|
-
url: response.url,
|
|
11307
|
-
status: response.status,
|
|
11308
|
-
headers: response.headers,
|
|
11309
|
-
durationMs: headersTime - startTime,
|
|
11310
|
-
}));
|
|
11311
|
-
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers);
|
|
11312
|
-
}
|
|
11313
|
-
const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
|
|
11314
|
-
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
11315
|
-
const errText = await response.text().catch((err) => castToError(err).message);
|
|
11316
|
-
const errJSON = safeJSON(errText);
|
|
11317
|
-
const errMessage = errJSON ? undefined : errText;
|
|
11318
|
-
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
|
|
11319
|
-
retryOfRequestLogID,
|
|
11320
|
-
url: response.url,
|
|
11321
|
-
status: response.status,
|
|
11322
|
-
headers: response.headers,
|
|
11323
|
-
message: errMessage,
|
|
11324
|
-
durationMs: Date.now() - startTime,
|
|
11325
|
-
}));
|
|
11326
|
-
const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
|
|
11327
|
-
throw err;
|
|
11328
|
-
}
|
|
11329
|
-
loggerFor(this).info(responseInfo);
|
|
11330
|
-
loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
|
|
11331
|
-
retryOfRequestLogID,
|
|
11332
|
-
url: response.url,
|
|
11333
|
-
status: response.status,
|
|
11334
|
-
headers: response.headers,
|
|
11335
|
-
durationMs: headersTime - startTime,
|
|
11336
|
-
}));
|
|
11337
|
-
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
|
|
11338
|
-
}
|
|
11339
|
-
getAPIList(path, Page, opts) {
|
|
11340
|
-
return this.requestAPIList(Page, { method: 'get', path, ...opts });
|
|
11341
|
-
}
|
|
11342
|
-
requestAPIList(Page, options) {
|
|
11343
|
-
const request = this.makeRequest(options, null, undefined);
|
|
11344
|
-
return new PagePromise(this, request, Page);
|
|
11345
|
-
}
|
|
11346
|
-
async fetchWithTimeout(url, init, ms, controller) {
|
|
11347
|
-
const { signal, method, ...options } = init || {};
|
|
11348
|
-
if (signal)
|
|
11349
|
-
signal.addEventListener('abort', () => controller.abort());
|
|
11350
|
-
const timeout = setTimeout(() => controller.abort(), ms);
|
|
11351
|
-
const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
|
|
11352
|
-
(typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
|
|
11353
|
-
const fetchOptions = {
|
|
11354
|
-
signal: controller.signal,
|
|
11355
|
-
...(isReadableBody ? { duplex: 'half' } : {}),
|
|
11356
|
-
method: 'GET',
|
|
11357
|
-
...options,
|
|
11358
|
-
};
|
|
11359
|
-
if (method) {
|
|
11360
|
-
// Custom methods like 'patch' need to be uppercased
|
|
11361
|
-
// See https://github.com/nodejs/undici/issues/2294
|
|
11362
|
-
fetchOptions.method = method.toUpperCase();
|
|
11363
|
+
return length / 4 * 3 | 0;
|
|
11364
|
+
};
|
|
11365
|
+
Coder.prototype.decodedLength = function (s) {
|
|
11366
|
+
return this.maxDecodedLength(s.length - this._getPaddingLength(s));
|
|
11367
|
+
};
|
|
11368
|
+
Coder.prototype.decode = function (s) {
|
|
11369
|
+
if (s.length === 0) {
|
|
11370
|
+
return new Uint8Array(0);
|
|
11363
11371
|
}
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11372
|
+
var paddingLength = this._getPaddingLength(s);
|
|
11373
|
+
var length = s.length - paddingLength;
|
|
11374
|
+
var out = new Uint8Array(this.maxDecodedLength(length));
|
|
11375
|
+
var op = 0;
|
|
11376
|
+
var i = 0;
|
|
11377
|
+
var haveBad = 0;
|
|
11378
|
+
var v0 = 0, v1 = 0, v2 = 0, v3 = 0;
|
|
11379
|
+
for (; i < length - 4; i += 4) {
|
|
11380
|
+
v0 = this._decodeChar(s.charCodeAt(i + 0));
|
|
11381
|
+
v1 = this._decodeChar(s.charCodeAt(i + 1));
|
|
11382
|
+
v2 = this._decodeChar(s.charCodeAt(i + 2));
|
|
11383
|
+
v3 = this._decodeChar(s.charCodeAt(i + 3));
|
|
11384
|
+
out[op++] = (v0 << 2) | (v1 >>> 4);
|
|
11385
|
+
out[op++] = (v1 << 4) | (v2 >>> 2);
|
|
11386
|
+
out[op++] = (v2 << 6) | v3;
|
|
11387
|
+
haveBad |= v0 & INVALID_BYTE;
|
|
11388
|
+
haveBad |= v1 & INVALID_BYTE;
|
|
11389
|
+
haveBad |= v2 & INVALID_BYTE;
|
|
11390
|
+
haveBad |= v3 & INVALID_BYTE;
|
|
11367
11391
|
}
|
|
11368
|
-
|
|
11369
|
-
|
|
11392
|
+
if (i < length - 1) {
|
|
11393
|
+
v0 = this._decodeChar(s.charCodeAt(i));
|
|
11394
|
+
v1 = this._decodeChar(s.charCodeAt(i + 1));
|
|
11395
|
+
out[op++] = (v0 << 2) | (v1 >>> 4);
|
|
11396
|
+
haveBad |= v0 & INVALID_BYTE;
|
|
11397
|
+
haveBad |= v1 & INVALID_BYTE;
|
|
11370
11398
|
}
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
// If the server explicitly says whether or not to retry, obey.
|
|
11376
|
-
if (shouldRetryHeader === 'true')
|
|
11377
|
-
return true;
|
|
11378
|
-
if (shouldRetryHeader === 'false')
|
|
11379
|
-
return false;
|
|
11380
|
-
// Retry on request timeouts.
|
|
11381
|
-
if (response.status === 408)
|
|
11382
|
-
return true;
|
|
11383
|
-
// Retry on lock timeouts.
|
|
11384
|
-
if (response.status === 409)
|
|
11385
|
-
return true;
|
|
11386
|
-
// Retry on rate limits.
|
|
11387
|
-
if (response.status === 429)
|
|
11388
|
-
return true;
|
|
11389
|
-
// Retry internal errors.
|
|
11390
|
-
if (response.status >= 500)
|
|
11391
|
-
return true;
|
|
11392
|
-
return false;
|
|
11393
|
-
}
|
|
11394
|
-
async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
|
|
11395
|
-
let timeoutMillis;
|
|
11396
|
-
// Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
|
|
11397
|
-
const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms');
|
|
11398
|
-
if (retryAfterMillisHeader) {
|
|
11399
|
-
const timeoutMs = parseFloat(retryAfterMillisHeader);
|
|
11400
|
-
if (!Number.isNaN(timeoutMs)) {
|
|
11401
|
-
timeoutMillis = timeoutMs;
|
|
11402
|
-
}
|
|
11399
|
+
if (i < length - 2) {
|
|
11400
|
+
v2 = this._decodeChar(s.charCodeAt(i + 2));
|
|
11401
|
+
out[op++] = (v1 << 4) | (v2 >>> 2);
|
|
11402
|
+
haveBad |= v2 & INVALID_BYTE;
|
|
11403
11403
|
}
|
|
11404
|
-
|
|
11405
|
-
|
|
11406
|
-
|
|
11407
|
-
|
|
11408
|
-
if (!Number.isNaN(timeoutSeconds)) {
|
|
11409
|
-
timeoutMillis = timeoutSeconds * 1000;
|
|
11410
|
-
}
|
|
11411
|
-
else {
|
|
11412
|
-
timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
|
|
11413
|
-
}
|
|
11404
|
+
if (i < length - 3) {
|
|
11405
|
+
v3 = this._decodeChar(s.charCodeAt(i + 3));
|
|
11406
|
+
out[op++] = (v2 << 6) | v3;
|
|
11407
|
+
haveBad |= v3 & INVALID_BYTE;
|
|
11414
11408
|
}
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
|
|
11418
|
-
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
11419
|
-
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
11409
|
+
if (haveBad !== 0) {
|
|
11410
|
+
throw new Error("Base64Coder: incorrect characters for decoding");
|
|
11420
11411
|
}
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11430
|
-
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
|
|
11438
|
-
|
|
11439
|
-
|
|
11440
|
-
|
|
11441
|
-
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11448
|
-
|
|
11449
|
-
|
|
11450
|
-
|
|
11451
|
-
|
|
11452
|
-
|
|
11453
|
-
|
|
11454
|
-
|
|
11455
|
-
|
|
11456
|
-
|
|
11457
|
-
|
|
11458
|
-
|
|
11459
|
-
|
|
11460
|
-
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11475
|
-
|
|
11476
|
-
|
|
11477
|
-
|
|
11478
|
-
|
|
11479
|
-
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
|
|
11485
|
-
|
|
11486
|
-
|
|
11487
|
-
|
|
11488
|
-
|
|
11489
|
-
|
|
11490
|
-
|
|
11491
|
-
|
|
11492
|
-
|
|
11493
|
-
(
|
|
11494
|
-
|
|
11495
|
-
|
|
11496
|
-
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
(
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
else if (typeof body === 'object' &&
|
|
11503
|
-
(Symbol.asyncIterator in body ||
|
|
11504
|
-
(Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
|
|
11505
|
-
return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
|
|
11506
|
-
}
|
|
11507
|
-
else {
|
|
11508
|
-
return __classPrivateFieldGet(this, _DodoPayments_encoder, "f").call(this, { body, headers });
|
|
11412
|
+
return out;
|
|
11413
|
+
};
|
|
11414
|
+
// Standard encoding have the following encoded/decoded ranges,
|
|
11415
|
+
// which we need to convert between.
|
|
11416
|
+
//
|
|
11417
|
+
// ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + /
|
|
11418
|
+
// Index: 0 - 25 26 - 51 52 - 61 62 63
|
|
11419
|
+
// ASCII: 65 - 90 97 - 122 48 - 57 43 47
|
|
11420
|
+
//
|
|
11421
|
+
// Encode 6 bits in b into a new character.
|
|
11422
|
+
Coder.prototype._encodeByte = function (b) {
|
|
11423
|
+
// Encoding uses constant time operations as follows:
|
|
11424
|
+
//
|
|
11425
|
+
// 1. Define comparison of A with B using (A - B) >>> 8:
|
|
11426
|
+
// if A > B, then result is positive integer
|
|
11427
|
+
// if A <= B, then result is 0
|
|
11428
|
+
//
|
|
11429
|
+
// 2. Define selection of C or 0 using bitwise AND: X & C:
|
|
11430
|
+
// if X == 0, then result is 0
|
|
11431
|
+
// if X != 0, then result is C
|
|
11432
|
+
//
|
|
11433
|
+
// 3. Start with the smallest comparison (b >= 0), which is always
|
|
11434
|
+
// true, so set the result to the starting ASCII value (65).
|
|
11435
|
+
//
|
|
11436
|
+
// 4. Continue comparing b to higher ASCII values, and selecting
|
|
11437
|
+
// zero if comparison isn't true, otherwise selecting a value
|
|
11438
|
+
// to add to result, which:
|
|
11439
|
+
//
|
|
11440
|
+
// a) undoes the previous addition
|
|
11441
|
+
// b) provides new value to add
|
|
11442
|
+
//
|
|
11443
|
+
var result = b;
|
|
11444
|
+
// b >= 0
|
|
11445
|
+
result += 65;
|
|
11446
|
+
// b > 25
|
|
11447
|
+
result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
|
|
11448
|
+
// b > 51
|
|
11449
|
+
result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
|
|
11450
|
+
// b > 61
|
|
11451
|
+
result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43);
|
|
11452
|
+
// b > 62
|
|
11453
|
+
result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47);
|
|
11454
|
+
return String.fromCharCode(result);
|
|
11455
|
+
};
|
|
11456
|
+
// Decode a character code into a byte.
|
|
11457
|
+
// Must return 256 if character is out of alphabet range.
|
|
11458
|
+
Coder.prototype._decodeChar = function (c) {
|
|
11459
|
+
// Decoding works similar to encoding: using the same comparison
|
|
11460
|
+
// function, but now it works on ranges: result is always incremented
|
|
11461
|
+
// by value, but this value becomes zero if the range is not
|
|
11462
|
+
// satisfied.
|
|
11463
|
+
//
|
|
11464
|
+
// Decoding starts with invalid value, 256, which is then
|
|
11465
|
+
// subtracted when the range is satisfied. If none of the ranges
|
|
11466
|
+
// apply, the function returns 256, which is then checked by
|
|
11467
|
+
// the caller to throw error.
|
|
11468
|
+
var result = INVALID_BYTE; // start with invalid character
|
|
11469
|
+
// c == 43 (c > 42 and c < 44)
|
|
11470
|
+
result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62);
|
|
11471
|
+
// c == 47 (c > 46 and c < 48)
|
|
11472
|
+
result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63);
|
|
11473
|
+
// c > 47 and c < 58
|
|
11474
|
+
result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
|
|
11475
|
+
// c > 64 and c < 91
|
|
11476
|
+
result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
|
|
11477
|
+
// c > 96 and c < 123
|
|
11478
|
+
result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
|
|
11479
|
+
return result;
|
|
11480
|
+
};
|
|
11481
|
+
Coder.prototype._getPaddingLength = function (s) {
|
|
11482
|
+
var paddingLength = 0;
|
|
11483
|
+
if (this._paddingCharacter) {
|
|
11484
|
+
for (var i = s.length - 1; i >= 0; i--) {
|
|
11485
|
+
if (s[i] !== this._paddingCharacter) {
|
|
11486
|
+
break;
|
|
11487
|
+
}
|
|
11488
|
+
paddingLength++;
|
|
11489
|
+
}
|
|
11490
|
+
if (s.length < 4 || paddingLength > 2) {
|
|
11491
|
+
throw new Error("Base64Coder: incorrect padding");
|
|
11492
|
+
}
|
|
11509
11493
|
}
|
|
11494
|
+
return paddingLength;
|
|
11495
|
+
};
|
|
11496
|
+
return Coder;
|
|
11497
|
+
}());
|
|
11498
|
+
base64$1.Coder = Coder;
|
|
11499
|
+
var stdCoder = new Coder();
|
|
11500
|
+
function encode(data) {
|
|
11501
|
+
return stdCoder.encode(data);
|
|
11502
|
+
}
|
|
11503
|
+
base64$1.encode = encode;
|
|
11504
|
+
function decode(s) {
|
|
11505
|
+
return stdCoder.decode(s);
|
|
11506
|
+
}
|
|
11507
|
+
base64$1.decode = decode;
|
|
11508
|
+
/**
|
|
11509
|
+
* Implements URL-safe Base64 encoding.
|
|
11510
|
+
* (Same as Base64, but '+' is replaced with '-', and '/' with '_').
|
|
11511
|
+
*
|
|
11512
|
+
* Operates in constant time.
|
|
11513
|
+
*/
|
|
11514
|
+
var URLSafeCoder = /** @class */ (function (_super) {
|
|
11515
|
+
__extends(URLSafeCoder, _super);
|
|
11516
|
+
function URLSafeCoder() {
|
|
11517
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
11510
11518
|
}
|
|
11519
|
+
// URL-safe encoding have the following encoded/decoded ranges:
|
|
11520
|
+
//
|
|
11521
|
+
// ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _
|
|
11522
|
+
// Index: 0 - 25 26 - 51 52 - 61 62 63
|
|
11523
|
+
// ASCII: 65 - 90 97 - 122 48 - 57 45 95
|
|
11524
|
+
//
|
|
11525
|
+
URLSafeCoder.prototype._encodeByte = function (b) {
|
|
11526
|
+
var result = b;
|
|
11527
|
+
// b >= 0
|
|
11528
|
+
result += 65;
|
|
11529
|
+
// b > 25
|
|
11530
|
+
result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
|
|
11531
|
+
// b > 51
|
|
11532
|
+
result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
|
|
11533
|
+
// b > 61
|
|
11534
|
+
result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45);
|
|
11535
|
+
// b > 62
|
|
11536
|
+
result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95);
|
|
11537
|
+
return String.fromCharCode(result);
|
|
11538
|
+
};
|
|
11539
|
+
URLSafeCoder.prototype._decodeChar = function (c) {
|
|
11540
|
+
var result = INVALID_BYTE;
|
|
11541
|
+
// c == 45 (c > 44 and c < 46)
|
|
11542
|
+
result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62);
|
|
11543
|
+
// c == 95 (c > 94 and c < 96)
|
|
11544
|
+
result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63);
|
|
11545
|
+
// c > 47 and c < 58
|
|
11546
|
+
result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
|
|
11547
|
+
// c > 64 and c < 91
|
|
11548
|
+
result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
|
|
11549
|
+
// c > 96 and c < 123
|
|
11550
|
+
result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
|
|
11551
|
+
return result;
|
|
11552
|
+
};
|
|
11553
|
+
return URLSafeCoder;
|
|
11554
|
+
}(Coder));
|
|
11555
|
+
base64$1.URLSafeCoder = URLSafeCoder;
|
|
11556
|
+
var urlSafeCoder = new URLSafeCoder();
|
|
11557
|
+
function encodeURLSafe(data) {
|
|
11558
|
+
return urlSafeCoder.encode(data);
|
|
11511
11559
|
}
|
|
11512
|
-
|
|
11513
|
-
|
|
11560
|
+
base64$1.encodeURLSafe = encodeURLSafe;
|
|
11561
|
+
function decodeURLSafe(s) {
|
|
11562
|
+
return urlSafeCoder.decode(s);
|
|
11563
|
+
}
|
|
11564
|
+
base64$1.decodeURLSafe = decodeURLSafe;
|
|
11565
|
+
base64$1.encodedLength = function (length) {
|
|
11566
|
+
return stdCoder.encodedLength(length);
|
|
11514
11567
|
};
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
DodoPayments.DodoPaymentsError = DodoPaymentsError;
|
|
11518
|
-
DodoPayments.APIError = APIError;
|
|
11519
|
-
DodoPayments.APIConnectionError = APIConnectionError;
|
|
11520
|
-
DodoPayments.APIConnectionTimeoutError = APIConnectionTimeoutError;
|
|
11521
|
-
DodoPayments.APIUserAbortError = APIUserAbortError;
|
|
11522
|
-
DodoPayments.NotFoundError = NotFoundError;
|
|
11523
|
-
DodoPayments.ConflictError = ConflictError;
|
|
11524
|
-
DodoPayments.RateLimitError = RateLimitError;
|
|
11525
|
-
DodoPayments.BadRequestError = BadRequestError;
|
|
11526
|
-
DodoPayments.AuthenticationError = AuthenticationError;
|
|
11527
|
-
DodoPayments.InternalServerError = InternalServerError;
|
|
11528
|
-
DodoPayments.PermissionDeniedError = PermissionDeniedError;
|
|
11529
|
-
DodoPayments.UnprocessableEntityError = UnprocessableEntityError;
|
|
11530
|
-
DodoPayments.toFile = toFile;
|
|
11531
|
-
DodoPayments.CheckoutSessions = CheckoutSessions;
|
|
11532
|
-
DodoPayments.Payments = Payments;
|
|
11533
|
-
DodoPayments.Subscriptions = Subscriptions;
|
|
11534
|
-
DodoPayments.Invoices = Invoices;
|
|
11535
|
-
DodoPayments.Licenses = Licenses;
|
|
11536
|
-
DodoPayments.LicenseKeys = LicenseKeys;
|
|
11537
|
-
DodoPayments.LicenseKeyInstances = LicenseKeyInstances;
|
|
11538
|
-
DodoPayments.Customers = Customers;
|
|
11539
|
-
DodoPayments.Refunds = Refunds;
|
|
11540
|
-
DodoPayments.Disputes = Disputes;
|
|
11541
|
-
DodoPayments.Payouts = Payouts;
|
|
11542
|
-
DodoPayments.WebhookEvents = WebhookEvents;
|
|
11543
|
-
DodoPayments.Products = Products;
|
|
11544
|
-
DodoPayments.Misc = Misc;
|
|
11545
|
-
DodoPayments.Discounts = Discounts;
|
|
11546
|
-
DodoPayments.Addons = Addons;
|
|
11547
|
-
DodoPayments.Brands = Brands;
|
|
11548
|
-
DodoPayments.Webhooks = Webhooks$1;
|
|
11549
|
-
DodoPayments.UsageEvents = UsageEvents;
|
|
11550
|
-
DodoPayments.Meters = Meters;
|
|
11551
|
-
|
|
11552
|
-
// src/checkout/checkout.ts
|
|
11553
|
-
var checkoutQuerySchema = objectType({
|
|
11554
|
-
productId: stringType(),
|
|
11555
|
-
quantity: stringType().optional(),
|
|
11556
|
-
// Customer fields
|
|
11557
|
-
fullName: stringType().optional(),
|
|
11558
|
-
firstName: stringType().optional(),
|
|
11559
|
-
lastName: stringType().optional(),
|
|
11560
|
-
email: stringType().optional(),
|
|
11561
|
-
country: stringType().optional(),
|
|
11562
|
-
addressLine: stringType().optional(),
|
|
11563
|
-
city: stringType().optional(),
|
|
11564
|
-
state: stringType().optional(),
|
|
11565
|
-
zipCode: stringType().optional(),
|
|
11566
|
-
// Disable flags
|
|
11567
|
-
disableFullName: stringType().optional(),
|
|
11568
|
-
disableFirstName: stringType().optional(),
|
|
11569
|
-
disableLastName: stringType().optional(),
|
|
11570
|
-
disableEmail: stringType().optional(),
|
|
11571
|
-
disableCountry: stringType().optional(),
|
|
11572
|
-
disableAddressLine: stringType().optional(),
|
|
11573
|
-
disableCity: stringType().optional(),
|
|
11574
|
-
disableState: stringType().optional(),
|
|
11575
|
-
disableZipCode: stringType().optional(),
|
|
11576
|
-
// Advanced controls
|
|
11577
|
-
paymentCurrency: stringType().optional(),
|
|
11578
|
-
showCurrencySelector: stringType().optional(),
|
|
11579
|
-
paymentAmount: stringType().optional(),
|
|
11580
|
-
showDiscounts: stringType().optional()
|
|
11581
|
-
// Metadata (allow any key starting with metadata_)
|
|
11582
|
-
// We'll handle metadata separately in the handler
|
|
11583
|
-
}).catchall(unknownType());
|
|
11584
|
-
var dynamicCheckoutBodySchema = objectType({
|
|
11585
|
-
// For subscription
|
|
11586
|
-
product_id: stringType().optional(),
|
|
11587
|
-
quantity: numberType().optional(),
|
|
11588
|
-
// For one-time payment
|
|
11589
|
-
product_cart: arrayType(
|
|
11590
|
-
objectType({
|
|
11591
|
-
product_id: stringType(),
|
|
11592
|
-
quantity: numberType()
|
|
11593
|
-
})
|
|
11594
|
-
).optional(),
|
|
11595
|
-
// Common fields
|
|
11596
|
-
billing: objectType({
|
|
11597
|
-
city: stringType(),
|
|
11598
|
-
country: stringType(),
|
|
11599
|
-
state: stringType(),
|
|
11600
|
-
street: stringType(),
|
|
11601
|
-
zipcode: stringType()
|
|
11602
|
-
}),
|
|
11603
|
-
customer: objectType({
|
|
11604
|
-
customer_id: stringType().optional(),
|
|
11605
|
-
email: stringType().optional(),
|
|
11606
|
-
name: stringType().optional()
|
|
11607
|
-
}),
|
|
11608
|
-
discount_id: stringType().optional(),
|
|
11609
|
-
addons: arrayType(
|
|
11610
|
-
objectType({
|
|
11611
|
-
addon_id: stringType(),
|
|
11612
|
-
quantity: numberType()
|
|
11613
|
-
})
|
|
11614
|
-
).optional(),
|
|
11615
|
-
metadata: recordType(stringType(), stringType()).optional(),
|
|
11616
|
-
currency: stringType().optional()
|
|
11617
|
-
// Allow any additional fields (for future compatibility)
|
|
11618
|
-
}).catchall(unknownType());
|
|
11619
|
-
var checkoutSessionProductCartItemSchema = objectType({
|
|
11620
|
-
product_id: stringType().min(1, "Product ID is required"),
|
|
11621
|
-
quantity: numberType().int().positive("Quantity must be a positive integer")
|
|
11622
|
-
});
|
|
11623
|
-
var checkoutSessionCustomerSchema = objectType({
|
|
11624
|
-
email: stringType().email().optional(),
|
|
11625
|
-
name: stringType().min(1).optional(),
|
|
11626
|
-
phone_number: stringType().optional()
|
|
11627
|
-
}).optional();
|
|
11628
|
-
var checkoutSessionBillingAddressSchema = objectType({
|
|
11629
|
-
street: stringType().optional(),
|
|
11630
|
-
city: stringType().optional(),
|
|
11631
|
-
state: stringType().optional(),
|
|
11632
|
-
country: stringType().length(2, "Country must be a 2-letter ISO code"),
|
|
11633
|
-
zipcode: stringType().optional()
|
|
11634
|
-
}).optional();
|
|
11635
|
-
var paymentMethodTypeSchema = enumType([
|
|
11636
|
-
"credit",
|
|
11637
|
-
"debit",
|
|
11638
|
-
"upi_collect",
|
|
11639
|
-
"upi_intent",
|
|
11640
|
-
"apple_pay",
|
|
11641
|
-
"google_pay",
|
|
11642
|
-
"amazon_pay",
|
|
11643
|
-
"klarna",
|
|
11644
|
-
"affirm",
|
|
11645
|
-
"afterpay_clearpay",
|
|
11646
|
-
"sepa",
|
|
11647
|
-
"ach"
|
|
11648
|
-
]);
|
|
11649
|
-
var checkoutSessionCustomizationSchema = objectType({
|
|
11650
|
-
theme: enumType(["light", "dark", "system"]).optional(),
|
|
11651
|
-
show_order_details: booleanType().optional(),
|
|
11652
|
-
show_on_demand_tag: booleanType().optional()
|
|
11653
|
-
}).optional();
|
|
11654
|
-
var checkoutSessionFeatureFlagsSchema = objectType({
|
|
11655
|
-
allow_currency_selection: booleanType().optional(),
|
|
11656
|
-
allow_discount_code: booleanType().optional(),
|
|
11657
|
-
allow_phone_number_collection: booleanType().optional(),
|
|
11658
|
-
allow_tax_id: booleanType().optional(),
|
|
11659
|
-
always_create_new_customer: booleanType().optional()
|
|
11660
|
-
}).optional();
|
|
11661
|
-
var checkoutSessionSubscriptionDataSchema = objectType({
|
|
11662
|
-
trial_period_days: numberType().int().nonnegative().optional()
|
|
11663
|
-
}).optional();
|
|
11664
|
-
var checkoutSessionPayloadSchema = objectType({
|
|
11665
|
-
// Required fields
|
|
11666
|
-
product_cart: arrayType(checkoutSessionProductCartItemSchema).min(1, "At least one product is required"),
|
|
11667
|
-
// Optional fields
|
|
11668
|
-
customer: checkoutSessionCustomerSchema,
|
|
11669
|
-
billing_address: checkoutSessionBillingAddressSchema,
|
|
11670
|
-
return_url: stringType().url().optional(),
|
|
11671
|
-
allowed_payment_method_types: arrayType(paymentMethodTypeSchema).optional(),
|
|
11672
|
-
billing_currency: stringType().length(3, "Currency must be a 3-letter ISO code").optional(),
|
|
11673
|
-
show_saved_payment_methods: booleanType().optional(),
|
|
11674
|
-
confirm: booleanType().optional(),
|
|
11675
|
-
discount_code: stringType().optional(),
|
|
11676
|
-
metadata: recordType(stringType(), stringType()).optional(),
|
|
11677
|
-
customization: checkoutSessionCustomizationSchema,
|
|
11678
|
-
feature_flags: checkoutSessionFeatureFlagsSchema,
|
|
11679
|
-
subscription_data: checkoutSessionSubscriptionDataSchema
|
|
11680
|
-
});
|
|
11681
|
-
var checkoutSessionResponseSchema = objectType({
|
|
11682
|
-
session_id: stringType().min(1, "Session ID is required"),
|
|
11683
|
-
checkout_url: stringType().url("Invalid checkout URL")
|
|
11684
|
-
});
|
|
11685
|
-
var createCheckoutSession = async (payload, config) => {
|
|
11686
|
-
const validation = checkoutSessionPayloadSchema.safeParse(payload);
|
|
11687
|
-
if (!validation.success) {
|
|
11688
|
-
throw new Error(
|
|
11689
|
-
`Invalid checkout session payload: ${validation.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(", ")}`
|
|
11690
|
-
);
|
|
11691
|
-
}
|
|
11692
|
-
const dodopayments = new DodoPayments({
|
|
11693
|
-
bearerToken: config.bearerToken,
|
|
11694
|
-
environment: config.environment
|
|
11695
|
-
});
|
|
11696
|
-
try {
|
|
11697
|
-
const sdkPayload = {
|
|
11698
|
-
...validation.data,
|
|
11699
|
-
...validation.data.billing_address && {
|
|
11700
|
-
billing_address: {
|
|
11701
|
-
...validation.data.billing_address,
|
|
11702
|
-
country: validation.data.billing_address.country
|
|
11703
|
-
}
|
|
11704
|
-
}
|
|
11705
|
-
};
|
|
11706
|
-
const session = await dodopayments.checkoutSessions.create(
|
|
11707
|
-
sdkPayload
|
|
11708
|
-
);
|
|
11709
|
-
const responseValidation = checkoutSessionResponseSchema.safeParse(session);
|
|
11710
|
-
if (!responseValidation.success) {
|
|
11711
|
-
throw new Error(
|
|
11712
|
-
`Invalid checkout session response from API: ${responseValidation.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(", ")}`
|
|
11713
|
-
);
|
|
11714
|
-
}
|
|
11715
|
-
return responseValidation.data;
|
|
11716
|
-
} catch (error) {
|
|
11717
|
-
if (error instanceof Error) {
|
|
11718
|
-
console.error("Dodo Payments Checkout Session API Error:", {
|
|
11719
|
-
message: error.message,
|
|
11720
|
-
payload: validation.data,
|
|
11721
|
-
config: {
|
|
11722
|
-
environment: config.environment,
|
|
11723
|
-
hasBearerToken: !!config.bearerToken
|
|
11724
|
-
}
|
|
11725
|
-
});
|
|
11726
|
-
throw new Error(`Failed to create checkout session: ${error.message}`);
|
|
11727
|
-
}
|
|
11728
|
-
console.error("Unknown error creating checkout session:", error);
|
|
11729
|
-
throw new Error(
|
|
11730
|
-
"Failed to create checkout session due to an unknown error"
|
|
11731
|
-
);
|
|
11732
|
-
}
|
|
11568
|
+
base64$1.maxDecodedLength = function (length) {
|
|
11569
|
+
return stdCoder.maxDecodedLength(length);
|
|
11733
11570
|
};
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
body,
|
|
11737
|
-
sessionPayload,
|
|
11738
|
-
returnUrl,
|
|
11739
|
-
bearerToken,
|
|
11740
|
-
environment,
|
|
11741
|
-
type = "static"
|
|
11742
|
-
}) => {
|
|
11743
|
-
if (type === "session") {
|
|
11744
|
-
if (!sessionPayload) {
|
|
11745
|
-
throw new Error("sessionPayload is required when type is 'session'");
|
|
11746
|
-
}
|
|
11747
|
-
const session = await createCheckoutSession(sessionPayload, {
|
|
11748
|
-
bearerToken,
|
|
11749
|
-
environment
|
|
11750
|
-
});
|
|
11751
|
-
return session.checkout_url;
|
|
11752
|
-
}
|
|
11753
|
-
const inputData = type === "dynamic" ? body : queryParams;
|
|
11754
|
-
let parseResult;
|
|
11755
|
-
if (type === "dynamic") {
|
|
11756
|
-
parseResult = dynamicCheckoutBodySchema.safeParse(inputData);
|
|
11757
|
-
} else {
|
|
11758
|
-
parseResult = checkoutQuerySchema.safeParse(inputData);
|
|
11759
|
-
}
|
|
11760
|
-
const { success, data, error } = parseResult;
|
|
11761
|
-
if (!success) {
|
|
11762
|
-
throw new Error(
|
|
11763
|
-
`Invalid ${type === "dynamic" ? "body" : "query parameters"}.
|
|
11764
|
-
${error.message}`
|
|
11765
|
-
);
|
|
11766
|
-
}
|
|
11767
|
-
if (type !== "dynamic") {
|
|
11768
|
-
const {
|
|
11769
|
-
productId,
|
|
11770
|
-
quantity: quantity2,
|
|
11771
|
-
fullName,
|
|
11772
|
-
firstName,
|
|
11773
|
-
lastName,
|
|
11774
|
-
email,
|
|
11775
|
-
country,
|
|
11776
|
-
addressLine,
|
|
11777
|
-
city,
|
|
11778
|
-
state,
|
|
11779
|
-
zipCode,
|
|
11780
|
-
disableFullName,
|
|
11781
|
-
disableFirstName,
|
|
11782
|
-
disableLastName,
|
|
11783
|
-
disableEmail,
|
|
11784
|
-
disableCountry,
|
|
11785
|
-
disableAddressLine,
|
|
11786
|
-
disableCity,
|
|
11787
|
-
disableState,
|
|
11788
|
-
disableZipCode,
|
|
11789
|
-
paymentCurrency,
|
|
11790
|
-
showCurrencySelector,
|
|
11791
|
-
paymentAmount,
|
|
11792
|
-
showDiscounts
|
|
11793
|
-
// metadata handled below
|
|
11794
|
-
} = data;
|
|
11795
|
-
const dodopayments2 = new DodoPayments({
|
|
11796
|
-
bearerToken,
|
|
11797
|
-
environment
|
|
11798
|
-
});
|
|
11799
|
-
if (!productId) throw new Error("Missing required field: productId");
|
|
11800
|
-
try {
|
|
11801
|
-
await dodopayments2.products.retrieve(productId);
|
|
11802
|
-
} catch (err) {
|
|
11803
|
-
console.error(err);
|
|
11804
|
-
throw new Error("Product not found");
|
|
11805
|
-
}
|
|
11806
|
-
const url = new URL(
|
|
11807
|
-
`${environment === "test_mode" ? "https://test.checkout.dodopayments.com" : "https://checkout.dodopayments.com"}/buy/${productId}`
|
|
11808
|
-
);
|
|
11809
|
-
url.searchParams.set("quantity", quantity2 ? String(quantity2) : "1");
|
|
11810
|
-
if (returnUrl) url.searchParams.set("redirect_url", returnUrl);
|
|
11811
|
-
if (fullName) url.searchParams.set("fullName", String(fullName));
|
|
11812
|
-
if (firstName) url.searchParams.set("firstName", String(firstName));
|
|
11813
|
-
if (lastName) url.searchParams.set("lastName", String(lastName));
|
|
11814
|
-
if (email) url.searchParams.set("email", String(email));
|
|
11815
|
-
if (country) url.searchParams.set("country", String(country));
|
|
11816
|
-
if (addressLine) url.searchParams.set("addressLine", String(addressLine));
|
|
11817
|
-
if (city) url.searchParams.set("city", String(city));
|
|
11818
|
-
if (state) url.searchParams.set("state", String(state));
|
|
11819
|
-
if (zipCode) url.searchParams.set("zipCode", String(zipCode));
|
|
11820
|
-
if (disableFullName === "true")
|
|
11821
|
-
url.searchParams.set("disableFullName", "true");
|
|
11822
|
-
if (disableFirstName === "true")
|
|
11823
|
-
url.searchParams.set("disableFirstName", "true");
|
|
11824
|
-
if (disableLastName === "true")
|
|
11825
|
-
url.searchParams.set("disableLastName", "true");
|
|
11826
|
-
if (disableEmail === "true") url.searchParams.set("disableEmail", "true");
|
|
11827
|
-
if (disableCountry === "true")
|
|
11828
|
-
url.searchParams.set("disableCountry", "true");
|
|
11829
|
-
if (disableAddressLine === "true")
|
|
11830
|
-
url.searchParams.set("disableAddressLine", "true");
|
|
11831
|
-
if (disableCity === "true") url.searchParams.set("disableCity", "true");
|
|
11832
|
-
if (disableState === "true") url.searchParams.set("disableState", "true");
|
|
11833
|
-
if (disableZipCode === "true")
|
|
11834
|
-
url.searchParams.set("disableZipCode", "true");
|
|
11835
|
-
if (paymentCurrency)
|
|
11836
|
-
url.searchParams.set("paymentCurrency", String(paymentCurrency));
|
|
11837
|
-
if (showCurrencySelector)
|
|
11838
|
-
url.searchParams.set(
|
|
11839
|
-
"showCurrencySelector",
|
|
11840
|
-
String(showCurrencySelector)
|
|
11841
|
-
);
|
|
11842
|
-
if (paymentAmount)
|
|
11843
|
-
url.searchParams.set("paymentAmount", String(paymentAmount));
|
|
11844
|
-
if (showDiscounts)
|
|
11845
|
-
url.searchParams.set("showDiscounts", String(showDiscounts));
|
|
11846
|
-
for (const [key, value] of Object.entries(queryParams || {})) {
|
|
11847
|
-
if (key.startsWith("metadata_") && value && typeof value !== "object") {
|
|
11848
|
-
url.searchParams.set(key, String(value));
|
|
11849
|
-
}
|
|
11850
|
-
}
|
|
11851
|
-
return url.toString();
|
|
11852
|
-
}
|
|
11853
|
-
const dyn = data;
|
|
11854
|
-
const {
|
|
11855
|
-
product_id,
|
|
11856
|
-
product_cart,
|
|
11857
|
-
quantity,
|
|
11858
|
-
billing,
|
|
11859
|
-
customer,
|
|
11860
|
-
addons,
|
|
11861
|
-
metadata,
|
|
11862
|
-
allowed_payment_method_types,
|
|
11863
|
-
billing_currency,
|
|
11864
|
-
discount_code,
|
|
11865
|
-
on_demand,
|
|
11866
|
-
return_url: bodyReturnUrl,
|
|
11867
|
-
show_saved_payment_methods,
|
|
11868
|
-
tax_id,
|
|
11869
|
-
trial_period_days
|
|
11870
|
-
} = dyn;
|
|
11871
|
-
const dodopayments = new DodoPayments({
|
|
11872
|
-
bearerToken,
|
|
11873
|
-
environment
|
|
11874
|
-
});
|
|
11875
|
-
let isSubscription = false;
|
|
11876
|
-
let productIdToFetch = product_id;
|
|
11877
|
-
if (!product_id && product_cart && product_cart.length > 0) {
|
|
11878
|
-
productIdToFetch = product_cart[0].product_id;
|
|
11879
|
-
}
|
|
11880
|
-
if (!productIdToFetch)
|
|
11881
|
-
throw new Error(
|
|
11882
|
-
"Missing required field: product_id or product_cart[0].product_id"
|
|
11883
|
-
);
|
|
11884
|
-
let product;
|
|
11885
|
-
try {
|
|
11886
|
-
product = await dodopayments.products.retrieve(productIdToFetch);
|
|
11887
|
-
} catch (err) {
|
|
11888
|
-
console.error(err);
|
|
11889
|
-
throw new Error("Product not found");
|
|
11890
|
-
}
|
|
11891
|
-
isSubscription = Boolean(product.is_recurring);
|
|
11892
|
-
if (isSubscription && !product_id)
|
|
11893
|
-
throw new Error("Missing required field: product_id for subscription");
|
|
11894
|
-
if (!billing) throw new Error("Missing required field: billing");
|
|
11895
|
-
if (!customer) throw new Error("Missing required field: customer");
|
|
11896
|
-
if (isSubscription) {
|
|
11897
|
-
const subscriptionPayload = {
|
|
11898
|
-
billing,
|
|
11899
|
-
customer,
|
|
11900
|
-
product_id,
|
|
11901
|
-
quantity: quantity ? Number(quantity) : 1
|
|
11902
|
-
};
|
|
11903
|
-
if (metadata) subscriptionPayload.metadata = metadata;
|
|
11904
|
-
if (discount_code) subscriptionPayload.discount_code = discount_code;
|
|
11905
|
-
if (addons) subscriptionPayload.addons = addons;
|
|
11906
|
-
if (allowed_payment_method_types)
|
|
11907
|
-
subscriptionPayload.allowed_payment_method_types = allowed_payment_method_types;
|
|
11908
|
-
if (billing_currency)
|
|
11909
|
-
subscriptionPayload.billing_currency = billing_currency;
|
|
11910
|
-
if (on_demand) subscriptionPayload.on_demand = on_demand;
|
|
11911
|
-
subscriptionPayload.payment_link = true;
|
|
11912
|
-
if (bodyReturnUrl) {
|
|
11913
|
-
subscriptionPayload.return_url = bodyReturnUrl;
|
|
11914
|
-
} else if (returnUrl) {
|
|
11915
|
-
subscriptionPayload.return_url = returnUrl;
|
|
11916
|
-
}
|
|
11917
|
-
if (show_saved_payment_methods)
|
|
11918
|
-
subscriptionPayload.show_saved_payment_methods = show_saved_payment_methods;
|
|
11919
|
-
if (tax_id) subscriptionPayload.tax_id = tax_id;
|
|
11920
|
-
if (trial_period_days)
|
|
11921
|
-
subscriptionPayload.trial_period_days = trial_period_days;
|
|
11922
|
-
let subscription;
|
|
11923
|
-
try {
|
|
11924
|
-
subscription = await dodopayments.subscriptions.create(subscriptionPayload);
|
|
11925
|
-
} catch (err) {
|
|
11926
|
-
console.error("Error when creating subscription", err);
|
|
11927
|
-
throw new Error(err instanceof Error ? err.message : String(err));
|
|
11928
|
-
}
|
|
11929
|
-
if (!subscription || !subscription.payment_link) {
|
|
11930
|
-
throw new Error(
|
|
11931
|
-
"No payment link returned from Dodo Payments API (subscription). Make sure to set payment_link as true in payload"
|
|
11932
|
-
);
|
|
11933
|
-
}
|
|
11934
|
-
return subscription.payment_link;
|
|
11935
|
-
} else {
|
|
11936
|
-
let cart = product_cart;
|
|
11937
|
-
if (!cart && product_id) {
|
|
11938
|
-
cart = [
|
|
11939
|
-
{ product_id, quantity: quantity ? Number(quantity) : 1 }
|
|
11940
|
-
];
|
|
11941
|
-
}
|
|
11942
|
-
if (!cart || cart.length === 0)
|
|
11943
|
-
throw new Error("Missing required field: product_cart or product_id");
|
|
11944
|
-
const paymentPayload = {
|
|
11945
|
-
billing,
|
|
11946
|
-
customer,
|
|
11947
|
-
product_cart: cart
|
|
11948
|
-
};
|
|
11949
|
-
if (metadata) paymentPayload.metadata = metadata;
|
|
11950
|
-
paymentPayload.payment_link = true;
|
|
11951
|
-
if (allowed_payment_method_types)
|
|
11952
|
-
paymentPayload.allowed_payment_method_types = allowed_payment_method_types;
|
|
11953
|
-
if (billing_currency) paymentPayload.billing_currency = billing_currency;
|
|
11954
|
-
if (discount_code) paymentPayload.discount_code = discount_code;
|
|
11955
|
-
if (bodyReturnUrl) {
|
|
11956
|
-
paymentPayload.return_url = bodyReturnUrl;
|
|
11957
|
-
} else if (returnUrl) {
|
|
11958
|
-
paymentPayload.return_url = returnUrl;
|
|
11959
|
-
}
|
|
11960
|
-
if (show_saved_payment_methods)
|
|
11961
|
-
paymentPayload.show_saved_payment_methods = show_saved_payment_methods;
|
|
11962
|
-
if (tax_id) paymentPayload.tax_id = tax_id;
|
|
11963
|
-
let payment;
|
|
11964
|
-
try {
|
|
11965
|
-
payment = await dodopayments.payments.create(paymentPayload);
|
|
11966
|
-
} catch (err) {
|
|
11967
|
-
console.error("Error when creating payment link", err);
|
|
11968
|
-
throw new Error(err instanceof Error ? err.message : String(err));
|
|
11969
|
-
}
|
|
11970
|
-
if (!payment || !payment.payment_link) {
|
|
11971
|
-
throw new Error(
|
|
11972
|
-
"No payment link returned from Dodo Payments API. Make sure to set payment_link as true in payload."
|
|
11973
|
-
);
|
|
11974
|
-
}
|
|
11975
|
-
return payment.payment_link;
|
|
11976
|
-
}
|
|
11571
|
+
base64$1.decodedLength = function (s) {
|
|
11572
|
+
return stdCoder.decodedLength(s);
|
|
11977
11573
|
};
|
|
11978
11574
|
|
|
11979
|
-
|
|
11980
|
-
const getHandler = async (req) => {
|
|
11981
|
-
const { searchParams } = new URL(req.url);
|
|
11982
|
-
const queryParams = Object.fromEntries(searchParams);
|
|
11983
|
-
if (!queryParams.productId) {
|
|
11984
|
-
return new serverExports.NextResponse("Please provide productId query parameter", {
|
|
11985
|
-
status: 400,
|
|
11986
|
-
});
|
|
11987
|
-
}
|
|
11988
|
-
const { success, data, error } = checkoutQuerySchema.safeParse(queryParams);
|
|
11989
|
-
if (!success) {
|
|
11990
|
-
if (error.errors.some((e) => e.path.toString() === "productId")) {
|
|
11991
|
-
return new serverExports.NextResponse("Please provide productId query parameter", {
|
|
11992
|
-
status: 400,
|
|
11993
|
-
});
|
|
11994
|
-
}
|
|
11995
|
-
return new serverExports.NextResponse(`Invalid query parameters.\n ${error.message}`, {
|
|
11996
|
-
status: 400,
|
|
11997
|
-
});
|
|
11998
|
-
}
|
|
11999
|
-
let url = "";
|
|
12000
|
-
try {
|
|
12001
|
-
url = await buildCheckoutUrl({ queryParams: data, ...config });
|
|
12002
|
-
}
|
|
12003
|
-
catch (error) {
|
|
12004
|
-
return new serverExports.NextResponse(error.message, { status: 400 });
|
|
12005
|
-
}
|
|
12006
|
-
return serverExports.NextResponse.json({ checkout_url: url });
|
|
12007
|
-
};
|
|
12008
|
-
const postHandler = async (req) => {
|
|
12009
|
-
let body;
|
|
12010
|
-
try {
|
|
12011
|
-
body = await req.json();
|
|
12012
|
-
}
|
|
12013
|
-
catch (e) {
|
|
12014
|
-
return new serverExports.NextResponse("Invalid JSON body", { status: 400 });
|
|
12015
|
-
}
|
|
12016
|
-
if (config.type === "dynamic") {
|
|
12017
|
-
// Handle dynamic checkout
|
|
12018
|
-
const { success, data, error } = dynamicCheckoutBodySchema.safeParse(body);
|
|
12019
|
-
if (!success) {
|
|
12020
|
-
return new serverExports.NextResponse(`Invalid request body.\n ${error.message}`, {
|
|
12021
|
-
status: 400,
|
|
12022
|
-
});
|
|
12023
|
-
}
|
|
12024
|
-
let url = "";
|
|
12025
|
-
try {
|
|
12026
|
-
url = await buildCheckoutUrl({
|
|
12027
|
-
body: data,
|
|
12028
|
-
...config,
|
|
12029
|
-
type: "dynamic",
|
|
12030
|
-
});
|
|
12031
|
-
}
|
|
12032
|
-
catch (error) {
|
|
12033
|
-
return new serverExports.NextResponse(error.message, { status: 400 });
|
|
12034
|
-
}
|
|
12035
|
-
return serverExports.NextResponse.json({ checkout_url: url });
|
|
12036
|
-
}
|
|
12037
|
-
else {
|
|
12038
|
-
// Handle checkout session
|
|
12039
|
-
const { success, data, error } = checkoutSessionPayloadSchema.safeParse(body);
|
|
12040
|
-
if (!success) {
|
|
12041
|
-
return new serverExports.NextResponse(`Invalid checkout session payload.\n ${error.message}`, {
|
|
12042
|
-
status: 400,
|
|
12043
|
-
});
|
|
12044
|
-
}
|
|
12045
|
-
let url = "";
|
|
12046
|
-
try {
|
|
12047
|
-
url = await buildCheckoutUrl({
|
|
12048
|
-
sessionPayload: data,
|
|
12049
|
-
...config,
|
|
12050
|
-
type: "session",
|
|
12051
|
-
});
|
|
12052
|
-
}
|
|
12053
|
-
catch (error) {
|
|
12054
|
-
return new serverExports.NextResponse(error.message, { status: 400 });
|
|
12055
|
-
}
|
|
12056
|
-
return serverExports.NextResponse.json({ checkout_url: url });
|
|
12057
|
-
}
|
|
12058
|
-
};
|
|
12059
|
-
return (req) => {
|
|
12060
|
-
if (req.method === "POST") {
|
|
12061
|
-
return postHandler(req);
|
|
12062
|
-
}
|
|
12063
|
-
return getHandler(req);
|
|
12064
|
-
};
|
|
12065
|
-
};
|
|
12066
|
-
|
|
12067
|
-
var dist = {};
|
|
12068
|
-
|
|
12069
|
-
var timing_safe_equal = {};
|
|
12070
|
-
|
|
12071
|
-
Object.defineProperty(timing_safe_equal, "__esModule", { value: true });
|
|
12072
|
-
timing_safe_equal.timingSafeEqual = void 0;
|
|
12073
|
-
function assert(expr, msg = "") {
|
|
12074
|
-
if (!expr) {
|
|
12075
|
-
throw new Error(msg);
|
|
12076
|
-
}
|
|
12077
|
-
}
|
|
12078
|
-
function timingSafeEqual(a, b) {
|
|
12079
|
-
if (a.byteLength !== b.byteLength) {
|
|
12080
|
-
return false;
|
|
12081
|
-
}
|
|
12082
|
-
if (!(a instanceof DataView)) {
|
|
12083
|
-
a = new DataView(ArrayBuffer.isView(a) ? a.buffer : a);
|
|
12084
|
-
}
|
|
12085
|
-
if (!(b instanceof DataView)) {
|
|
12086
|
-
b = new DataView(ArrayBuffer.isView(b) ? b.buffer : b);
|
|
12087
|
-
}
|
|
12088
|
-
assert(a instanceof DataView);
|
|
12089
|
-
assert(b instanceof DataView);
|
|
12090
|
-
const length = a.byteLength;
|
|
12091
|
-
let out = 0;
|
|
12092
|
-
let i = -1;
|
|
12093
|
-
while (++i < length) {
|
|
12094
|
-
out |= a.getUint8(i) ^ b.getUint8(i);
|
|
12095
|
-
}
|
|
12096
|
-
return out === 0;
|
|
12097
|
-
}
|
|
12098
|
-
timing_safe_equal.timingSafeEqual = timingSafeEqual;
|
|
12099
|
-
|
|
12100
|
-
var base64$1 = {};
|
|
12101
|
-
|
|
12102
|
-
// Copyright (C) 2016 Dmitry Chestnykh
|
|
12103
|
-
// MIT License. See LICENSE file for details.
|
|
12104
|
-
var __extends = (commonjsGlobal && commonjsGlobal.__extends) || (function () {
|
|
12105
|
-
var extendStatics = function (d, b) {
|
|
12106
|
-
extendStatics = Object.setPrototypeOf ||
|
|
12107
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
12108
|
-
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
|
12109
|
-
return extendStatics(d, b);
|
|
12110
|
-
};
|
|
12111
|
-
return function (d, b) {
|
|
12112
|
-
extendStatics(d, b);
|
|
12113
|
-
function __() { this.constructor = d; }
|
|
12114
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
12115
|
-
};
|
|
12116
|
-
})();
|
|
12117
|
-
Object.defineProperty(base64$1, "__esModule", { value: true });
|
|
12118
|
-
/**
|
|
12119
|
-
* Package base64 implements Base64 encoding and decoding.
|
|
12120
|
-
*/
|
|
12121
|
-
// Invalid character used in decoding to indicate
|
|
12122
|
-
// that the character to decode is out of range of
|
|
12123
|
-
// alphabet and cannot be decoded.
|
|
12124
|
-
var INVALID_BYTE = 256;
|
|
12125
|
-
/**
|
|
12126
|
-
* Implements standard Base64 encoding.
|
|
12127
|
-
*
|
|
12128
|
-
* Operates in constant time.
|
|
12129
|
-
*/
|
|
12130
|
-
var Coder = /** @class */ (function () {
|
|
12131
|
-
// TODO(dchest): methods to encode chunk-by-chunk.
|
|
12132
|
-
function Coder(_paddingCharacter) {
|
|
12133
|
-
if (_paddingCharacter === void 0) { _paddingCharacter = "="; }
|
|
12134
|
-
this._paddingCharacter = _paddingCharacter;
|
|
12135
|
-
}
|
|
12136
|
-
Coder.prototype.encodedLength = function (length) {
|
|
12137
|
-
if (!this._paddingCharacter) {
|
|
12138
|
-
return (length * 8 + 5) / 6 | 0;
|
|
12139
|
-
}
|
|
12140
|
-
return (length + 2) / 3 * 4 | 0;
|
|
12141
|
-
};
|
|
12142
|
-
Coder.prototype.encode = function (data) {
|
|
12143
|
-
var out = "";
|
|
12144
|
-
var i = 0;
|
|
12145
|
-
for (; i < data.length - 2; i += 3) {
|
|
12146
|
-
var c = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
|
|
12147
|
-
out += this._encodeByte((c >>> 3 * 6) & 63);
|
|
12148
|
-
out += this._encodeByte((c >>> 2 * 6) & 63);
|
|
12149
|
-
out += this._encodeByte((c >>> 1 * 6) & 63);
|
|
12150
|
-
out += this._encodeByte((c >>> 0 * 6) & 63);
|
|
12151
|
-
}
|
|
12152
|
-
var left = data.length - i;
|
|
12153
|
-
if (left > 0) {
|
|
12154
|
-
var c = (data[i] << 16) | (left === 2 ? data[i + 1] << 8 : 0);
|
|
12155
|
-
out += this._encodeByte((c >>> 3 * 6) & 63);
|
|
12156
|
-
out += this._encodeByte((c >>> 2 * 6) & 63);
|
|
12157
|
-
if (left === 2) {
|
|
12158
|
-
out += this._encodeByte((c >>> 1 * 6) & 63);
|
|
12159
|
-
}
|
|
12160
|
-
else {
|
|
12161
|
-
out += this._paddingCharacter || "";
|
|
12162
|
-
}
|
|
12163
|
-
out += this._paddingCharacter || "";
|
|
12164
|
-
}
|
|
12165
|
-
return out;
|
|
12166
|
-
};
|
|
12167
|
-
Coder.prototype.maxDecodedLength = function (length) {
|
|
12168
|
-
if (!this._paddingCharacter) {
|
|
12169
|
-
return (length * 6 + 7) / 8 | 0;
|
|
12170
|
-
}
|
|
12171
|
-
return length / 4 * 3 | 0;
|
|
12172
|
-
};
|
|
12173
|
-
Coder.prototype.decodedLength = function (s) {
|
|
12174
|
-
return this.maxDecodedLength(s.length - this._getPaddingLength(s));
|
|
12175
|
-
};
|
|
12176
|
-
Coder.prototype.decode = function (s) {
|
|
12177
|
-
if (s.length === 0) {
|
|
12178
|
-
return new Uint8Array(0);
|
|
12179
|
-
}
|
|
12180
|
-
var paddingLength = this._getPaddingLength(s);
|
|
12181
|
-
var length = s.length - paddingLength;
|
|
12182
|
-
var out = new Uint8Array(this.maxDecodedLength(length));
|
|
12183
|
-
var op = 0;
|
|
12184
|
-
var i = 0;
|
|
12185
|
-
var haveBad = 0;
|
|
12186
|
-
var v0 = 0, v1 = 0, v2 = 0, v3 = 0;
|
|
12187
|
-
for (; i < length - 4; i += 4) {
|
|
12188
|
-
v0 = this._decodeChar(s.charCodeAt(i + 0));
|
|
12189
|
-
v1 = this._decodeChar(s.charCodeAt(i + 1));
|
|
12190
|
-
v2 = this._decodeChar(s.charCodeAt(i + 2));
|
|
12191
|
-
v3 = this._decodeChar(s.charCodeAt(i + 3));
|
|
12192
|
-
out[op++] = (v0 << 2) | (v1 >>> 4);
|
|
12193
|
-
out[op++] = (v1 << 4) | (v2 >>> 2);
|
|
12194
|
-
out[op++] = (v2 << 6) | v3;
|
|
12195
|
-
haveBad |= v0 & INVALID_BYTE;
|
|
12196
|
-
haveBad |= v1 & INVALID_BYTE;
|
|
12197
|
-
haveBad |= v2 & INVALID_BYTE;
|
|
12198
|
-
haveBad |= v3 & INVALID_BYTE;
|
|
12199
|
-
}
|
|
12200
|
-
if (i < length - 1) {
|
|
12201
|
-
v0 = this._decodeChar(s.charCodeAt(i));
|
|
12202
|
-
v1 = this._decodeChar(s.charCodeAt(i + 1));
|
|
12203
|
-
out[op++] = (v0 << 2) | (v1 >>> 4);
|
|
12204
|
-
haveBad |= v0 & INVALID_BYTE;
|
|
12205
|
-
haveBad |= v1 & INVALID_BYTE;
|
|
12206
|
-
}
|
|
12207
|
-
if (i < length - 2) {
|
|
12208
|
-
v2 = this._decodeChar(s.charCodeAt(i + 2));
|
|
12209
|
-
out[op++] = (v1 << 4) | (v2 >>> 2);
|
|
12210
|
-
haveBad |= v2 & INVALID_BYTE;
|
|
12211
|
-
}
|
|
12212
|
-
if (i < length - 3) {
|
|
12213
|
-
v3 = this._decodeChar(s.charCodeAt(i + 3));
|
|
12214
|
-
out[op++] = (v2 << 6) | v3;
|
|
12215
|
-
haveBad |= v3 & INVALID_BYTE;
|
|
12216
|
-
}
|
|
12217
|
-
if (haveBad !== 0) {
|
|
12218
|
-
throw new Error("Base64Coder: incorrect characters for decoding");
|
|
12219
|
-
}
|
|
12220
|
-
return out;
|
|
12221
|
-
};
|
|
12222
|
-
// Standard encoding have the following encoded/decoded ranges,
|
|
12223
|
-
// which we need to convert between.
|
|
12224
|
-
//
|
|
12225
|
-
// ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 + /
|
|
12226
|
-
// Index: 0 - 25 26 - 51 52 - 61 62 63
|
|
12227
|
-
// ASCII: 65 - 90 97 - 122 48 - 57 43 47
|
|
12228
|
-
//
|
|
12229
|
-
// Encode 6 bits in b into a new character.
|
|
12230
|
-
Coder.prototype._encodeByte = function (b) {
|
|
12231
|
-
// Encoding uses constant time operations as follows:
|
|
12232
|
-
//
|
|
12233
|
-
// 1. Define comparison of A with B using (A - B) >>> 8:
|
|
12234
|
-
// if A > B, then result is positive integer
|
|
12235
|
-
// if A <= B, then result is 0
|
|
12236
|
-
//
|
|
12237
|
-
// 2. Define selection of C or 0 using bitwise AND: X & C:
|
|
12238
|
-
// if X == 0, then result is 0
|
|
12239
|
-
// if X != 0, then result is C
|
|
12240
|
-
//
|
|
12241
|
-
// 3. Start with the smallest comparison (b >= 0), which is always
|
|
12242
|
-
// true, so set the result to the starting ASCII value (65).
|
|
12243
|
-
//
|
|
12244
|
-
// 4. Continue comparing b to higher ASCII values, and selecting
|
|
12245
|
-
// zero if comparison isn't true, otherwise selecting a value
|
|
12246
|
-
// to add to result, which:
|
|
12247
|
-
//
|
|
12248
|
-
// a) undoes the previous addition
|
|
12249
|
-
// b) provides new value to add
|
|
12250
|
-
//
|
|
12251
|
-
var result = b;
|
|
12252
|
-
// b >= 0
|
|
12253
|
-
result += 65;
|
|
12254
|
-
// b > 25
|
|
12255
|
-
result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
|
|
12256
|
-
// b > 51
|
|
12257
|
-
result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
|
|
12258
|
-
// b > 61
|
|
12259
|
-
result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 43);
|
|
12260
|
-
// b > 62
|
|
12261
|
-
result += ((62 - b) >>> 8) & ((62 - 43) - 63 + 47);
|
|
12262
|
-
return String.fromCharCode(result);
|
|
12263
|
-
};
|
|
12264
|
-
// Decode a character code into a byte.
|
|
12265
|
-
// Must return 256 if character is out of alphabet range.
|
|
12266
|
-
Coder.prototype._decodeChar = function (c) {
|
|
12267
|
-
// Decoding works similar to encoding: using the same comparison
|
|
12268
|
-
// function, but now it works on ranges: result is always incremented
|
|
12269
|
-
// by value, but this value becomes zero if the range is not
|
|
12270
|
-
// satisfied.
|
|
12271
|
-
//
|
|
12272
|
-
// Decoding starts with invalid value, 256, which is then
|
|
12273
|
-
// subtracted when the range is satisfied. If none of the ranges
|
|
12274
|
-
// apply, the function returns 256, which is then checked by
|
|
12275
|
-
// the caller to throw error.
|
|
12276
|
-
var result = INVALID_BYTE; // start with invalid character
|
|
12277
|
-
// c == 43 (c > 42 and c < 44)
|
|
12278
|
-
result += (((42 - c) & (c - 44)) >>> 8) & (-INVALID_BYTE + c - 43 + 62);
|
|
12279
|
-
// c == 47 (c > 46 and c < 48)
|
|
12280
|
-
result += (((46 - c) & (c - 48)) >>> 8) & (-INVALID_BYTE + c - 47 + 63);
|
|
12281
|
-
// c > 47 and c < 58
|
|
12282
|
-
result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
|
|
12283
|
-
// c > 64 and c < 91
|
|
12284
|
-
result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
|
|
12285
|
-
// c > 96 and c < 123
|
|
12286
|
-
result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
|
|
12287
|
-
return result;
|
|
12288
|
-
};
|
|
12289
|
-
Coder.prototype._getPaddingLength = function (s) {
|
|
12290
|
-
var paddingLength = 0;
|
|
12291
|
-
if (this._paddingCharacter) {
|
|
12292
|
-
for (var i = s.length - 1; i >= 0; i--) {
|
|
12293
|
-
if (s[i] !== this._paddingCharacter) {
|
|
12294
|
-
break;
|
|
12295
|
-
}
|
|
12296
|
-
paddingLength++;
|
|
12297
|
-
}
|
|
12298
|
-
if (s.length < 4 || paddingLength > 2) {
|
|
12299
|
-
throw new Error("Base64Coder: incorrect padding");
|
|
12300
|
-
}
|
|
12301
|
-
}
|
|
12302
|
-
return paddingLength;
|
|
12303
|
-
};
|
|
12304
|
-
return Coder;
|
|
12305
|
-
}());
|
|
12306
|
-
base64$1.Coder = Coder;
|
|
12307
|
-
var stdCoder = new Coder();
|
|
12308
|
-
function encode(data) {
|
|
12309
|
-
return stdCoder.encode(data);
|
|
12310
|
-
}
|
|
12311
|
-
base64$1.encode = encode;
|
|
12312
|
-
function decode(s) {
|
|
12313
|
-
return stdCoder.decode(s);
|
|
12314
|
-
}
|
|
12315
|
-
base64$1.decode = decode;
|
|
12316
|
-
/**
|
|
12317
|
-
* Implements URL-safe Base64 encoding.
|
|
12318
|
-
* (Same as Base64, but '+' is replaced with '-', and '/' with '_').
|
|
12319
|
-
*
|
|
12320
|
-
* Operates in constant time.
|
|
12321
|
-
*/
|
|
12322
|
-
var URLSafeCoder = /** @class */ (function (_super) {
|
|
12323
|
-
__extends(URLSafeCoder, _super);
|
|
12324
|
-
function URLSafeCoder() {
|
|
12325
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
12326
|
-
}
|
|
12327
|
-
// URL-safe encoding have the following encoded/decoded ranges:
|
|
12328
|
-
//
|
|
12329
|
-
// ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 - _
|
|
12330
|
-
// Index: 0 - 25 26 - 51 52 - 61 62 63
|
|
12331
|
-
// ASCII: 65 - 90 97 - 122 48 - 57 45 95
|
|
12332
|
-
//
|
|
12333
|
-
URLSafeCoder.prototype._encodeByte = function (b) {
|
|
12334
|
-
var result = b;
|
|
12335
|
-
// b >= 0
|
|
12336
|
-
result += 65;
|
|
12337
|
-
// b > 25
|
|
12338
|
-
result += ((25 - b) >>> 8) & ((0 - 65) - 26 + 97);
|
|
12339
|
-
// b > 51
|
|
12340
|
-
result += ((51 - b) >>> 8) & ((26 - 97) - 52 + 48);
|
|
12341
|
-
// b > 61
|
|
12342
|
-
result += ((61 - b) >>> 8) & ((52 - 48) - 62 + 45);
|
|
12343
|
-
// b > 62
|
|
12344
|
-
result += ((62 - b) >>> 8) & ((62 - 45) - 63 + 95);
|
|
12345
|
-
return String.fromCharCode(result);
|
|
12346
|
-
};
|
|
12347
|
-
URLSafeCoder.prototype._decodeChar = function (c) {
|
|
12348
|
-
var result = INVALID_BYTE;
|
|
12349
|
-
// c == 45 (c > 44 and c < 46)
|
|
12350
|
-
result += (((44 - c) & (c - 46)) >>> 8) & (-INVALID_BYTE + c - 45 + 62);
|
|
12351
|
-
// c == 95 (c > 94 and c < 96)
|
|
12352
|
-
result += (((94 - c) & (c - 96)) >>> 8) & (-INVALID_BYTE + c - 95 + 63);
|
|
12353
|
-
// c > 47 and c < 58
|
|
12354
|
-
result += (((47 - c) & (c - 58)) >>> 8) & (-INVALID_BYTE + c - 48 + 52);
|
|
12355
|
-
// c > 64 and c < 91
|
|
12356
|
-
result += (((64 - c) & (c - 91)) >>> 8) & (-INVALID_BYTE + c - 65 + 0);
|
|
12357
|
-
// c > 96 and c < 123
|
|
12358
|
-
result += (((96 - c) & (c - 123)) >>> 8) & (-INVALID_BYTE + c - 97 + 26);
|
|
12359
|
-
return result;
|
|
12360
|
-
};
|
|
12361
|
-
return URLSafeCoder;
|
|
12362
|
-
}(Coder));
|
|
12363
|
-
base64$1.URLSafeCoder = URLSafeCoder;
|
|
12364
|
-
var urlSafeCoder = new URLSafeCoder();
|
|
12365
|
-
function encodeURLSafe(data) {
|
|
12366
|
-
return urlSafeCoder.encode(data);
|
|
12367
|
-
}
|
|
12368
|
-
base64$1.encodeURLSafe = encodeURLSafe;
|
|
12369
|
-
function decodeURLSafe(s) {
|
|
12370
|
-
return urlSafeCoder.decode(s);
|
|
12371
|
-
}
|
|
12372
|
-
base64$1.decodeURLSafe = decodeURLSafe;
|
|
12373
|
-
base64$1.encodedLength = function (length) {
|
|
12374
|
-
return stdCoder.encodedLength(length);
|
|
12375
|
-
};
|
|
12376
|
-
base64$1.maxDecodedLength = function (length) {
|
|
12377
|
-
return stdCoder.maxDecodedLength(length);
|
|
12378
|
-
};
|
|
12379
|
-
base64$1.decodedLength = function (s) {
|
|
12380
|
-
return stdCoder.decodedLength(s);
|
|
12381
|
-
};
|
|
12382
|
-
|
|
12383
|
-
var sha256$1 = {exports: {}};
|
|
11575
|
+
var sha256$1 = {exports: {}};
|
|
12384
11576
|
|
|
12385
11577
|
(function (module) {
|
|
12386
11578
|
(function (root, factory) {
|
|
@@ -12822,96 +12014,1230 @@ class ExtendableError extends Error {
|
|
|
12822
12014
|
this.name = "ExtendableError";
|
|
12823
12015
|
this.stack = new Error(message).stack;
|
|
12824
12016
|
}
|
|
12825
|
-
}
|
|
12826
|
-
class WebhookVerificationError extends ExtendableError {
|
|
12827
|
-
constructor(message) {
|
|
12828
|
-
super(message);
|
|
12829
|
-
Object.setPrototypeOf(this, WebhookVerificationError.prototype);
|
|
12830
|
-
this.name = "WebhookVerificationError";
|
|
12017
|
+
}
|
|
12018
|
+
class WebhookVerificationError extends ExtendableError {
|
|
12019
|
+
constructor(message) {
|
|
12020
|
+
super(message);
|
|
12021
|
+
Object.setPrototypeOf(this, WebhookVerificationError.prototype);
|
|
12022
|
+
this.name = "WebhookVerificationError";
|
|
12023
|
+
}
|
|
12024
|
+
}
|
|
12025
|
+
var WebhookVerificationError_1 = dist.WebhookVerificationError = WebhookVerificationError;
|
|
12026
|
+
class Webhook {
|
|
12027
|
+
constructor(secret, options) {
|
|
12028
|
+
if (!secret) {
|
|
12029
|
+
throw new Error("Secret can't be empty.");
|
|
12030
|
+
}
|
|
12031
|
+
if ((options === null || options === void 0 ? void 0 : options.format) === "raw") {
|
|
12032
|
+
if (secret instanceof Uint8Array) {
|
|
12033
|
+
this.key = secret;
|
|
12034
|
+
}
|
|
12035
|
+
else {
|
|
12036
|
+
this.key = Uint8Array.from(secret, (c) => c.charCodeAt(0));
|
|
12037
|
+
}
|
|
12038
|
+
}
|
|
12039
|
+
else {
|
|
12040
|
+
if (typeof secret !== "string") {
|
|
12041
|
+
throw new Error("Expected secret to be of type string");
|
|
12042
|
+
}
|
|
12043
|
+
if (secret.startsWith(Webhook.prefix)) {
|
|
12044
|
+
secret = secret.substring(Webhook.prefix.length);
|
|
12045
|
+
}
|
|
12046
|
+
this.key = base64.decode(secret);
|
|
12047
|
+
}
|
|
12048
|
+
}
|
|
12049
|
+
verify(payload, headers_) {
|
|
12050
|
+
const headers = {};
|
|
12051
|
+
for (const key of Object.keys(headers_)) {
|
|
12052
|
+
headers[key.toLowerCase()] = headers_[key];
|
|
12053
|
+
}
|
|
12054
|
+
const msgId = headers["webhook-id"];
|
|
12055
|
+
const msgSignature = headers["webhook-signature"];
|
|
12056
|
+
const msgTimestamp = headers["webhook-timestamp"];
|
|
12057
|
+
if (!msgSignature || !msgId || !msgTimestamp) {
|
|
12058
|
+
throw new WebhookVerificationError("Missing required headers");
|
|
12059
|
+
}
|
|
12060
|
+
const timestamp = this.verifyTimestamp(msgTimestamp);
|
|
12061
|
+
const computedSignature = this.sign(msgId, timestamp, payload);
|
|
12062
|
+
const expectedSignature = computedSignature.split(",")[1];
|
|
12063
|
+
const passedSignatures = msgSignature.split(" ");
|
|
12064
|
+
const encoder = new globalThis.TextEncoder();
|
|
12065
|
+
for (const versionedSignature of passedSignatures) {
|
|
12066
|
+
const [version, signature] = versionedSignature.split(",");
|
|
12067
|
+
if (version !== "v1") {
|
|
12068
|
+
continue;
|
|
12069
|
+
}
|
|
12070
|
+
if ((0, timing_safe_equal_1.timingSafeEqual)(encoder.encode(signature), encoder.encode(expectedSignature))) {
|
|
12071
|
+
return JSON.parse(payload.toString());
|
|
12072
|
+
}
|
|
12073
|
+
}
|
|
12074
|
+
throw new WebhookVerificationError("No matching signature found");
|
|
12075
|
+
}
|
|
12076
|
+
sign(msgId, timestamp, payload) {
|
|
12077
|
+
if (typeof payload === "string") ;
|
|
12078
|
+
else if (payload.constructor.name === "Buffer") {
|
|
12079
|
+
payload = payload.toString();
|
|
12080
|
+
}
|
|
12081
|
+
else {
|
|
12082
|
+
throw new Error("Expected payload to be of type string or Buffer.");
|
|
12083
|
+
}
|
|
12084
|
+
const encoder = new TextEncoder();
|
|
12085
|
+
const timestampNumber = Math.floor(timestamp.getTime() / 1000);
|
|
12086
|
+
const toSign = encoder.encode(`${msgId}.${timestampNumber}.${payload}`);
|
|
12087
|
+
const expectedSignature = base64.encode(sha256.hmac(this.key, toSign));
|
|
12088
|
+
return `v1,${expectedSignature}`;
|
|
12089
|
+
}
|
|
12090
|
+
verifyTimestamp(timestampHeader) {
|
|
12091
|
+
const now = Math.floor(Date.now() / 1000);
|
|
12092
|
+
const timestamp = parseInt(timestampHeader, 10);
|
|
12093
|
+
if (isNaN(timestamp)) {
|
|
12094
|
+
throw new WebhookVerificationError("Invalid Signature Headers");
|
|
12095
|
+
}
|
|
12096
|
+
if (now - timestamp > WEBHOOK_TOLERANCE_IN_SECONDS) {
|
|
12097
|
+
throw new WebhookVerificationError("Message timestamp too old");
|
|
12098
|
+
}
|
|
12099
|
+
if (timestamp > now + WEBHOOK_TOLERANCE_IN_SECONDS) {
|
|
12100
|
+
throw new WebhookVerificationError("Message timestamp too new");
|
|
12101
|
+
}
|
|
12102
|
+
return new Date(timestamp * 1000);
|
|
12103
|
+
}
|
|
12104
|
+
}
|
|
12105
|
+
Webhook_1 = dist.Webhook = Webhook;
|
|
12106
|
+
Webhook.prefix = "whsec_";
|
|
12107
|
+
|
|
12108
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
12109
|
+
let Webhooks$1 = class Webhooks extends APIResource {
|
|
12110
|
+
constructor() {
|
|
12111
|
+
super(...arguments);
|
|
12112
|
+
this.headers = new Headers$1(this._client);
|
|
12113
|
+
}
|
|
12114
|
+
/**
|
|
12115
|
+
* Create a new webhook
|
|
12116
|
+
*/
|
|
12117
|
+
create(body, options) {
|
|
12118
|
+
return this._client.post('/webhooks', { body, ...options });
|
|
12119
|
+
}
|
|
12120
|
+
/**
|
|
12121
|
+
* Get a webhook by id
|
|
12122
|
+
*/
|
|
12123
|
+
retrieve(webhookID, options) {
|
|
12124
|
+
return this._client.get(path `/webhooks/${webhookID}`, options);
|
|
12125
|
+
}
|
|
12126
|
+
/**
|
|
12127
|
+
* Patch a webhook by id
|
|
12128
|
+
*/
|
|
12129
|
+
update(webhookID, body, options) {
|
|
12130
|
+
return this._client.patch(path `/webhooks/${webhookID}`, { body, ...options });
|
|
12131
|
+
}
|
|
12132
|
+
/**
|
|
12133
|
+
* List all webhooks
|
|
12134
|
+
*/
|
|
12135
|
+
list(query = {}, options) {
|
|
12136
|
+
return this._client.getAPIList('/webhooks', (CursorPagePagination), { query, ...options });
|
|
12137
|
+
}
|
|
12138
|
+
/**
|
|
12139
|
+
* Delete a webhook by id
|
|
12140
|
+
*/
|
|
12141
|
+
delete(webhookID, options) {
|
|
12142
|
+
return this._client.delete(path `/webhooks/${webhookID}`, {
|
|
12143
|
+
...options,
|
|
12144
|
+
headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
|
|
12145
|
+
});
|
|
12146
|
+
}
|
|
12147
|
+
/**
|
|
12148
|
+
* Get webhook secret by id
|
|
12149
|
+
*/
|
|
12150
|
+
retrieveSecret(webhookID, options) {
|
|
12151
|
+
return this._client.get(path `/webhooks/${webhookID}/secret`, options);
|
|
12152
|
+
}
|
|
12153
|
+
unsafeUnwrap(body) {
|
|
12154
|
+
return JSON.parse(body);
|
|
12155
|
+
}
|
|
12156
|
+
unwrap(body, { headers, key }) {
|
|
12157
|
+
if (headers !== undefined) {
|
|
12158
|
+
const keyStr = key === undefined ? this._client.webhookKey : key;
|
|
12159
|
+
if (keyStr === null)
|
|
12160
|
+
throw new Error('Webhook key must not be null in order to unwrap');
|
|
12161
|
+
const wh = new Webhook_1(keyStr);
|
|
12162
|
+
wh.verify(body, headers);
|
|
12163
|
+
}
|
|
12164
|
+
return JSON.parse(body);
|
|
12165
|
+
}
|
|
12166
|
+
};
|
|
12167
|
+
Webhooks$1.Headers = Headers$1;
|
|
12168
|
+
|
|
12169
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
12170
|
+
/**
|
|
12171
|
+
* Read an environment variable.
|
|
12172
|
+
*
|
|
12173
|
+
* Trims beginning and trailing whitespace.
|
|
12174
|
+
*
|
|
12175
|
+
* Will return undefined if the environment variable doesn't exist or cannot be accessed.
|
|
12176
|
+
*/
|
|
12177
|
+
const readEnv = (env) => {
|
|
12178
|
+
if (typeof globalThis.process !== 'undefined') {
|
|
12179
|
+
return globalThis.process.env?.[env]?.trim() ?? undefined;
|
|
12180
|
+
}
|
|
12181
|
+
if (typeof globalThis.Deno !== 'undefined') {
|
|
12182
|
+
return globalThis.Deno.env?.get?.(env)?.trim();
|
|
12183
|
+
}
|
|
12184
|
+
return undefined;
|
|
12185
|
+
};
|
|
12186
|
+
|
|
12187
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
12188
|
+
var _DodoPayments_instances, _a, _DodoPayments_encoder, _DodoPayments_baseURLOverridden;
|
|
12189
|
+
const environments = {
|
|
12190
|
+
live_mode: 'https://live.dodopayments.com',
|
|
12191
|
+
test_mode: 'https://test.dodopayments.com',
|
|
12192
|
+
};
|
|
12193
|
+
/**
|
|
12194
|
+
* API Client for interfacing with the Dodo Payments API.
|
|
12195
|
+
*/
|
|
12196
|
+
class DodoPayments {
|
|
12197
|
+
/**
|
|
12198
|
+
* API Client for interfacing with the Dodo Payments API.
|
|
12199
|
+
*
|
|
12200
|
+
* @param {string | undefined} [opts.bearerToken=process.env['DODO_PAYMENTS_API_KEY'] ?? undefined]
|
|
12201
|
+
* @param {string | null | undefined} [opts.webhookKey=process.env['DODO_PAYMENTS_WEBHOOK_KEY'] ?? null]
|
|
12202
|
+
* @param {Environment} [opts.environment=live_mode] - Specifies the environment URL to use for the API.
|
|
12203
|
+
* @param {string} [opts.baseURL=process.env['DODO_PAYMENTS_BASE_URL'] ?? https://live.dodopayments.com] - Override the default base URL for the API.
|
|
12204
|
+
* @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
|
|
12205
|
+
* @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
|
|
12206
|
+
* @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
|
|
12207
|
+
* @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
|
|
12208
|
+
* @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
|
|
12209
|
+
* @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
|
|
12210
|
+
*/
|
|
12211
|
+
constructor({ baseURL = readEnv('DODO_PAYMENTS_BASE_URL'), bearerToken = readEnv('DODO_PAYMENTS_API_KEY'), webhookKey = readEnv('DODO_PAYMENTS_WEBHOOK_KEY') ?? null, ...opts } = {}) {
|
|
12212
|
+
_DodoPayments_instances.add(this);
|
|
12213
|
+
_DodoPayments_encoder.set(this, void 0);
|
|
12214
|
+
this.checkoutSessions = new CheckoutSessions(this);
|
|
12215
|
+
this.payments = new Payments(this);
|
|
12216
|
+
this.subscriptions = new Subscriptions(this);
|
|
12217
|
+
this.invoices = new Invoices(this);
|
|
12218
|
+
this.licenses = new Licenses(this);
|
|
12219
|
+
this.licenseKeys = new LicenseKeys(this);
|
|
12220
|
+
this.licenseKeyInstances = new LicenseKeyInstances(this);
|
|
12221
|
+
this.customers = new Customers(this);
|
|
12222
|
+
this.refunds = new Refunds(this);
|
|
12223
|
+
this.disputes = new Disputes(this);
|
|
12224
|
+
this.payouts = new Payouts(this);
|
|
12225
|
+
this.products = new Products(this);
|
|
12226
|
+
this.misc = new Misc(this);
|
|
12227
|
+
this.discounts = new Discounts(this);
|
|
12228
|
+
this.addons = new Addons(this);
|
|
12229
|
+
this.brands = new Brands(this);
|
|
12230
|
+
this.webhooks = new Webhooks$1(this);
|
|
12231
|
+
this.webhookEvents = new WebhookEvents(this);
|
|
12232
|
+
this.usageEvents = new UsageEvents(this);
|
|
12233
|
+
this.meters = new Meters(this);
|
|
12234
|
+
if (bearerToken === undefined) {
|
|
12235
|
+
throw new DodoPaymentsError("The DODO_PAYMENTS_API_KEY environment variable is missing or empty; either provide it, or instantiate the DodoPayments client with an bearerToken option, like new DodoPayments({ bearerToken: 'My Bearer Token' }).");
|
|
12236
|
+
}
|
|
12237
|
+
const options = {
|
|
12238
|
+
bearerToken,
|
|
12239
|
+
webhookKey,
|
|
12240
|
+
...opts,
|
|
12241
|
+
baseURL,
|
|
12242
|
+
environment: opts.environment ?? 'live_mode',
|
|
12243
|
+
};
|
|
12244
|
+
if (baseURL && opts.environment) {
|
|
12245
|
+
throw new DodoPaymentsError('Ambiguous URL; The `baseURL` option (or DODO_PAYMENTS_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null');
|
|
12246
|
+
}
|
|
12247
|
+
this.baseURL = options.baseURL || environments[options.environment || 'live_mode'];
|
|
12248
|
+
this.timeout = options.timeout ?? _a.DEFAULT_TIMEOUT /* 1 minute */;
|
|
12249
|
+
this.logger = options.logger ?? console;
|
|
12250
|
+
const defaultLogLevel = 'warn';
|
|
12251
|
+
// Set default logLevel early so that we can log a warning in parseLogLevel.
|
|
12252
|
+
this.logLevel = defaultLogLevel;
|
|
12253
|
+
this.logLevel =
|
|
12254
|
+
parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this) ??
|
|
12255
|
+
parseLogLevel(readEnv('DODO_PAYMENTS_LOG'), "process.env['DODO_PAYMENTS_LOG']", this) ??
|
|
12256
|
+
defaultLogLevel;
|
|
12257
|
+
this.fetchOptions = options.fetchOptions;
|
|
12258
|
+
this.maxRetries = options.maxRetries ?? 2;
|
|
12259
|
+
this.fetch = options.fetch ?? getDefaultFetch();
|
|
12260
|
+
__classPrivateFieldSet(this, _DodoPayments_encoder, FallbackEncoder);
|
|
12261
|
+
this._options = options;
|
|
12262
|
+
this.bearerToken = bearerToken;
|
|
12263
|
+
this.webhookKey = webhookKey;
|
|
12264
|
+
}
|
|
12265
|
+
/**
|
|
12266
|
+
* Create a new client instance re-using the same options given to the current client with optional overriding.
|
|
12267
|
+
*/
|
|
12268
|
+
withOptions(options) {
|
|
12269
|
+
const client = new this.constructor({
|
|
12270
|
+
...this._options,
|
|
12271
|
+
environment: options.environment ? options.environment : undefined,
|
|
12272
|
+
baseURL: options.environment ? undefined : this.baseURL,
|
|
12273
|
+
maxRetries: this.maxRetries,
|
|
12274
|
+
timeout: this.timeout,
|
|
12275
|
+
logger: this.logger,
|
|
12276
|
+
logLevel: this.logLevel,
|
|
12277
|
+
fetch: this.fetch,
|
|
12278
|
+
fetchOptions: this.fetchOptions,
|
|
12279
|
+
bearerToken: this.bearerToken,
|
|
12280
|
+
webhookKey: this.webhookKey,
|
|
12281
|
+
...options,
|
|
12282
|
+
});
|
|
12283
|
+
return client;
|
|
12284
|
+
}
|
|
12285
|
+
defaultQuery() {
|
|
12286
|
+
return this._options.defaultQuery;
|
|
12287
|
+
}
|
|
12288
|
+
validateHeaders({ values, nulls }) {
|
|
12289
|
+
return;
|
|
12290
|
+
}
|
|
12291
|
+
async authHeaders(opts) {
|
|
12292
|
+
return buildHeaders([{ Authorization: `Bearer ${this.bearerToken}` }]);
|
|
12293
|
+
}
|
|
12294
|
+
/**
|
|
12295
|
+
* Basic re-implementation of `qs.stringify` for primitive types.
|
|
12296
|
+
*/
|
|
12297
|
+
stringifyQuery(query) {
|
|
12298
|
+
return Object.entries(query)
|
|
12299
|
+
.filter(([_, value]) => typeof value !== 'undefined')
|
|
12300
|
+
.map(([key, value]) => {
|
|
12301
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
12302
|
+
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
12303
|
+
}
|
|
12304
|
+
if (value === null) {
|
|
12305
|
+
return `${encodeURIComponent(key)}=`;
|
|
12306
|
+
}
|
|
12307
|
+
throw new DodoPaymentsError(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`);
|
|
12308
|
+
})
|
|
12309
|
+
.join('&');
|
|
12310
|
+
}
|
|
12311
|
+
getUserAgent() {
|
|
12312
|
+
return `${this.constructor.name}/JS ${VERSION}`;
|
|
12313
|
+
}
|
|
12314
|
+
defaultIdempotencyKey() {
|
|
12315
|
+
return `stainless-node-retry-${uuid4()}`;
|
|
12316
|
+
}
|
|
12317
|
+
makeStatusError(status, error, message, headers) {
|
|
12318
|
+
return APIError.generate(status, error, message, headers);
|
|
12319
|
+
}
|
|
12320
|
+
buildURL(path, query, defaultBaseURL) {
|
|
12321
|
+
const baseURL = (!__classPrivateFieldGet(this, _DodoPayments_instances, "m", _DodoPayments_baseURLOverridden).call(this) && defaultBaseURL) || this.baseURL;
|
|
12322
|
+
const url = isAbsoluteURL(path) ?
|
|
12323
|
+
new URL(path)
|
|
12324
|
+
: new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
|
|
12325
|
+
const defaultQuery = this.defaultQuery();
|
|
12326
|
+
if (!isEmptyObj(defaultQuery)) {
|
|
12327
|
+
query = { ...defaultQuery, ...query };
|
|
12328
|
+
}
|
|
12329
|
+
if (typeof query === 'object' && query && !Array.isArray(query)) {
|
|
12330
|
+
url.search = this.stringifyQuery(query);
|
|
12331
|
+
}
|
|
12332
|
+
return url.toString();
|
|
12333
|
+
}
|
|
12334
|
+
/**
|
|
12335
|
+
* Used as a callback for mutating the given `FinalRequestOptions` object.
|
|
12336
|
+
*/
|
|
12337
|
+
async prepareOptions(options) { }
|
|
12338
|
+
/**
|
|
12339
|
+
* Used as a callback for mutating the given `RequestInit` object.
|
|
12340
|
+
*
|
|
12341
|
+
* This is useful for cases where you want to add certain headers based off of
|
|
12342
|
+
* the request properties, e.g. `method` or `url`.
|
|
12343
|
+
*/
|
|
12344
|
+
async prepareRequest(request, { url, options }) { }
|
|
12345
|
+
get(path, opts) {
|
|
12346
|
+
return this.methodRequest('get', path, opts);
|
|
12347
|
+
}
|
|
12348
|
+
post(path, opts) {
|
|
12349
|
+
return this.methodRequest('post', path, opts);
|
|
12350
|
+
}
|
|
12351
|
+
patch(path, opts) {
|
|
12352
|
+
return this.methodRequest('patch', path, opts);
|
|
12353
|
+
}
|
|
12354
|
+
put(path, opts) {
|
|
12355
|
+
return this.methodRequest('put', path, opts);
|
|
12356
|
+
}
|
|
12357
|
+
delete(path, opts) {
|
|
12358
|
+
return this.methodRequest('delete', path, opts);
|
|
12359
|
+
}
|
|
12360
|
+
methodRequest(method, path, opts) {
|
|
12361
|
+
return this.request(Promise.resolve(opts).then((opts) => {
|
|
12362
|
+
return { method, path, ...opts };
|
|
12363
|
+
}));
|
|
12364
|
+
}
|
|
12365
|
+
request(options, remainingRetries = null) {
|
|
12366
|
+
return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
|
|
12367
|
+
}
|
|
12368
|
+
async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
|
|
12369
|
+
const options = await optionsInput;
|
|
12370
|
+
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
12371
|
+
if (retriesRemaining == null) {
|
|
12372
|
+
retriesRemaining = maxRetries;
|
|
12373
|
+
}
|
|
12374
|
+
await this.prepareOptions(options);
|
|
12375
|
+
const { req, url, timeout } = await this.buildRequest(options, {
|
|
12376
|
+
retryCount: maxRetries - retriesRemaining,
|
|
12377
|
+
});
|
|
12378
|
+
await this.prepareRequest(req, { url, options });
|
|
12379
|
+
/** Not an API request ID, just for correlating local log entries. */
|
|
12380
|
+
const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
|
|
12381
|
+
const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
|
|
12382
|
+
const startTime = Date.now();
|
|
12383
|
+
loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({
|
|
12384
|
+
retryOfRequestLogID,
|
|
12385
|
+
method: options.method,
|
|
12386
|
+
url,
|
|
12387
|
+
options,
|
|
12388
|
+
headers: req.headers,
|
|
12389
|
+
}));
|
|
12390
|
+
if (options.signal?.aborted) {
|
|
12391
|
+
throw new APIUserAbortError();
|
|
12392
|
+
}
|
|
12393
|
+
const controller = new AbortController();
|
|
12394
|
+
const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
|
|
12395
|
+
const headersTime = Date.now();
|
|
12396
|
+
if (response instanceof globalThis.Error) {
|
|
12397
|
+
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
12398
|
+
if (options.signal?.aborted) {
|
|
12399
|
+
throw new APIUserAbortError();
|
|
12400
|
+
}
|
|
12401
|
+
// detect native connection timeout errors
|
|
12402
|
+
// deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
|
|
12403
|
+
// undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
|
|
12404
|
+
// others do not provide enough information to distinguish timeouts from other connection errors
|
|
12405
|
+
const isTimeout = isAbortError(response) ||
|
|
12406
|
+
/timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
|
|
12407
|
+
if (retriesRemaining) {
|
|
12408
|
+
loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`);
|
|
12409
|
+
loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({
|
|
12410
|
+
retryOfRequestLogID,
|
|
12411
|
+
url,
|
|
12412
|
+
durationMs: headersTime - startTime,
|
|
12413
|
+
message: response.message,
|
|
12414
|
+
}));
|
|
12415
|
+
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID);
|
|
12416
|
+
}
|
|
12417
|
+
loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`);
|
|
12418
|
+
loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({
|
|
12419
|
+
retryOfRequestLogID,
|
|
12420
|
+
url,
|
|
12421
|
+
durationMs: headersTime - startTime,
|
|
12422
|
+
message: response.message,
|
|
12423
|
+
}));
|
|
12424
|
+
if (isTimeout) {
|
|
12425
|
+
throw new APIConnectionTimeoutError();
|
|
12426
|
+
}
|
|
12427
|
+
throw new APIConnectionError({ cause: response });
|
|
12428
|
+
}
|
|
12429
|
+
const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
|
|
12430
|
+
if (!response.ok) {
|
|
12431
|
+
const shouldRetry = await this.shouldRetry(response);
|
|
12432
|
+
if (retriesRemaining && shouldRetry) {
|
|
12433
|
+
const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
|
|
12434
|
+
// We don't need the body of this response.
|
|
12435
|
+
await CancelReadableStream(response.body);
|
|
12436
|
+
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
12437
|
+
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
|
|
12438
|
+
retryOfRequestLogID,
|
|
12439
|
+
url: response.url,
|
|
12440
|
+
status: response.status,
|
|
12441
|
+
headers: response.headers,
|
|
12442
|
+
durationMs: headersTime - startTime,
|
|
12443
|
+
}));
|
|
12444
|
+
return this.retryRequest(options, retriesRemaining, retryOfRequestLogID ?? requestLogID, response.headers);
|
|
12445
|
+
}
|
|
12446
|
+
const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
|
|
12447
|
+
loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
|
|
12448
|
+
const errText = await response.text().catch((err) => castToError(err).message);
|
|
12449
|
+
const errJSON = safeJSON(errText);
|
|
12450
|
+
const errMessage = errJSON ? undefined : errText;
|
|
12451
|
+
loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
|
|
12452
|
+
retryOfRequestLogID,
|
|
12453
|
+
url: response.url,
|
|
12454
|
+
status: response.status,
|
|
12455
|
+
headers: response.headers,
|
|
12456
|
+
message: errMessage,
|
|
12457
|
+
durationMs: Date.now() - startTime,
|
|
12458
|
+
}));
|
|
12459
|
+
const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
|
|
12460
|
+
throw err;
|
|
12461
|
+
}
|
|
12462
|
+
loggerFor(this).info(responseInfo);
|
|
12463
|
+
loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
|
|
12464
|
+
retryOfRequestLogID,
|
|
12465
|
+
url: response.url,
|
|
12466
|
+
status: response.status,
|
|
12467
|
+
headers: response.headers,
|
|
12468
|
+
durationMs: headersTime - startTime,
|
|
12469
|
+
}));
|
|
12470
|
+
return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
|
|
12471
|
+
}
|
|
12472
|
+
getAPIList(path, Page, opts) {
|
|
12473
|
+
return this.requestAPIList(Page, { method: 'get', path, ...opts });
|
|
12474
|
+
}
|
|
12475
|
+
requestAPIList(Page, options) {
|
|
12476
|
+
const request = this.makeRequest(options, null, undefined);
|
|
12477
|
+
return new PagePromise(this, request, Page);
|
|
12478
|
+
}
|
|
12479
|
+
async fetchWithTimeout(url, init, ms, controller) {
|
|
12480
|
+
const { signal, method, ...options } = init || {};
|
|
12481
|
+
if (signal)
|
|
12482
|
+
signal.addEventListener('abort', () => controller.abort());
|
|
12483
|
+
const timeout = setTimeout(() => controller.abort(), ms);
|
|
12484
|
+
const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
|
|
12485
|
+
(typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
|
|
12486
|
+
const fetchOptions = {
|
|
12487
|
+
signal: controller.signal,
|
|
12488
|
+
...(isReadableBody ? { duplex: 'half' } : {}),
|
|
12489
|
+
method: 'GET',
|
|
12490
|
+
...options,
|
|
12491
|
+
};
|
|
12492
|
+
if (method) {
|
|
12493
|
+
// Custom methods like 'patch' need to be uppercased
|
|
12494
|
+
// See https://github.com/nodejs/undici/issues/2294
|
|
12495
|
+
fetchOptions.method = method.toUpperCase();
|
|
12496
|
+
}
|
|
12497
|
+
try {
|
|
12498
|
+
// use undefined this binding; fetch errors if bound to something else in browser/cloudflare
|
|
12499
|
+
return await this.fetch.call(undefined, url, fetchOptions);
|
|
12500
|
+
}
|
|
12501
|
+
finally {
|
|
12502
|
+
clearTimeout(timeout);
|
|
12503
|
+
}
|
|
12504
|
+
}
|
|
12505
|
+
async shouldRetry(response) {
|
|
12506
|
+
// Note this is not a standard header.
|
|
12507
|
+
const shouldRetryHeader = response.headers.get('x-should-retry');
|
|
12508
|
+
// If the server explicitly says whether or not to retry, obey.
|
|
12509
|
+
if (shouldRetryHeader === 'true')
|
|
12510
|
+
return true;
|
|
12511
|
+
if (shouldRetryHeader === 'false')
|
|
12512
|
+
return false;
|
|
12513
|
+
// Retry on request timeouts.
|
|
12514
|
+
if (response.status === 408)
|
|
12515
|
+
return true;
|
|
12516
|
+
// Retry on lock timeouts.
|
|
12517
|
+
if (response.status === 409)
|
|
12518
|
+
return true;
|
|
12519
|
+
// Retry on rate limits.
|
|
12520
|
+
if (response.status === 429)
|
|
12521
|
+
return true;
|
|
12522
|
+
// Retry internal errors.
|
|
12523
|
+
if (response.status >= 500)
|
|
12524
|
+
return true;
|
|
12525
|
+
return false;
|
|
12526
|
+
}
|
|
12527
|
+
async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
|
|
12528
|
+
let timeoutMillis;
|
|
12529
|
+
// Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
|
|
12530
|
+
const retryAfterMillisHeader = responseHeaders?.get('retry-after-ms');
|
|
12531
|
+
if (retryAfterMillisHeader) {
|
|
12532
|
+
const timeoutMs = parseFloat(retryAfterMillisHeader);
|
|
12533
|
+
if (!Number.isNaN(timeoutMs)) {
|
|
12534
|
+
timeoutMillis = timeoutMs;
|
|
12535
|
+
}
|
|
12536
|
+
}
|
|
12537
|
+
// About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
|
|
12538
|
+
const retryAfterHeader = responseHeaders?.get('retry-after');
|
|
12539
|
+
if (retryAfterHeader && !timeoutMillis) {
|
|
12540
|
+
const timeoutSeconds = parseFloat(retryAfterHeader);
|
|
12541
|
+
if (!Number.isNaN(timeoutSeconds)) {
|
|
12542
|
+
timeoutMillis = timeoutSeconds * 1000;
|
|
12543
|
+
}
|
|
12544
|
+
else {
|
|
12545
|
+
timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
|
|
12546
|
+
}
|
|
12547
|
+
}
|
|
12548
|
+
// If the API asks us to wait a certain amount of time (and it's a reasonable amount),
|
|
12549
|
+
// just do what it says, but otherwise calculate a default
|
|
12550
|
+
if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
|
|
12551
|
+
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
12552
|
+
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
12553
|
+
}
|
|
12554
|
+
await sleep(timeoutMillis);
|
|
12555
|
+
return this.makeRequest(options, retriesRemaining - 1, requestLogID);
|
|
12556
|
+
}
|
|
12557
|
+
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
12558
|
+
const initialRetryDelay = 0.5;
|
|
12559
|
+
const maxRetryDelay = 8.0;
|
|
12560
|
+
const numRetries = maxRetries - retriesRemaining;
|
|
12561
|
+
// Apply exponential backoff, but not more than the max.
|
|
12562
|
+
const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
|
|
12563
|
+
// Apply some jitter, take up to at most 25 percent of the retry time.
|
|
12564
|
+
const jitter = 1 - Math.random() * 0.25;
|
|
12565
|
+
return sleepSeconds * jitter * 1000;
|
|
12566
|
+
}
|
|
12567
|
+
async buildRequest(inputOptions, { retryCount = 0 } = {}) {
|
|
12568
|
+
const options = { ...inputOptions };
|
|
12569
|
+
const { method, path, query, defaultBaseURL } = options;
|
|
12570
|
+
const url = this.buildURL(path, query, defaultBaseURL);
|
|
12571
|
+
if ('timeout' in options)
|
|
12572
|
+
validatePositiveInteger('timeout', options.timeout);
|
|
12573
|
+
options.timeout = options.timeout ?? this.timeout;
|
|
12574
|
+
const { bodyHeaders, body } = this.buildBody({ options });
|
|
12575
|
+
const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
|
|
12576
|
+
const req = {
|
|
12577
|
+
method,
|
|
12578
|
+
headers: reqHeaders,
|
|
12579
|
+
...(options.signal && { signal: options.signal }),
|
|
12580
|
+
...(globalThis.ReadableStream &&
|
|
12581
|
+
body instanceof globalThis.ReadableStream && { duplex: 'half' }),
|
|
12582
|
+
...(body && { body }),
|
|
12583
|
+
...(this.fetchOptions ?? {}),
|
|
12584
|
+
...(options.fetchOptions ?? {}),
|
|
12585
|
+
};
|
|
12586
|
+
return { req, url, timeout: options.timeout };
|
|
12587
|
+
}
|
|
12588
|
+
async buildHeaders({ options, method, bodyHeaders, retryCount, }) {
|
|
12589
|
+
let idempotencyHeaders = {};
|
|
12590
|
+
if (this.idempotencyHeader && method !== 'get') {
|
|
12591
|
+
if (!options.idempotencyKey)
|
|
12592
|
+
options.idempotencyKey = this.defaultIdempotencyKey();
|
|
12593
|
+
idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
|
|
12594
|
+
}
|
|
12595
|
+
const headers = buildHeaders([
|
|
12596
|
+
idempotencyHeaders,
|
|
12597
|
+
{
|
|
12598
|
+
Accept: 'application/json',
|
|
12599
|
+
'User-Agent': this.getUserAgent(),
|
|
12600
|
+
'X-Stainless-Retry-Count': String(retryCount),
|
|
12601
|
+
...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
|
|
12602
|
+
...getPlatformHeaders(),
|
|
12603
|
+
},
|
|
12604
|
+
await this.authHeaders(options),
|
|
12605
|
+
this._options.defaultHeaders,
|
|
12606
|
+
bodyHeaders,
|
|
12607
|
+
options.headers,
|
|
12608
|
+
]);
|
|
12609
|
+
this.validateHeaders(headers);
|
|
12610
|
+
return headers.values;
|
|
12611
|
+
}
|
|
12612
|
+
buildBody({ options: { body, headers: rawHeaders } }) {
|
|
12613
|
+
if (!body) {
|
|
12614
|
+
return { bodyHeaders: undefined, body: undefined };
|
|
12615
|
+
}
|
|
12616
|
+
const headers = buildHeaders([rawHeaders]);
|
|
12617
|
+
if (
|
|
12618
|
+
// Pass raw type verbatim
|
|
12619
|
+
ArrayBuffer.isView(body) ||
|
|
12620
|
+
body instanceof ArrayBuffer ||
|
|
12621
|
+
body instanceof DataView ||
|
|
12622
|
+
(typeof body === 'string' &&
|
|
12623
|
+
// Preserve legacy string encoding behavior for now
|
|
12624
|
+
headers.values.has('content-type')) ||
|
|
12625
|
+
// `Blob` is superset of `File`
|
|
12626
|
+
(globalThis.Blob && body instanceof globalThis.Blob) ||
|
|
12627
|
+
// `FormData` -> `multipart/form-data`
|
|
12628
|
+
body instanceof FormData ||
|
|
12629
|
+
// `URLSearchParams` -> `application/x-www-form-urlencoded`
|
|
12630
|
+
body instanceof URLSearchParams ||
|
|
12631
|
+
// Send chunked stream (each chunk has own `length`)
|
|
12632
|
+
(globalThis.ReadableStream && body instanceof globalThis.ReadableStream)) {
|
|
12633
|
+
return { bodyHeaders: undefined, body: body };
|
|
12634
|
+
}
|
|
12635
|
+
else if (typeof body === 'object' &&
|
|
12636
|
+
(Symbol.asyncIterator in body ||
|
|
12637
|
+
(Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
|
|
12638
|
+
return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
|
|
12639
|
+
}
|
|
12640
|
+
else {
|
|
12641
|
+
return __classPrivateFieldGet(this, _DodoPayments_encoder, "f").call(this, { body, headers });
|
|
12642
|
+
}
|
|
12643
|
+
}
|
|
12644
|
+
}
|
|
12645
|
+
_a = DodoPayments, _DodoPayments_encoder = new WeakMap(), _DodoPayments_instances = new WeakSet(), _DodoPayments_baseURLOverridden = function _DodoPayments_baseURLOverridden() {
|
|
12646
|
+
return this.baseURL !== environments[this._options.environment || 'live_mode'];
|
|
12647
|
+
};
|
|
12648
|
+
DodoPayments.DodoPayments = _a;
|
|
12649
|
+
DodoPayments.DEFAULT_TIMEOUT = 60000; // 1 minute
|
|
12650
|
+
DodoPayments.DodoPaymentsError = DodoPaymentsError;
|
|
12651
|
+
DodoPayments.APIError = APIError;
|
|
12652
|
+
DodoPayments.APIConnectionError = APIConnectionError;
|
|
12653
|
+
DodoPayments.APIConnectionTimeoutError = APIConnectionTimeoutError;
|
|
12654
|
+
DodoPayments.APIUserAbortError = APIUserAbortError;
|
|
12655
|
+
DodoPayments.NotFoundError = NotFoundError;
|
|
12656
|
+
DodoPayments.ConflictError = ConflictError;
|
|
12657
|
+
DodoPayments.RateLimitError = RateLimitError;
|
|
12658
|
+
DodoPayments.BadRequestError = BadRequestError;
|
|
12659
|
+
DodoPayments.AuthenticationError = AuthenticationError;
|
|
12660
|
+
DodoPayments.InternalServerError = InternalServerError;
|
|
12661
|
+
DodoPayments.PermissionDeniedError = PermissionDeniedError;
|
|
12662
|
+
DodoPayments.UnprocessableEntityError = UnprocessableEntityError;
|
|
12663
|
+
DodoPayments.toFile = toFile;
|
|
12664
|
+
DodoPayments.CheckoutSessions = CheckoutSessions;
|
|
12665
|
+
DodoPayments.Payments = Payments;
|
|
12666
|
+
DodoPayments.Subscriptions = Subscriptions;
|
|
12667
|
+
DodoPayments.Invoices = Invoices;
|
|
12668
|
+
DodoPayments.Licenses = Licenses;
|
|
12669
|
+
DodoPayments.LicenseKeys = LicenseKeys;
|
|
12670
|
+
DodoPayments.LicenseKeyInstances = LicenseKeyInstances;
|
|
12671
|
+
DodoPayments.Customers = Customers;
|
|
12672
|
+
DodoPayments.Refunds = Refunds;
|
|
12673
|
+
DodoPayments.Disputes = Disputes;
|
|
12674
|
+
DodoPayments.Payouts = Payouts;
|
|
12675
|
+
DodoPayments.Products = Products;
|
|
12676
|
+
DodoPayments.Misc = Misc;
|
|
12677
|
+
DodoPayments.Discounts = Discounts;
|
|
12678
|
+
DodoPayments.Addons = Addons;
|
|
12679
|
+
DodoPayments.Brands = Brands;
|
|
12680
|
+
DodoPayments.Webhooks = Webhooks$1;
|
|
12681
|
+
DodoPayments.WebhookEvents = WebhookEvents;
|
|
12682
|
+
DodoPayments.UsageEvents = UsageEvents;
|
|
12683
|
+
DodoPayments.Meters = Meters;
|
|
12684
|
+
|
|
12685
|
+
// src/checkout/checkout.ts
|
|
12686
|
+
var checkoutQuerySchema = objectType({
|
|
12687
|
+
productId: stringType(),
|
|
12688
|
+
quantity: stringType().optional(),
|
|
12689
|
+
// Customer fields
|
|
12690
|
+
fullName: stringType().optional(),
|
|
12691
|
+
firstName: stringType().optional(),
|
|
12692
|
+
lastName: stringType().optional(),
|
|
12693
|
+
email: stringType().optional(),
|
|
12694
|
+
country: stringType().optional(),
|
|
12695
|
+
addressLine: stringType().optional(),
|
|
12696
|
+
city: stringType().optional(),
|
|
12697
|
+
state: stringType().optional(),
|
|
12698
|
+
zipCode: stringType().optional(),
|
|
12699
|
+
// Disable flags
|
|
12700
|
+
disableFullName: stringType().optional(),
|
|
12701
|
+
disableFirstName: stringType().optional(),
|
|
12702
|
+
disableLastName: stringType().optional(),
|
|
12703
|
+
disableEmail: stringType().optional(),
|
|
12704
|
+
disableCountry: stringType().optional(),
|
|
12705
|
+
disableAddressLine: stringType().optional(),
|
|
12706
|
+
disableCity: stringType().optional(),
|
|
12707
|
+
disableState: stringType().optional(),
|
|
12708
|
+
disableZipCode: stringType().optional(),
|
|
12709
|
+
// Advanced controls
|
|
12710
|
+
paymentCurrency: stringType().optional(),
|
|
12711
|
+
showCurrencySelector: stringType().optional(),
|
|
12712
|
+
paymentAmount: stringType().optional(),
|
|
12713
|
+
showDiscounts: stringType().optional()
|
|
12714
|
+
// Metadata (allow any key starting with metadata_)
|
|
12715
|
+
// We'll handle metadata separately in the handler
|
|
12716
|
+
}).catchall(unknownType());
|
|
12717
|
+
var dynamicCheckoutBodySchema = objectType({
|
|
12718
|
+
// For subscription
|
|
12719
|
+
product_id: stringType().optional(),
|
|
12720
|
+
quantity: numberType().optional(),
|
|
12721
|
+
// For one-time payment
|
|
12722
|
+
product_cart: arrayType(
|
|
12723
|
+
objectType({
|
|
12724
|
+
product_id: stringType(),
|
|
12725
|
+
quantity: numberType()
|
|
12726
|
+
})
|
|
12727
|
+
).optional(),
|
|
12728
|
+
// Common fields
|
|
12729
|
+
billing: objectType({
|
|
12730
|
+
city: stringType(),
|
|
12731
|
+
country: stringType(),
|
|
12732
|
+
state: stringType(),
|
|
12733
|
+
street: stringType(),
|
|
12734
|
+
zipcode: stringType()
|
|
12735
|
+
}),
|
|
12736
|
+
customer: objectType({
|
|
12737
|
+
customer_id: stringType().optional(),
|
|
12738
|
+
email: stringType().optional(),
|
|
12739
|
+
name: stringType().optional()
|
|
12740
|
+
}),
|
|
12741
|
+
discount_id: stringType().optional(),
|
|
12742
|
+
addons: arrayType(
|
|
12743
|
+
objectType({
|
|
12744
|
+
addon_id: stringType(),
|
|
12745
|
+
quantity: numberType()
|
|
12746
|
+
})
|
|
12747
|
+
).optional(),
|
|
12748
|
+
metadata: recordType(stringType(), stringType()).optional(),
|
|
12749
|
+
currency: stringType().optional()
|
|
12750
|
+
// Allow any additional fields (for future compatibility)
|
|
12751
|
+
}).catchall(unknownType());
|
|
12752
|
+
var checkoutSessionProductCartItemSchema = objectType({
|
|
12753
|
+
product_id: stringType().min(1, "Product ID is required"),
|
|
12754
|
+
quantity: numberType().int().positive("Quantity must be a positive integer"),
|
|
12755
|
+
addons: arrayType(
|
|
12756
|
+
objectType({
|
|
12757
|
+
addon_id: stringType(),
|
|
12758
|
+
quantity: numberType().int().nonnegative()
|
|
12759
|
+
})
|
|
12760
|
+
).optional(),
|
|
12761
|
+
amount: numberType().int().nonnegative(
|
|
12762
|
+
"Amount must be a non-negative integer (for pay-what-you-want products)"
|
|
12763
|
+
).optional()
|
|
12764
|
+
});
|
|
12765
|
+
var checkoutSessionCustomerSchema = unionType([
|
|
12766
|
+
objectType({
|
|
12767
|
+
email: stringType().email(),
|
|
12768
|
+
name: stringType().min(1).optional(),
|
|
12769
|
+
phone_number: stringType().optional()
|
|
12770
|
+
}),
|
|
12771
|
+
objectType({
|
|
12772
|
+
customer_id: stringType()
|
|
12773
|
+
})
|
|
12774
|
+
]).optional();
|
|
12775
|
+
var checkoutSessionBillingAddressSchema = objectType({
|
|
12776
|
+
street: stringType().optional(),
|
|
12777
|
+
city: stringType().optional(),
|
|
12778
|
+
state: stringType().optional(),
|
|
12779
|
+
country: stringType().length(2, "Country must be a 2-letter ISO code"),
|
|
12780
|
+
zipcode: stringType().optional()
|
|
12781
|
+
}).optional();
|
|
12782
|
+
var paymentMethodTypeSchema = enumType([
|
|
12783
|
+
"credit",
|
|
12784
|
+
"debit",
|
|
12785
|
+
"upi_collect",
|
|
12786
|
+
"upi_intent",
|
|
12787
|
+
"apple_pay",
|
|
12788
|
+
"cashapp",
|
|
12789
|
+
"google_pay",
|
|
12790
|
+
"multibanco",
|
|
12791
|
+
"bancontact_card",
|
|
12792
|
+
"eps",
|
|
12793
|
+
"ideal",
|
|
12794
|
+
"przelewy24",
|
|
12795
|
+
"paypal",
|
|
12796
|
+
"affirm",
|
|
12797
|
+
"klarna",
|
|
12798
|
+
"sepa",
|
|
12799
|
+
"ach",
|
|
12800
|
+
"amazon_pay",
|
|
12801
|
+
"afterpay_clearpay"
|
|
12802
|
+
]);
|
|
12803
|
+
var checkoutSessionCustomizationSchema = objectType({
|
|
12804
|
+
theme: enumType(["light", "dark", "system"]).optional(),
|
|
12805
|
+
show_order_details: booleanType().optional(),
|
|
12806
|
+
show_on_demand_tag: booleanType().optional(),
|
|
12807
|
+
force_language: stringType().optional()
|
|
12808
|
+
}).optional();
|
|
12809
|
+
var checkoutSessionFeatureFlagsSchema = objectType({
|
|
12810
|
+
allow_currency_selection: booleanType().optional(),
|
|
12811
|
+
allow_customer_editing_city: booleanType().optional(),
|
|
12812
|
+
allow_customer_editing_country: booleanType().optional(),
|
|
12813
|
+
allow_customer_editing_email: booleanType().optional(),
|
|
12814
|
+
allow_customer_editing_name: booleanType().optional(),
|
|
12815
|
+
allow_customer_editing_state: booleanType().optional(),
|
|
12816
|
+
allow_customer_editing_street: booleanType().optional(),
|
|
12817
|
+
allow_customer_editing_zipcode: booleanType().optional(),
|
|
12818
|
+
allow_discount_code: booleanType().optional(),
|
|
12819
|
+
allow_phone_number_collection: booleanType().optional(),
|
|
12820
|
+
allow_tax_id: booleanType().optional(),
|
|
12821
|
+
always_create_new_customer: booleanType().optional()
|
|
12822
|
+
}).optional();
|
|
12823
|
+
var checkoutSessionOnDemandSchema = objectType({
|
|
12824
|
+
mandate_only: booleanType(),
|
|
12825
|
+
product_price: numberType().int().optional(),
|
|
12826
|
+
product_currency: stringType().length(3).optional(),
|
|
12827
|
+
product_description: stringType().optional(),
|
|
12828
|
+
adaptive_currency_fees_inclusive: booleanType().optional()
|
|
12829
|
+
}).optional();
|
|
12830
|
+
var checkoutSessionSubscriptionDataSchema = objectType({
|
|
12831
|
+
trial_period_days: numberType().int().nonnegative().optional(),
|
|
12832
|
+
on_demand: checkoutSessionOnDemandSchema
|
|
12833
|
+
}).optional();
|
|
12834
|
+
var checkoutSessionPayloadSchema = objectType({
|
|
12835
|
+
// Required fields
|
|
12836
|
+
product_cart: arrayType(checkoutSessionProductCartItemSchema).min(1, "At least one product is required"),
|
|
12837
|
+
// Optional fields
|
|
12838
|
+
customer: checkoutSessionCustomerSchema,
|
|
12839
|
+
billing_address: checkoutSessionBillingAddressSchema,
|
|
12840
|
+
return_url: stringType().url().optional(),
|
|
12841
|
+
allowed_payment_method_types: arrayType(paymentMethodTypeSchema).optional(),
|
|
12842
|
+
billing_currency: stringType().length(3, "Currency must be a 3-letter ISO code").optional(),
|
|
12843
|
+
show_saved_payment_methods: booleanType().optional(),
|
|
12844
|
+
confirm: booleanType().optional(),
|
|
12845
|
+
discount_code: stringType().optional(),
|
|
12846
|
+
metadata: recordType(stringType(), stringType()).optional(),
|
|
12847
|
+
customization: checkoutSessionCustomizationSchema,
|
|
12848
|
+
feature_flags: checkoutSessionFeatureFlagsSchema,
|
|
12849
|
+
subscription_data: checkoutSessionSubscriptionDataSchema,
|
|
12850
|
+
force_3ds: booleanType().optional()
|
|
12851
|
+
});
|
|
12852
|
+
var checkoutSessionResponseSchema = objectType({
|
|
12853
|
+
session_id: stringType().min(1, "Session ID is required"),
|
|
12854
|
+
checkout_url: stringType().url("Invalid checkout URL")
|
|
12855
|
+
});
|
|
12856
|
+
var createCheckoutSession = async (payload, config) => {
|
|
12857
|
+
const validation = checkoutSessionPayloadSchema.safeParse(payload);
|
|
12858
|
+
if (!validation.success) {
|
|
12859
|
+
throw new Error(
|
|
12860
|
+
`Invalid checkout session payload: ${validation.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(", ")}`
|
|
12861
|
+
);
|
|
12862
|
+
}
|
|
12863
|
+
const dodopayments = new DodoPayments({
|
|
12864
|
+
bearerToken: config.bearerToken,
|
|
12865
|
+
environment: config.environment
|
|
12866
|
+
});
|
|
12867
|
+
try {
|
|
12868
|
+
const sdkPayload = {
|
|
12869
|
+
...validation.data,
|
|
12870
|
+
...validation.data.billing_address && {
|
|
12871
|
+
billing_address: {
|
|
12872
|
+
...validation.data.billing_address,
|
|
12873
|
+
country: validation.data.billing_address.country
|
|
12874
|
+
}
|
|
12875
|
+
}
|
|
12876
|
+
};
|
|
12877
|
+
const session = await dodopayments.checkoutSessions.create(
|
|
12878
|
+
sdkPayload
|
|
12879
|
+
);
|
|
12880
|
+
const responseValidation = checkoutSessionResponseSchema.safeParse(session);
|
|
12881
|
+
if (!responseValidation.success) {
|
|
12882
|
+
throw new Error(
|
|
12883
|
+
`Invalid checkout session response from API: ${responseValidation.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(", ")}`
|
|
12884
|
+
);
|
|
12885
|
+
}
|
|
12886
|
+
return responseValidation.data;
|
|
12887
|
+
} catch (error) {
|
|
12888
|
+
if (error instanceof Error) {
|
|
12889
|
+
console.error("Dodo Payments Checkout Session API Error:", {
|
|
12890
|
+
message: error.message,
|
|
12891
|
+
payload: validation.data,
|
|
12892
|
+
config: {
|
|
12893
|
+
environment: config.environment,
|
|
12894
|
+
hasBearerToken: !!config.bearerToken
|
|
12895
|
+
}
|
|
12896
|
+
});
|
|
12897
|
+
throw new Error(`Failed to create checkout session: ${error.message}`);
|
|
12898
|
+
}
|
|
12899
|
+
console.error("Unknown error creating checkout session:", error);
|
|
12900
|
+
throw new Error(
|
|
12901
|
+
"Failed to create checkout session due to an unknown error"
|
|
12902
|
+
);
|
|
12903
|
+
}
|
|
12904
|
+
};
|
|
12905
|
+
var buildCheckoutUrl = async ({
|
|
12906
|
+
queryParams,
|
|
12907
|
+
body,
|
|
12908
|
+
sessionPayload,
|
|
12909
|
+
returnUrl,
|
|
12910
|
+
bearerToken,
|
|
12911
|
+
environment,
|
|
12912
|
+
type = "static"
|
|
12913
|
+
}) => {
|
|
12914
|
+
if (type === "session") {
|
|
12915
|
+
if (!sessionPayload) {
|
|
12916
|
+
throw new Error("sessionPayload is required when type is 'session'");
|
|
12917
|
+
}
|
|
12918
|
+
const finalPayload = {
|
|
12919
|
+
...sessionPayload,
|
|
12920
|
+
return_url: sessionPayload.return_url ?? returnUrl
|
|
12921
|
+
};
|
|
12922
|
+
const session = await createCheckoutSession(finalPayload, {
|
|
12923
|
+
bearerToken,
|
|
12924
|
+
environment
|
|
12925
|
+
});
|
|
12926
|
+
return session.checkout_url;
|
|
12927
|
+
}
|
|
12928
|
+
const inputData = type === "dynamic" ? body : queryParams;
|
|
12929
|
+
let parseResult;
|
|
12930
|
+
if (type === "dynamic") {
|
|
12931
|
+
parseResult = dynamicCheckoutBodySchema.safeParse(inputData);
|
|
12932
|
+
} else {
|
|
12933
|
+
parseResult = checkoutQuerySchema.safeParse(inputData);
|
|
12934
|
+
}
|
|
12935
|
+
const { success, data, error } = parseResult;
|
|
12936
|
+
if (!success) {
|
|
12937
|
+
throw new Error(
|
|
12938
|
+
`Invalid ${type === "dynamic" ? "body" : "query parameters"}.
|
|
12939
|
+
${error.message}`
|
|
12940
|
+
);
|
|
12941
|
+
}
|
|
12942
|
+
if (type !== "dynamic") {
|
|
12943
|
+
const {
|
|
12944
|
+
productId,
|
|
12945
|
+
quantity: quantity2,
|
|
12946
|
+
fullName,
|
|
12947
|
+
firstName,
|
|
12948
|
+
lastName,
|
|
12949
|
+
email,
|
|
12950
|
+
country,
|
|
12951
|
+
addressLine,
|
|
12952
|
+
city,
|
|
12953
|
+
state,
|
|
12954
|
+
zipCode,
|
|
12955
|
+
disableFullName,
|
|
12956
|
+
disableFirstName,
|
|
12957
|
+
disableLastName,
|
|
12958
|
+
disableEmail,
|
|
12959
|
+
disableCountry,
|
|
12960
|
+
disableAddressLine,
|
|
12961
|
+
disableCity,
|
|
12962
|
+
disableState,
|
|
12963
|
+
disableZipCode,
|
|
12964
|
+
paymentCurrency,
|
|
12965
|
+
showCurrencySelector,
|
|
12966
|
+
paymentAmount,
|
|
12967
|
+
showDiscounts
|
|
12968
|
+
// metadata handled below
|
|
12969
|
+
} = data;
|
|
12970
|
+
const dodopayments2 = new DodoPayments({
|
|
12971
|
+
bearerToken,
|
|
12972
|
+
environment
|
|
12973
|
+
});
|
|
12974
|
+
if (!productId) throw new Error("Missing required field: productId");
|
|
12975
|
+
try {
|
|
12976
|
+
await dodopayments2.products.retrieve(productId);
|
|
12977
|
+
} catch (err) {
|
|
12978
|
+
console.error(err);
|
|
12979
|
+
throw new Error("Product not found");
|
|
12980
|
+
}
|
|
12981
|
+
const url = new URL(
|
|
12982
|
+
`${environment === "test_mode" ? "https://test.checkout.dodopayments.com" : "https://checkout.dodopayments.com"}/buy/${productId}`
|
|
12983
|
+
);
|
|
12984
|
+
url.searchParams.set("quantity", quantity2 ? String(quantity2) : "1");
|
|
12985
|
+
if (returnUrl) url.searchParams.set("redirect_url", returnUrl);
|
|
12986
|
+
if (fullName) url.searchParams.set("fullName", String(fullName));
|
|
12987
|
+
if (firstName) url.searchParams.set("firstName", String(firstName));
|
|
12988
|
+
if (lastName) url.searchParams.set("lastName", String(lastName));
|
|
12989
|
+
if (email) url.searchParams.set("email", String(email));
|
|
12990
|
+
if (country) url.searchParams.set("country", String(country));
|
|
12991
|
+
if (addressLine) url.searchParams.set("addressLine", String(addressLine));
|
|
12992
|
+
if (city) url.searchParams.set("city", String(city));
|
|
12993
|
+
if (state) url.searchParams.set("state", String(state));
|
|
12994
|
+
if (zipCode) url.searchParams.set("zipCode", String(zipCode));
|
|
12995
|
+
if (disableFullName === "true")
|
|
12996
|
+
url.searchParams.set("disableFullName", "true");
|
|
12997
|
+
if (disableFirstName === "true")
|
|
12998
|
+
url.searchParams.set("disableFirstName", "true");
|
|
12999
|
+
if (disableLastName === "true")
|
|
13000
|
+
url.searchParams.set("disableLastName", "true");
|
|
13001
|
+
if (disableEmail === "true") url.searchParams.set("disableEmail", "true");
|
|
13002
|
+
if (disableCountry === "true")
|
|
13003
|
+
url.searchParams.set("disableCountry", "true");
|
|
13004
|
+
if (disableAddressLine === "true")
|
|
13005
|
+
url.searchParams.set("disableAddressLine", "true");
|
|
13006
|
+
if (disableCity === "true") url.searchParams.set("disableCity", "true");
|
|
13007
|
+
if (disableState === "true") url.searchParams.set("disableState", "true");
|
|
13008
|
+
if (disableZipCode === "true")
|
|
13009
|
+
url.searchParams.set("disableZipCode", "true");
|
|
13010
|
+
if (paymentCurrency)
|
|
13011
|
+
url.searchParams.set("paymentCurrency", String(paymentCurrency));
|
|
13012
|
+
if (showCurrencySelector)
|
|
13013
|
+
url.searchParams.set(
|
|
13014
|
+
"showCurrencySelector",
|
|
13015
|
+
String(showCurrencySelector)
|
|
13016
|
+
);
|
|
13017
|
+
if (paymentAmount)
|
|
13018
|
+
url.searchParams.set("paymentAmount", String(paymentAmount));
|
|
13019
|
+
if (showDiscounts)
|
|
13020
|
+
url.searchParams.set("showDiscounts", String(showDiscounts));
|
|
13021
|
+
for (const [key, value] of Object.entries(queryParams || {})) {
|
|
13022
|
+
if (key.startsWith("metadata_") && value && typeof value !== "object") {
|
|
13023
|
+
url.searchParams.set(key, String(value));
|
|
13024
|
+
}
|
|
13025
|
+
}
|
|
13026
|
+
return url.toString();
|
|
13027
|
+
}
|
|
13028
|
+
const dyn = data;
|
|
13029
|
+
const {
|
|
13030
|
+
product_id,
|
|
13031
|
+
product_cart,
|
|
13032
|
+
quantity,
|
|
13033
|
+
billing,
|
|
13034
|
+
customer,
|
|
13035
|
+
addons,
|
|
13036
|
+
metadata,
|
|
13037
|
+
allowed_payment_method_types,
|
|
13038
|
+
billing_currency,
|
|
13039
|
+
discount_code,
|
|
13040
|
+
on_demand,
|
|
13041
|
+
return_url: bodyReturnUrl,
|
|
13042
|
+
show_saved_payment_methods,
|
|
13043
|
+
tax_id,
|
|
13044
|
+
trial_period_days
|
|
13045
|
+
} = dyn;
|
|
13046
|
+
const dodopayments = new DodoPayments({
|
|
13047
|
+
bearerToken,
|
|
13048
|
+
environment
|
|
13049
|
+
});
|
|
13050
|
+
let isSubscription = false;
|
|
13051
|
+
let productIdToFetch = product_id;
|
|
13052
|
+
if (!product_id && product_cart && product_cart.length > 0) {
|
|
13053
|
+
productIdToFetch = product_cart[0].product_id;
|
|
13054
|
+
}
|
|
13055
|
+
if (!productIdToFetch)
|
|
13056
|
+
throw new Error(
|
|
13057
|
+
"Missing required field: product_id or product_cart[0].product_id"
|
|
13058
|
+
);
|
|
13059
|
+
let product;
|
|
13060
|
+
try {
|
|
13061
|
+
product = await dodopayments.products.retrieve(productIdToFetch);
|
|
13062
|
+
} catch (err) {
|
|
13063
|
+
console.error(err);
|
|
13064
|
+
throw new Error("Product not found");
|
|
13065
|
+
}
|
|
13066
|
+
isSubscription = Boolean(product.is_recurring);
|
|
13067
|
+
if (isSubscription && !product_id)
|
|
13068
|
+
throw new Error("Missing required field: product_id for subscription");
|
|
13069
|
+
if (!billing) throw new Error("Missing required field: billing");
|
|
13070
|
+
if (!customer) throw new Error("Missing required field: customer");
|
|
13071
|
+
if (isSubscription) {
|
|
13072
|
+
const subscriptionPayload = {
|
|
13073
|
+
billing,
|
|
13074
|
+
customer,
|
|
13075
|
+
product_id,
|
|
13076
|
+
quantity: quantity ? Number(quantity) : 1
|
|
13077
|
+
};
|
|
13078
|
+
if (metadata) subscriptionPayload.metadata = metadata;
|
|
13079
|
+
if (discount_code) subscriptionPayload.discount_code = discount_code;
|
|
13080
|
+
if (addons) subscriptionPayload.addons = addons;
|
|
13081
|
+
if (allowed_payment_method_types)
|
|
13082
|
+
subscriptionPayload.allowed_payment_method_types = allowed_payment_method_types;
|
|
13083
|
+
if (billing_currency)
|
|
13084
|
+
subscriptionPayload.billing_currency = billing_currency;
|
|
13085
|
+
if (on_demand) subscriptionPayload.on_demand = on_demand;
|
|
13086
|
+
subscriptionPayload.payment_link = true;
|
|
13087
|
+
if (bodyReturnUrl) {
|
|
13088
|
+
subscriptionPayload.return_url = bodyReturnUrl;
|
|
13089
|
+
} else if (returnUrl) {
|
|
13090
|
+
subscriptionPayload.return_url = returnUrl;
|
|
13091
|
+
}
|
|
13092
|
+
if (show_saved_payment_methods)
|
|
13093
|
+
subscriptionPayload.show_saved_payment_methods = show_saved_payment_methods;
|
|
13094
|
+
if (tax_id) subscriptionPayload.tax_id = tax_id;
|
|
13095
|
+
if (trial_period_days)
|
|
13096
|
+
subscriptionPayload.trial_period_days = trial_period_days;
|
|
13097
|
+
let subscription;
|
|
13098
|
+
try {
|
|
13099
|
+
subscription = await dodopayments.subscriptions.create(subscriptionPayload);
|
|
13100
|
+
} catch (err) {
|
|
13101
|
+
console.error("Error when creating subscription", err);
|
|
13102
|
+
throw new Error(err instanceof Error ? err.message : String(err));
|
|
12831
13103
|
}
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
13104
|
+
if (!subscription || !subscription.payment_link) {
|
|
13105
|
+
throw new Error(
|
|
13106
|
+
"No payment link returned from Dodo Payments API (subscription). Make sure to set payment_link as true in payload"
|
|
13107
|
+
);
|
|
13108
|
+
}
|
|
13109
|
+
return subscription.payment_link;
|
|
13110
|
+
} else {
|
|
13111
|
+
let cart = product_cart;
|
|
13112
|
+
if (!cart && product_id) {
|
|
13113
|
+
cart = [
|
|
13114
|
+
{ product_id, quantity: quantity ? Number(quantity) : 1 }
|
|
13115
|
+
];
|
|
13116
|
+
}
|
|
13117
|
+
if (!cart || cart.length === 0)
|
|
13118
|
+
throw new Error("Missing required field: product_cart or product_id");
|
|
13119
|
+
const paymentPayload = {
|
|
13120
|
+
billing,
|
|
13121
|
+
customer,
|
|
13122
|
+
product_cart: cart
|
|
13123
|
+
};
|
|
13124
|
+
if (metadata) paymentPayload.metadata = metadata;
|
|
13125
|
+
paymentPayload.payment_link = true;
|
|
13126
|
+
if (allowed_payment_method_types)
|
|
13127
|
+
paymentPayload.allowed_payment_method_types = allowed_payment_method_types;
|
|
13128
|
+
if (billing_currency) paymentPayload.billing_currency = billing_currency;
|
|
13129
|
+
if (discount_code) paymentPayload.discount_code = discount_code;
|
|
13130
|
+
if (bodyReturnUrl) {
|
|
13131
|
+
paymentPayload.return_url = bodyReturnUrl;
|
|
13132
|
+
} else if (returnUrl) {
|
|
13133
|
+
paymentPayload.return_url = returnUrl;
|
|
13134
|
+
}
|
|
13135
|
+
if (show_saved_payment_methods)
|
|
13136
|
+
paymentPayload.show_saved_payment_methods = show_saved_payment_methods;
|
|
13137
|
+
if (tax_id) paymentPayload.tax_id = tax_id;
|
|
13138
|
+
let payment;
|
|
13139
|
+
try {
|
|
13140
|
+
payment = await dodopayments.payments.create(paymentPayload);
|
|
13141
|
+
} catch (err) {
|
|
13142
|
+
console.error("Error when creating payment link", err);
|
|
13143
|
+
throw new Error(err instanceof Error ? err.message : String(err));
|
|
13144
|
+
}
|
|
13145
|
+
if (!payment || !payment.payment_link) {
|
|
13146
|
+
throw new Error(
|
|
13147
|
+
"No payment link returned from Dodo Payments API. Make sure to set payment_link as true in payload."
|
|
13148
|
+
);
|
|
13149
|
+
}
|
|
13150
|
+
return payment.payment_link;
|
|
13151
|
+
}
|
|
13152
|
+
};
|
|
13153
|
+
|
|
13154
|
+
const Checkout = (config) => {
|
|
13155
|
+
const getHandler = async (req) => {
|
|
13156
|
+
const { searchParams } = new URL(req.url);
|
|
13157
|
+
const queryParams = Object.fromEntries(searchParams);
|
|
13158
|
+
if (!queryParams.productId) {
|
|
13159
|
+
return new serverExports.NextResponse("Please provide productId query parameter", {
|
|
13160
|
+
status: 400,
|
|
13161
|
+
});
|
|
12838
13162
|
}
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
12842
|
-
|
|
12843
|
-
|
|
12844
|
-
|
|
13163
|
+
const { success, data, error } = checkoutQuerySchema.safeParse(queryParams);
|
|
13164
|
+
if (!success) {
|
|
13165
|
+
if (error.errors.some((e) => e.path.toString() === "productId")) {
|
|
13166
|
+
return new serverExports.NextResponse("Please provide productId query parameter", {
|
|
13167
|
+
status: 400,
|
|
13168
|
+
});
|
|
12845
13169
|
}
|
|
13170
|
+
return new serverExports.NextResponse(`Invalid query parameters.\n ${error.message}`, {
|
|
13171
|
+
status: 400,
|
|
13172
|
+
});
|
|
12846
13173
|
}
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
}
|
|
12851
|
-
if (secret.startsWith(Webhook.prefix)) {
|
|
12852
|
-
secret = secret.substring(Webhook.prefix.length);
|
|
12853
|
-
}
|
|
12854
|
-
this.key = base64.decode(secret);
|
|
13174
|
+
let url = "";
|
|
13175
|
+
try {
|
|
13176
|
+
url = await buildCheckoutUrl({ queryParams: data, ...config });
|
|
12855
13177
|
}
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
const headers = {};
|
|
12859
|
-
for (const key of Object.keys(headers_)) {
|
|
12860
|
-
headers[key.toLowerCase()] = headers_[key];
|
|
13178
|
+
catch (error) {
|
|
13179
|
+
return new serverExports.NextResponse(error.message, { status: 400 });
|
|
12861
13180
|
}
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12865
|
-
|
|
12866
|
-
|
|
13181
|
+
return serverExports.NextResponse.json({ checkout_url: url });
|
|
13182
|
+
};
|
|
13183
|
+
const postHandler = async (req) => {
|
|
13184
|
+
let body;
|
|
13185
|
+
try {
|
|
13186
|
+
body = await req.json();
|
|
12867
13187
|
}
|
|
12868
|
-
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
|
|
12874
|
-
|
|
12875
|
-
|
|
12876
|
-
|
|
13188
|
+
catch (e) {
|
|
13189
|
+
return new serverExports.NextResponse("Invalid JSON body", { status: 400 });
|
|
13190
|
+
}
|
|
13191
|
+
if (config.type === "dynamic") {
|
|
13192
|
+
// Handle dynamic checkout
|
|
13193
|
+
const { success, data, error } = dynamicCheckoutBodySchema.safeParse(body);
|
|
13194
|
+
if (!success) {
|
|
13195
|
+
return new serverExports.NextResponse(`Invalid request body.\n ${error.message}`, {
|
|
13196
|
+
status: 400,
|
|
13197
|
+
});
|
|
12877
13198
|
}
|
|
12878
|
-
|
|
12879
|
-
|
|
13199
|
+
let url = "";
|
|
13200
|
+
try {
|
|
13201
|
+
url = await buildCheckoutUrl({
|
|
13202
|
+
body: data,
|
|
13203
|
+
...config,
|
|
13204
|
+
type: "dynamic",
|
|
13205
|
+
});
|
|
12880
13206
|
}
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
if (typeof payload === "string") ;
|
|
12886
|
-
else if (payload.constructor.name === "Buffer") {
|
|
12887
|
-
payload = payload.toString();
|
|
13207
|
+
catch (error) {
|
|
13208
|
+
return new serverExports.NextResponse(error.message, { status: 400 });
|
|
13209
|
+
}
|
|
13210
|
+
return serverExports.NextResponse.json({ checkout_url: url });
|
|
12888
13211
|
}
|
|
12889
13212
|
else {
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
|
|
12900
|
-
|
|
12901
|
-
|
|
12902
|
-
|
|
12903
|
-
|
|
12904
|
-
|
|
12905
|
-
|
|
13213
|
+
// Handle checkout session
|
|
13214
|
+
const { success, data, error } = checkoutSessionPayloadSchema.safeParse(body);
|
|
13215
|
+
if (!success) {
|
|
13216
|
+
return new serverExports.NextResponse(`Invalid checkout session payload.\n ${error.message}`, {
|
|
13217
|
+
status: 400,
|
|
13218
|
+
});
|
|
13219
|
+
}
|
|
13220
|
+
let url = "";
|
|
13221
|
+
try {
|
|
13222
|
+
url = await buildCheckoutUrl({
|
|
13223
|
+
sessionPayload: data,
|
|
13224
|
+
...config,
|
|
13225
|
+
type: "session",
|
|
13226
|
+
});
|
|
13227
|
+
}
|
|
13228
|
+
catch (error) {
|
|
13229
|
+
return new serverExports.NextResponse(error.message, { status: 400 });
|
|
13230
|
+
}
|
|
13231
|
+
return serverExports.NextResponse.json({ checkout_url: url });
|
|
12906
13232
|
}
|
|
12907
|
-
|
|
12908
|
-
|
|
13233
|
+
};
|
|
13234
|
+
return (req) => {
|
|
13235
|
+
if (req.method === "POST") {
|
|
13236
|
+
return postHandler(req);
|
|
12909
13237
|
}
|
|
12910
|
-
return
|
|
12911
|
-
}
|
|
12912
|
-
}
|
|
12913
|
-
Webhook_1 = dist.Webhook = Webhook;
|
|
12914
|
-
Webhook.prefix = "whsec_";
|
|
13238
|
+
return getHandler(req);
|
|
13239
|
+
};
|
|
13240
|
+
};
|
|
12915
13241
|
|
|
12916
13242
|
// src/schemas/webhook.ts
|
|
12917
13243
|
var PaymentSchema = objectType({
|
|
@@ -13224,6 +13550,12 @@ var SubscriptionExpiredPayloadSchema = objectType({
|
|
|
13224
13550
|
timestamp: stringType().transform((d) => new Date(d)),
|
|
13225
13551
|
data: SubscriptionSchema
|
|
13226
13552
|
});
|
|
13553
|
+
var SubscriptionUpdatedPayloadSchema = objectType({
|
|
13554
|
+
business_id: stringType(),
|
|
13555
|
+
type: literalType("subscription.updated"),
|
|
13556
|
+
timestamp: stringType().transform((d) => new Date(d)),
|
|
13557
|
+
data: SubscriptionSchema
|
|
13558
|
+
});
|
|
13227
13559
|
var LicenseKeyCreatedPayloadSchema = objectType({
|
|
13228
13560
|
business_id: stringType(),
|
|
13229
13561
|
type: literalType("license_key.created"),
|
|
@@ -13252,6 +13584,7 @@ var WebhookPayloadSchema = discriminatedUnionType("type", [
|
|
|
13252
13584
|
SubscriptionCancelledPayloadSchema,
|
|
13253
13585
|
SubscriptionFailedPayloadSchema,
|
|
13254
13586
|
SubscriptionExpiredPayloadSchema,
|
|
13587
|
+
SubscriptionUpdatedPayloadSchema,
|
|
13255
13588
|
LicenseKeyCreatedPayloadSchema
|
|
13256
13589
|
]);
|
|
13257
13590
|
|
|
@@ -13326,6 +13659,9 @@ async function handleWebhookPayload(payload, config, context) {
|
|
|
13326
13659
|
if (payload.type === "subscription.expired") {
|
|
13327
13660
|
await callHandler(config.onSubscriptionExpired, payload);
|
|
13328
13661
|
}
|
|
13662
|
+
if (payload.type === "subscription.updated") {
|
|
13663
|
+
await callHandler(config.onSubscriptionUpdated, payload);
|
|
13664
|
+
}
|
|
13329
13665
|
if (payload.type === "license_key.created") {
|
|
13330
13666
|
await callHandler(config.onLicenseKeyCreated, payload);
|
|
13331
13667
|
}
|