@stamprally/core 0.5.1 → 0.7.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.cjs +233 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +329 -19
- package/dist/index.d.ts +329 -19
- package/dist/index.js +228 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -110,9 +110,119 @@ type Result<T, E> = {
|
|
|
110
110
|
readonly error: E;
|
|
111
111
|
};
|
|
112
112
|
|
|
113
|
+
/** A human-readable value that may be supplied in one or more locales. */
|
|
114
|
+
type UniversalLocalizedText<TLocale extends string = string> = string | Partial<Record<TLocale, string>>;
|
|
115
|
+
/** A link to an entity owned by the host application or another system. */
|
|
116
|
+
interface ExternalReference$1 {
|
|
117
|
+
readonly type: string;
|
|
118
|
+
readonly id: string;
|
|
119
|
+
readonly url?: string;
|
|
120
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
121
|
+
}
|
|
122
|
+
/** Server-only verification material. Never send this shape to a browser. */
|
|
123
|
+
type VerificationCondition = {
|
|
124
|
+
readonly type: "qr";
|
|
125
|
+
readonly secretToken: string;
|
|
126
|
+
readonly qrEntryUrl?: string;
|
|
127
|
+
} | {
|
|
128
|
+
readonly type: "passcode";
|
|
129
|
+
readonly code: string;
|
|
130
|
+
readonly caseSensitive?: boolean;
|
|
131
|
+
} | {
|
|
132
|
+
readonly type: "gps";
|
|
133
|
+
readonly latitude: number;
|
|
134
|
+
readonly longitude: number;
|
|
135
|
+
readonly radiusMeters: number;
|
|
136
|
+
} | {
|
|
137
|
+
readonly type: "custom";
|
|
138
|
+
readonly validatorName: string;
|
|
139
|
+
readonly secretParams?: Readonly<Record<string, unknown>>;
|
|
140
|
+
};
|
|
141
|
+
/** Safe condition metadata intended for a participant client. */
|
|
142
|
+
type PublicCheckInCondition = {
|
|
143
|
+
readonly type: "qr";
|
|
144
|
+
readonly qrEntryUrl: string;
|
|
145
|
+
} | {
|
|
146
|
+
readonly type: "passcode";
|
|
147
|
+
} | {
|
|
148
|
+
readonly type: "gps";
|
|
149
|
+
readonly latitude: number;
|
|
150
|
+
readonly longitude: number;
|
|
151
|
+
readonly radiusMeters: number;
|
|
152
|
+
} | {
|
|
153
|
+
readonly type: "custom";
|
|
154
|
+
readonly validatorName: string;
|
|
155
|
+
};
|
|
156
|
+
interface UniversalSpotItem<TLocale extends string = string, TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
157
|
+
readonly id: string;
|
|
158
|
+
readonly orderIndex: number;
|
|
159
|
+
readonly name: UniversalLocalizedText<TLocale>;
|
|
160
|
+
readonly description?: UniversalLocalizedText<TLocale>;
|
|
161
|
+
readonly hint?: UniversalLocalizedText<TLocale>;
|
|
162
|
+
readonly imageUrl?: string;
|
|
163
|
+
readonly iconUrl?: string;
|
|
164
|
+
readonly redirectUrlAfterClaim?: string;
|
|
165
|
+
readonly externalReferences?: ReadonlyArray<ExternalReference$1>;
|
|
166
|
+
readonly metadata?: TMeta;
|
|
167
|
+
readonly conditions: ReadonlyArray<VerificationCondition>;
|
|
168
|
+
readonly prerequisites?: ReadonlyArray<string>;
|
|
169
|
+
}
|
|
170
|
+
type AdminReward<TLocale extends string = string> = {
|
|
171
|
+
readonly id: string;
|
|
172
|
+
readonly title: UniversalLocalizedText<TLocale>;
|
|
173
|
+
readonly description?: UniversalLocalizedText<TLocale>;
|
|
174
|
+
readonly type: "digital" | "in_person";
|
|
175
|
+
readonly redemptionMethod: "manual_slide" | "staff_passcode" | "view_only" | "server_claim";
|
|
176
|
+
readonly requiredStampCount: number;
|
|
177
|
+
readonly conditions?: ReadonlyArray<RewardUnlockCondition$1>;
|
|
178
|
+
readonly stockLimit?: number;
|
|
179
|
+
readonly userClaimLimit?: number;
|
|
180
|
+
readonly staffPasscode?: string;
|
|
181
|
+
readonly digitalContentUrl?: string;
|
|
182
|
+
};
|
|
183
|
+
type PublicReward<TLocale extends string = string> = Omit<AdminReward<TLocale>, "staffPasscode" | "digitalContentUrl">;
|
|
184
|
+
type RewardUnlockCondition$1 = {
|
|
185
|
+
readonly type: "stamp_count";
|
|
186
|
+
readonly count: number;
|
|
187
|
+
} | {
|
|
188
|
+
readonly type: "stamps";
|
|
189
|
+
readonly stampIds: ReadonlyArray<string>;
|
|
190
|
+
} | {
|
|
191
|
+
readonly type: "all" | "any";
|
|
192
|
+
readonly conditions: ReadonlyArray<RewardUnlockCondition$1>;
|
|
193
|
+
};
|
|
194
|
+
interface AdminRallyConfig<TLocale extends string = string, TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
195
|
+
readonly id: string;
|
|
196
|
+
readonly version: string;
|
|
197
|
+
readonly title: UniversalLocalizedText<TLocale>;
|
|
198
|
+
readonly description?: UniversalLocalizedText<TLocale>;
|
|
199
|
+
readonly theme?: SheetTheme;
|
|
200
|
+
readonly spots: ReadonlyArray<UniversalSpotItem<TLocale, TMeta>>;
|
|
201
|
+
readonly rewards: ReadonlyArray<AdminReward<TLocale>>;
|
|
202
|
+
readonly serverEndpoint?: string;
|
|
203
|
+
readonly metadata?: TMeta;
|
|
204
|
+
}
|
|
205
|
+
interface PublicRallyConfig<TLocale extends string = string, TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
206
|
+
readonly id: string;
|
|
207
|
+
readonly version: string;
|
|
208
|
+
readonly title: UniversalLocalizedText<TLocale>;
|
|
209
|
+
readonly description?: UniversalLocalizedText<TLocale>;
|
|
210
|
+
readonly theme?: SheetTheme;
|
|
211
|
+
readonly spots: ReadonlyArray<Omit<UniversalSpotItem<TLocale, TMeta>, "conditions"> & {
|
|
212
|
+
readonly conditions: ReadonlyArray<PublicCheckInCondition>;
|
|
213
|
+
}>;
|
|
214
|
+
readonly rewards: ReadonlyArray<PublicReward<TLocale>>;
|
|
215
|
+
readonly serverEndpoint?: string;
|
|
216
|
+
readonly metadata?: TMeta;
|
|
217
|
+
}
|
|
218
|
+
/** Produce the browser-safe projection without mutating the admin config. */
|
|
219
|
+
declare function toPublicRallyConfig<TLocale extends string, TMeta extends Record<string, unknown>>(config: AdminRallyConfig<TLocale, TMeta>): PublicRallyConfig<TLocale, TMeta>;
|
|
220
|
+
/** Runtime guard for values crossing the public configuration boundary. */
|
|
221
|
+
declare function isPublicRallyConfig(value: unknown): value is PublicRallyConfig;
|
|
222
|
+
|
|
113
223
|
type SupportedLocale = "ja" | "en";
|
|
114
224
|
type LocalizedString<TLocale extends string = SupportedLocale> = Record<TLocale, string>;
|
|
115
|
-
type LocalizedText<TLocale extends string = string> = string | Partial<Record<TLocale, string>>;
|
|
225
|
+
type LocalizedText$1<TLocale extends string = string> = string | Partial<Record<TLocale, string>>;
|
|
116
226
|
type LocaleDictionary<TLocale extends string = string> = Readonly<Record<TLocale, Readonly<Record<string, string>>>>;
|
|
117
227
|
type SlotShape = "circle" | "square" | "rounded";
|
|
118
228
|
type FontFamily = "system-ui" | "serif" | "rounded-sans" | "monospace" | "handwritten";
|
|
@@ -138,9 +248,9 @@ interface ThemePreset<TLocale extends string = SupportedLocale> {
|
|
|
138
248
|
declare const DEFAULT_SHEET_THEME: SheetTheme;
|
|
139
249
|
interface SpotItem<TLocale extends string = SupportedLocale, TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
140
250
|
readonly id: string;
|
|
141
|
-
readonly name: LocalizedText<TLocale>;
|
|
142
|
-
readonly description?: LocalizedText<TLocale>;
|
|
143
|
-
readonly hint?: LocalizedText<TLocale>;
|
|
251
|
+
readonly name: LocalizedText$1<TLocale>;
|
|
252
|
+
readonly description?: LocalizedText$1<TLocale>;
|
|
253
|
+
readonly hint?: LocalizedText$1<TLocale>;
|
|
144
254
|
readonly condition: StampCondition;
|
|
145
255
|
readonly orderIndex?: number;
|
|
146
256
|
readonly order?: number;
|
|
@@ -152,12 +262,16 @@ interface SpotItem<TLocale extends string = SupportedLocale, TMeta extends Recor
|
|
|
152
262
|
readonly externalUrl?: string;
|
|
153
263
|
readonly redirectUrlAfterClaim?: string;
|
|
154
264
|
readonly metadata?: TMeta;
|
|
265
|
+
/** Canonical universal-model conditions. Legacy `condition` remains for engine internals. */
|
|
266
|
+
readonly conditions?: ReadonlyArray<VerificationCondition>;
|
|
267
|
+
readonly externalReferences?: ReadonlyArray<ExternalReference$1>;
|
|
268
|
+
readonly prerequisites?: ReadonlyArray<string>;
|
|
155
269
|
readonly dependsOn?: ReadonlyArray<string>;
|
|
156
270
|
readonly requiresStampIds?: ReadonlyArray<string>;
|
|
157
271
|
}
|
|
158
272
|
/** @deprecated Use SpotItem instead. */
|
|
159
273
|
type StampDefinition<TLocale extends string = SupportedLocale, TMeta extends Record<string, unknown> = Record<string, unknown>> = SpotItem<TLocale, TMeta>;
|
|
160
|
-
interface StampRecord {
|
|
274
|
+
interface StampRecord$1 {
|
|
161
275
|
readonly stampId: string;
|
|
162
276
|
readonly acquiredAt: string;
|
|
163
277
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
@@ -180,8 +294,8 @@ type RewardUnlockCondition = {
|
|
|
180
294
|
type RewardStatus = "LOCKED" | "AVAILABLE" | "CONSUMED" | "EXPIRED";
|
|
181
295
|
interface RewardItem<TLocale extends string = SupportedLocale> {
|
|
182
296
|
readonly id: string;
|
|
183
|
-
readonly title: LocalizedText<TLocale>;
|
|
184
|
-
readonly description: LocalizedText<TLocale>;
|
|
297
|
+
readonly title: LocalizedText$1<TLocale>;
|
|
298
|
+
readonly description: LocalizedText$1<TLocale>;
|
|
185
299
|
readonly type: RewardType;
|
|
186
300
|
readonly redemptionMethod: RedemptionMethod;
|
|
187
301
|
readonly requiredStampCount: number;
|
|
@@ -207,14 +321,14 @@ interface RewardState {
|
|
|
207
321
|
}
|
|
208
322
|
interface StampRallyState {
|
|
209
323
|
readonly rallyId: string;
|
|
210
|
-
readonly records: ReadonlyArray<StampRecord>;
|
|
324
|
+
readonly records: ReadonlyArray<StampRecord$1>;
|
|
211
325
|
readonly rewards?: ReadonlyArray<RewardState>;
|
|
212
326
|
readonly updatedAt: string;
|
|
213
327
|
}
|
|
214
328
|
interface RallyConfig<TLocale extends string = SupportedLocale, TMeta extends Record<string, unknown> = Record<string, unknown>> {
|
|
215
329
|
readonly id: string;
|
|
216
|
-
readonly title?: LocalizedText<TLocale>;
|
|
217
|
-
readonly description?: LocalizedText<TLocale>;
|
|
330
|
+
readonly title?: LocalizedText$1<TLocale>;
|
|
331
|
+
readonly description?: LocalizedText$1<TLocale>;
|
|
218
332
|
readonly stamps: ReadonlyArray<StampDefinition<TLocale, TMeta>>;
|
|
219
333
|
readonly rewards?: ReadonlyArray<RewardItem<TLocale>>;
|
|
220
334
|
readonly isSequential?: boolean;
|
|
@@ -224,20 +338,35 @@ interface RallyConfig<TLocale extends string = SupportedLocale, TMeta extends Re
|
|
|
224
338
|
readonly endDate?: string;
|
|
225
339
|
}
|
|
226
340
|
|
|
227
|
-
declare function resolveLocalizedText<TLocale extends string = SupportedLocale>(text: LocalizedText<TLocale> | undefined, locale: string, fallbackLocale?: string): string;
|
|
228
|
-
declare function toLocalizedString(text: LocalizedText | undefined): LocalizedString;
|
|
229
|
-
declare function toLocalizedString<TLocale extends string>(text: LocalizedText<TLocale> | undefined): LocalizedString<TLocale>;
|
|
341
|
+
declare function resolveLocalizedText<TLocale extends string = SupportedLocale>(text: LocalizedText$1<TLocale> | undefined, locale: string, fallbackLocale?: string): string;
|
|
342
|
+
declare function toLocalizedString(text: LocalizedText$1 | undefined): LocalizedString;
|
|
343
|
+
declare function toLocalizedString<TLocale extends string>(text: LocalizedText$1<TLocale> | undefined): LocalizedString<TLocale>;
|
|
230
344
|
|
|
231
345
|
declare function migrateRallyConfig<TLocale extends string = SupportedLocale>(raw: unknown): RallyConfig<TLocale>;
|
|
232
346
|
|
|
233
347
|
type PublicRewardItem<TLocale extends string = string> = Omit<RewardItem<TLocale>, "staffPasscode">;
|
|
234
|
-
type
|
|
348
|
+
type LegacyPublicRallyConfig<TLocale extends string = string, TMeta extends Record<string, unknown> = Record<string, unknown>> = Omit<RallyConfig<TLocale, TMeta>, "rewards"> & {
|
|
235
349
|
readonly rewards?: ReadonlyArray<PublicRewardItem<TLocale>>;
|
|
236
350
|
};
|
|
237
|
-
declare function stripSensitiveConfig<TLocale extends string, TMeta extends Record<string, unknown>>(config:
|
|
351
|
+
declare function stripSensitiveConfig<TLocale extends string, TMeta extends Record<string, unknown>>(config: AdminRallyConfig<TLocale, TMeta>): PublicRallyConfig<TLocale, TMeta>;
|
|
352
|
+
declare function stripSensitiveConfig<TLocale extends string, TMeta extends Record<string, unknown>>(config: RallyConfig<TLocale, TMeta>): LegacyPublicRallyConfig<TLocale, TMeta>;
|
|
238
353
|
|
|
239
354
|
declare const THEME_PRESETS: ReadonlyArray<ThemePreset>;
|
|
240
355
|
|
|
356
|
+
interface UniversalValidationError {
|
|
357
|
+
readonly path: string;
|
|
358
|
+
readonly code: "INVALID_TYPE" | "REQUIRED" | "EMPTY_STRING" | "DUPLICATE_ID" | "INVALID_COORDINATES" | "INVALID_RADIUS" | "INVALID_VERSION" | "INVALID_REWARD" | "CYCLE_DETECTED" | "SECRET_IN_PUBLIC_CONFIG";
|
|
359
|
+
readonly message: string;
|
|
360
|
+
}
|
|
361
|
+
interface UniversalValidationResult {
|
|
362
|
+
readonly valid: boolean;
|
|
363
|
+
readonly errors: ReadonlyArray<UniversalValidationError>;
|
|
364
|
+
}
|
|
365
|
+
declare function validateAdminRallyConfig(value: unknown): UniversalValidationResult;
|
|
366
|
+
declare function validatePublicRallyConfig(value: unknown): UniversalValidationResult;
|
|
367
|
+
declare function isAdminRallyConfig(value: unknown): value is AdminRallyConfig;
|
|
368
|
+
declare function isPublicRallyConfigShape(value: unknown): value is PublicRallyConfig;
|
|
369
|
+
|
|
241
370
|
declare const CURRENT_RALLY_CONFIG_VERSION = 2;
|
|
242
371
|
interface ValidationError {
|
|
243
372
|
readonly path: string;
|
|
@@ -303,7 +432,7 @@ declare function issueClaimTicketNumber(reward: RewardItem, currentState: Reward
|
|
|
303
432
|
|
|
304
433
|
type StampRallyEvent = {
|
|
305
434
|
readonly type: "stampAcquired";
|
|
306
|
-
readonly record: StampRecord;
|
|
435
|
+
readonly record: StampRecord$1;
|
|
307
436
|
} | {
|
|
308
437
|
readonly type: "rallyCompleted";
|
|
309
438
|
readonly rallyId: string;
|
|
@@ -382,7 +511,7 @@ declare function isStampRallyState(value: unknown): value is StampRallyState;
|
|
|
382
511
|
interface RallySnapshot {
|
|
383
512
|
readonly version: 1;
|
|
384
513
|
readonly rallyId: string;
|
|
385
|
-
readonly stamps: ReadonlyArray<StampRecord>;
|
|
514
|
+
readonly stamps: ReadonlyArray<StampRecord$1>;
|
|
386
515
|
readonly rewards: ReadonlyArray<RewardState>;
|
|
387
516
|
readonly exportedAt: string;
|
|
388
517
|
}
|
|
@@ -449,7 +578,7 @@ declare class StampRallyClient {
|
|
|
449
578
|
readonly events: true;
|
|
450
579
|
}): () => void;
|
|
451
580
|
subscribeEvents(listener: StampRallyEventListener): () => void;
|
|
452
|
-
updateConfig(newConfig:
|
|
581
|
+
updateConfig(newConfig: LegacyPublicRallyConfig): Promise<StampRallyState>;
|
|
453
582
|
notifyRewardClaimed(rewardId: string, state?: StampRallyState | null): void;
|
|
454
583
|
notifySyncCompleted(state?: StampRallyState | null): void;
|
|
455
584
|
init(): Promise<StampRallyState>;
|
|
@@ -537,6 +666,187 @@ interface QrDetectorOptions {
|
|
|
537
666
|
declare function isQrSupported(): boolean;
|
|
538
667
|
declare function readQrContext(videoElement: HTMLVideoElement, options?: QrDetectorOptions): Promise<DetectorResult<TokenVerificationContext>>;
|
|
539
668
|
|
|
669
|
+
/**
|
|
670
|
+
* Branded identifiers keep values from different parts of the domain from
|
|
671
|
+
* being exchanged accidentally while remaining plain strings at runtime.
|
|
672
|
+
*/
|
|
673
|
+
type RallyId = string & {
|
|
674
|
+
readonly __brand: "RallyId";
|
|
675
|
+
};
|
|
676
|
+
type SpotId = string & {
|
|
677
|
+
readonly __brand: "SpotId";
|
|
678
|
+
};
|
|
679
|
+
type UserId = string & {
|
|
680
|
+
readonly __brand: "UserId";
|
|
681
|
+
};
|
|
682
|
+
type Metadata = Readonly<Record<string, unknown>>;
|
|
683
|
+
/** A locale-independent fallback plus zero or more locale-specific values. */
|
|
684
|
+
interface LocalizedText<TLocale extends string = string> {
|
|
685
|
+
readonly default: string;
|
|
686
|
+
readonly translations: Readonly<Partial<Record<TLocale, string>>>;
|
|
687
|
+
}
|
|
688
|
+
/** A reference to an entity owned by an external system. */
|
|
689
|
+
interface ExternalReference {
|
|
690
|
+
readonly systemId: string;
|
|
691
|
+
readonly entityType: string;
|
|
692
|
+
readonly entityId: string;
|
|
693
|
+
readonly attributes?: Metadata;
|
|
694
|
+
}
|
|
695
|
+
/** Public, non-secret configuration for one check-in location. */
|
|
696
|
+
interface SpotDefinition<TLocale extends string = string> {
|
|
697
|
+
readonly id: SpotId;
|
|
698
|
+
readonly name: LocalizedText<TLocale>;
|
|
699
|
+
readonly description?: LocalizedText<TLocale>;
|
|
700
|
+
readonly hint?: LocalizedText<TLocale>;
|
|
701
|
+
readonly order?: number;
|
|
702
|
+
readonly iconUrl?: string;
|
|
703
|
+
readonly imageUrl?: string;
|
|
704
|
+
readonly externalReference?: ExternalReference;
|
|
705
|
+
readonly metadata?: Metadata;
|
|
706
|
+
readonly verification: VerificationRequirement;
|
|
707
|
+
readonly dependsOn?: ReadonlyArray<SpotId>;
|
|
708
|
+
}
|
|
709
|
+
/** Public description of a verifier selected at runtime through DI. */
|
|
710
|
+
interface VerificationRequirement {
|
|
711
|
+
readonly pluginId: string;
|
|
712
|
+
/** Public parameters only; secrets belong to SpotVerificationSecret. */
|
|
713
|
+
readonly parameters?: Metadata;
|
|
714
|
+
}
|
|
715
|
+
/** Public configuration safe to distribute to a browser client. */
|
|
716
|
+
interface RallyDefinition<TLocale extends string = string> {
|
|
717
|
+
readonly id: RallyId;
|
|
718
|
+
readonly title: LocalizedText<TLocale>;
|
|
719
|
+
readonly description?: LocalizedText<TLocale>;
|
|
720
|
+
readonly spots: ReadonlyArray<SpotDefinition<TLocale>>;
|
|
721
|
+
readonly startsAt?: string;
|
|
722
|
+
readonly endsAt?: string;
|
|
723
|
+
readonly externalReference?: ExternalReference;
|
|
724
|
+
readonly metadata?: Metadata;
|
|
725
|
+
}
|
|
726
|
+
interface VerificationCoordinates {
|
|
727
|
+
readonly latitude: number;
|
|
728
|
+
readonly longitude: number;
|
|
729
|
+
readonly radiusMeters: number;
|
|
730
|
+
}
|
|
731
|
+
/** Server-only material used by a verifier. Never include this in a public definition. */
|
|
732
|
+
interface SpotVerificationSecret {
|
|
733
|
+
readonly spotId: SpotId;
|
|
734
|
+
readonly pluginId: string;
|
|
735
|
+
readonly secret?: string | Readonly<Uint8Array>;
|
|
736
|
+
readonly expectedValue?: string;
|
|
737
|
+
readonly coordinates?: VerificationCoordinates;
|
|
738
|
+
readonly metadata?: Metadata;
|
|
739
|
+
}
|
|
740
|
+
/** Server-only configuration composed from a public definition and secrets. */
|
|
741
|
+
interface ServerRallyConfig<TLocale extends string = string> {
|
|
742
|
+
readonly definition: RallyDefinition<TLocale>;
|
|
743
|
+
readonly verificationSecrets: ReadonlyArray<SpotVerificationSecret>;
|
|
744
|
+
readonly schemaVersion: SchemaVersion;
|
|
745
|
+
readonly metadata?: Metadata;
|
|
746
|
+
}
|
|
747
|
+
type SchemaVersion = number;
|
|
748
|
+
interface StampRecord {
|
|
749
|
+
readonly stampId: SpotId;
|
|
750
|
+
readonly acquiredAt: string;
|
|
751
|
+
readonly verificationPluginId?: string;
|
|
752
|
+
readonly metadata?: Metadata;
|
|
753
|
+
}
|
|
754
|
+
interface RallyProgress {
|
|
755
|
+
readonly rallyId: RallyId;
|
|
756
|
+
readonly userId: UserId;
|
|
757
|
+
readonly stamps: ReadonlyArray<StampRecord>;
|
|
758
|
+
/** Monotonically increasing revision used for optimistic locking. */
|
|
759
|
+
readonly stateSequence: number;
|
|
760
|
+
readonly schemaVersion: SchemaVersion;
|
|
761
|
+
readonly updatedAt: string;
|
|
762
|
+
readonly completedAt?: string;
|
|
763
|
+
readonly metadata?: Metadata;
|
|
764
|
+
}
|
|
765
|
+
interface StorageSaveRequest {
|
|
766
|
+
readonly progress: RallyProgress;
|
|
767
|
+
readonly expectedStateSequence: number;
|
|
768
|
+
readonly idempotencyKey: string;
|
|
769
|
+
}
|
|
770
|
+
type StorageSaveOutcome = {
|
|
771
|
+
readonly status: "saved";
|
|
772
|
+
readonly progress: RallyProgress;
|
|
773
|
+
readonly idempotent: boolean;
|
|
774
|
+
} | {
|
|
775
|
+
readonly status: "conflict";
|
|
776
|
+
readonly current: RallyProgress | null;
|
|
777
|
+
};
|
|
778
|
+
/** Persistence boundary. Implementations own transactions and concurrency control. */
|
|
779
|
+
interface StorageAdapter {
|
|
780
|
+
load(rallyId: RallyId, userId: UserId): Promise<RallyProgress | null>;
|
|
781
|
+
save(request: StorageSaveRequest): Promise<StorageSaveOutcome>;
|
|
782
|
+
}
|
|
783
|
+
interface AuthContextAdapter<TRequest = unknown> {
|
|
784
|
+
getUserId(request: TRequest): Promise<UserId | null> | UserId | null;
|
|
785
|
+
}
|
|
786
|
+
interface ValidationInput<TProof = unknown> {
|
|
787
|
+
readonly rallyId: RallyId;
|
|
788
|
+
readonly spotId: SpotId;
|
|
789
|
+
readonly userId: UserId;
|
|
790
|
+
readonly proof: TProof;
|
|
791
|
+
readonly requestedAt: string;
|
|
792
|
+
readonly publicParameters?: Metadata;
|
|
793
|
+
}
|
|
794
|
+
type ValidationOutcome = {
|
|
795
|
+
readonly valid: true;
|
|
796
|
+
readonly reason?: string;
|
|
797
|
+
readonly metadata?: Metadata;
|
|
798
|
+
} | {
|
|
799
|
+
readonly valid: false;
|
|
800
|
+
readonly code: string;
|
|
801
|
+
readonly reason?: string;
|
|
802
|
+
readonly metadata?: Metadata;
|
|
803
|
+
};
|
|
804
|
+
/** Pluggable verifier for GPS, TOTP/HMAC, signatures, or application rules. */
|
|
805
|
+
interface ConditionVerifierPlugin<TProof = unknown> {
|
|
806
|
+
readonly id: string;
|
|
807
|
+
verify(input: ValidationInput<TProof>, secret: SpotVerificationSecret): Promise<ValidationOutcome> | ValidationOutcome;
|
|
808
|
+
}
|
|
809
|
+
interface CheckInAttemptAuditEntry {
|
|
810
|
+
readonly rallyId: RallyId;
|
|
811
|
+
readonly spotId: SpotId;
|
|
812
|
+
readonly userId: UserId;
|
|
813
|
+
readonly attemptedAt: string;
|
|
814
|
+
readonly outcome: ValidationOutcome;
|
|
815
|
+
readonly idempotencyKey?: string;
|
|
816
|
+
/** Use a digest or other redacted representation; never require raw proof data. */
|
|
817
|
+
readonly proofDigest?: string;
|
|
818
|
+
readonly metadata?: Metadata;
|
|
819
|
+
}
|
|
820
|
+
interface AuditLoggerAdapter {
|
|
821
|
+
logCheckInAttempt(entry: CheckInAttemptAuditEntry): Promise<void>;
|
|
822
|
+
}
|
|
823
|
+
interface StampAcquiredEvent {
|
|
824
|
+
readonly type: "stampAcquired";
|
|
825
|
+
readonly rallyId: RallyId;
|
|
826
|
+
readonly spotId: SpotId;
|
|
827
|
+
readonly userId: UserId;
|
|
828
|
+
readonly record: StampRecord;
|
|
829
|
+
}
|
|
830
|
+
interface RallyCompletedEvent {
|
|
831
|
+
readonly type: "rallyCompleted";
|
|
832
|
+
readonly rallyId: RallyId;
|
|
833
|
+
readonly userId: UserId;
|
|
834
|
+
readonly completedAt: string;
|
|
835
|
+
}
|
|
836
|
+
type RallyEvent = StampAcquiredEvent | RallyCompletedEvent;
|
|
837
|
+
interface EventPublisherAdapter {
|
|
838
|
+
publish(event: RallyEvent): Promise<void>;
|
|
839
|
+
}
|
|
840
|
+
interface SystemClockAdapter {
|
|
841
|
+
now(): string;
|
|
842
|
+
}
|
|
843
|
+
interface IdGeneratorAdapter {
|
|
844
|
+
generate(): string;
|
|
845
|
+
}
|
|
846
|
+
interface StateMigrator {
|
|
847
|
+
migrate(state: unknown, fromVersion: SchemaVersion, toVersion: SchemaVersion): RallyProgress;
|
|
848
|
+
}
|
|
849
|
+
|
|
540
850
|
type SnapshotSecretKey = string | Uint8Array;
|
|
541
851
|
interface SnapshotTokenPayload {
|
|
542
852
|
readonly [key: string]: unknown;
|
|
@@ -560,4 +870,4 @@ type SnapshotTokenVerification<T extends SnapshotTokenPayload = SnapshotTokenPay
|
|
|
560
870
|
declare function createSignedSnapshotToken<T extends SnapshotTokenPayload>(payload: T, secretKey: SnapshotSecretKey): Promise<string>;
|
|
561
871
|
declare function verifySnapshotToken<T extends SnapshotTokenPayload = SnapshotTokenPayload>(token: string, secretKey: SnapshotSecretKey, now?: number): Promise<SnapshotTokenVerification<T>>;
|
|
562
872
|
|
|
563
|
-
export { CURRENT_RALLY_CONFIG_VERSION, type CheckInContext, type CheckInErrorCode, type CheckInInput, type CheckInResult$1 as CheckInResult, type ClaimTicketOptions, type Clock, type CompositeConditionFailure, type ConditionMatch, type ConditionMismatch, type ConsumeResult, type ConsumeRewardParams, DEFAULT_SHEET_THEME, type DetectorError, type DetectorErrorCode, type DetectorKind, type DetectorResult, type FontFamily, type GeoDetectorOptions, type GeoVerificationContext, InMemoryStorage, IndexedDBAdapter, type IndexedDBAdapterOptions, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocaleDictionary, type LocalizedString, type LocalizedText, type NfcDetectorOptions, type PasscodeCondition, type ProcessStampValue, type PublicRallyConfig, type PublicRewardItem, type QrDetectorOptions, type RallyConfig, type RallyConfigValidationResult, type RallySnapshot, type RedemptionMethod, type Result, type RewardConsumeError, type RewardItem, type RewardState, type RewardStatus, type RewardType, type RewardUnlockCondition, type SecureTokenError, type SecureTokenErrorCode, type SecureTokenOptions, type SecureTokenPayload, type SecureTokenSecretKey, type SecureTokenVerification, type SheetTheme, type SlotShape, type SnapshotSecretKey, type SnapshotTokenError, type SnapshotTokenErrorCode, type SnapshotTokenPayload, type SnapshotTokenVerification, type SpotItem, type StampCondition, type StampDefinition, type StampError, StampRallyClient, type StampRallyClientEvent, type StampRallyEvent, type StampRallyEventListener, type StampRallyListener, type StampRallyProgress, type StampRallyState, type StampRecord, type StampStorage, StorageAdapterError, type StorageAdapterErrorCode, type StorageLike, type StorageOperation, type StorageWarningHandler, type SupportedLocale, THEME_PRESETS, type ThemePreset, type ThemePresetId, type TokenVerificationContext, type ValidationError, type VerificationContext, calculateDistanceMeters, calculateProgress, consumeReward, createClaimTicketNumber, createSecureToken, createSignedSnapshotToken, createUniqueClaimTicketNumber, evaluateCheckIn, evaluateCondition, evaluateConditionDetailed, exportProgressToken, getCurrentGeoContext, importProgressToken, isGeolocationSupported, isNfcSupported, isQrSupported, isRewardState, isStampRallyState, issueClaimTicketNumber, migrateRallyConfig, normalizePasscode, processStamp, readNfcContext, readQrContext, reconcileRewardStates, resolveLocalizedText, stripSensitiveConfig, toLocalizedString, validateRallyConfig, verifyPasscode, verifySecureToken, verifySnapshotToken };
|
|
873
|
+
export { type AdminRallyConfig, type AdminReward, type AuditLoggerAdapter, type AuthContextAdapter, CURRENT_RALLY_CONFIG_VERSION, type CheckInAttemptAuditEntry, type CheckInContext, type CheckInErrorCode, type CheckInInput, type CheckInResult$1 as CheckInResult, type ClaimTicketOptions, type Clock, type CompositeConditionFailure, type ConditionMatch, type ConditionMismatch, type ConditionVerifierPlugin, type ConsumeResult, type ConsumeRewardParams, DEFAULT_SHEET_THEME, type DetectorError, type DetectorErrorCode, type DetectorKind, type DetectorResult, type EventPublisherAdapter, type ExternalReference$1 as ExternalReference, type FontFamily, type GeoDetectorOptions, type GeoVerificationContext, type LocalizedText as HeadlessLocalizedText, type IdGeneratorAdapter, InMemoryStorage, IndexedDBAdapter, type IndexedDBAdapterOptions, type LegacyPublicRallyConfig, LocalStorageAdapter, type LocalStorageAdapterOptions, type LocalStorageFailureMode, type LocaleDictionary, type LocalizedString, type LocalizedText$1 as LocalizedText, type Metadata, type NfcDetectorOptions, type PasscodeCondition, type ProcessStampValue, type PublicCheckInCondition, type PublicRallyConfig, type PublicReward, type PublicRewardItem, type QrDetectorOptions, type RallyCompletedEvent, type RallyConfig, type RallyConfigValidationResult, type RallyDefinition, type RallyEvent, type RallyId, type RallyProgress, type RallySnapshot, type RedemptionMethod, type Result, type RewardConsumeError, type RewardItem, type RewardState, type RewardStatus, type RewardType, type RewardUnlockCondition, type SchemaVersion, type SecureTokenError, type SecureTokenErrorCode, type SecureTokenOptions, type SecureTokenPayload, type SecureTokenSecretKey, type SecureTokenVerification, type ServerRallyConfig, type SheetTheme, type SlotShape, type SnapshotSecretKey, type SnapshotTokenError, type SnapshotTokenErrorCode, type SnapshotTokenPayload, type SnapshotTokenVerification, type SpotDefinition, type SpotId, type SpotItem, type SpotVerificationSecret, type StampAcquiredEvent, type StampCondition, type StampDefinition, type StampError, StampRallyClient, type StampRallyClientEvent, type StampRallyEvent, type StampRallyEventListener, type StampRallyListener, type StampRallyProgress, type StampRallyState, type StampRecord$1 as StampRecord, type StampStorage, type StateMigrator, type StorageAdapter, StorageAdapterError, type StorageAdapterErrorCode, type StorageLike, type StorageOperation, type StorageSaveOutcome, type StorageSaveRequest, type StorageWarningHandler, type SupportedLocale, type SystemClockAdapter, THEME_PRESETS, type ThemePreset, type ThemePresetId, type TokenVerificationContext, type UniversalLocalizedText, type UniversalSpotItem, type UniversalValidationError, type UniversalValidationResult, type UserId, type ValidationError, type ValidationInput, type ValidationOutcome, type VerificationCondition, type VerificationContext, type VerificationCoordinates, type VerificationRequirement, calculateDistanceMeters, calculateProgress, consumeReward, createClaimTicketNumber, createSecureToken, createSignedSnapshotToken, createUniqueClaimTicketNumber, evaluateCheckIn, evaluateCondition, evaluateConditionDetailed, exportProgressToken, getCurrentGeoContext, importProgressToken, isAdminRallyConfig, isGeolocationSupported, isNfcSupported, isPublicRallyConfig, isPublicRallyConfigShape, isQrSupported, isRewardState, isStampRallyState, issueClaimTicketNumber, migrateRallyConfig, normalizePasscode, processStamp, readNfcContext, readQrContext, reconcileRewardStates, resolveLocalizedText, stripSensitiveConfig, toLocalizedString, toPublicRallyConfig, validateAdminRallyConfig, validatePublicRallyConfig, validateRallyConfig, verifyPasscode, verifySecureToken, verifySnapshotToken };
|