@proofchain/sdk 2.23.0 → 3.1.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.mts +102 -12
- package/dist/index.d.ts +102 -12
- package/dist/index.js +161 -25
- package/dist/index.mjs +159 -24
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HTTP Client for ProofChain API
|
|
3
3
|
*/
|
|
4
|
+
/**
|
|
5
|
+
* Returns the per-tenant Cloudflare edge API URL for `slug`.
|
|
6
|
+
*
|
|
7
|
+
* Cloudflare can cache responses from per-tenant hosts
|
|
8
|
+
* (`https://{slug}.proofchain.co.za/api`) because the full URL is the cache
|
|
9
|
+
* key. The shared `api.proofchain.co.za` host is keyed on the `X-Tenant-ID`
|
|
10
|
+
* header and cannot be cached safely at the CDN layer.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { tenantApiUrl, ProofChain } from '@proofchain/sdk';
|
|
15
|
+
*
|
|
16
|
+
* const client = new ProofChain({
|
|
17
|
+
* apiKey: 'atst_…',
|
|
18
|
+
* baseUrl: tenantApiUrl('acme'), // https://acme.proofchain.co.za/api
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function tenantApiUrl(slug: string): string;
|
|
4
23
|
interface HttpClientOptions {
|
|
5
24
|
apiKey?: string;
|
|
6
25
|
userToken?: string;
|
|
7
26
|
tenantId?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Explicit base URL — highest precedence.
|
|
29
|
+
* Covers custom domains (e.g. `https://fanpass.onefootball.com/api`).
|
|
30
|
+
*/
|
|
8
31
|
baseUrl?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Tenant slug used to derive the per-tenant edge URL when no explicit
|
|
34
|
+
* `baseUrl` is provided. Precedence: baseUrl > tenant > default.
|
|
35
|
+
*/
|
|
36
|
+
tenant?: string;
|
|
9
37
|
timeout?: number;
|
|
10
38
|
maxRetries?: number;
|
|
11
39
|
}
|
|
@@ -16,6 +44,7 @@ declare class HttpClient {
|
|
|
16
44
|
private baseUrl;
|
|
17
45
|
private timeout;
|
|
18
46
|
private maxRetries;
|
|
47
|
+
private readonly inflight;
|
|
19
48
|
constructor(options: HttpClientOptions);
|
|
20
49
|
private getHeaders;
|
|
21
50
|
private handleResponse;
|
|
@@ -384,9 +413,51 @@ interface ProofChainOptions {
|
|
|
384
413
|
apiKey?: string;
|
|
385
414
|
/** End-user JWT for JWKS auth (alternative to apiKey). For PWA clients. */
|
|
386
415
|
userToken?: string;
|
|
387
|
-
/**
|
|
416
|
+
/**
|
|
417
|
+
* Tenant slug or client_id. Required when using userToken.
|
|
418
|
+
*
|
|
419
|
+
* When used as the sole host hint (no explicit `baseUrl`), the SDK also
|
|
420
|
+
* derives the base URL as `https://{tenantId}.proofchain.co.za/api` so
|
|
421
|
+
* requests hit the per-tenant Cloudflare edge host — enabling response
|
|
422
|
+
* caching that the shared `api.proofchain.co.za` origin cannot provide
|
|
423
|
+
* (the shared host is keyed on headers, not URL, and is therefore
|
|
424
|
+
* uncacheable at the CDN layer).
|
|
425
|
+
*/
|
|
388
426
|
tenantId?: string;
|
|
427
|
+
/**
|
|
428
|
+
* Override the API base URL (highest precedence).
|
|
429
|
+
*
|
|
430
|
+
* Use this for custom domains (e.g. `https://fanpass-portal.onefootball.com/api`)
|
|
431
|
+
* or self-hosted deployments. When omitted and `tenantId` is set, the SDK
|
|
432
|
+
* automatically uses `https://{tenantId}.proofchain.co.za/api`.
|
|
433
|
+
*
|
|
434
|
+
* Precedence: `baseUrl` > `tenantId`-derived URL > shared default.
|
|
435
|
+
*/
|
|
389
436
|
baseUrl?: string;
|
|
437
|
+
/**
|
|
438
|
+
* Tenant slug used to derive the per-tenant Cloudflare edge URL
|
|
439
|
+
* (`https://{tenant}.proofchain.co.za/api`) when no explicit `baseUrl` is
|
|
440
|
+
* supplied.
|
|
441
|
+
*
|
|
442
|
+
* Edge caching requires the per-tenant host: the shared `api.proofchain.co.za`
|
|
443
|
+
* host is keyed on the `X-Tenant-ID` header and cannot be safely cached by
|
|
444
|
+
* Cloudflare. Providing this option is the easiest way for integrators to opt
|
|
445
|
+
* into cached responses without managing a custom domain.
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```typescript
|
|
449
|
+
* // Requests go to https://acme.proofchain.co.za/api — edge cached.
|
|
450
|
+
* const client = new ProofChain({ apiKey: 'atst_…', tenant: 'acme' });
|
|
451
|
+
*
|
|
452
|
+
* // Custom domain takes precedence; tenant is ignored for URL derivation.
|
|
453
|
+
* const client = new ProofChain({
|
|
454
|
+
* apiKey: 'atst_…',
|
|
455
|
+
* tenant: 'acme',
|
|
456
|
+
* baseUrl: 'https://fanpass.onefootball.com/api',
|
|
457
|
+
* });
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
460
|
+
tenant?: string;
|
|
390
461
|
timeout?: number;
|
|
391
462
|
maxRetries?: number;
|
|
392
463
|
}
|
|
@@ -2238,7 +2309,7 @@ interface QuestStep {
|
|
|
2238
2309
|
name: string;
|
|
2239
2310
|
description?: string;
|
|
2240
2311
|
order: number;
|
|
2241
|
-
step_type: '
|
|
2312
|
+
step_type: 'event_count' | 'event_match' | 'unique_values' | 'cumulative' | 'streak' | 'manual' | 'threshold' | 'recency' | 'time_windowed_count' | 'wallet_holds' | 'milestone';
|
|
2242
2313
|
event_type?: string;
|
|
2243
2314
|
event_types?: string[];
|
|
2244
2315
|
criteria?: Record<string, any>;
|
|
@@ -2354,7 +2425,7 @@ interface CreateQuestStepRequest {
|
|
|
2354
2425
|
name: string;
|
|
2355
2426
|
description?: string;
|
|
2356
2427
|
order?: number;
|
|
2357
|
-
step_type?: '
|
|
2428
|
+
step_type?: 'event_count' | 'event_match' | 'unique_values' | 'cumulative' | 'streak' | 'manual' | 'threshold' | 'recency' | 'time_windowed_count' | 'wallet_holds' | 'milestone';
|
|
2358
2429
|
event_type?: string;
|
|
2359
2430
|
event_types?: string[];
|
|
2360
2431
|
criteria?: Record<string, any>;
|
|
@@ -2394,9 +2465,10 @@ declare class QuestsClient {
|
|
|
2394
2465
|
category?: string;
|
|
2395
2466
|
}): Promise<QuestWithProgress[]>;
|
|
2396
2467
|
/**
|
|
2397
|
-
*
|
|
2468
|
+
* REMOVED: getBySlug() — the server never implemented GET /quests/slug/{slug}.
|
|
2469
|
+
* There is no slug-based lookup route in the API. Use list() with a status/category
|
|
2470
|
+
* filter and find the quest client-side, or use get() with the quest ID.
|
|
2398
2471
|
*/
|
|
2399
|
-
getBySlug(slug: string): Promise<Quest>;
|
|
2400
2472
|
/**
|
|
2401
2473
|
* Create a quest
|
|
2402
2474
|
*/
|
|
@@ -2422,9 +2494,9 @@ declare class QuestsClient {
|
|
|
2422
2494
|
*/
|
|
2423
2495
|
pause(questId: string): Promise<Quest>;
|
|
2424
2496
|
/**
|
|
2425
|
-
*
|
|
2497
|
+
* REMOVED: archive() — the server never implemented POST /quests/{id}/archive.
|
|
2498
|
+
* To archive a quest, use update(questId, { status: 'archived' }) via PUT /quests/{id}.
|
|
2426
2499
|
*/
|
|
2427
|
-
archive(questId: string): Promise<Quest>;
|
|
2428
2500
|
/**
|
|
2429
2501
|
* Get quest with user progress
|
|
2430
2502
|
* Fetches the quest and user's progress separately and combines them
|
|
@@ -2469,19 +2541,37 @@ declare class QuestsClient {
|
|
|
2469
2541
|
*/
|
|
2470
2542
|
claimReward(questId: string, userId: string): Promise<ClaimRewardResult>;
|
|
2471
2543
|
/**
|
|
2472
|
-
* Add a step to a quest
|
|
2544
|
+
* Add a step to a quest.
|
|
2545
|
+
*
|
|
2546
|
+
* The server has no dedicated step-create endpoint — steps are managed via the
|
|
2547
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, appends the new
|
|
2548
|
+
* step, and issues a full update. The returned QuestStep is synthesised from the
|
|
2549
|
+
* updated quest's steps array (matched by order or last position).
|
|
2473
2550
|
*/
|
|
2474
2551
|
addStep(questId: string, step: CreateQuestStepRequest): Promise<QuestStep>;
|
|
2475
2552
|
/**
|
|
2476
|
-
* Update a step
|
|
2553
|
+
* Update a step by step ID.
|
|
2554
|
+
*
|
|
2555
|
+
* The server has no dedicated step-update endpoint — steps are managed via the
|
|
2556
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, replaces the
|
|
2557
|
+
* matching step, and issues a full update.
|
|
2477
2558
|
*/
|
|
2478
2559
|
updateStep(questId: string, stepId: string, data: Partial<CreateQuestStepRequest>): Promise<QuestStep>;
|
|
2479
2560
|
/**
|
|
2480
|
-
* Delete a step
|
|
2561
|
+
* Delete a step by step ID.
|
|
2562
|
+
*
|
|
2563
|
+
* The server has no dedicated step-delete endpoint — steps are managed via the
|
|
2564
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, filters out the
|
|
2565
|
+
* target step, and issues a full update.
|
|
2481
2566
|
*/
|
|
2482
2567
|
deleteStep(questId: string, stepId: string): Promise<void>;
|
|
2483
2568
|
/**
|
|
2484
|
-
* Reorder steps
|
|
2569
|
+
* Reorder steps by providing step IDs in the desired order.
|
|
2570
|
+
*
|
|
2571
|
+
* The server has no dedicated reorder endpoint — steps are managed via the
|
|
2572
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, reassigns
|
|
2573
|
+
* the `order` field according to the given stepIds sequence, and issues a
|
|
2574
|
+
* full update.
|
|
2485
2575
|
*/
|
|
2486
2576
|
reorderSteps(questId: string, stepIds: string[]): Promise<Quest>;
|
|
2487
2577
|
}
|
|
@@ -4186,4 +4276,4 @@ declare class TimeoutError extends ProofChainError {
|
|
|
4186
4276
|
constructor(message?: string);
|
|
4187
4277
|
}
|
|
4188
4278
|
|
|
4189
|
-
export { type Achievement, type ActivitySummaryView, type AddNFTRequest, type AnchorResult, type ApiKey, type AttestRequest, type AttestationConfig, type AttestationMode, type Attestation as AttestationRecord, type AttestationResult, type AttestationSchema, AttestationsClient, AuthenticationError, AuthorizationError, type AvailableView, type Badge, type BatchIngestRequest, type BatchIngestResponse, type BatchVerifyResult, type BlockchainProof, type BlockchainStats, type Certificate, type CertificateVerifyResult, CertificatesResource, type Channel, type ChannelState, type ChannelStatus, ChannelsResource, type ClaimNFTResult, type ClaimRewardResult, type CohortDefinition, type CohortGroupStats, CohortLeaderboardClient, type CohortLeaderboardEntry, type CohortLeaderboardOptions, type CohortLeaderboardResponse, type ComprehensiveWalletInfo, type CreateAchievementRequest, type CreateApiKeyRequest, type CreateAttestationRequest, type CreateBadgeRequest, type CreateChannelRequest, type CreateCredentialTypeRequest, type CreateDataViewRequest, type CreateDualWalletsRequest, type CreateEndUserRequest, type CreateEventRequest, type CreatePassportDefinitionRequest, type CreatePassportRequest, type CreateQuestRequest, type CreateQuestStepRequest, type CreateRewardDefinitionRequest, type CreateSchemaRequest, type CreateTemplateFieldRequest, type CreateTemplateRequest, type CreateWalletRequest as CreateUserWalletRequest, type CreateWalletRequest$1 as CreateWalletRequest, type CreateWebhookRequest, type CredentialType, type CredentialVerifyResult, CredentialsClient, type DataViewColumn, type DataViewComputation, type DataViewDetail, type DataViewExecuteResult, type DataViewInfo, type DataViewListResponse, type DataViewPreviewRequest, type DataViewPreviewResult, type DataViewSummary, DataViewsClient, type DistributeResult, DocumentsResource, type DualWallets, type EarnedReward, type EndUser, EndUserIngestionClient, type EndUserIngestionClientOptions, type EndUserListResponse, EndUsersClient, type Event, type EventBatchProof, type EventMetadata, type EventStatus, EventsResource, type ExecuteSwapRequest, type Facet, type FacetsResponse, type FanProfileView, type FanpassGroupStats, FanpassLeaderboardClient, type FanpassLeaderboardEntry, type FanpassLeaderboardOptions, type FanpassLeaderboardResponse, type FanpassUserComparisonResponse, type FieldValue, type GDPRDeletionRequest, type GDPRDeletionResponse, type GDPRPreviewResponse, type IngestEventRequest, type IngestEventResponse, IngestionClient, type IngestionClientOptions, type IssueCertificateRequest, type IssueCredentialRequest, type IssuedCredential, type LeaderboardUserProfile$1 as LeaderboardUserProfile, type LinkWalletRequest, type ListAttestationsOptions, type ListCertificatesRequest, type ListCohortsOptions, type ListEndUsersOptions, type ListEventsRequest, type ListIssuedCredentialsOptions, type ListMintsOptions, type ListMintsResponse, type ListQuestsOptions, type ListRewardsOptions, type ListSchemasOptions, type ListWalletCredentialsOptions, type ManualRewardRequest, type MergeUsersRequest, type Milestone, type MintNFTRequest, type NFT, type NFTMint, NetworkError, NftClient, NotFoundError, type NotificationCallback, type NotificationEvent, type NotificationEventType, NotificationsClient, type OTTConfigResponse, type OTTConfigUpdate, type OTTGenerateRequest, type OTTGenerateResponse, type OTTRedeemResponse, type OTTRequestResponse, PartnerKeysClient, type Passport, PassportClient, type PassportDefinition, type PassportFieldValue, type PassportHistory, type PassportTemplate, type PassportV2Data, type PassportWithFields, ProofChain, ProofChainError, type ProofChainOptions, type ProofVerifyResult, type PushSubscriptionJSON, type Quest, type QuestStep, type QuestWithProgress, QuestsClient, RateLimitError, type RegisterWalletRequest, type RevokeResult, type RewardAsset, type RewardAttestationResult, type RewardDefinition, type RewardEarned, type VerifyResult as RewardVerifyResult, RewardsClient, type Schema, type SchemaDetail, type SchemaField, type SchemaListResponse, type ValidationError$1 as SchemaValidationError, SchemasClient, type SearchFilters, type SearchQueryRequest, type SearchRequest, SearchResource, type SearchResponse, type SearchResult, type SearchStats, ServerError, type SetProfileRequest, type Settlement, type StepCompletionResult, type StepProgress, type StepStartResult, type StreamAck, type StreamEventRequest, type SubscribeOptions, type SwapQuote, type SwapQuoteRequest, type SwapResult, type TemplateField, type TenantInfo, TenantResource, type TierDefinition, TimeoutError, type TokenBalance, type TransferRequest, type TransferResult, type Unsubscribe, type UpdateConfigRequest as UpdateAttestationConfigRequest, type UpdateDataViewRequest, type UpdateEndUserRequest, type UpdatePassportRequest, type UpdateWebhookRequest, type UsageStats, type UserAchievement, type UserActivity, type UserActivityResponse, type UserBadge, type UserBreakdownResponse, type UserCohortBreakdownEntry, type UserCredentialsSummary, type UserQuestProgress, type UserReward$1 as UserReward, type UserRewardsResponse, type UserWalletSummary, type UserWithWallets, type UsersWithWalletsResponse, type ValidateDataRequest, ValidationError, type ValidationErrorDetail, type ValidationResult, type VaultFile, type VaultFolder, type VaultListResponse, VaultResource, type VaultStats, type VaultUploadRequest, type VerificationResult, VerifyResource, type ViewColumn, type ViewTemplate, type Wallet, type WalletBalance, WalletClient, type WalletCreationResult, type WalletCredential, type WalletCredentialVerifySummary, type WalletStats, type Webhook, WebhooksResource };
|
|
4279
|
+
export { type Achievement, type ActivitySummaryView, type AddNFTRequest, type AnchorResult, type ApiKey, type AttestRequest, type AttestationConfig, type AttestationMode, type Attestation as AttestationRecord, type AttestationResult, type AttestationSchema, AttestationsClient, AuthenticationError, AuthorizationError, type AvailableView, type Badge, type BatchIngestRequest, type BatchIngestResponse, type BatchVerifyResult, type BlockchainProof, type BlockchainStats, type Certificate, type CertificateVerifyResult, CertificatesResource, type Channel, type ChannelState, type ChannelStatus, ChannelsResource, type ClaimNFTResult, type ClaimRewardResult, type CohortDefinition, type CohortGroupStats, CohortLeaderboardClient, type CohortLeaderboardEntry, type CohortLeaderboardOptions, type CohortLeaderboardResponse, type ComprehensiveWalletInfo, type CreateAchievementRequest, type CreateApiKeyRequest, type CreateAttestationRequest, type CreateBadgeRequest, type CreateChannelRequest, type CreateCredentialTypeRequest, type CreateDataViewRequest, type CreateDualWalletsRequest, type CreateEndUserRequest, type CreateEventRequest, type CreatePassportDefinitionRequest, type CreatePassportRequest, type CreateQuestRequest, type CreateQuestStepRequest, type CreateRewardDefinitionRequest, type CreateSchemaRequest, type CreateTemplateFieldRequest, type CreateTemplateRequest, type CreateWalletRequest as CreateUserWalletRequest, type CreateWalletRequest$1 as CreateWalletRequest, type CreateWebhookRequest, type CredentialType, type CredentialVerifyResult, CredentialsClient, type DataViewColumn, type DataViewComputation, type DataViewDetail, type DataViewExecuteResult, type DataViewInfo, type DataViewListResponse, type DataViewPreviewRequest, type DataViewPreviewResult, type DataViewSummary, DataViewsClient, type DistributeResult, DocumentsResource, type DualWallets, type EarnedReward, type EndUser, EndUserIngestionClient, type EndUserIngestionClientOptions, type EndUserListResponse, EndUsersClient, type Event, type EventBatchProof, type EventMetadata, type EventStatus, EventsResource, type ExecuteSwapRequest, type Facet, type FacetsResponse, type FanProfileView, type FanpassGroupStats, FanpassLeaderboardClient, type FanpassLeaderboardEntry, type FanpassLeaderboardOptions, type FanpassLeaderboardResponse, type FanpassUserComparisonResponse, type FieldValue, type GDPRDeletionRequest, type GDPRDeletionResponse, type GDPRPreviewResponse, type IngestEventRequest, type IngestEventResponse, IngestionClient, type IngestionClientOptions, type IssueCertificateRequest, type IssueCredentialRequest, type IssuedCredential, type LeaderboardUserProfile$1 as LeaderboardUserProfile, type LinkWalletRequest, type ListAttestationsOptions, type ListCertificatesRequest, type ListCohortsOptions, type ListEndUsersOptions, type ListEventsRequest, type ListIssuedCredentialsOptions, type ListMintsOptions, type ListMintsResponse, type ListQuestsOptions, type ListRewardsOptions, type ListSchemasOptions, type ListWalletCredentialsOptions, type ManualRewardRequest, type MergeUsersRequest, type Milestone, type MintNFTRequest, type NFT, type NFTMint, NetworkError, NftClient, NotFoundError, type NotificationCallback, type NotificationEvent, type NotificationEventType, NotificationsClient, type OTTConfigResponse, type OTTConfigUpdate, type OTTGenerateRequest, type OTTGenerateResponse, type OTTRedeemResponse, type OTTRequestResponse, PartnerKeysClient, type Passport, PassportClient, type PassportDefinition, type PassportFieldValue, type PassportHistory, type PassportTemplate, type PassportV2Data, type PassportWithFields, ProofChain, ProofChainError, type ProofChainOptions, type ProofVerifyResult, type PushSubscriptionJSON, type Quest, type QuestStep, type QuestWithProgress, QuestsClient, RateLimitError, type RegisterWalletRequest, type RevokeResult, type RewardAsset, type RewardAttestationResult, type RewardDefinition, type RewardEarned, type VerifyResult as RewardVerifyResult, RewardsClient, type Schema, type SchemaDetail, type SchemaField, type SchemaListResponse, type ValidationError$1 as SchemaValidationError, SchemasClient, type SearchFilters, type SearchQueryRequest, type SearchRequest, SearchResource, type SearchResponse, type SearchResult, type SearchStats, ServerError, type SetProfileRequest, type Settlement, type StepCompletionResult, type StepProgress, type StepStartResult, type StreamAck, type StreamEventRequest, type SubscribeOptions, type SwapQuote, type SwapQuoteRequest, type SwapResult, type TemplateField, type TenantInfo, TenantResource, type TierDefinition, TimeoutError, type TokenBalance, type TransferRequest, type TransferResult, type Unsubscribe, type UpdateConfigRequest as UpdateAttestationConfigRequest, type UpdateDataViewRequest, type UpdateEndUserRequest, type UpdatePassportRequest, type UpdateWebhookRequest, type UsageStats, type UserAchievement, type UserActivity, type UserActivityResponse, type UserBadge, type UserBreakdownResponse, type UserCohortBreakdownEntry, type UserCredentialsSummary, type UserQuestProgress, type UserReward$1 as UserReward, type UserRewardsResponse, type UserWalletSummary, type UserWithWallets, type UsersWithWalletsResponse, type ValidateDataRequest, ValidationError, type ValidationErrorDetail, type ValidationResult, type VaultFile, type VaultFolder, type VaultListResponse, VaultResource, type VaultStats, type VaultUploadRequest, type VerificationResult, VerifyResource, type ViewColumn, type ViewTemplate, type Wallet, type WalletBalance, WalletClient, type WalletCreationResult, type WalletCredential, type WalletCredentialVerifySummary, type WalletStats, type Webhook, WebhooksResource, tenantApiUrl };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HTTP Client for ProofChain API
|
|
3
3
|
*/
|
|
4
|
+
/**
|
|
5
|
+
* Returns the per-tenant Cloudflare edge API URL for `slug`.
|
|
6
|
+
*
|
|
7
|
+
* Cloudflare can cache responses from per-tenant hosts
|
|
8
|
+
* (`https://{slug}.proofchain.co.za/api`) because the full URL is the cache
|
|
9
|
+
* key. The shared `api.proofchain.co.za` host is keyed on the `X-Tenant-ID`
|
|
10
|
+
* header and cannot be cached safely at the CDN layer.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { tenantApiUrl, ProofChain } from '@proofchain/sdk';
|
|
15
|
+
*
|
|
16
|
+
* const client = new ProofChain({
|
|
17
|
+
* apiKey: 'atst_…',
|
|
18
|
+
* baseUrl: tenantApiUrl('acme'), // https://acme.proofchain.co.za/api
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function tenantApiUrl(slug: string): string;
|
|
4
23
|
interface HttpClientOptions {
|
|
5
24
|
apiKey?: string;
|
|
6
25
|
userToken?: string;
|
|
7
26
|
tenantId?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Explicit base URL — highest precedence.
|
|
29
|
+
* Covers custom domains (e.g. `https://fanpass.onefootball.com/api`).
|
|
30
|
+
*/
|
|
8
31
|
baseUrl?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Tenant slug used to derive the per-tenant edge URL when no explicit
|
|
34
|
+
* `baseUrl` is provided. Precedence: baseUrl > tenant > default.
|
|
35
|
+
*/
|
|
36
|
+
tenant?: string;
|
|
9
37
|
timeout?: number;
|
|
10
38
|
maxRetries?: number;
|
|
11
39
|
}
|
|
@@ -16,6 +44,7 @@ declare class HttpClient {
|
|
|
16
44
|
private baseUrl;
|
|
17
45
|
private timeout;
|
|
18
46
|
private maxRetries;
|
|
47
|
+
private readonly inflight;
|
|
19
48
|
constructor(options: HttpClientOptions);
|
|
20
49
|
private getHeaders;
|
|
21
50
|
private handleResponse;
|
|
@@ -384,9 +413,51 @@ interface ProofChainOptions {
|
|
|
384
413
|
apiKey?: string;
|
|
385
414
|
/** End-user JWT for JWKS auth (alternative to apiKey). For PWA clients. */
|
|
386
415
|
userToken?: string;
|
|
387
|
-
/**
|
|
416
|
+
/**
|
|
417
|
+
* Tenant slug or client_id. Required when using userToken.
|
|
418
|
+
*
|
|
419
|
+
* When used as the sole host hint (no explicit `baseUrl`), the SDK also
|
|
420
|
+
* derives the base URL as `https://{tenantId}.proofchain.co.za/api` so
|
|
421
|
+
* requests hit the per-tenant Cloudflare edge host — enabling response
|
|
422
|
+
* caching that the shared `api.proofchain.co.za` origin cannot provide
|
|
423
|
+
* (the shared host is keyed on headers, not URL, and is therefore
|
|
424
|
+
* uncacheable at the CDN layer).
|
|
425
|
+
*/
|
|
388
426
|
tenantId?: string;
|
|
427
|
+
/**
|
|
428
|
+
* Override the API base URL (highest precedence).
|
|
429
|
+
*
|
|
430
|
+
* Use this for custom domains (e.g. `https://fanpass-portal.onefootball.com/api`)
|
|
431
|
+
* or self-hosted deployments. When omitted and `tenantId` is set, the SDK
|
|
432
|
+
* automatically uses `https://{tenantId}.proofchain.co.za/api`.
|
|
433
|
+
*
|
|
434
|
+
* Precedence: `baseUrl` > `tenantId`-derived URL > shared default.
|
|
435
|
+
*/
|
|
389
436
|
baseUrl?: string;
|
|
437
|
+
/**
|
|
438
|
+
* Tenant slug used to derive the per-tenant Cloudflare edge URL
|
|
439
|
+
* (`https://{tenant}.proofchain.co.za/api`) when no explicit `baseUrl` is
|
|
440
|
+
* supplied.
|
|
441
|
+
*
|
|
442
|
+
* Edge caching requires the per-tenant host: the shared `api.proofchain.co.za`
|
|
443
|
+
* host is keyed on the `X-Tenant-ID` header and cannot be safely cached by
|
|
444
|
+
* Cloudflare. Providing this option is the easiest way for integrators to opt
|
|
445
|
+
* into cached responses without managing a custom domain.
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```typescript
|
|
449
|
+
* // Requests go to https://acme.proofchain.co.za/api — edge cached.
|
|
450
|
+
* const client = new ProofChain({ apiKey: 'atst_…', tenant: 'acme' });
|
|
451
|
+
*
|
|
452
|
+
* // Custom domain takes precedence; tenant is ignored for URL derivation.
|
|
453
|
+
* const client = new ProofChain({
|
|
454
|
+
* apiKey: 'atst_…',
|
|
455
|
+
* tenant: 'acme',
|
|
456
|
+
* baseUrl: 'https://fanpass.onefootball.com/api',
|
|
457
|
+
* });
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
460
|
+
tenant?: string;
|
|
390
461
|
timeout?: number;
|
|
391
462
|
maxRetries?: number;
|
|
392
463
|
}
|
|
@@ -2238,7 +2309,7 @@ interface QuestStep {
|
|
|
2238
2309
|
name: string;
|
|
2239
2310
|
description?: string;
|
|
2240
2311
|
order: number;
|
|
2241
|
-
step_type: '
|
|
2312
|
+
step_type: 'event_count' | 'event_match' | 'unique_values' | 'cumulative' | 'streak' | 'manual' | 'threshold' | 'recency' | 'time_windowed_count' | 'wallet_holds' | 'milestone';
|
|
2242
2313
|
event_type?: string;
|
|
2243
2314
|
event_types?: string[];
|
|
2244
2315
|
criteria?: Record<string, any>;
|
|
@@ -2354,7 +2425,7 @@ interface CreateQuestStepRequest {
|
|
|
2354
2425
|
name: string;
|
|
2355
2426
|
description?: string;
|
|
2356
2427
|
order?: number;
|
|
2357
|
-
step_type?: '
|
|
2428
|
+
step_type?: 'event_count' | 'event_match' | 'unique_values' | 'cumulative' | 'streak' | 'manual' | 'threshold' | 'recency' | 'time_windowed_count' | 'wallet_holds' | 'milestone';
|
|
2358
2429
|
event_type?: string;
|
|
2359
2430
|
event_types?: string[];
|
|
2360
2431
|
criteria?: Record<string, any>;
|
|
@@ -2394,9 +2465,10 @@ declare class QuestsClient {
|
|
|
2394
2465
|
category?: string;
|
|
2395
2466
|
}): Promise<QuestWithProgress[]>;
|
|
2396
2467
|
/**
|
|
2397
|
-
*
|
|
2468
|
+
* REMOVED: getBySlug() — the server never implemented GET /quests/slug/{slug}.
|
|
2469
|
+
* There is no slug-based lookup route in the API. Use list() with a status/category
|
|
2470
|
+
* filter and find the quest client-side, or use get() with the quest ID.
|
|
2398
2471
|
*/
|
|
2399
|
-
getBySlug(slug: string): Promise<Quest>;
|
|
2400
2472
|
/**
|
|
2401
2473
|
* Create a quest
|
|
2402
2474
|
*/
|
|
@@ -2422,9 +2494,9 @@ declare class QuestsClient {
|
|
|
2422
2494
|
*/
|
|
2423
2495
|
pause(questId: string): Promise<Quest>;
|
|
2424
2496
|
/**
|
|
2425
|
-
*
|
|
2497
|
+
* REMOVED: archive() — the server never implemented POST /quests/{id}/archive.
|
|
2498
|
+
* To archive a quest, use update(questId, { status: 'archived' }) via PUT /quests/{id}.
|
|
2426
2499
|
*/
|
|
2427
|
-
archive(questId: string): Promise<Quest>;
|
|
2428
2500
|
/**
|
|
2429
2501
|
* Get quest with user progress
|
|
2430
2502
|
* Fetches the quest and user's progress separately and combines them
|
|
@@ -2469,19 +2541,37 @@ declare class QuestsClient {
|
|
|
2469
2541
|
*/
|
|
2470
2542
|
claimReward(questId: string, userId: string): Promise<ClaimRewardResult>;
|
|
2471
2543
|
/**
|
|
2472
|
-
* Add a step to a quest
|
|
2544
|
+
* Add a step to a quest.
|
|
2545
|
+
*
|
|
2546
|
+
* The server has no dedicated step-create endpoint — steps are managed via the
|
|
2547
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, appends the new
|
|
2548
|
+
* step, and issues a full update. The returned QuestStep is synthesised from the
|
|
2549
|
+
* updated quest's steps array (matched by order or last position).
|
|
2473
2550
|
*/
|
|
2474
2551
|
addStep(questId: string, step: CreateQuestStepRequest): Promise<QuestStep>;
|
|
2475
2552
|
/**
|
|
2476
|
-
* Update a step
|
|
2553
|
+
* Update a step by step ID.
|
|
2554
|
+
*
|
|
2555
|
+
* The server has no dedicated step-update endpoint — steps are managed via the
|
|
2556
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, replaces the
|
|
2557
|
+
* matching step, and issues a full update.
|
|
2477
2558
|
*/
|
|
2478
2559
|
updateStep(questId: string, stepId: string, data: Partial<CreateQuestStepRequest>): Promise<QuestStep>;
|
|
2479
2560
|
/**
|
|
2480
|
-
* Delete a step
|
|
2561
|
+
* Delete a step by step ID.
|
|
2562
|
+
*
|
|
2563
|
+
* The server has no dedicated step-delete endpoint — steps are managed via the
|
|
2564
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, filters out the
|
|
2565
|
+
* target step, and issues a full update.
|
|
2481
2566
|
*/
|
|
2482
2567
|
deleteStep(questId: string, stepId: string): Promise<void>;
|
|
2483
2568
|
/**
|
|
2484
|
-
* Reorder steps
|
|
2569
|
+
* Reorder steps by providing step IDs in the desired order.
|
|
2570
|
+
*
|
|
2571
|
+
* The server has no dedicated reorder endpoint — steps are managed via the
|
|
2572
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, reassigns
|
|
2573
|
+
* the `order` field according to the given stepIds sequence, and issues a
|
|
2574
|
+
* full update.
|
|
2485
2575
|
*/
|
|
2486
2576
|
reorderSteps(questId: string, stepIds: string[]): Promise<Quest>;
|
|
2487
2577
|
}
|
|
@@ -4186,4 +4276,4 @@ declare class TimeoutError extends ProofChainError {
|
|
|
4186
4276
|
constructor(message?: string);
|
|
4187
4277
|
}
|
|
4188
4278
|
|
|
4189
|
-
export { type Achievement, type ActivitySummaryView, type AddNFTRequest, type AnchorResult, type ApiKey, type AttestRequest, type AttestationConfig, type AttestationMode, type Attestation as AttestationRecord, type AttestationResult, type AttestationSchema, AttestationsClient, AuthenticationError, AuthorizationError, type AvailableView, type Badge, type BatchIngestRequest, type BatchIngestResponse, type BatchVerifyResult, type BlockchainProof, type BlockchainStats, type Certificate, type CertificateVerifyResult, CertificatesResource, type Channel, type ChannelState, type ChannelStatus, ChannelsResource, type ClaimNFTResult, type ClaimRewardResult, type CohortDefinition, type CohortGroupStats, CohortLeaderboardClient, type CohortLeaderboardEntry, type CohortLeaderboardOptions, type CohortLeaderboardResponse, type ComprehensiveWalletInfo, type CreateAchievementRequest, type CreateApiKeyRequest, type CreateAttestationRequest, type CreateBadgeRequest, type CreateChannelRequest, type CreateCredentialTypeRequest, type CreateDataViewRequest, type CreateDualWalletsRequest, type CreateEndUserRequest, type CreateEventRequest, type CreatePassportDefinitionRequest, type CreatePassportRequest, type CreateQuestRequest, type CreateQuestStepRequest, type CreateRewardDefinitionRequest, type CreateSchemaRequest, type CreateTemplateFieldRequest, type CreateTemplateRequest, type CreateWalletRequest as CreateUserWalletRequest, type CreateWalletRequest$1 as CreateWalletRequest, type CreateWebhookRequest, type CredentialType, type CredentialVerifyResult, CredentialsClient, type DataViewColumn, type DataViewComputation, type DataViewDetail, type DataViewExecuteResult, type DataViewInfo, type DataViewListResponse, type DataViewPreviewRequest, type DataViewPreviewResult, type DataViewSummary, DataViewsClient, type DistributeResult, DocumentsResource, type DualWallets, type EarnedReward, type EndUser, EndUserIngestionClient, type EndUserIngestionClientOptions, type EndUserListResponse, EndUsersClient, type Event, type EventBatchProof, type EventMetadata, type EventStatus, EventsResource, type ExecuteSwapRequest, type Facet, type FacetsResponse, type FanProfileView, type FanpassGroupStats, FanpassLeaderboardClient, type FanpassLeaderboardEntry, type FanpassLeaderboardOptions, type FanpassLeaderboardResponse, type FanpassUserComparisonResponse, type FieldValue, type GDPRDeletionRequest, type GDPRDeletionResponse, type GDPRPreviewResponse, type IngestEventRequest, type IngestEventResponse, IngestionClient, type IngestionClientOptions, type IssueCertificateRequest, type IssueCredentialRequest, type IssuedCredential, type LeaderboardUserProfile$1 as LeaderboardUserProfile, type LinkWalletRequest, type ListAttestationsOptions, type ListCertificatesRequest, type ListCohortsOptions, type ListEndUsersOptions, type ListEventsRequest, type ListIssuedCredentialsOptions, type ListMintsOptions, type ListMintsResponse, type ListQuestsOptions, type ListRewardsOptions, type ListSchemasOptions, type ListWalletCredentialsOptions, type ManualRewardRequest, type MergeUsersRequest, type Milestone, type MintNFTRequest, type NFT, type NFTMint, NetworkError, NftClient, NotFoundError, type NotificationCallback, type NotificationEvent, type NotificationEventType, NotificationsClient, type OTTConfigResponse, type OTTConfigUpdate, type OTTGenerateRequest, type OTTGenerateResponse, type OTTRedeemResponse, type OTTRequestResponse, PartnerKeysClient, type Passport, PassportClient, type PassportDefinition, type PassportFieldValue, type PassportHistory, type PassportTemplate, type PassportV2Data, type PassportWithFields, ProofChain, ProofChainError, type ProofChainOptions, type ProofVerifyResult, type PushSubscriptionJSON, type Quest, type QuestStep, type QuestWithProgress, QuestsClient, RateLimitError, type RegisterWalletRequest, type RevokeResult, type RewardAsset, type RewardAttestationResult, type RewardDefinition, type RewardEarned, type VerifyResult as RewardVerifyResult, RewardsClient, type Schema, type SchemaDetail, type SchemaField, type SchemaListResponse, type ValidationError$1 as SchemaValidationError, SchemasClient, type SearchFilters, type SearchQueryRequest, type SearchRequest, SearchResource, type SearchResponse, type SearchResult, type SearchStats, ServerError, type SetProfileRequest, type Settlement, type StepCompletionResult, type StepProgress, type StepStartResult, type StreamAck, type StreamEventRequest, type SubscribeOptions, type SwapQuote, type SwapQuoteRequest, type SwapResult, type TemplateField, type TenantInfo, TenantResource, type TierDefinition, TimeoutError, type TokenBalance, type TransferRequest, type TransferResult, type Unsubscribe, type UpdateConfigRequest as UpdateAttestationConfigRequest, type UpdateDataViewRequest, type UpdateEndUserRequest, type UpdatePassportRequest, type UpdateWebhookRequest, type UsageStats, type UserAchievement, type UserActivity, type UserActivityResponse, type UserBadge, type UserBreakdownResponse, type UserCohortBreakdownEntry, type UserCredentialsSummary, type UserQuestProgress, type UserReward$1 as UserReward, type UserRewardsResponse, type UserWalletSummary, type UserWithWallets, type UsersWithWalletsResponse, type ValidateDataRequest, ValidationError, type ValidationErrorDetail, type ValidationResult, type VaultFile, type VaultFolder, type VaultListResponse, VaultResource, type VaultStats, type VaultUploadRequest, type VerificationResult, VerifyResource, type ViewColumn, type ViewTemplate, type Wallet, type WalletBalance, WalletClient, type WalletCreationResult, type WalletCredential, type WalletCredentialVerifySummary, type WalletStats, type Webhook, WebhooksResource };
|
|
4279
|
+
export { type Achievement, type ActivitySummaryView, type AddNFTRequest, type AnchorResult, type ApiKey, type AttestRequest, type AttestationConfig, type AttestationMode, type Attestation as AttestationRecord, type AttestationResult, type AttestationSchema, AttestationsClient, AuthenticationError, AuthorizationError, type AvailableView, type Badge, type BatchIngestRequest, type BatchIngestResponse, type BatchVerifyResult, type BlockchainProof, type BlockchainStats, type Certificate, type CertificateVerifyResult, CertificatesResource, type Channel, type ChannelState, type ChannelStatus, ChannelsResource, type ClaimNFTResult, type ClaimRewardResult, type CohortDefinition, type CohortGroupStats, CohortLeaderboardClient, type CohortLeaderboardEntry, type CohortLeaderboardOptions, type CohortLeaderboardResponse, type ComprehensiveWalletInfo, type CreateAchievementRequest, type CreateApiKeyRequest, type CreateAttestationRequest, type CreateBadgeRequest, type CreateChannelRequest, type CreateCredentialTypeRequest, type CreateDataViewRequest, type CreateDualWalletsRequest, type CreateEndUserRequest, type CreateEventRequest, type CreatePassportDefinitionRequest, type CreatePassportRequest, type CreateQuestRequest, type CreateQuestStepRequest, type CreateRewardDefinitionRequest, type CreateSchemaRequest, type CreateTemplateFieldRequest, type CreateTemplateRequest, type CreateWalletRequest as CreateUserWalletRequest, type CreateWalletRequest$1 as CreateWalletRequest, type CreateWebhookRequest, type CredentialType, type CredentialVerifyResult, CredentialsClient, type DataViewColumn, type DataViewComputation, type DataViewDetail, type DataViewExecuteResult, type DataViewInfo, type DataViewListResponse, type DataViewPreviewRequest, type DataViewPreviewResult, type DataViewSummary, DataViewsClient, type DistributeResult, DocumentsResource, type DualWallets, type EarnedReward, type EndUser, EndUserIngestionClient, type EndUserIngestionClientOptions, type EndUserListResponse, EndUsersClient, type Event, type EventBatchProof, type EventMetadata, type EventStatus, EventsResource, type ExecuteSwapRequest, type Facet, type FacetsResponse, type FanProfileView, type FanpassGroupStats, FanpassLeaderboardClient, type FanpassLeaderboardEntry, type FanpassLeaderboardOptions, type FanpassLeaderboardResponse, type FanpassUserComparisonResponse, type FieldValue, type GDPRDeletionRequest, type GDPRDeletionResponse, type GDPRPreviewResponse, type IngestEventRequest, type IngestEventResponse, IngestionClient, type IngestionClientOptions, type IssueCertificateRequest, type IssueCredentialRequest, type IssuedCredential, type LeaderboardUserProfile$1 as LeaderboardUserProfile, type LinkWalletRequest, type ListAttestationsOptions, type ListCertificatesRequest, type ListCohortsOptions, type ListEndUsersOptions, type ListEventsRequest, type ListIssuedCredentialsOptions, type ListMintsOptions, type ListMintsResponse, type ListQuestsOptions, type ListRewardsOptions, type ListSchemasOptions, type ListWalletCredentialsOptions, type ManualRewardRequest, type MergeUsersRequest, type Milestone, type MintNFTRequest, type NFT, type NFTMint, NetworkError, NftClient, NotFoundError, type NotificationCallback, type NotificationEvent, type NotificationEventType, NotificationsClient, type OTTConfigResponse, type OTTConfigUpdate, type OTTGenerateRequest, type OTTGenerateResponse, type OTTRedeemResponse, type OTTRequestResponse, PartnerKeysClient, type Passport, PassportClient, type PassportDefinition, type PassportFieldValue, type PassportHistory, type PassportTemplate, type PassportV2Data, type PassportWithFields, ProofChain, ProofChainError, type ProofChainOptions, type ProofVerifyResult, type PushSubscriptionJSON, type Quest, type QuestStep, type QuestWithProgress, QuestsClient, RateLimitError, type RegisterWalletRequest, type RevokeResult, type RewardAsset, type RewardAttestationResult, type RewardDefinition, type RewardEarned, type VerifyResult as RewardVerifyResult, RewardsClient, type Schema, type SchemaDetail, type SchemaField, type SchemaListResponse, type ValidationError$1 as SchemaValidationError, SchemasClient, type SearchFilters, type SearchQueryRequest, type SearchRequest, SearchResource, type SearchResponse, type SearchResult, type SearchStats, ServerError, type SetProfileRequest, type Settlement, type StepCompletionResult, type StepProgress, type StepStartResult, type StreamAck, type StreamEventRequest, type SubscribeOptions, type SwapQuote, type SwapQuoteRequest, type SwapResult, type TemplateField, type TenantInfo, TenantResource, type TierDefinition, TimeoutError, type TokenBalance, type TransferRequest, type TransferResult, type Unsubscribe, type UpdateConfigRequest as UpdateAttestationConfigRequest, type UpdateDataViewRequest, type UpdateEndUserRequest, type UpdatePassportRequest, type UpdateWebhookRequest, type UsageStats, type UserAchievement, type UserActivity, type UserActivityResponse, type UserBadge, type UserBreakdownResponse, type UserCohortBreakdownEntry, type UserCredentialsSummary, type UserQuestProgress, type UserReward$1 as UserReward, type UserRewardsResponse, type UserWalletSummary, type UserWithWallets, type UsersWithWalletsResponse, type ValidateDataRequest, ValidationError, type ValidationErrorDetail, type ValidationResult, type VaultFile, type VaultFolder, type VaultListResponse, VaultResource, type VaultStats, type VaultUploadRequest, type VerificationResult, VerifyResource, type ViewColumn, type ViewTemplate, type Wallet, type WalletBalance, WalletClient, type WalletCreationResult, type WalletCredential, type WalletCredentialVerifySummary, type WalletStats, type Webhook, WebhooksResource, tenantApiUrl };
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,8 @@ __export(index_exports, {
|
|
|
54
54
|
VaultResource: () => VaultResource,
|
|
55
55
|
VerifyResource: () => VerifyResource,
|
|
56
56
|
WalletClient: () => WalletClient,
|
|
57
|
-
WebhooksResource: () => WebhooksResource
|
|
57
|
+
WebhooksResource: () => WebhooksResource,
|
|
58
|
+
tenantApiUrl: () => tenantApiUrl
|
|
58
59
|
});
|
|
59
60
|
module.exports = __toCommonJS(index_exports);
|
|
60
61
|
|
|
@@ -123,12 +124,19 @@ var TimeoutError = class extends ProofChainError {
|
|
|
123
124
|
var DEFAULT_BASE_URL = "https://api.proofchain.co.za";
|
|
124
125
|
var DEFAULT_TIMEOUT = 3e4;
|
|
125
126
|
var USER_AGENT = "proofchain-js/0.1.0";
|
|
127
|
+
function tenantApiUrl(slug) {
|
|
128
|
+
return `https://${slug}.proofchain.co.za/api`;
|
|
129
|
+
}
|
|
126
130
|
var HttpClient = class {
|
|
127
131
|
constructor(options) {
|
|
132
|
+
// In-flight GET de-duplication: concurrent identical GETs share one network
|
|
133
|
+
// request (and its response), cutting origin load for chatty UIs/pollers.
|
|
134
|
+
this.inflight = /* @__PURE__ */ new Map();
|
|
128
135
|
this.apiKey = options.apiKey || "";
|
|
129
136
|
this.userToken = options.userToken || "";
|
|
130
137
|
this.tenantId = options.tenantId || "";
|
|
131
|
-
|
|
138
|
+
const resolvedBase = options.baseUrl || (options.tenant ? tenantApiUrl(options.tenant) : DEFAULT_BASE_URL);
|
|
139
|
+
this.baseUrl = resolvedBase.replace(/\/$/, "");
|
|
132
140
|
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
133
141
|
this.maxRetries = options.maxRetries ?? 3;
|
|
134
142
|
}
|
|
@@ -193,7 +201,8 @@ var HttpClient = class {
|
|
|
193
201
|
clearTimeout(timeoutId);
|
|
194
202
|
if (error instanceof ProofChainError) {
|
|
195
203
|
if (error instanceof RateLimitError && retries < this.maxRetries) {
|
|
196
|
-
const
|
|
204
|
+
const base = Math.min((error.retryAfter || 1) * 1e3, 6e4);
|
|
205
|
+
const delay = base + Math.floor(Math.random() * 1e3);
|
|
197
206
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
198
207
|
return this.fetchWithRetry(url, options, retries + 1);
|
|
199
208
|
}
|
|
@@ -204,7 +213,9 @@ var HttpClient = class {
|
|
|
204
213
|
throw new TimeoutError();
|
|
205
214
|
}
|
|
206
215
|
if (retries < this.maxRetries) {
|
|
207
|
-
|
|
216
|
+
const base = 1e3 * (retries + 1);
|
|
217
|
+
const delay = base + Math.floor(Math.random() * 500);
|
|
218
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
208
219
|
return this.fetchWithRetry(url, options, retries + 1);
|
|
209
220
|
}
|
|
210
221
|
throw new NetworkError(error.message, error);
|
|
@@ -233,6 +244,17 @@ var HttpClient = class {
|
|
|
233
244
|
if (options.body) {
|
|
234
245
|
fetchOptions.body = JSON.stringify(options.body);
|
|
235
246
|
}
|
|
247
|
+
if (method === "GET") {
|
|
248
|
+
const existing = this.inflight.get(url);
|
|
249
|
+
if (existing) {
|
|
250
|
+
return existing;
|
|
251
|
+
}
|
|
252
|
+
const pending = this.fetchWithRetry(url, fetchOptions).finally(() => {
|
|
253
|
+
this.inflight.delete(url);
|
|
254
|
+
});
|
|
255
|
+
this.inflight.set(url, pending);
|
|
256
|
+
return pending;
|
|
257
|
+
}
|
|
236
258
|
return this.fetchWithRetry(url, fetchOptions);
|
|
237
259
|
}
|
|
238
260
|
async requestMultipart(path, formData) {
|
|
@@ -1726,11 +1748,10 @@ var QuestsClient = class {
|
|
|
1726
1748
|
return this.http.get(`/quests/available?${params.toString()}`);
|
|
1727
1749
|
}
|
|
1728
1750
|
/**
|
|
1729
|
-
*
|
|
1751
|
+
* REMOVED: getBySlug() — the server never implemented GET /quests/slug/{slug}.
|
|
1752
|
+
* There is no slug-based lookup route in the API. Use list() with a status/category
|
|
1753
|
+
* filter and find the quest client-side, or use get() with the quest ID.
|
|
1730
1754
|
*/
|
|
1731
|
-
async getBySlug(slug) {
|
|
1732
|
-
return this.http.get(`/quests/slug/${encodeURIComponent(slug)}`);
|
|
1733
|
-
}
|
|
1734
1755
|
/**
|
|
1735
1756
|
* Create a quest
|
|
1736
1757
|
*/
|
|
@@ -1771,11 +1792,9 @@ var QuestsClient = class {
|
|
|
1771
1792
|
return this.http.post(`/quests/${questId}/pause`, {});
|
|
1772
1793
|
}
|
|
1773
1794
|
/**
|
|
1774
|
-
*
|
|
1795
|
+
* REMOVED: archive() — the server never implemented POST /quests/{id}/archive.
|
|
1796
|
+
* To archive a quest, use update(questId, { status: 'archived' }) via PUT /quests/{id}.
|
|
1775
1797
|
*/
|
|
1776
|
-
async archive(questId) {
|
|
1777
|
-
return this.http.post(`/quests/${questId}/archive`, {});
|
|
1778
|
-
}
|
|
1779
1798
|
// ---------------------------------------------------------------------------
|
|
1780
1799
|
// User Progress
|
|
1781
1800
|
// ---------------------------------------------------------------------------
|
|
@@ -1855,28 +1874,144 @@ var QuestsClient = class {
|
|
|
1855
1874
|
// Quest Steps
|
|
1856
1875
|
// ---------------------------------------------------------------------------
|
|
1857
1876
|
/**
|
|
1858
|
-
* Add a step to a quest
|
|
1877
|
+
* Add a step to a quest.
|
|
1878
|
+
*
|
|
1879
|
+
* The server has no dedicated step-create endpoint — steps are managed via the
|
|
1880
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, appends the new
|
|
1881
|
+
* step, and issues a full update. The returned QuestStep is synthesised from the
|
|
1882
|
+
* updated quest's steps array (matched by order or last position).
|
|
1859
1883
|
*/
|
|
1860
1884
|
async addStep(questId, step) {
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1885
|
+
const quest = await this.get(questId);
|
|
1886
|
+
const newOrder = step.order ?? (quest.steps.length > 0 ? Math.max(...quest.steps.map((s) => s.order)) + 1 : 0);
|
|
1887
|
+
const stepsPayload = [
|
|
1888
|
+
...quest.steps.map((s) => ({
|
|
1889
|
+
name: s.name,
|
|
1890
|
+
description: s.description,
|
|
1891
|
+
order: s.order,
|
|
1892
|
+
step_type: s.step_type,
|
|
1893
|
+
event_type: s.event_type,
|
|
1894
|
+
event_types: s.event_types,
|
|
1895
|
+
criteria: s.criteria,
|
|
1896
|
+
required_data_fields: s.required_data_fields,
|
|
1897
|
+
step_points: s.step_points,
|
|
1898
|
+
cta_text: s.cta_text,
|
|
1899
|
+
cta_url: s.cta_url,
|
|
1900
|
+
icon_url: s.icon_url,
|
|
1901
|
+
is_optional: s.is_optional
|
|
1902
|
+
})),
|
|
1903
|
+
{ ...step, order: newOrder }
|
|
1904
|
+
];
|
|
1905
|
+
const updated = await this.update(questId, { steps: stepsPayload });
|
|
1906
|
+
const added = updated.steps.find((s) => s.order === newOrder) ?? updated.steps[updated.steps.length - 1];
|
|
1907
|
+
return added;
|
|
1908
|
+
}
|
|
1909
|
+
/**
|
|
1910
|
+
* Update a step by step ID.
|
|
1911
|
+
*
|
|
1912
|
+
* The server has no dedicated step-update endpoint — steps are managed via the
|
|
1913
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, replaces the
|
|
1914
|
+
* matching step, and issues a full update.
|
|
1865
1915
|
*/
|
|
1866
1916
|
async updateStep(questId, stepId, data) {
|
|
1867
|
-
|
|
1917
|
+
const quest = await this.get(questId);
|
|
1918
|
+
const stepsPayload = quest.steps.map((s) => {
|
|
1919
|
+
if (s.id !== stepId) {
|
|
1920
|
+
return {
|
|
1921
|
+
name: s.name,
|
|
1922
|
+
description: s.description,
|
|
1923
|
+
order: s.order,
|
|
1924
|
+
step_type: s.step_type,
|
|
1925
|
+
event_type: s.event_type,
|
|
1926
|
+
event_types: s.event_types,
|
|
1927
|
+
criteria: s.criteria,
|
|
1928
|
+
required_data_fields: s.required_data_fields,
|
|
1929
|
+
step_points: s.step_points,
|
|
1930
|
+
cta_text: s.cta_text,
|
|
1931
|
+
cta_url: s.cta_url,
|
|
1932
|
+
icon_url: s.icon_url,
|
|
1933
|
+
is_optional: s.is_optional
|
|
1934
|
+
};
|
|
1935
|
+
}
|
|
1936
|
+
return {
|
|
1937
|
+
name: s.name,
|
|
1938
|
+
description: s.description,
|
|
1939
|
+
order: s.order,
|
|
1940
|
+
step_type: s.step_type,
|
|
1941
|
+
event_type: s.event_type,
|
|
1942
|
+
event_types: s.event_types,
|
|
1943
|
+
criteria: s.criteria,
|
|
1944
|
+
required_data_fields: s.required_data_fields,
|
|
1945
|
+
step_points: s.step_points,
|
|
1946
|
+
cta_text: s.cta_text,
|
|
1947
|
+
cta_url: s.cta_url,
|
|
1948
|
+
icon_url: s.icon_url,
|
|
1949
|
+
is_optional: s.is_optional,
|
|
1950
|
+
...data
|
|
1951
|
+
};
|
|
1952
|
+
});
|
|
1953
|
+
const updated = await this.update(questId, { steps: stepsPayload });
|
|
1954
|
+
const found = updated.steps.find((s) => s.id === stepId);
|
|
1955
|
+
if (!found) throw new Error(`Step ${stepId} not found after update`);
|
|
1956
|
+
return found;
|
|
1868
1957
|
}
|
|
1869
1958
|
/**
|
|
1870
|
-
* Delete a step
|
|
1959
|
+
* Delete a step by step ID.
|
|
1960
|
+
*
|
|
1961
|
+
* The server has no dedicated step-delete endpoint — steps are managed via the
|
|
1962
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, filters out the
|
|
1963
|
+
* target step, and issues a full update.
|
|
1871
1964
|
*/
|
|
1872
1965
|
async deleteStep(questId, stepId) {
|
|
1873
|
-
await this.
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1966
|
+
const quest = await this.get(questId);
|
|
1967
|
+
const stepsPayload = quest.steps.filter((s) => s.id !== stepId).map((s) => ({
|
|
1968
|
+
name: s.name,
|
|
1969
|
+
description: s.description,
|
|
1970
|
+
order: s.order,
|
|
1971
|
+
step_type: s.step_type,
|
|
1972
|
+
event_type: s.event_type,
|
|
1973
|
+
event_types: s.event_types,
|
|
1974
|
+
criteria: s.criteria,
|
|
1975
|
+
required_data_fields: s.required_data_fields,
|
|
1976
|
+
step_points: s.step_points,
|
|
1977
|
+
cta_text: s.cta_text,
|
|
1978
|
+
cta_url: s.cta_url,
|
|
1979
|
+
icon_url: s.icon_url,
|
|
1980
|
+
is_optional: s.is_optional
|
|
1981
|
+
}));
|
|
1982
|
+
await this.update(questId, { steps: stepsPayload });
|
|
1983
|
+
}
|
|
1984
|
+
/**
|
|
1985
|
+
* Reorder steps by providing step IDs in the desired order.
|
|
1986
|
+
*
|
|
1987
|
+
* The server has no dedicated reorder endpoint — steps are managed via the
|
|
1988
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, reassigns
|
|
1989
|
+
* the `order` field according to the given stepIds sequence, and issues a
|
|
1990
|
+
* full update.
|
|
1877
1991
|
*/
|
|
1878
1992
|
async reorderSteps(questId, stepIds) {
|
|
1879
|
-
|
|
1993
|
+
const quest = await this.get(questId);
|
|
1994
|
+
const stepMap = new Map(quest.steps.map((s) => [s.id, s]));
|
|
1995
|
+
const stepsPayload = stepIds.map((id, index) => {
|
|
1996
|
+
const s = stepMap.get(id);
|
|
1997
|
+
if (!s) throw new Error(`Step ${id} not found in quest ${questId}`);
|
|
1998
|
+
return {
|
|
1999
|
+
name: s.name,
|
|
2000
|
+
description: s.description,
|
|
2001
|
+
order: index,
|
|
2002
|
+
step_type: s.step_type,
|
|
2003
|
+
event_type: s.event_type,
|
|
2004
|
+
event_types: s.event_types,
|
|
2005
|
+
criteria: s.criteria,
|
|
2006
|
+
required_data_fields: s.required_data_fields,
|
|
2007
|
+
step_points: s.step_points,
|
|
2008
|
+
cta_text: s.cta_text,
|
|
2009
|
+
cta_url: s.cta_url,
|
|
2010
|
+
icon_url: s.icon_url,
|
|
2011
|
+
is_optional: s.is_optional
|
|
2012
|
+
};
|
|
2013
|
+
});
|
|
2014
|
+
return this.update(questId, { steps: stepsPayload });
|
|
1880
2015
|
}
|
|
1881
2016
|
};
|
|
1882
2017
|
|
|
@@ -3563,5 +3698,6 @@ var EndUserIngestionClient = class {
|
|
|
3563
3698
|
VaultResource,
|
|
3564
3699
|
VerifyResource,
|
|
3565
3700
|
WalletClient,
|
|
3566
|
-
WebhooksResource
|
|
3701
|
+
WebhooksResource,
|
|
3702
|
+
tenantApiUrl
|
|
3567
3703
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -63,12 +63,19 @@ var TimeoutError = class extends ProofChainError {
|
|
|
63
63
|
var DEFAULT_BASE_URL = "https://api.proofchain.co.za";
|
|
64
64
|
var DEFAULT_TIMEOUT = 3e4;
|
|
65
65
|
var USER_AGENT = "proofchain-js/0.1.0";
|
|
66
|
+
function tenantApiUrl(slug) {
|
|
67
|
+
return `https://${slug}.proofchain.co.za/api`;
|
|
68
|
+
}
|
|
66
69
|
var HttpClient = class {
|
|
67
70
|
constructor(options) {
|
|
71
|
+
// In-flight GET de-duplication: concurrent identical GETs share one network
|
|
72
|
+
// request (and its response), cutting origin load for chatty UIs/pollers.
|
|
73
|
+
this.inflight = /* @__PURE__ */ new Map();
|
|
68
74
|
this.apiKey = options.apiKey || "";
|
|
69
75
|
this.userToken = options.userToken || "";
|
|
70
76
|
this.tenantId = options.tenantId || "";
|
|
71
|
-
|
|
77
|
+
const resolvedBase = options.baseUrl || (options.tenant ? tenantApiUrl(options.tenant) : DEFAULT_BASE_URL);
|
|
78
|
+
this.baseUrl = resolvedBase.replace(/\/$/, "");
|
|
72
79
|
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
|
73
80
|
this.maxRetries = options.maxRetries ?? 3;
|
|
74
81
|
}
|
|
@@ -133,7 +140,8 @@ var HttpClient = class {
|
|
|
133
140
|
clearTimeout(timeoutId);
|
|
134
141
|
if (error instanceof ProofChainError) {
|
|
135
142
|
if (error instanceof RateLimitError && retries < this.maxRetries) {
|
|
136
|
-
const
|
|
143
|
+
const base = Math.min((error.retryAfter || 1) * 1e3, 6e4);
|
|
144
|
+
const delay = base + Math.floor(Math.random() * 1e3);
|
|
137
145
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
138
146
|
return this.fetchWithRetry(url, options, retries + 1);
|
|
139
147
|
}
|
|
@@ -144,7 +152,9 @@ var HttpClient = class {
|
|
|
144
152
|
throw new TimeoutError();
|
|
145
153
|
}
|
|
146
154
|
if (retries < this.maxRetries) {
|
|
147
|
-
|
|
155
|
+
const base = 1e3 * (retries + 1);
|
|
156
|
+
const delay = base + Math.floor(Math.random() * 500);
|
|
157
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
148
158
|
return this.fetchWithRetry(url, options, retries + 1);
|
|
149
159
|
}
|
|
150
160
|
throw new NetworkError(error.message, error);
|
|
@@ -173,6 +183,17 @@ var HttpClient = class {
|
|
|
173
183
|
if (options.body) {
|
|
174
184
|
fetchOptions.body = JSON.stringify(options.body);
|
|
175
185
|
}
|
|
186
|
+
if (method === "GET") {
|
|
187
|
+
const existing = this.inflight.get(url);
|
|
188
|
+
if (existing) {
|
|
189
|
+
return existing;
|
|
190
|
+
}
|
|
191
|
+
const pending = this.fetchWithRetry(url, fetchOptions).finally(() => {
|
|
192
|
+
this.inflight.delete(url);
|
|
193
|
+
});
|
|
194
|
+
this.inflight.set(url, pending);
|
|
195
|
+
return pending;
|
|
196
|
+
}
|
|
176
197
|
return this.fetchWithRetry(url, fetchOptions);
|
|
177
198
|
}
|
|
178
199
|
async requestMultipart(path, formData) {
|
|
@@ -1666,11 +1687,10 @@ var QuestsClient = class {
|
|
|
1666
1687
|
return this.http.get(`/quests/available?${params.toString()}`);
|
|
1667
1688
|
}
|
|
1668
1689
|
/**
|
|
1669
|
-
*
|
|
1690
|
+
* REMOVED: getBySlug() — the server never implemented GET /quests/slug/{slug}.
|
|
1691
|
+
* There is no slug-based lookup route in the API. Use list() with a status/category
|
|
1692
|
+
* filter and find the quest client-side, or use get() with the quest ID.
|
|
1670
1693
|
*/
|
|
1671
|
-
async getBySlug(slug) {
|
|
1672
|
-
return this.http.get(`/quests/slug/${encodeURIComponent(slug)}`);
|
|
1673
|
-
}
|
|
1674
1694
|
/**
|
|
1675
1695
|
* Create a quest
|
|
1676
1696
|
*/
|
|
@@ -1711,11 +1731,9 @@ var QuestsClient = class {
|
|
|
1711
1731
|
return this.http.post(`/quests/${questId}/pause`, {});
|
|
1712
1732
|
}
|
|
1713
1733
|
/**
|
|
1714
|
-
*
|
|
1734
|
+
* REMOVED: archive() — the server never implemented POST /quests/{id}/archive.
|
|
1735
|
+
* To archive a quest, use update(questId, { status: 'archived' }) via PUT /quests/{id}.
|
|
1715
1736
|
*/
|
|
1716
|
-
async archive(questId) {
|
|
1717
|
-
return this.http.post(`/quests/${questId}/archive`, {});
|
|
1718
|
-
}
|
|
1719
1737
|
// ---------------------------------------------------------------------------
|
|
1720
1738
|
// User Progress
|
|
1721
1739
|
// ---------------------------------------------------------------------------
|
|
@@ -1795,28 +1813,144 @@ var QuestsClient = class {
|
|
|
1795
1813
|
// Quest Steps
|
|
1796
1814
|
// ---------------------------------------------------------------------------
|
|
1797
1815
|
/**
|
|
1798
|
-
* Add a step to a quest
|
|
1816
|
+
* Add a step to a quest.
|
|
1817
|
+
*
|
|
1818
|
+
* The server has no dedicated step-create endpoint — steps are managed via the
|
|
1819
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, appends the new
|
|
1820
|
+
* step, and issues a full update. The returned QuestStep is synthesised from the
|
|
1821
|
+
* updated quest's steps array (matched by order or last position).
|
|
1799
1822
|
*/
|
|
1800
1823
|
async addStep(questId, step) {
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1824
|
+
const quest = await this.get(questId);
|
|
1825
|
+
const newOrder = step.order ?? (quest.steps.length > 0 ? Math.max(...quest.steps.map((s) => s.order)) + 1 : 0);
|
|
1826
|
+
const stepsPayload = [
|
|
1827
|
+
...quest.steps.map((s) => ({
|
|
1828
|
+
name: s.name,
|
|
1829
|
+
description: s.description,
|
|
1830
|
+
order: s.order,
|
|
1831
|
+
step_type: s.step_type,
|
|
1832
|
+
event_type: s.event_type,
|
|
1833
|
+
event_types: s.event_types,
|
|
1834
|
+
criteria: s.criteria,
|
|
1835
|
+
required_data_fields: s.required_data_fields,
|
|
1836
|
+
step_points: s.step_points,
|
|
1837
|
+
cta_text: s.cta_text,
|
|
1838
|
+
cta_url: s.cta_url,
|
|
1839
|
+
icon_url: s.icon_url,
|
|
1840
|
+
is_optional: s.is_optional
|
|
1841
|
+
})),
|
|
1842
|
+
{ ...step, order: newOrder }
|
|
1843
|
+
];
|
|
1844
|
+
const updated = await this.update(questId, { steps: stepsPayload });
|
|
1845
|
+
const added = updated.steps.find((s) => s.order === newOrder) ?? updated.steps[updated.steps.length - 1];
|
|
1846
|
+
return added;
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Update a step by step ID.
|
|
1850
|
+
*
|
|
1851
|
+
* The server has no dedicated step-update endpoint — steps are managed via the
|
|
1852
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, replaces the
|
|
1853
|
+
* matching step, and issues a full update.
|
|
1805
1854
|
*/
|
|
1806
1855
|
async updateStep(questId, stepId, data) {
|
|
1807
|
-
|
|
1856
|
+
const quest = await this.get(questId);
|
|
1857
|
+
const stepsPayload = quest.steps.map((s) => {
|
|
1858
|
+
if (s.id !== stepId) {
|
|
1859
|
+
return {
|
|
1860
|
+
name: s.name,
|
|
1861
|
+
description: s.description,
|
|
1862
|
+
order: s.order,
|
|
1863
|
+
step_type: s.step_type,
|
|
1864
|
+
event_type: s.event_type,
|
|
1865
|
+
event_types: s.event_types,
|
|
1866
|
+
criteria: s.criteria,
|
|
1867
|
+
required_data_fields: s.required_data_fields,
|
|
1868
|
+
step_points: s.step_points,
|
|
1869
|
+
cta_text: s.cta_text,
|
|
1870
|
+
cta_url: s.cta_url,
|
|
1871
|
+
icon_url: s.icon_url,
|
|
1872
|
+
is_optional: s.is_optional
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1875
|
+
return {
|
|
1876
|
+
name: s.name,
|
|
1877
|
+
description: s.description,
|
|
1878
|
+
order: s.order,
|
|
1879
|
+
step_type: s.step_type,
|
|
1880
|
+
event_type: s.event_type,
|
|
1881
|
+
event_types: s.event_types,
|
|
1882
|
+
criteria: s.criteria,
|
|
1883
|
+
required_data_fields: s.required_data_fields,
|
|
1884
|
+
step_points: s.step_points,
|
|
1885
|
+
cta_text: s.cta_text,
|
|
1886
|
+
cta_url: s.cta_url,
|
|
1887
|
+
icon_url: s.icon_url,
|
|
1888
|
+
is_optional: s.is_optional,
|
|
1889
|
+
...data
|
|
1890
|
+
};
|
|
1891
|
+
});
|
|
1892
|
+
const updated = await this.update(questId, { steps: stepsPayload });
|
|
1893
|
+
const found = updated.steps.find((s) => s.id === stepId);
|
|
1894
|
+
if (!found) throw new Error(`Step ${stepId} not found after update`);
|
|
1895
|
+
return found;
|
|
1808
1896
|
}
|
|
1809
1897
|
/**
|
|
1810
|
-
* Delete a step
|
|
1898
|
+
* Delete a step by step ID.
|
|
1899
|
+
*
|
|
1900
|
+
* The server has no dedicated step-delete endpoint — steps are managed via the
|
|
1901
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, filters out the
|
|
1902
|
+
* target step, and issues a full update.
|
|
1811
1903
|
*/
|
|
1812
1904
|
async deleteStep(questId, stepId) {
|
|
1813
|
-
await this.
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1905
|
+
const quest = await this.get(questId);
|
|
1906
|
+
const stepsPayload = quest.steps.filter((s) => s.id !== stepId).map((s) => ({
|
|
1907
|
+
name: s.name,
|
|
1908
|
+
description: s.description,
|
|
1909
|
+
order: s.order,
|
|
1910
|
+
step_type: s.step_type,
|
|
1911
|
+
event_type: s.event_type,
|
|
1912
|
+
event_types: s.event_types,
|
|
1913
|
+
criteria: s.criteria,
|
|
1914
|
+
required_data_fields: s.required_data_fields,
|
|
1915
|
+
step_points: s.step_points,
|
|
1916
|
+
cta_text: s.cta_text,
|
|
1917
|
+
cta_url: s.cta_url,
|
|
1918
|
+
icon_url: s.icon_url,
|
|
1919
|
+
is_optional: s.is_optional
|
|
1920
|
+
}));
|
|
1921
|
+
await this.update(questId, { steps: stepsPayload });
|
|
1922
|
+
}
|
|
1923
|
+
/**
|
|
1924
|
+
* Reorder steps by providing step IDs in the desired order.
|
|
1925
|
+
*
|
|
1926
|
+
* The server has no dedicated reorder endpoint — steps are managed via the
|
|
1927
|
+
* full-replace PUT /quests/{id}. This method fetches the quest, reassigns
|
|
1928
|
+
* the `order` field according to the given stepIds sequence, and issues a
|
|
1929
|
+
* full update.
|
|
1817
1930
|
*/
|
|
1818
1931
|
async reorderSteps(questId, stepIds) {
|
|
1819
|
-
|
|
1932
|
+
const quest = await this.get(questId);
|
|
1933
|
+
const stepMap = new Map(quest.steps.map((s) => [s.id, s]));
|
|
1934
|
+
const stepsPayload = stepIds.map((id, index) => {
|
|
1935
|
+
const s = stepMap.get(id);
|
|
1936
|
+
if (!s) throw new Error(`Step ${id} not found in quest ${questId}`);
|
|
1937
|
+
return {
|
|
1938
|
+
name: s.name,
|
|
1939
|
+
description: s.description,
|
|
1940
|
+
order: index,
|
|
1941
|
+
step_type: s.step_type,
|
|
1942
|
+
event_type: s.event_type,
|
|
1943
|
+
event_types: s.event_types,
|
|
1944
|
+
criteria: s.criteria,
|
|
1945
|
+
required_data_fields: s.required_data_fields,
|
|
1946
|
+
step_points: s.step_points,
|
|
1947
|
+
cta_text: s.cta_text,
|
|
1948
|
+
cta_url: s.cta_url,
|
|
1949
|
+
icon_url: s.icon_url,
|
|
1950
|
+
is_optional: s.is_optional
|
|
1951
|
+
};
|
|
1952
|
+
});
|
|
1953
|
+
return this.update(questId, { steps: stepsPayload });
|
|
1820
1954
|
}
|
|
1821
1955
|
};
|
|
1822
1956
|
|
|
@@ -3502,5 +3636,6 @@ export {
|
|
|
3502
3636
|
VaultResource,
|
|
3503
3637
|
VerifyResource,
|
|
3504
3638
|
WalletClient,
|
|
3505
|
-
WebhooksResource
|
|
3639
|
+
WebhooksResource,
|
|
3640
|
+
tenantApiUrl
|
|
3506
3641
|
};
|
package/package.json
CHANGED