@windrun-huaiin/backend-core 20.0.1 → 20.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -0
- package/dist/index.mjs +1 -1
- package/dist/lib/index.js +4 -0
- package/dist/lib/index.mjs +1 -1
- package/dist/lib/stripe-config.d.ts +4 -1
- package/dist/lib/stripe-config.d.ts.map +1 -1
- package/dist/lib/stripe-config.js +1 -1
- package/dist/lib/stripe-config.mjs +1 -1
- package/dist/lib/upstash/qstash.d.ts.map +1 -1
- package/dist/lib/upstash/qstash.js +1 -23
- package/dist/lib/upstash/qstash.mjs +2 -24
- package/dist/lib/upstash/redis-structures.d.ts +1 -1
- package/dist/lib/upstash/redis-structures.d.ts.map +1 -1
- package/dist/lib/upstash/redis-structures.js +20 -21
- package/dist/lib/upstash/redis-structures.mjs +20 -21
- package/dist/lib/upstash-config.d.ts +4 -0
- package/dist/lib/upstash-config.d.ts.map +1 -1
- package/dist/lib/upstash-config.js +29 -5
- package/dist/lib/upstash-config.mjs +26 -6
- package/package.json +5 -5
- package/src/lib/stripe-config.ts +6 -3
- package/src/lib/upstash/qstash.ts +2 -36
- package/src/lib/upstash/redis-structures.ts +25 -23
- package/src/lib/upstash-config.ts +33 -5
- package/src/services/stripe/webhook-handler.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -115,7 +115,11 @@ exports.fetchPaymentId = stripeConfig.fetchPaymentId;
|
|
|
115
115
|
exports.getStripe = stripeConfig.getStripe;
|
|
116
116
|
exports.updateSubscription = stripeConfig.updateSubscription;
|
|
117
117
|
exports.validateStripeWebhook = stripeConfig.validateStripeWebhook;
|
|
118
|
+
exports.getPrefixedQstashQueueName = upstashConfig.getPrefixedQstashQueueName;
|
|
119
|
+
exports.getPrefixedRedisKey = upstashConfig.getPrefixedRedisKey;
|
|
120
|
+
exports.getPrefixedRedisKeys = upstashConfig.getPrefixedRedisKeys;
|
|
118
121
|
exports.getQstash = upstashConfig.getQstash;
|
|
122
|
+
exports.getQstashNamePrefix = upstashConfig.getQstashNamePrefix;
|
|
119
123
|
exports.getRedis = upstashConfig.getRedis;
|
|
120
124
|
exports.withQstash = upstashConfig.withQstash;
|
|
121
125
|
exports.withRedis = upstashConfig.withRedis;
|
package/dist/index.mjs
CHANGED
|
@@ -26,7 +26,7 @@ export { getMoneyPriceInitUserContext } from './lib/money-price-helper.mjs';
|
|
|
26
26
|
export { fingerprintConfig } from './lib/fingerprint-config.mjs';
|
|
27
27
|
export { creditsConfig, freeAmount, freeExpiredDays, freeRegisterAmount, oneTimeExpiredDays } from './lib/credit-init.mjs';
|
|
28
28
|
export { ActiveSubscriptionExistsError, cancelSubscription, createCheckoutSession, createCustomerPortalSession, createOrGetCustomer, fetchPaymentId, getStripe, updateSubscription, validateStripeWebhook } from './lib/stripe-config.mjs';
|
|
29
|
-
export { getQstash, getRedis, withQstash, withRedis } from './lib/upstash-config.mjs';
|
|
29
|
+
export { getPrefixedQstashQueueName, getPrefixedRedisKey, getPrefixedRedisKeys, getQstash, getQstashNamePrefix, getRedis, withQstash, withRedis } from './lib/upstash-config.mjs';
|
|
30
30
|
export { acquireLock, releaseLock, withLock } from './lib/upstash/redis-lock.mjs';
|
|
31
31
|
export { getTargetLikeCount, getUserLikedTargets, isTargetLiked, likeTarget, unlikeTarget } from './lib/upstash/redis-like.mjs';
|
|
32
32
|
export { addFavorite, getFavoriteCount, getUserFavorites, isFavorited, removeFavorite } from './lib/upstash/redis-favorite.mjs';
|
package/dist/lib/index.js
CHANGED
|
@@ -35,7 +35,11 @@ exports.fetchPaymentId = stripeConfig.fetchPaymentId;
|
|
|
35
35
|
exports.getStripe = stripeConfig.getStripe;
|
|
36
36
|
exports.updateSubscription = stripeConfig.updateSubscription;
|
|
37
37
|
exports.validateStripeWebhook = stripeConfig.validateStripeWebhook;
|
|
38
|
+
exports.getPrefixedQstashQueueName = upstashConfig.getPrefixedQstashQueueName;
|
|
39
|
+
exports.getPrefixedRedisKey = upstashConfig.getPrefixedRedisKey;
|
|
40
|
+
exports.getPrefixedRedisKeys = upstashConfig.getPrefixedRedisKeys;
|
|
38
41
|
exports.getQstash = upstashConfig.getQstash;
|
|
42
|
+
exports.getQstashNamePrefix = upstashConfig.getQstashNamePrefix;
|
|
39
43
|
exports.getRedis = upstashConfig.getRedis;
|
|
40
44
|
exports.withQstash = upstashConfig.withQstash;
|
|
41
45
|
exports.withRedis = upstashConfig.withRedis;
|
package/dist/lib/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ export { getMoneyPriceInitUserContext } from './money-price-helper.mjs';
|
|
|
3
3
|
export { fingerprintConfig } from './fingerprint-config.mjs';
|
|
4
4
|
export { creditsConfig, freeAmount, freeExpiredDays, freeRegisterAmount, oneTimeExpiredDays } from './credit-init.mjs';
|
|
5
5
|
export { ActiveSubscriptionExistsError, cancelSubscription, createCheckoutSession, createCustomerPortalSession, createOrGetCustomer, fetchPaymentId, getStripe, updateSubscription, validateStripeWebhook } from './stripe-config.mjs';
|
|
6
|
-
export { getQstash, getRedis, withQstash, withRedis } from './upstash-config.mjs';
|
|
6
|
+
export { getPrefixedQstashQueueName, getPrefixedRedisKey, getPrefixedRedisKeys, getQstash, getQstashNamePrefix, getRedis, withQstash, withRedis } from './upstash-config.mjs';
|
|
7
7
|
export { acquireLock, releaseLock, withLock } from './upstash/redis-lock.mjs';
|
|
8
8
|
export { getTargetLikeCount, getUserLikedTargets, isTargetLiked, likeTarget, unlikeTarget } from './upstash/redis-like.mjs';
|
|
9
9
|
export { addFavorite, getFavoriteCount, getUserFavorites, isFavorited, removeFavorite } from './upstash/redis-favorite.mjs';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import Stripe from 'stripe';
|
|
2
|
+
type CheckoutSessionCreateParams = Parameters<Stripe['checkout']['sessions']['create']>[0];
|
|
3
|
+
type CheckoutSubscriptionData = NonNullable<CheckoutSessionCreateParams>['subscription_data'];
|
|
2
4
|
export declare const getStripe: () => Stripe;
|
|
3
5
|
export declare const validateStripeWebhook: (payload: string | Buffer, signature: string, secret: string) => Stripe.Event;
|
|
4
6
|
export interface BasicCheckoutSessionParams {
|
|
@@ -10,7 +12,7 @@ export interface BasicCheckoutSessionParams {
|
|
|
10
12
|
metadata?: Record<string, string>;
|
|
11
13
|
interval?: string;
|
|
12
14
|
}
|
|
13
|
-
export declare const createCheckoutSession: (params: BasicCheckoutSessionParams, subscriptionData?:
|
|
15
|
+
export declare const createCheckoutSession: (params: BasicCheckoutSessionParams, subscriptionData?: CheckoutSubscriptionData) => Promise<Stripe.Checkout.Session>;
|
|
14
16
|
export declare const fetchPaymentId: (invoiceId: string) => Promise<string>;
|
|
15
17
|
export declare const createOrGetCustomer: (params: {
|
|
16
18
|
userId: string;
|
|
@@ -28,4 +30,5 @@ export declare const cancelSubscription: (subscriptionId: string, cancelAtPeriod
|
|
|
28
30
|
export declare class ActiveSubscriptionExistsError extends Error {
|
|
29
31
|
constructor();
|
|
30
32
|
}
|
|
33
|
+
export {};
|
|
31
34
|
//# sourceMappingURL=stripe-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stripe-config.d.ts","sourceRoot":"","sources":["../../src/lib/stripe-config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAK5B,eAAO,MAAM,SAAS,QAAO,MAa5B,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAChC,SAAS,MAAM,GAAG,MAAM,EACxB,WAAW,MAAM,EACjB,QAAQ,MAAM,KACb,MAAM,CAAC,KAET,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAGnB;AAGD,eAAO,MAAM,qBAAqB,GAChC,QAAQ,0BAA0B,EAClC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"stripe-config.d.ts","sourceRoot":"","sources":["../../src/lib/stripe-config.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAK5B,KAAK,2BAA2B,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3F,KAAK,wBAAwB,GAAG,WAAW,CAAC,2BAA2B,CAAC,CAAC,mBAAmB,CAAC,CAAC;AAE9F,eAAO,MAAM,SAAS,QAAO,MAa5B,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAChC,SAAS,MAAM,GAAG,MAAM,EACxB,WAAW,MAAM,EACjB,QAAQ,MAAM,KACb,MAAM,CAAC,KAET,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAElC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAGnB;AAGD,eAAO,MAAM,qBAAqB,GAChC,QAAQ,0BAA0B,EAClC,mBAAmB,wBAAwB,KAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAgFjC,CAAC;AAGF,eAAO,MAAM,cAAc,GAAU,WAAW,MAAM,KAAI,OAAO,CAAC,MAAM,CAQvE,CAAA;AAGD,eAAO,MAAM,mBAAmB,GAAU,QAAQ;IAChD,MAAM,EAAE,MAAM,CAAC;CAChB,KAAG,OAAO,CAAC,MAAM,CA0FjB,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAU,QAAQ;IAC/C,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,mBAAmB,GAAG,MAAM,GAAG,gBAAgB,CAAC;CACrE,KAAG,OAAO,CAAC,MAAM,CAAC,YAAY,CAiC9B,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAU,QAAQ;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,KAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAqBvC,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAC7B,gBAAgB,MAAM,EACtB,oBAAmB,OAAc,KAChC,OAAO,CAAC,MAAM,CAAC,YAAY,CAiC7B,CAAC;AAEF,qBAAa,6BAA8B,SAAQ,KAAK;;CAKvD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qstash.d.ts","sourceRoot":"","sources":["../../../src/lib/upstash/qstash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"qstash.d.ts","sourceRoot":"","sources":["../../../src/lib/upstash/qstash.ts"],"names":[],"mappings":"AA8CA,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAErF,MAAM,WAAW,cAAc,CAAC,KAAK,SAAS,WAAW,GAAG,WAAW;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,KAAK,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB,CAAC,KAAK,SAAS,WAAW,GAAG,WAAW;IAC5E,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,KAAK,CAAC;CACb;AAED,MAAM,WAAW,8BAA8B,CAAC,KAAK,SAAS,WAAW,GAAG,WAAW;IACrF,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,KAAK,CAAC;CACb;AAED,MAAM,WAAW,8BAA8B,CAAC,KAAK,SAAS,WAAW,GAAG,WAAW;IACrF,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,KAAK,CAAC;CACb;AAiBD;;GAEG;AACH,eAAO,MAAM,cAAc,GAAU,KAAK,SAAS,WAAW,EAC5D,SAAS,qBAAqB,CAAC,KAAK,CAAC,KACpC,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAA;CAAE,GAAG,IAAI,CAa7E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAU,KAAK,SAAS,WAAW,EACrE,SAAS,8BAA8B,CAAC,KAAK,CAAC,KAC7C,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAA;CAAE,GAAG,IAAI,CA0BzE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAU,KAAK,SAAS,WAAW,EACrE,SAAS,8BAA8B,CAAC,KAAK,CAAC,KAC7C,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAA;CAAE,GAAG,IAAI,CAqB7E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAU,KAAK,SAAS,WAAW,EACnE,SAAS,qBAAqB,CAAC,KAAK,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,KAC3D,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAA;CAAE,GAAG,IAAI,CAc7E,CAAC;AAEF,MAAM,WAAW,sBAAsB,CAAC,KAAK,SAAS,WAAW,GAAG,WAAW,CAC7E,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,GAAU,KAAK,SAAS,WAAW,EAC7D,SAAS,sBAAsB,CAAC,KAAK,CAAC,KACrC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAA;CAAE,GAAG,IAAI,CAsB9E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,GAAU,YAAY,MAAM,KAAG,OAAO,CAAC,OAAO,CAexE,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAU,SAAS,mBAAmB,KAAG,OAAO,CAAC,OAAO,CAqBzF,CAAC"}
|
|
@@ -7,30 +7,8 @@ var upstashConfig = require('../upstash-config.js');
|
|
|
7
7
|
let cachedReceiver = null;
|
|
8
8
|
let receiverWarnedMissingEnv = false;
|
|
9
9
|
let receiverWarnedInitError = false;
|
|
10
|
-
const isNonEmpty = (value) => typeof value === 'string' && value.trim().length > 0;
|
|
11
10
|
const isTruthy = (value) => value === '1' || value === 'true' || value === 'TRUE';
|
|
12
11
|
const shouldSkipVerify = () => process.env.NODE_ENV === 'development' && isTruthy(process.env.SKIP_UPSTASH_QSTASH_VERIFY);
|
|
13
|
-
const getRequiredAppName = () => {
|
|
14
|
-
const appName = process.env.NEXT_PUBLIC_APP_NAME;
|
|
15
|
-
if (!isNonEmpty(appName)) {
|
|
16
|
-
throw new Error('[Upstash QStash] NEXT_PUBLIC_APP_NAME is required for QStash naming and must not be empty');
|
|
17
|
-
}
|
|
18
|
-
const normalized = appName.replace(/\s+/g, '').toLowerCase();
|
|
19
|
-
if (!normalized) {
|
|
20
|
-
throw new Error('[Upstash QStash] NEXT_PUBLIC_APP_NAME must contain non-whitespace characters for QStash naming');
|
|
21
|
-
}
|
|
22
|
-
return normalized;
|
|
23
|
-
};
|
|
24
|
-
const getQstashNamePrefix = () => {
|
|
25
|
-
const envSuffix = process.env.NODE_ENV === 'production' ? 'live' : 'test';
|
|
26
|
-
return `${getRequiredAppName()}_${envSuffix}`;
|
|
27
|
-
};
|
|
28
|
-
const prefixQstashName = (resourceType, name) => {
|
|
29
|
-
if (!isNonEmpty(name)) {
|
|
30
|
-
throw new Error(`[Upstash QStash] ${resourceType} name must not be empty`);
|
|
31
|
-
}
|
|
32
|
-
return `${getQstashNamePrefix()}_${resourceType}_${name}`;
|
|
33
|
-
};
|
|
34
12
|
const getReceiver = () => {
|
|
35
13
|
if (cachedReceiver) {
|
|
36
14
|
return cachedReceiver;
|
|
@@ -123,7 +101,7 @@ const publishBroadcastMessage = (options) => tslib.__awaiter(void 0, void 0, voi
|
|
|
123
101
|
*/
|
|
124
102
|
const publishFIFOQueueMessage = (options) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
125
103
|
const message = createEnvelope(options.body);
|
|
126
|
-
const queueName =
|
|
104
|
+
const queueName = upstashConfig.getPrefixedQstashQueueName(options.queueName);
|
|
127
105
|
return upstashConfig.withQstash((client) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
128
106
|
var _a, _b;
|
|
129
107
|
const anyClient = client;
|
|
@@ -1,34 +1,12 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import { Receiver } from '@upstash/qstash';
|
|
3
|
-
import { withQstash } from '../upstash-config.mjs';
|
|
3
|
+
import { withQstash, getPrefixedQstashQueueName } from '../upstash-config.mjs';
|
|
4
4
|
|
|
5
5
|
let cachedReceiver = null;
|
|
6
6
|
let receiverWarnedMissingEnv = false;
|
|
7
7
|
let receiverWarnedInitError = false;
|
|
8
|
-
const isNonEmpty = (value) => typeof value === 'string' && value.trim().length > 0;
|
|
9
8
|
const isTruthy = (value) => value === '1' || value === 'true' || value === 'TRUE';
|
|
10
9
|
const shouldSkipVerify = () => process.env.NODE_ENV === 'development' && isTruthy(process.env.SKIP_UPSTASH_QSTASH_VERIFY);
|
|
11
|
-
const getRequiredAppName = () => {
|
|
12
|
-
const appName = process.env.NEXT_PUBLIC_APP_NAME;
|
|
13
|
-
if (!isNonEmpty(appName)) {
|
|
14
|
-
throw new Error('[Upstash QStash] NEXT_PUBLIC_APP_NAME is required for QStash naming and must not be empty');
|
|
15
|
-
}
|
|
16
|
-
const normalized = appName.replace(/\s+/g, '').toLowerCase();
|
|
17
|
-
if (!normalized) {
|
|
18
|
-
throw new Error('[Upstash QStash] NEXT_PUBLIC_APP_NAME must contain non-whitespace characters for QStash naming');
|
|
19
|
-
}
|
|
20
|
-
return normalized;
|
|
21
|
-
};
|
|
22
|
-
const getQstashNamePrefix = () => {
|
|
23
|
-
const envSuffix = process.env.NODE_ENV === 'production' ? 'live' : 'test';
|
|
24
|
-
return `${getRequiredAppName()}_${envSuffix}`;
|
|
25
|
-
};
|
|
26
|
-
const prefixQstashName = (resourceType, name) => {
|
|
27
|
-
if (!isNonEmpty(name)) {
|
|
28
|
-
throw new Error(`[Upstash QStash] ${resourceType} name must not be empty`);
|
|
29
|
-
}
|
|
30
|
-
return `${getQstashNamePrefix()}_${resourceType}_${name}`;
|
|
31
|
-
};
|
|
32
10
|
const getReceiver = () => {
|
|
33
11
|
if (cachedReceiver) {
|
|
34
12
|
return cachedReceiver;
|
|
@@ -121,7 +99,7 @@ const publishBroadcastMessage = (options) => __awaiter(void 0, void 0, void 0, f
|
|
|
121
99
|
*/
|
|
122
100
|
const publishFIFOQueueMessage = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
123
101
|
const message = createEnvelope(options.body);
|
|
124
|
-
const queueName =
|
|
102
|
+
const queueName = getPrefixedQstashQueueName(options.queueName);
|
|
125
103
|
return withQstash((client) => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
104
|
var _a, _b;
|
|
127
105
|
const anyClient = client;
|
|
@@ -30,7 +30,7 @@ export declare const setJson: <T>(key: string, value: T, ttlSec?: number) => Pro
|
|
|
30
30
|
*/
|
|
31
31
|
export declare const getJson: <T>(key: string) => Promise<T | null>;
|
|
32
32
|
/**
|
|
33
|
-
* MGET JSON values
|
|
33
|
+
* MGET JSON values. Missing or invalid string values are returned as null.
|
|
34
34
|
*/
|
|
35
35
|
export declare const mgetJson: <T>(keys: string[]) => Promise<(T | null)[] | null>;
|
|
36
36
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-structures.d.ts","sourceRoot":"","sources":["../../../src/lib/upstash/redis-structures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAI5C,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACzD,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACrD,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC1D,MAAM,MAAM,oBAAoB,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK;IACvF,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9B,CAAC;
|
|
1
|
+
{"version":3,"file":"redis-structures.d.ts","sourceRoot":"","sources":["../../../src/lib/upstash/redis-structures.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
var tslib = require('tslib');
|
|
4
4
|
var upstashConfig = require('../upstash-config.js');
|
|
5
5
|
|
|
6
|
+
const parseJsonPayload = (payload) => {
|
|
7
|
+
if (payload == null) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
if (typeof payload === 'string') {
|
|
11
|
+
if (!payload) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(payload);
|
|
16
|
+
}
|
|
17
|
+
catch (_a) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return payload;
|
|
22
|
+
};
|
|
6
23
|
/**
|
|
7
24
|
* Set a plain string value with optional TTL (seconds).
|
|
8
25
|
*/
|
|
@@ -66,19 +83,11 @@ const setJson = (key, value, ttlSec) => tslib.__awaiter(void 0, void 0, void 0,
|
|
|
66
83
|
const getJson = (key) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
67
84
|
return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
68
85
|
const payload = yield redis.get(key);
|
|
69
|
-
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
return JSON.parse(payload);
|
|
74
|
-
}
|
|
75
|
-
catch (_a) {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
86
|
+
return parseJsonPayload(payload);
|
|
78
87
|
}));
|
|
79
88
|
});
|
|
80
89
|
/**
|
|
81
|
-
* MGET JSON values
|
|
90
|
+
* MGET JSON values. Missing or invalid string values are returned as null.
|
|
82
91
|
*/
|
|
83
92
|
const mgetJson = (keys) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
84
93
|
return upstashConfig.withRedis((redis) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -86,17 +95,7 @@ const mgetJson = (keys) => tslib.__awaiter(void 0, void 0, void 0, function* ()
|
|
|
86
95
|
return [];
|
|
87
96
|
}
|
|
88
97
|
const payloads = yield redis.mget(...keys);
|
|
89
|
-
return payloads.map((payload) =>
|
|
90
|
-
if (!payload) {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
try {
|
|
94
|
-
return JSON.parse(payload);
|
|
95
|
-
}
|
|
96
|
-
catch (_a) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
});
|
|
98
|
+
return payloads.map((payload) => parseJsonPayload(payload));
|
|
100
99
|
}));
|
|
101
100
|
});
|
|
102
101
|
/**
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import { withRedis } from '../upstash-config.mjs';
|
|
3
3
|
|
|
4
|
+
const parseJsonPayload = (payload) => {
|
|
5
|
+
if (payload == null) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
if (typeof payload === 'string') {
|
|
9
|
+
if (!payload) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(payload);
|
|
14
|
+
}
|
|
15
|
+
catch (_a) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return payload;
|
|
20
|
+
};
|
|
4
21
|
/**
|
|
5
22
|
* Set a plain string value with optional TTL (seconds).
|
|
6
23
|
*/
|
|
@@ -64,19 +81,11 @@ const setJson = (key, value, ttlSec) => __awaiter(void 0, void 0, void 0, functi
|
|
|
64
81
|
const getJson = (key) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
82
|
return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
83
|
const payload = yield redis.get(key);
|
|
67
|
-
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
try {
|
|
71
|
-
return JSON.parse(payload);
|
|
72
|
-
}
|
|
73
|
-
catch (_a) {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
84
|
+
return parseJsonPayload(payload);
|
|
76
85
|
}));
|
|
77
86
|
});
|
|
78
87
|
/**
|
|
79
|
-
* MGET JSON values
|
|
88
|
+
* MGET JSON values. Missing or invalid string values are returned as null.
|
|
80
89
|
*/
|
|
81
90
|
const mgetJson = (keys) => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
91
|
return withRedis((redis) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -84,17 +93,7 @@ const mgetJson = (keys) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
84
93
|
return [];
|
|
85
94
|
}
|
|
86
95
|
const payloads = yield redis.mget(...keys);
|
|
87
|
-
return payloads.map((payload) =>
|
|
88
|
-
if (!payload) {
|
|
89
|
-
return null;
|
|
90
|
-
}
|
|
91
|
-
try {
|
|
92
|
-
return JSON.parse(payload);
|
|
93
|
-
}
|
|
94
|
-
catch (_a) {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
});
|
|
96
|
+
return payloads.map((payload) => parseJsonPayload(payload));
|
|
98
97
|
}));
|
|
99
98
|
});
|
|
100
99
|
/**
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { Redis } from '@upstash/redis';
|
|
2
2
|
import { Client as QstashClient } from '@upstash/qstash';
|
|
3
|
+
export declare const getPrefixedRedisKey: (key: string) => string;
|
|
4
|
+
export declare const getPrefixedRedisKeys: (keys: string[]) => string[];
|
|
5
|
+
export declare const getQstashNamePrefix: () => string;
|
|
6
|
+
export declare const getPrefixedQstashQueueName: (name: string) => string;
|
|
3
7
|
/**
|
|
4
8
|
* Get the Upstash Redis client. Returns null when required env vars are missing/invalid.
|
|
5
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upstash-config.d.ts","sourceRoot":"","sources":["../../src/lib/upstash-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"upstash-config.d.ts","sourceRoot":"","sources":["../../src/lib/upstash-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA2DzD,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG,MAAyD,CAAC;AAE5G,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,KAAG,MAAM,EAAmC,CAAC;AAEhG,eAAO,MAAM,mBAAmB,QAAO,MAEtC,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,MAAM,MAAM,KAAG,MAMzD,CAAC;AAiMF;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAO,KAAK,GAAG,IAEnC,CAAC;AAwDF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,QAAO,YAAY,GAAG,IAE3C,CAAC;AA+CF,eAAO,MAAM,SAAS,GAAU,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAMzF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,CAAC,EAChC,IAAI,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAC3C,OAAO,CAAC,CAAC,GAAG,IAAI,CAMlB,CAAC"}
|
|
@@ -45,7 +45,19 @@ const getRedisKeyPrefix = () => {
|
|
|
45
45
|
const envSuffix = process.env.NODE_ENV === 'production' ? 'live' : 'test';
|
|
46
46
|
return `${getRequiredRedisAppName()}_${envSuffix}`;
|
|
47
47
|
};
|
|
48
|
-
const
|
|
48
|
+
const buildPrefixedRedisKey = (prefix, key) => `${prefix}:${key}`;
|
|
49
|
+
const getPrefixedRedisKey = (key) => buildPrefixedRedisKey(getRedisKeyPrefix(), key);
|
|
50
|
+
const getPrefixedRedisKeys = (keys) => keys.map(getPrefixedRedisKey);
|
|
51
|
+
const getQstashNamePrefix = () => {
|
|
52
|
+
return getRedisKeyPrefix();
|
|
53
|
+
};
|
|
54
|
+
const getPrefixedQstashQueueName = (name) => {
|
|
55
|
+
if (!isNonEmpty(name)) {
|
|
56
|
+
throw new Error('[Upstash QStash] queue name must not be empty');
|
|
57
|
+
}
|
|
58
|
+
return `${getQstashNamePrefix()}_queue_${name}`;
|
|
59
|
+
};
|
|
60
|
+
const prefixRedisKey = (prefix, key) => buildPrefixedRedisKey(prefix, key);
|
|
49
61
|
const prefixRedisKeys = (prefix, keys) => keys.map((key) => prefixRedisKey(prefix, key));
|
|
50
62
|
const prefixFirstStringArg = (args, prefix) => {
|
|
51
63
|
if (typeof args[0] !== 'string') {
|
|
@@ -55,8 +67,16 @@ const prefixFirstStringArg = (args, prefix) => {
|
|
|
55
67
|
nextArgs[0] = prefixRedisKey(prefix, args[0]);
|
|
56
68
|
return nextArgs;
|
|
57
69
|
};
|
|
58
|
-
const
|
|
59
|
-
return args.
|
|
70
|
+
const prefixVariadicKeyArgs = (args, prefix) => {
|
|
71
|
+
return args.flatMap((arg) => {
|
|
72
|
+
if (typeof arg === 'string') {
|
|
73
|
+
return [prefixRedisKey(prefix, arg)];
|
|
74
|
+
}
|
|
75
|
+
if (Array.isArray(arg) && arg.every((key) => typeof key === 'string')) {
|
|
76
|
+
return prefixRedisKeys(prefix, arg);
|
|
77
|
+
}
|
|
78
|
+
return [arg];
|
|
79
|
+
});
|
|
60
80
|
};
|
|
61
81
|
const keyArrayCommands = new Set(['mget', 'del']);
|
|
62
82
|
const allStringKeyCommands = new Set(['exists']);
|
|
@@ -77,11 +97,11 @@ const createPrefixedPipeline = (target, prefix) => {
|
|
|
77
97
|
return createPrefixedPipeline(nested, prefix);
|
|
78
98
|
}
|
|
79
99
|
if (typeof prop === 'string' && keyArrayCommands.has(prop)) {
|
|
80
|
-
const nextArgs =
|
|
100
|
+
const nextArgs = prefixVariadicKeyArgs(args, prefix);
|
|
81
101
|
return value.apply(obj, nextArgs);
|
|
82
102
|
}
|
|
83
103
|
if (typeof prop === 'string' && allStringKeyCommands.has(prop)) {
|
|
84
|
-
const nextArgs =
|
|
104
|
+
const nextArgs = prefixVariadicKeyArgs(args, prefix);
|
|
85
105
|
return value.apply(obj, nextArgs);
|
|
86
106
|
}
|
|
87
107
|
if (prop === 'mset') {
|
|
@@ -325,7 +345,11 @@ const withQstash = (fn) => tslib.__awaiter(void 0, void 0, void 0, function* ()
|
|
|
325
345
|
return fn(qstash);
|
|
326
346
|
});
|
|
327
347
|
|
|
348
|
+
exports.getPrefixedQstashQueueName = getPrefixedQstashQueueName;
|
|
349
|
+
exports.getPrefixedRedisKey = getPrefixedRedisKey;
|
|
350
|
+
exports.getPrefixedRedisKeys = getPrefixedRedisKeys;
|
|
328
351
|
exports.getQstash = getQstash;
|
|
352
|
+
exports.getQstashNamePrefix = getQstashNamePrefix;
|
|
329
353
|
exports.getRedis = getRedis;
|
|
330
354
|
exports.withQstash = withQstash;
|
|
331
355
|
exports.withRedis = withRedis;
|
|
@@ -43,7 +43,19 @@ const getRedisKeyPrefix = () => {
|
|
|
43
43
|
const envSuffix = process.env.NODE_ENV === 'production' ? 'live' : 'test';
|
|
44
44
|
return `${getRequiredRedisAppName()}_${envSuffix}`;
|
|
45
45
|
};
|
|
46
|
-
const
|
|
46
|
+
const buildPrefixedRedisKey = (prefix, key) => `${prefix}:${key}`;
|
|
47
|
+
const getPrefixedRedisKey = (key) => buildPrefixedRedisKey(getRedisKeyPrefix(), key);
|
|
48
|
+
const getPrefixedRedisKeys = (keys) => keys.map(getPrefixedRedisKey);
|
|
49
|
+
const getQstashNamePrefix = () => {
|
|
50
|
+
return getRedisKeyPrefix();
|
|
51
|
+
};
|
|
52
|
+
const getPrefixedQstashQueueName = (name) => {
|
|
53
|
+
if (!isNonEmpty(name)) {
|
|
54
|
+
throw new Error('[Upstash QStash] queue name must not be empty');
|
|
55
|
+
}
|
|
56
|
+
return `${getQstashNamePrefix()}_queue_${name}`;
|
|
57
|
+
};
|
|
58
|
+
const prefixRedisKey = (prefix, key) => buildPrefixedRedisKey(prefix, key);
|
|
47
59
|
const prefixRedisKeys = (prefix, keys) => keys.map((key) => prefixRedisKey(prefix, key));
|
|
48
60
|
const prefixFirstStringArg = (args, prefix) => {
|
|
49
61
|
if (typeof args[0] !== 'string') {
|
|
@@ -53,8 +65,16 @@ const prefixFirstStringArg = (args, prefix) => {
|
|
|
53
65
|
nextArgs[0] = prefixRedisKey(prefix, args[0]);
|
|
54
66
|
return nextArgs;
|
|
55
67
|
};
|
|
56
|
-
const
|
|
57
|
-
return args.
|
|
68
|
+
const prefixVariadicKeyArgs = (args, prefix) => {
|
|
69
|
+
return args.flatMap((arg) => {
|
|
70
|
+
if (typeof arg === 'string') {
|
|
71
|
+
return [prefixRedisKey(prefix, arg)];
|
|
72
|
+
}
|
|
73
|
+
if (Array.isArray(arg) && arg.every((key) => typeof key === 'string')) {
|
|
74
|
+
return prefixRedisKeys(prefix, arg);
|
|
75
|
+
}
|
|
76
|
+
return [arg];
|
|
77
|
+
});
|
|
58
78
|
};
|
|
59
79
|
const keyArrayCommands = new Set(['mget', 'del']);
|
|
60
80
|
const allStringKeyCommands = new Set(['exists']);
|
|
@@ -75,11 +95,11 @@ const createPrefixedPipeline = (target, prefix) => {
|
|
|
75
95
|
return createPrefixedPipeline(nested, prefix);
|
|
76
96
|
}
|
|
77
97
|
if (typeof prop === 'string' && keyArrayCommands.has(prop)) {
|
|
78
|
-
const nextArgs =
|
|
98
|
+
const nextArgs = prefixVariadicKeyArgs(args, prefix);
|
|
79
99
|
return value.apply(obj, nextArgs);
|
|
80
100
|
}
|
|
81
101
|
if (typeof prop === 'string' && allStringKeyCommands.has(prop)) {
|
|
82
|
-
const nextArgs =
|
|
102
|
+
const nextArgs = prefixVariadicKeyArgs(args, prefix);
|
|
83
103
|
return value.apply(obj, nextArgs);
|
|
84
104
|
}
|
|
85
105
|
if (prop === 'mset') {
|
|
@@ -323,4 +343,4 @@ const withQstash = (fn) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
323
343
|
return fn(qstash);
|
|
324
344
|
});
|
|
325
345
|
|
|
326
|
-
export { getQstash, getRedis, withQstash, withRedis };
|
|
346
|
+
export { getPrefixedQstashQueueName, getPrefixedRedisKey, getPrefixedRedisKeys, getQstash, getQstashNamePrefix, getRedis, withQstash, withRedis };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windrun-huaiin/backend-core",
|
|
3
|
-
"version": "20.0
|
|
3
|
+
"version": "20.2.0",
|
|
4
4
|
"description": "Shared backend primitives: Prisma schema/client, database services, routing helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -108,13 +108,13 @@
|
|
|
108
108
|
"@upstash/lock": "^0.2.1",
|
|
109
109
|
"next": "16.1.6",
|
|
110
110
|
"prisma": "^6.19.0",
|
|
111
|
-
"stripe": "
|
|
111
|
+
"stripe": "22.0.2",
|
|
112
112
|
"svix": "^1.86.0",
|
|
113
113
|
"tslib": "^2.8.1",
|
|
114
114
|
"zod": "^4.3.6",
|
|
115
115
|
"@windrun-huaiin/contracts": "^20.0.0",
|
|
116
|
-
"@windrun-huaiin/
|
|
117
|
-
"@windrun-huaiin/
|
|
116
|
+
"@windrun-huaiin/lib": "^20.0.0",
|
|
117
|
+
"@windrun-huaiin/third-ui": "^20.1.0"
|
|
118
118
|
},
|
|
119
119
|
"devDependencies": {
|
|
120
120
|
"@rollup/plugin-alias": "^5.1.1",
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
"@prisma/client": "^6.19.0",
|
|
131
131
|
"next": "16.1.6",
|
|
132
132
|
"prisma": "^6.19.0",
|
|
133
|
-
"stripe": "
|
|
133
|
+
"stripe": "22.0.2",
|
|
134
134
|
"svix": "^1.86.0",
|
|
135
135
|
"@windrun-huaiin/contracts": "^20.0.0"
|
|
136
136
|
},
|
package/src/lib/stripe-config.ts
CHANGED
|
@@ -3,6 +3,9 @@ import { Apilogger, userService, subscriptionService } from '../services/databas
|
|
|
3
3
|
|
|
4
4
|
let stripeInstance: Stripe | null = null;
|
|
5
5
|
|
|
6
|
+
type CheckoutSessionCreateParams = Parameters<Stripe['checkout']['sessions']['create']>[0];
|
|
7
|
+
type CheckoutSubscriptionData = NonNullable<CheckoutSessionCreateParams>['subscription_data'];
|
|
8
|
+
|
|
6
9
|
export const getStripe = (): Stripe => {
|
|
7
10
|
const apiKey = process.env.STRIPE_SECRET_KEY;
|
|
8
11
|
if (!apiKey) {
|
|
@@ -11,7 +14,7 @@ export const getStripe = (): Stripe => {
|
|
|
11
14
|
|
|
12
15
|
if (!stripeInstance) {
|
|
13
16
|
stripeInstance = new Stripe(apiKey, {
|
|
14
|
-
apiVersion: '
|
|
17
|
+
apiVersion: '2026-03-25.dahlia',
|
|
15
18
|
});
|
|
16
19
|
}
|
|
17
20
|
|
|
@@ -43,7 +46,7 @@ export interface BasicCheckoutSessionParams {
|
|
|
43
46
|
// Helper function to create checkout session
|
|
44
47
|
export const createCheckoutSession = async (
|
|
45
48
|
params: BasicCheckoutSessionParams,
|
|
46
|
-
subscriptionData?:
|
|
49
|
+
subscriptionData?: CheckoutSubscriptionData
|
|
47
50
|
): Promise<Stripe.Checkout.Session> => {
|
|
48
51
|
const {
|
|
49
52
|
priceId,
|
|
@@ -69,7 +72,7 @@ export const createCheckoutSession = async (
|
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
74
|
|
|
72
|
-
const sessionParams:
|
|
75
|
+
const sessionParams: CheckoutSessionCreateParams = {
|
|
73
76
|
mode, // ✅ Dynamic mode
|
|
74
77
|
payment_method_types: ['card'],
|
|
75
78
|
line_items: [
|
|
@@ -1,50 +1,16 @@
|
|
|
1
1
|
import { Receiver } from '@upstash/qstash';
|
|
2
|
-
import { withQstash } from '../upstash-config';
|
|
2
|
+
import { getPrefixedQstashQueueName, withQstash } from '../upstash-config';
|
|
3
3
|
|
|
4
4
|
let cachedReceiver: Receiver | null = null;
|
|
5
5
|
let receiverWarnedMissingEnv = false;
|
|
6
6
|
let receiverWarnedInitError = false;
|
|
7
7
|
|
|
8
|
-
const isNonEmpty = (value: string | undefined): value is string =>
|
|
9
|
-
typeof value === 'string' && value.trim().length > 0;
|
|
10
|
-
|
|
11
8
|
const isTruthy = (value: string | undefined): boolean =>
|
|
12
9
|
value === '1' || value === 'true' || value === 'TRUE';
|
|
13
10
|
|
|
14
11
|
const shouldSkipVerify = (): boolean =>
|
|
15
12
|
process.env.NODE_ENV === 'development' && isTruthy(process.env.SKIP_UPSTASH_QSTASH_VERIFY);
|
|
16
13
|
|
|
17
|
-
const getRequiredAppName = (): string => {
|
|
18
|
-
const appName = process.env.NEXT_PUBLIC_APP_NAME;
|
|
19
|
-
if (!isNonEmpty(appName)) {
|
|
20
|
-
throw new Error(
|
|
21
|
-
'[Upstash QStash] NEXT_PUBLIC_APP_NAME is required for QStash naming and must not be empty'
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const normalized = appName.replace(/\s+/g, '').toLowerCase();
|
|
26
|
-
if (!normalized) {
|
|
27
|
-
throw new Error(
|
|
28
|
-
'[Upstash QStash] NEXT_PUBLIC_APP_NAME must contain non-whitespace characters for QStash naming'
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return normalized;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const getQstashNamePrefix = (): string => {
|
|
36
|
-
const envSuffix = process.env.NODE_ENV === 'production' ? 'live' : 'test';
|
|
37
|
-
return `${getRequiredAppName()}_${envSuffix}`;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const prefixQstashName = (resourceType: 'queue', name: string): string => {
|
|
41
|
-
if (!isNonEmpty(name)) {
|
|
42
|
-
throw new Error(`[Upstash QStash] ${resourceType} name must not be empty`);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return `${getQstashNamePrefix()}_${resourceType}_${name}`;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
14
|
const getReceiver = (): Receiver | null => {
|
|
49
15
|
if (cachedReceiver) {
|
|
50
16
|
return cachedReceiver;
|
|
@@ -178,7 +144,7 @@ export const publishFIFOQueueMessage = async <TBody extends PublishBody>(
|
|
|
178
144
|
options: PublishFIFOQueueMessageOptions<TBody>
|
|
179
145
|
): Promise<{ messageId: string | null; message: QstashEnvelope<TBody> } | null> => {
|
|
180
146
|
const message = createEnvelope(options.body);
|
|
181
|
-
const queueName =
|
|
147
|
+
const queueName = getPrefixedQstashQueueName(options.queueName);
|
|
182
148
|
|
|
183
149
|
return withQstash(async (client) => {
|
|
184
150
|
const anyClient = client as any;
|
|
@@ -9,6 +9,26 @@ export type RedisPipelineBuilder<TResult> = (pipeline: ReturnType<Redis['pipelin
|
|
|
9
9
|
exec: () => Promise<TResult>;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
const parseJsonPayload = <T>(payload: unknown): T | null => {
|
|
13
|
+
if (payload == null) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (typeof payload === 'string') {
|
|
18
|
+
if (!payload) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(payload) as T;
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return payload as T;
|
|
30
|
+
};
|
|
31
|
+
|
|
12
32
|
/**
|
|
13
33
|
* Set a plain string value with optional TTL (seconds).
|
|
14
34
|
*/
|
|
@@ -88,21 +108,13 @@ export const setJson = async <T>(
|
|
|
88
108
|
*/
|
|
89
109
|
export const getJson = async <T>(key: string): Promise<T | null> => {
|
|
90
110
|
return withRedis(async (redis) => {
|
|
91
|
-
const payload = await redis.get<
|
|
92
|
-
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
return JSON.parse(payload) as T;
|
|
98
|
-
} catch {
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
111
|
+
const payload = await redis.get<unknown>(key);
|
|
112
|
+
return parseJsonPayload<T>(payload);
|
|
101
113
|
});
|
|
102
114
|
};
|
|
103
115
|
|
|
104
116
|
/**
|
|
105
|
-
* MGET JSON values
|
|
117
|
+
* MGET JSON values. Missing or invalid string values are returned as null.
|
|
106
118
|
*/
|
|
107
119
|
export const mgetJson = async <T>(keys: string[]): Promise<(T | null)[] | null> => {
|
|
108
120
|
return withRedis(async (redis) => {
|
|
@@ -110,18 +122,8 @@ export const mgetJson = async <T>(keys: string[]): Promise<(T | null)[] | null>
|
|
|
110
122
|
return [];
|
|
111
123
|
}
|
|
112
124
|
|
|
113
|
-
const payloads = await redis.mget<
|
|
114
|
-
return payloads.map((payload) =>
|
|
115
|
-
if (!payload) {
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
return JSON.parse(payload) as T;
|
|
121
|
-
} catch {
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
+
const payloads = await redis.mget<unknown[]>(...keys);
|
|
126
|
+
return payloads.map((payload) => parseJsonPayload<T>(payload));
|
|
125
127
|
});
|
|
126
128
|
};
|
|
127
129
|
|
|
@@ -56,7 +56,25 @@ const getRedisKeyPrefix = (): string => {
|
|
|
56
56
|
return `${getRequiredRedisAppName()}_${envSuffix}`;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
const
|
|
59
|
+
const buildPrefixedRedisKey = (prefix: string, key: string): string => `${prefix}:${key}`;
|
|
60
|
+
|
|
61
|
+
export const getPrefixedRedisKey = (key: string): string => buildPrefixedRedisKey(getRedisKeyPrefix(), key);
|
|
62
|
+
|
|
63
|
+
export const getPrefixedRedisKeys = (keys: string[]): string[] => keys.map(getPrefixedRedisKey);
|
|
64
|
+
|
|
65
|
+
export const getQstashNamePrefix = (): string => {
|
|
66
|
+
return getRedisKeyPrefix();
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const getPrefixedQstashQueueName = (name: string): string => {
|
|
70
|
+
if (!isNonEmpty(name)) {
|
|
71
|
+
throw new Error('[Upstash QStash] queue name must not be empty');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return `${getQstashNamePrefix()}_queue_${name}`;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const prefixRedisKey = (prefix: string, key: string): string => buildPrefixedRedisKey(prefix, key);
|
|
60
78
|
|
|
61
79
|
const prefixRedisKeys = (prefix: string, keys: string[]): string[] =>
|
|
62
80
|
keys.map((key) => prefixRedisKey(prefix, key));
|
|
@@ -71,8 +89,18 @@ const prefixFirstStringArg = (args: unknown[], prefix: string): unknown[] => {
|
|
|
71
89
|
return nextArgs;
|
|
72
90
|
};
|
|
73
91
|
|
|
74
|
-
const
|
|
75
|
-
return args.
|
|
92
|
+
const prefixVariadicKeyArgs = (args: unknown[], prefix: string): unknown[] => {
|
|
93
|
+
return args.flatMap((arg) => {
|
|
94
|
+
if (typeof arg === 'string') {
|
|
95
|
+
return [prefixRedisKey(prefix, arg)];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (Array.isArray(arg) && arg.every((key) => typeof key === 'string')) {
|
|
99
|
+
return prefixRedisKeys(prefix, arg);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return [arg];
|
|
103
|
+
});
|
|
76
104
|
};
|
|
77
105
|
|
|
78
106
|
const keyArrayCommands = new Set(['mget', 'del']);
|
|
@@ -103,12 +131,12 @@ const createPrefixedPipeline = <T extends object>(target: T, prefix: string): T
|
|
|
103
131
|
}
|
|
104
132
|
|
|
105
133
|
if (typeof prop === 'string' && keyArrayCommands.has(prop)) {
|
|
106
|
-
const nextArgs =
|
|
134
|
+
const nextArgs = prefixVariadicKeyArgs(args, prefix);
|
|
107
135
|
return (value as (...innerArgs: unknown[]) => unknown).apply(obj, nextArgs);
|
|
108
136
|
}
|
|
109
137
|
|
|
110
138
|
if (typeof prop === 'string' && allStringKeyCommands.has(prop)) {
|
|
111
|
-
const nextArgs =
|
|
139
|
+
const nextArgs = prefixVariadicKeyArgs(args, prefix);
|
|
112
140
|
return (value as (...innerArgs: unknown[]) => unknown).apply(obj, nextArgs);
|
|
113
141
|
}
|
|
114
142
|
|
|
@@ -18,7 +18,7 @@ import Stripe from 'stripe';
|
|
|
18
18
|
import { viewLocalTime } from '@windrun-huaiin/lib/utils';
|
|
19
19
|
|
|
20
20
|
const mapPaymentStatus = (
|
|
21
|
-
status?: Stripe.Checkout.Session
|
|
21
|
+
status?: Stripe.Checkout.Session['payment_status'] | null
|
|
22
22
|
): PaymentStatus => {
|
|
23
23
|
switch (status) {
|
|
24
24
|
case 'paid':
|