@stamprally/server 0.17.0 → 0.18.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/README.md +1 -1
- package/dist/index.cjs +45 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +45 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -78,6 +78,7 @@ async function executeRedisTransaction(redis, queue) {
|
|
|
78
78
|
// src/persistence.ts
|
|
79
79
|
var InMemoryServerPersistenceAdapter = class {
|
|
80
80
|
supportsRewardStock = true;
|
|
81
|
+
supportsSecondaryStock = true;
|
|
81
82
|
#locks = /* @__PURE__ */ new Map();
|
|
82
83
|
#idempotent = /* @__PURE__ */ new Map();
|
|
83
84
|
#states = /* @__PURE__ */ new Map();
|
|
@@ -642,26 +643,41 @@ function initialState(config, userId, timestamp) {
|
|
|
642
643
|
updatedAt: timestamp
|
|
643
644
|
};
|
|
644
645
|
}
|
|
645
|
-
function rewardStock(config,
|
|
646
|
-
const
|
|
646
|
+
function rewardStock(config, reward) {
|
|
647
|
+
const stockLimit = reward.stockLimit;
|
|
648
|
+
const key = reward.stockKey ?? reward.id;
|
|
649
|
+
const configured = key === "__shared__" ? config.inventory?.sharedStock : config.inventory?.[key];
|
|
647
650
|
if (stockLimit === void 0) return configured ?? null;
|
|
648
651
|
if (configured === void 0) return stockLimit;
|
|
649
652
|
return Math.min(stockLimit, configured);
|
|
650
653
|
}
|
|
651
654
|
function sharedStock(config) {
|
|
652
|
-
return config.inventory?.sharedStock ??
|
|
655
|
+
return config.inventory?.sharedStock ?? null;
|
|
653
656
|
}
|
|
654
657
|
function inventoryPlan(config, rewardId, stockLimit) {
|
|
655
|
-
const
|
|
658
|
+
const reward = config.rewards.find((item) => item.id === rewardId);
|
|
659
|
+
const individual = reward === void 0 ? stockLimit ?? null : rewardStock(config, reward);
|
|
656
660
|
const shared = sharedStock(config);
|
|
661
|
+
const explicitPrimaryKey = reward?.stockKey;
|
|
662
|
+
const explicitSecondaryKey = reward?.secondaryStockKey;
|
|
657
663
|
if (config.inventoryMode === "shared" && shared !== null) {
|
|
658
664
|
return {
|
|
659
|
-
primaryKey: "__shared__",
|
|
660
|
-
primaryInitial: shared,
|
|
661
|
-
...
|
|
665
|
+
primaryKey: explicitPrimaryKey ?? "__shared__",
|
|
666
|
+
primaryInitial: explicitPrimaryKey === void 0 ? shared : individual,
|
|
667
|
+
...explicitSecondaryKey !== void 0 ? {
|
|
668
|
+
secondaryKey: explicitSecondaryKey,
|
|
669
|
+
secondaryInitial: config.inventory?.[explicitSecondaryKey] ?? individual
|
|
670
|
+
} : individual === null ? {} : { secondaryKey: rewardId, secondaryInitial: individual }
|
|
662
671
|
};
|
|
663
672
|
}
|
|
664
|
-
return {
|
|
673
|
+
return {
|
|
674
|
+
primaryKey: explicitPrimaryKey ?? rewardId,
|
|
675
|
+
primaryInitial: individual,
|
|
676
|
+
...explicitSecondaryKey === void 0 ? {} : {
|
|
677
|
+
secondaryKey: explicitSecondaryKey,
|
|
678
|
+
secondaryInitial: config.inventory?.[explicitSecondaryKey] ?? null
|
|
679
|
+
}
|
|
680
|
+
};
|
|
665
681
|
}
|
|
666
682
|
function getProof(context) {
|
|
667
683
|
return context.type === "qr" ? context.token : context.type === "passcode" ? context.code : context.type === "gps" ? { latitude: context.latitude, longitude: context.longitude } : context.type === "nfc" ? context.tagId : context.value;
|
|
@@ -823,14 +839,20 @@ var StampRallyServer = class {
|
|
|
823
839
|
401
|
|
824
840
|
);
|
|
825
841
|
const sessionId = request.headers.get("x-anonymous-session-id");
|
|
842
|
+
const authContext = {
|
|
843
|
+
authenticatedUserId: userId,
|
|
844
|
+
...sessionId === null ? {} : { isAnonymous: true, sessionId }
|
|
845
|
+
};
|
|
826
846
|
try {
|
|
827
847
|
return json({
|
|
828
848
|
ok: true,
|
|
829
|
-
state: await this.syncProgress(
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
849
|
+
state: await this.syncProgress(
|
|
850
|
+
{
|
|
851
|
+
rallyId: body.data.rallyId,
|
|
852
|
+
...sessionId === null ? {} : { anonymousSessionId: sessionId }
|
|
853
|
+
},
|
|
854
|
+
authContext
|
|
855
|
+
)
|
|
834
856
|
});
|
|
835
857
|
} catch (error) {
|
|
836
858
|
if (error instanceof RequestValidationException) return validationResponse(error.errors);
|
|
@@ -990,6 +1012,8 @@ var StampRallyServer = class {
|
|
|
990
1012
|
now(this.#options)
|
|
991
1013
|
);
|
|
992
1014
|
const plan = inventoryPlan(this.#config, reward.id, reward.stockLimit);
|
|
1015
|
+
if (plan.secondaryKey !== void 0 && this.#persistence.supportsSecondaryStock !== true)
|
|
1016
|
+
throw new Error("SECONDARY_STOCK_UNSUPPORTED");
|
|
993
1017
|
const inventoryEnabled = plan.primaryInitial !== null || plan.secondaryInitial !== void 0 && plan.secondaryInitial !== null;
|
|
994
1018
|
if (inventoryEnabled && (this.#persistence.supportsRewardStock === false || typeof this.#persistence.getRewardStock !== "function" || typeof this.#persistence.executeClaimRewardTransaction !== "function"))
|
|
995
1019
|
return this.#rememberClaim(
|
|
@@ -1024,7 +1048,7 @@ var StampRallyServer = class {
|
|
|
1024
1048
|
rewardId: reward.id,
|
|
1025
1049
|
stockKey: plan.primaryKey,
|
|
1026
1050
|
...plan.secondaryKey === void 0 ? {} : { secondaryStockKey: plan.secondaryKey },
|
|
1027
|
-
rewardStockLimit: rewardStock(this.#config, reward
|
|
1051
|
+
rewardStockLimit: rewardStock(this.#config, reward),
|
|
1028
1052
|
sharedStockLimit: this.#config.inventoryMode === "shared" ? sharedStock(this.#config) : null,
|
|
1029
1053
|
initialStock: plan.primaryInitial,
|
|
1030
1054
|
...plan.secondaryInitial === void 0 ? {} : { initialSecondaryStock: plan.secondaryInitial },
|
|
@@ -1156,21 +1180,24 @@ var StampRallyServer = class {
|
|
|
1156
1180
|
await this.#persistence.releaseLock(request.rallyId, lockKey);
|
|
1157
1181
|
}
|
|
1158
1182
|
}
|
|
1159
|
-
async sync(rallyId,
|
|
1183
|
+
async sync(rallyId, identity) {
|
|
1184
|
+
const userId = typeof identity === "string" ? identity : identity.authenticatedUserId;
|
|
1160
1185
|
assertValidSyncParams({ rallyId, userId }, this.#config);
|
|
1161
1186
|
const state2 = await this.#persistence.getUserState(rallyId, userId) ?? initialState(this.#config, userId, now(this.#options));
|
|
1162
1187
|
return this.#attachInventory(state2);
|
|
1163
1188
|
}
|
|
1164
|
-
async syncProgress(request) {
|
|
1165
|
-
const directRequest = withDirectIdentity(request);
|
|
1189
|
+
async syncProgress(request, authContext) {
|
|
1190
|
+
const directRequest = withDirectIdentity(request, authContext);
|
|
1166
1191
|
assertValidSyncParams(directRequest, this.#config);
|
|
1167
|
-
return this.sync(directRequest.rallyId,
|
|
1192
|
+
return this.sync(directRequest.rallyId, authContext);
|
|
1168
1193
|
}
|
|
1169
1194
|
async #attachInventory(state2) {
|
|
1170
1195
|
const rewardRemaining = {};
|
|
1171
1196
|
for (const reward of this.#config.rewards) {
|
|
1172
1197
|
const plan = inventoryPlan(this.#config, reward.id, reward.stockLimit);
|
|
1173
1198
|
if (plan.secondaryKey !== void 0) {
|
|
1199
|
+
if (this.#persistence.supportsSecondaryStock !== true)
|
|
1200
|
+
throw new Error("SECONDARY_STOCK_UNSUPPORTED");
|
|
1174
1201
|
const stock = await this.#persistence.getRewardStock(state2.rallyId, plan.secondaryKey);
|
|
1175
1202
|
const remaining = stock ?? plan.secondaryInitial ?? null;
|
|
1176
1203
|
if (remaining !== null) rewardRemaining[reward.id] = Math.max(0, remaining);
|