@stamprally/server 0.18.0 → 0.19.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.d.cts CHANGED
@@ -248,6 +248,7 @@ declare function validateSyncRequest(value: unknown): RequestValidationResult<{
248
248
  readonly rallyId: string;
249
249
  readonly userId?: string;
250
250
  readonly anonymousSessionId?: string;
251
+ readonly operations?: SyncProgressRequest["operations"];
251
252
  }>;
252
253
 
253
254
  type ErrorResponse = {
@@ -275,11 +276,7 @@ declare class StampRallyServer {
275
276
  checkIn(request: CheckInRequest, authContext?: TrustedAuthContext): Promise<CheckInResponse>;
276
277
  claimReward(request: ClaimRewardRequest, authContext?: TrustedAuthContext): Promise<ClaimResponse>;
277
278
  sync(rallyId: string, identity: string | TrustedAuthContext): Promise<UserRallyState>;
278
- syncProgress(request: {
279
- readonly rallyId: string;
280
- readonly userId?: string;
281
- readonly anonymousSessionId?: string;
282
- }, authContext: TrustedAuthContext): Promise<UserRallyState>;
279
+ syncProgress(request: SyncProgressRequest, authContext: TrustedAuthContext): Promise<UserRallyState>;
283
280
  }
284
281
 
285
282
  /**
@@ -319,6 +316,19 @@ interface ClaimRewardRequest {
319
316
  readonly staffId?: string;
320
317
  readonly now?: string | number;
321
318
  }
319
+ type SyncProgressOperation = {
320
+ readonly kind: "checkIn";
321
+ readonly request: CheckInRequest;
322
+ } | {
323
+ readonly kind: "claimReward";
324
+ readonly request: ClaimRewardRequest;
325
+ };
326
+ interface SyncProgressRequest {
327
+ readonly rallyId: string;
328
+ readonly userId?: string;
329
+ readonly anonymousSessionId?: string;
330
+ readonly operations?: ReadonlyArray<SyncProgressOperation>;
331
+ }
322
332
  type CheckInResponse = {
323
333
  readonly ok: true;
324
334
  readonly state: UserRallyState;
@@ -338,4 +348,4 @@ interface ServerOptions {
338
348
  readonly anonymousPolicy?: "session_scoped" | "reject" | "shared_global_opt_in_insecure";
339
349
  }
340
350
 
341
- export { type AuditLog, type AuthenticationContext, type CheckInRequest, type CheckInResponse, type CheckInTransactionMutation, type CheckInTransactionParams, type ClaimRewardMutationContext, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type RedisMultiExecutor, type RequestValidationError, RequestValidationException, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlCheckInStore, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type TrustedAuthContext, type UserClaimRecord, assertValidCheckInParams, assertValidClaimParams, assertValidSyncParams, executeCheckInTransaction, executeClaimRewardTransaction, executeRedisTransaction, runPersistenceAdapterComplianceTests, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };
351
+ export { type AuditLog, type AuthenticationContext, type CheckInRequest, type CheckInResponse, type CheckInTransactionMutation, type CheckInTransactionParams, type ClaimRewardMutationContext, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type RedisMultiExecutor, type RequestValidationError, RequestValidationException, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlCheckInStore, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type SyncProgressOperation, type SyncProgressRequest, type TrustedAuthContext, type UserClaimRecord, assertValidCheckInParams, assertValidClaimParams, assertValidSyncParams, executeCheckInTransaction, executeClaimRewardTransaction, executeRedisTransaction, runPersistenceAdapterComplianceTests, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };
package/dist/index.d.ts CHANGED
@@ -248,6 +248,7 @@ declare function validateSyncRequest(value: unknown): RequestValidationResult<{
248
248
  readonly rallyId: string;
249
249
  readonly userId?: string;
250
250
  readonly anonymousSessionId?: string;
251
+ readonly operations?: SyncProgressRequest["operations"];
251
252
  }>;
252
253
 
253
254
  type ErrorResponse = {
@@ -275,11 +276,7 @@ declare class StampRallyServer {
275
276
  checkIn(request: CheckInRequest, authContext?: TrustedAuthContext): Promise<CheckInResponse>;
276
277
  claimReward(request: ClaimRewardRequest, authContext?: TrustedAuthContext): Promise<ClaimResponse>;
277
278
  sync(rallyId: string, identity: string | TrustedAuthContext): Promise<UserRallyState>;
278
- syncProgress(request: {
279
- readonly rallyId: string;
280
- readonly userId?: string;
281
- readonly anonymousSessionId?: string;
282
- }, authContext: TrustedAuthContext): Promise<UserRallyState>;
279
+ syncProgress(request: SyncProgressRequest, authContext: TrustedAuthContext): Promise<UserRallyState>;
283
280
  }
284
281
 
285
282
  /**
@@ -319,6 +316,19 @@ interface ClaimRewardRequest {
319
316
  readonly staffId?: string;
320
317
  readonly now?: string | number;
321
318
  }
319
+ type SyncProgressOperation = {
320
+ readonly kind: "checkIn";
321
+ readonly request: CheckInRequest;
322
+ } | {
323
+ readonly kind: "claimReward";
324
+ readonly request: ClaimRewardRequest;
325
+ };
326
+ interface SyncProgressRequest {
327
+ readonly rallyId: string;
328
+ readonly userId?: string;
329
+ readonly anonymousSessionId?: string;
330
+ readonly operations?: ReadonlyArray<SyncProgressOperation>;
331
+ }
322
332
  type CheckInResponse = {
323
333
  readonly ok: true;
324
334
  readonly state: UserRallyState;
@@ -338,4 +348,4 @@ interface ServerOptions {
338
348
  readonly anonymousPolicy?: "session_scoped" | "reject" | "shared_global_opt_in_insecure";
339
349
  }
340
350
 
341
- export { type AuditLog, type AuthenticationContext, type CheckInRequest, type CheckInResponse, type CheckInTransactionMutation, type CheckInTransactionParams, type ClaimRewardMutationContext, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type RedisMultiExecutor, type RequestValidationError, RequestValidationException, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlCheckInStore, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type TrustedAuthContext, type UserClaimRecord, assertValidCheckInParams, assertValidClaimParams, assertValidSyncParams, executeCheckInTransaction, executeClaimRewardTransaction, executeRedisTransaction, runPersistenceAdapterComplianceTests, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };
351
+ export { type AuditLog, type AuthenticationContext, type CheckInRequest, type CheckInResponse, type CheckInTransactionMutation, type CheckInTransactionParams, type ClaimRewardMutationContext, type ClaimRewardRequest, type ClaimRewardTransactionMutation, type ClaimRewardTransactionParams, InMemoryServerPersistenceAdapter, type InMemoryServerPersistenceOptions, type RedisMultiExecutor, type RequestValidationError, RequestValidationException, type RequestValidationResult, type ServerOptions, type ServerPersistenceAdapter, type SqlCheckInStore, type SqlClaimRewardStore, type SqlTransactionDatabase, StampRallyServer, type SyncOperationStatus, type SyncProgressOperation, type SyncProgressRequest, type TrustedAuthContext, type UserClaimRecord, assertValidCheckInParams, assertValidClaimParams, assertValidSyncParams, executeCheckInTransaction, executeClaimRewardTransaction, executeRedisTransaction, runPersistenceAdapterComplianceTests, validateCheckInRequest, validateClaimRewardRequest, validateSyncRequest };
package/dist/index.js CHANGED
@@ -2,9 +2,13 @@ import { reconcileRewardStates, consumeReward, evaluateConditionDetailed } from
2
2
 
3
3
  // src/examples/transaction.ts
4
4
  async function executeClaimRewardTransaction(database, store, params2, mutation2) {
5
+ if (params2.secondaryStockKey !== void 0 && store.writeSecondaryStock === void 0)
6
+ return { success: false, error: "SECONDARY_STOCK_UNSUPPORTED" };
5
7
  try {
6
8
  return await database.transaction(async (transaction) => {
7
9
  const current = await store.readContext(transaction, params2);
10
+ if (params2.secondaryStockKey !== void 0 && current.secondaryStock === void 0)
11
+ return { success: false, error: "SECONDARY_STOCK_UNSUPPORTED" };
8
12
  const secondaryStock = current.secondaryStock ?? null;
9
13
  const rewardStock2 = params2.stockKey === "__shared__" ? secondaryStock : current.stock;
10
14
  const next = mutation2({
@@ -596,6 +600,40 @@ function validateSyncRequest(value) {
596
600
  return errors({ path: "$", message: "Expected an object.", code: "INVALID_TYPE" });
597
601
  if (value.userId !== void 0 && !nonEmpty(value.userId))
598
602
  return errors({ path: "userId", message: "userId must be non-empty.", code: "INVALID_TYPE" });
603
+ if (value.operations !== void 0) {
604
+ if (!Array.isArray(value.operations))
605
+ return errors({
606
+ path: "operations",
607
+ message: "operations must be an array.",
608
+ code: "INVALID_TYPE"
609
+ });
610
+ const operationErrors = [];
611
+ value.operations.forEach((operation, index) => {
612
+ const path = `operations[${index}]`;
613
+ if (!record(operation)) {
614
+ operationErrors.push({
615
+ path,
616
+ message: "Expected an operation object.",
617
+ code: "INVALID_TYPE"
618
+ });
619
+ return;
620
+ }
621
+ if (operation.kind !== "checkIn" && operation.kind !== "claimReward") {
622
+ operationErrors.push({
623
+ path: `${path}.kind`,
624
+ message: "Unknown sync operation.",
625
+ code: "INVALID_ENUM"
626
+ });
627
+ return;
628
+ }
629
+ const result = operation.kind === "checkIn" ? validateCheckInRequest(operation.request) : validateClaimRewardRequest(operation.request);
630
+ if (!result.success)
631
+ operationErrors.push(
632
+ ...result.errors.map((error) => ({ ...error, path: `${path}.request.${error.path}` }))
633
+ );
634
+ });
635
+ if (operationErrors.length > 0) return errors(...operationErrors);
636
+ }
599
637
  return {
600
638
  success: true,
601
639
  data: value
@@ -847,6 +885,7 @@ var StampRallyServer = class {
847
885
  state: await this.syncProgress(
848
886
  {
849
887
  rallyId: body.data.rallyId,
888
+ ...body.data.operations === void 0 ? {} : { operations: body.data.operations },
850
889
  ...sessionId === null ? {} : { anonymousSessionId: sessionId }
851
890
  },
852
891
  authContext
@@ -1187,6 +1226,10 @@ var StampRallyServer = class {
1187
1226
  async syncProgress(request, authContext) {
1188
1227
  const directRequest = withDirectIdentity(request, authContext);
1189
1228
  assertValidSyncParams(directRequest, this.#config);
1229
+ for (const operation of request.operations ?? []) {
1230
+ if (operation.kind === "checkIn") await this.checkIn(operation.request, authContext);
1231
+ else await this.claimReward(operation.request, authContext);
1232
+ }
1190
1233
  return this.sync(directRequest.rallyId, authContext);
1191
1234
  }
1192
1235
  async #attachInventory(state2) {