@croct/sdk 0.17.7 → 0.17.8
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/activeRecord.cjs.map +1 -0
- package/activeRecord.d.ts +8 -4
- package/activeRecord.js +115 -106
- package/activeRecord.js.map +1 -1
- package/apiKey.cjs.map +1 -0
- package/apiKey.d.ts +4 -2
- package/apiKey.js +152 -141
- package/apiKey.js.map +1 -1
- package/base64Url.cjs.map +1 -0
- package/base64Url.d.ts +4 -2
- package/base64Url.js +8 -15
- package/base64Url.js.map +1 -1
- package/cache/cache.cjs.map +1 -0
- package/cache/cache.d.ts +6 -4
- package/cache/cache.js +9 -10
- package/cache/cache.js.map +1 -1
- package/cache/cookieCache.cjs.map +1 -0
- package/cache/cookieCache.d.ts +6 -3
- package/cache/cookieCache.js +52 -54
- package/cache/cookieCache.js.map +1 -1
- package/cache/fallbackCache.cjs.map +1 -0
- package/cache/fallbackCache.d.ts +5 -2
- package/cache/fallbackCache.js +20 -21
- package/cache/fallbackCache.js.map +1 -1
- package/cache/inMemoryCache.cjs.map +1 -0
- package/cache/inMemoryCache.d.ts +5 -2
- package/cache/inMemoryCache.js +15 -17
- package/cache/inMemoryCache.js.map +1 -1
- package/cache/index.cjs.map +1 -0
- package/cache/index.d.ts +4 -4
- package/cache/index.js +9 -11
- package/cache/index.js.map +1 -1
- package/cache/localStorageCache.cjs.map +1 -0
- package/cache/localStorageCache.d.ts +5 -2
- package/cache/localStorageCache.js +55 -63
- package/cache/localStorageCache.js.map +1 -1
- package/channel/channel.cjs.map +1 -0
- package/channel/channel.d.ts +8 -6
- package/channel/channel.js +21 -22
- package/channel/channel.js.map +1 -1
- package/channel/encodedChannel.cjs.map +1 -0
- package/channel/encodedChannel.d.ts +6 -3
- package/channel/encodedChannel.js +13 -14
- package/channel/encodedChannel.js.map +1 -1
- package/channel/guaranteedChannel.cjs.map +1 -0
- package/channel/guaranteedChannel.d.ts +9 -7
- package/channel/guaranteedChannel.js +74 -73
- package/channel/guaranteedChannel.js.map +1 -1
- package/channel/httpBeaconChannel.cjs.map +1 -0
- package/channel/httpBeaconChannel.d.ts +9 -6
- package/channel/httpBeaconChannel.js +82 -83
- package/channel/httpBeaconChannel.js.map +1 -1
- package/channel/index.cjs.map +1 -0
- package/channel/index.d.ts +12 -7
- package/channel/index.js +15 -17
- package/channel/index.js.map +1 -1
- package/channel/queuedChannel.cjs.map +1 -0
- package/channel/queuedChannel.d.ts +7 -4
- package/channel/queuedChannel.js +87 -97
- package/channel/queuedChannel.js.map +1 -1
- package/channel/retryChannel.cjs.map +1 -0
- package/channel/retryChannel.d.ts +7 -5
- package/channel/retryChannel.js +58 -57
- package/channel/retryChannel.js.map +1 -1
- package/channel/sandboxChannel.cjs.map +1 -0
- package/channel/sandboxChannel.d.ts +5 -2
- package/channel/sandboxChannel.js +34 -35
- package/channel/sandboxChannel.js.map +1 -1
- package/cid/assigner.cjs.map +1 -0
- package/cid/assigner.d.ts +3 -1
- package/cid/assigner.js +0 -2
- package/cid/assigner.js.map +1 -1
- package/cid/cachedAssigner.cjs.map +1 -0
- package/cid/cachedAssigner.d.ts +7 -5
- package/cid/cachedAssigner.js +37 -43
- package/cid/cachedAssigner.js.map +1 -1
- package/cid/fixedAssigner.cjs.map +1 -0
- package/cid/fixedAssigner.d.ts +5 -2
- package/cid/fixedAssigner.js +9 -10
- package/cid/fixedAssigner.js.map +1 -1
- package/cid/index.cjs.map +1 -0
- package/cid/index.d.ts +6 -4
- package/cid/index.js +9 -11
- package/cid/index.js.map +1 -1
- package/cid/remoteAssigner.cjs.map +1 -0
- package/cid/remoteAssigner.d.ts +6 -3
- package/cid/remoteAssigner.js +36 -37
- package/cid/remoteAssigner.js.map +1 -1
- package/constants.cjs.map +1 -0
- package/constants.d.ts +6 -4
- package/constants.js +10 -7
- package/constants.js.map +1 -1
- package/container.cjs.map +1 -0
- package/container.d.ts +28 -15
- package/container.js +269 -252
- package/container.js.map +1 -1
- package/contentFetcher.cjs.map +1 -0
- package/contentFetcher.d.ts +17 -14
- package/contentFetcher.js +156 -163
- package/contentFetcher.js.map +1 -1
- package/context.cjs.map +1 -0
- package/context.d.ts +13 -9
- package/context.js +80 -81
- package/context.js.map +1 -1
- package/error.cjs.map +1 -0
- package/error.d.ts +4 -2
- package/error.js +21 -21
- package/error.js.map +1 -1
- package/evaluator.cjs.map +1 -0
- package/evaluator.d.ts +18 -16
- package/evaluator.js +179 -179
- package/evaluator.js.map +1 -1
- package/eventManager.cjs.map +1 -0
- package/eventManager.d.ts +8 -6
- package/eventManager.js +24 -26
- package/eventManager.js.map +1 -1
- package/eventSubjectProcessor.cjs.map +1 -0
- package/eventSubjectProcessor.d.ts +16 -3
- package/eventSubjectProcessor.js +53 -59
- package/eventSubjectProcessor.js.map +1 -1
- package/facade/contentFetcherFacade.cjs.map +1 -0
- package/facade/contentFetcherFacade.d.ts +16 -7
- package/facade/contentFetcherFacade.js +32 -35
- package/facade/contentFetcherFacade.js.map +1 -1
- package/facade/evaluatorFacade.cjs.map +1 -0
- package/facade/evaluatorFacade.d.ts +17 -10
- package/facade/evaluatorFacade.js +56 -60
- package/facade/evaluatorFacade.js.map +1 -1
- package/facade/index.cjs.map +1 -0
- package/facade/index.d.ts +29 -7
- package/facade/index.js +19 -19
- package/facade/index.js.map +1 -1
- package/facade/sdkFacade.cjs.map +1 -0
- package/facade/sdkFacade.d.ts +33 -15
- package/facade/sdkFacade.js +201 -214
- package/facade/sdkFacade.js.map +1 -1
- package/facade/sessionFacade.cjs.map +1 -0
- package/facade/sessionFacade.d.ts +18 -3
- package/facade/sessionFacade.js +10 -11
- package/facade/sessionFacade.js.map +1 -1
- package/facade/sessionPatch.cjs.map +1 -0
- package/facade/sessionPatch.d.ts +17 -4
- package/facade/sessionPatch.js +22 -24
- package/facade/sessionPatch.js.map +1 -1
- package/facade/trackerFacade.cjs.map +1 -0
- package/facade/trackerFacade.d.ts +17 -4
- package/facade/trackerFacade.js +67 -57
- package/facade/trackerFacade.js.map +1 -1
- package/facade/userFacade.cjs.map +1 -0
- package/facade/userFacade.d.ts +21 -4
- package/facade/userFacade.js +17 -18
- package/facade/userFacade.js.map +1 -1
- package/facade/userPatch.cjs.map +1 -0
- package/facade/userPatch.d.ts +17 -4
- package/facade/userPatch.js +22 -24
- package/facade/userPatch.js.map +1 -1
- package/help.cjs.map +1 -0
- package/help.d.ts +3 -1
- package/help.js +19 -23
- package/help.js.map +1 -1
- package/index.cjs.map +1 -0
- package/index.d.ts +25 -3
- package/index.js +7 -7
- package/index.js.map +1 -1
- package/logging/consoleLogger.cjs.map +1 -0
- package/logging/consoleLogger.d.ts +5 -2
- package/logging/consoleLogger.js +23 -24
- package/logging/consoleLogger.js.map +1 -1
- package/logging/filteredLogger.cjs.map +1 -0
- package/logging/filteredLogger.d.ts +8 -5
- package/logging/filteredLogger.js +36 -37
- package/logging/filteredLogger.js.map +1 -1
- package/logging/index.cjs.map +1 -0
- package/logging/index.d.ts +5 -5
- package/logging/index.js +11 -13
- package/logging/index.js.map +1 -1
- package/logging/logger.cjs.map +1 -0
- package/logging/logger.d.ts +4 -2
- package/logging/logger.js +0 -2
- package/logging/logger.js.map +1 -1
- package/logging/namespacedLogger.cjs.map +1 -0
- package/logging/namespacedLogger.d.ts +5 -2
- package/logging/namespacedLogger.js +22 -23
- package/logging/namespacedLogger.js.map +1 -1
- package/logging/nullLogger.cjs.map +1 -0
- package/logging/nullLogger.d.ts +5 -2
- package/logging/nullLogger.js +11 -16
- package/logging/nullLogger.js.map +1 -1
- package/namespacedStorage.cjs.map +1 -0
- package/namespacedStorage.d.ts +3 -1
- package/namespacedStorage.js +51 -52
- package/namespacedStorage.js.map +1 -1
- package/package.json +60 -6
- package/patch.cjs.map +1 -0
- package/patch.d.ts +6 -4
- package/patch.js +0 -2
- package/patch.js.map +1 -1
- package/queue/capacityRestrictedQueue.cjs.map +1 -0
- package/queue/capacityRestrictedQueue.d.ts +5 -2
- package/queue/capacityRestrictedQueue.js +31 -32
- package/queue/capacityRestrictedQueue.js.map +1 -1
- package/queue/inMemoryQueue.cjs.map +1 -0
- package/queue/inMemoryQueue.d.ts +5 -2
- package/queue/inMemoryQueue.js +32 -34
- package/queue/inMemoryQueue.js.map +1 -1
- package/queue/index.cjs.map +1 -0
- package/queue/index.d.ts +6 -5
- package/queue/index.js +11 -13
- package/queue/index.js.map +1 -1
- package/queue/monitoredQueue.cjs.map +1 -0
- package/queue/monitoredQueue.d.ts +8 -5
- package/queue/monitoredQueue.js +104 -110
- package/queue/monitoredQueue.js.map +1 -1
- package/queue/persistentQueue.cjs.map +1 -0
- package/queue/persistentQueue.d.ts +5 -2
- package/queue/persistentQueue.js +52 -54
- package/queue/persistentQueue.js.map +1 -1
- package/queue/queue.cjs.map +1 -0
- package/queue/queue.d.ts +3 -1
- package/queue/queue.js +0 -2
- package/queue/queue.js.map +1 -1
- package/retry/arbitraryPolicy.cjs.map +1 -0
- package/retry/arbitraryPolicy.d.ts +5 -2
- package/retry/arbitraryPolicy.js +14 -15
- package/retry/arbitraryPolicy.js.map +1 -1
- package/retry/backoffPolicy.cjs.map +1 -0
- package/retry/backoffPolicy.d.ts +5 -3
- package/retry/backoffPolicy.js +52 -50
- package/retry/backoffPolicy.js.map +1 -1
- package/retry/index.cjs.map +1 -0
- package/retry/index.d.ts +5 -5
- package/retry/index.js +11 -13
- package/retry/index.js.map +1 -1
- package/retry/maxAttemptsPolicy.cjs.map +1 -0
- package/retry/maxAttemptsPolicy.d.ts +5 -2
- package/retry/maxAttemptsPolicy.js +17 -18
- package/retry/maxAttemptsPolicy.js.map +1 -1
- package/retry/neverPolicy.cjs.map +1 -0
- package/retry/neverPolicy.d.ts +5 -2
- package/retry/neverPolicy.js +9 -10
- package/retry/neverPolicy.js.map +1 -1
- package/retry/policy.cjs.map +1 -0
- package/retry/policy.d.ts +3 -1
- package/retry/policy.js +0 -2
- package/retry/policy.js.map +1 -1
- package/schema/attributeSchema.cjs.map +1 -0
- package/schema/attributeSchema.d.ts +6 -2
- package/schema/attributeSchema.js +7 -7
- package/schema/attributeSchema.js.map +1 -1
- package/schema/contentFetcherSchemas.cjs.map +1 -0
- package/schema/contentFetcherSchemas.d.ts +6 -2
- package/schema/contentFetcherSchemas.js +24 -21
- package/schema/contentFetcherSchemas.js.map +1 -1
- package/schema/contentSchemas.cjs.map +1 -0
- package/schema/contentSchemas.d.ts +6 -2
- package/schema/contentSchemas.js +45 -45
- package/schema/contentSchemas.js.map +1 -1
- package/schema/contextSchemas.cjs.map +1 -0
- package/schema/contextSchemas.d.ts +6 -2
- package/schema/contextSchemas.js +6 -6
- package/schema/contextSchemas.js.map +1 -1
- package/schema/ecommerceSchemas.cjs.map +1 -0
- package/schema/ecommerceSchemas.d.ts +10 -6
- package/schema/ecommerceSchemas.js +176 -172
- package/schema/ecommerceSchemas.js.map +1 -1
- package/schema/evaluatorSchemas.cjs.map +1 -0
- package/schema/evaluatorSchemas.d.ts +6 -2
- package/schema/evaluatorSchemas.js +46 -30
- package/schema/evaluatorSchemas.js.map +1 -1
- package/schema/eventSchemas.cjs.map +1 -0
- package/schema/eventSchemas.d.ts +16 -12
- package/schema/eventSchemas.js +125 -102
- package/schema/eventSchemas.js.map +1 -1
- package/schema/index.cjs.map +1 -0
- package/schema/index.d.ts +14 -11
- package/schema/index.js +11 -14
- package/schema/index.js.map +1 -1
- package/schema/loggerSchema.cjs.map +1 -0
- package/schema/loggerSchema.d.ts +6 -2
- package/schema/loggerSchema.js +13 -13
- package/schema/loggerSchema.js.map +1 -1
- package/schema/operationSchemas.cjs.map +1 -0
- package/schema/operationSchemas.d.ts +14 -10
- package/schema/operationSchemas.js +85 -69
- package/schema/operationSchemas.js.map +1 -1
- package/schema/sdkFacadeSchemas.cjs.map +1 -0
- package/schema/sdkFacadeSchemas.d.ts +6 -2
- package/schema/sdkFacadeSchemas.js +65 -51
- package/schema/sdkFacadeSchemas.js.map +1 -1
- package/schema/sdkSchemas.cjs.map +1 -0
- package/schema/sdkSchemas.d.ts +8 -4
- package/schema/sdkSchemas.js +80 -78
- package/schema/sdkSchemas.js.map +1 -1
- package/schema/tokenSchema.cjs.map +1 -0
- package/schema/tokenSchema.d.ts +6 -2
- package/schema/tokenSchema.js +41 -38
- package/schema/tokenSchema.js.map +1 -1
- package/schema/userSchema.cjs.map +1 -0
- package/schema/userSchema.d.ts +6 -2
- package/schema/userSchema.js +183 -134
- package/schema/userSchema.js.map +1 -1
- package/sdk.cjs.map +1 -0
- package/sdk.d.ts +28 -14
- package/sdk.js +106 -108
- package/sdk.js.map +1 -1
- package/sdkEvents.cjs.map +1 -0
- package/sdkEvents.d.ts +10 -5
- package/sdkEvents.js +0 -2
- package/sdkEvents.js.map +1 -1
- package/sourceLocation.cjs.map +1 -0
- package/sourceLocation.d.ts +7 -5
- package/sourceLocation.js +56 -57
- package/sourceLocation.js.map +1 -1
- package/tab.cjs.map +1 -0
- package/tab.d.ts +9 -7
- package/tab.js +93 -90
- package/tab.js.map +1 -1
- package/token/cachedTokenStore.cjs.map +1 -0
- package/token/cachedTokenStore.d.ts +8 -3
- package/token/cachedTokenStore.js +22 -24
- package/token/cachedTokenStore.js.map +1 -1
- package/token/inMemoryTokenStore.cjs.map +1 -0
- package/token/inMemoryTokenStore.d.ts +7 -2
- package/token/inMemoryTokenStore.js +12 -13
- package/token/inMemoryTokenStore.js.map +1 -1
- package/token/index.cjs.map +1 -0
- package/token/index.d.ts +7 -4
- package/token/index.js +9 -11
- package/token/index.js.map +1 -1
- package/token/replicatedTokenStore.cjs.map +1 -0
- package/token/replicatedTokenStore.d.ts +7 -2
- package/token/replicatedTokenStore.js +14 -15
- package/token/replicatedTokenStore.js.map +1 -1
- package/token/token.cjs.map +1 -0
- package/token/token.d.ts +11 -8
- package/token/token.js +212 -195
- package/token/token.js.map +1 -1
- package/tracker.cjs.map +1 -0
- package/tracker.d.ts +20 -13
- package/tracker.js +307 -307
- package/tracker.js.map +1 -1
- package/trackingEvents.cjs.map +1 -0
- package/trackingEvents.d.ts +65 -62
- package/trackingEvents.js +57 -56
- package/trackingEvents.js.map +1 -1
- package/transformer.cjs.map +1 -0
- package/transformer.d.ts +4 -2
- package/transformer.js +5 -6
- package/transformer.js.map +1 -1
- package/utilityTypes.cjs.map +1 -0
- package/utilityTypes.d.ts +4 -2
- package/utilityTypes.js +0 -2
- package/utilityTypes.js.map +1 -1
- package/uuid.cjs.map +1 -0
- package/uuid.d.ts +3 -1
- package/uuid.js +27 -32
- package/uuid.js.map +1 -1
- package/validation/arrayType.cjs.map +1 -0
- package/validation/arrayType.d.ts +5 -3
- package/validation/arrayType.js +45 -41
- package/validation/arrayType.js.map +1 -1
- package/validation/booleanType.cjs.map +1 -0
- package/validation/booleanType.d.ts +5 -2
- package/validation/booleanType.js +19 -16
- package/validation/booleanType.js.map +1 -1
- package/validation/functionType.cjs.map +1 -0
- package/validation/functionType.d.ts +5 -2
- package/validation/functionType.js +19 -16
- package/validation/functionType.js.map +1 -1
- package/validation/index.cjs.map +1 -0
- package/validation/index.d.ts +12 -12
- package/validation/index.js +27 -29
- package/validation/index.js.map +1 -1
- package/validation/jsonType.cjs.map +1 -0
- package/validation/jsonType.d.ts +8 -6
- package/validation/jsonType.js +89 -82
- package/validation/jsonType.js.map +1 -1
- package/validation/mixedSchema.cjs.map +1 -0
- package/validation/mixedSchema.d.ts +5 -2
- package/validation/mixedSchema.js +5 -7
- package/validation/mixedSchema.js.map +1 -1
- package/validation/nullType.cjs.map +1 -0
- package/validation/nullType.d.ts +5 -2
- package/validation/nullType.js +19 -16
- package/validation/nullType.js.map +1 -1
- package/validation/numberType.cjs.map +1 -0
- package/validation/numberType.d.ts +5 -3
- package/validation/numberType.js +40 -32
- package/validation/numberType.js.map +1 -1
- package/validation/objectType.cjs.map +1 -0
- package/validation/objectType.d.ts +5 -3
- package/validation/objectType.js +84 -85
- package/validation/objectType.js.map +1 -1
- package/validation/schema.cjs.map +1 -0
- package/validation/schema.d.ts +5 -3
- package/validation/schema.js +8 -9
- package/validation/schema.js.map +1 -1
- package/validation/stringType.cjs.map +1 -0
- package/validation/stringType.d.ts +5 -3
- package/validation/stringType.js +74 -70
- package/validation/stringType.js.map +1 -1
- package/validation/unionType.cjs.map +1 -0
- package/validation/unionType.d.ts +5 -2
- package/validation/unionType.js +37 -35
- package/validation/unionType.js.map +1 -1
- package/validation/violation.cjs.map +1 -0
- package/validation/violation.d.ts +4 -2
- package/validation/violation.js +18 -18
- package/validation/violation.js.map +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/contentFetcher.ts"],"sourcesContent":["import {JsonObject} from '@croct/json';\nimport {EvaluationContext} from './evaluator';\nimport {Token} from './token';\nimport {BASE_ENDPOINT_URL, CLIENT_LIBRARY} from './constants';\nimport {formatMessage} from './error';\nimport {Logger, NullLogger} from './logging';\nimport type {ApiKey} from './apiKey';\nimport {Help} from './help';\n\nexport type ErrorResponse = {\n type: string,\n title: string,\n status: number,\n detail?: string,\n};\n\nexport enum ContentErrorType {\n TIMEOUT = 'https://croct.help/api/content#timeout',\n UNEXPECTED_ERROR = 'https://croct.help/api/content#unexpected-error',\n}\n\ntype FetchPayload = {\n slotId: string,\n version?: string,\n preferredLocale?: string,\n previewToken?: string,\n context?: EvaluationContext,\n};\n\nexport class ContentError<T extends ErrorResponse = ErrorResponse> extends Error {\n public readonly response: T;\n\n public constructor(response: T) {\n super(response.title);\n\n this.response = response;\n\n Object.setPrototypeOf(this, ContentError.prototype);\n }\n}\n\ntype BasicOptions = {\n version?: `${number}` | number,\n preferredLocale?: string,\n timeout?: number,\n extra?: ExtraFetchOptions,\n};\n\nexport type StaticContentOptions = BasicOptions & {\n static: true,\n};\n\nexport type DynamicContentOptions = BasicOptions & {\n static?: false,\n clientId?: string,\n clientIp?: string,\n clientAgent?: string,\n userToken?: Token|string,\n previewToken?: Token|string,\n context?: EvaluationContext,\n};\n\ntype AllowedFetchOptions = Exclude<keyof RequestInit, 'method' | 'body' | 'headers' | 'signal'>;\n\ntype ExtraFetchOptions<T extends keyof RequestInit = AllowedFetchOptions> = Pick<RequestInit, T>\n & {[key in Exclude<keyof RequestInit, T>]?: never}\n & Record<string, any>;\n\nexport type FetchOptions = StaticContentOptions | DynamicContentOptions;\n\nexport type FetchResponse<P extends JsonObject = JsonObject> = {\n content: P,\n};\n\nexport type Configuration = {\n appId?: string,\n apiKey?: string|ApiKey,\n baseEndpointUrl?: string,\n logger?: Logger,\n defaultTimeout?: number,\n defaultPreferredLocale?: string,\n};\n\ntype InternalConfiguration = {\n appId?: string,\n apiKey?: string,\n defaultTimeout?: number,\n defaultPreferredLocale?: string,\n};\n\nexport class ContentFetcher {\n private readonly configuration: InternalConfiguration;\n\n private readonly dynamicEndpoint: string;\n\n private readonly staticEndpoint: string;\n\n private readonly logger: Logger;\n\n public constructor(configuration: Configuration) {\n if ((configuration.appId === undefined) === (configuration.apiKey === undefined)) {\n throw new Error('Either the application ID or the API key must be provided.');\n }\n\n const {baseEndpointUrl} = configuration;\n const apiKey = typeof configuration.apiKey === 'object'\n ? configuration.apiKey.getIdentifier()\n : configuration.apiKey;\n\n // eslint-disable-next-line prefer-template -- Better readability\n const baseEndpoint = (baseEndpointUrl ?? BASE_ENDPOINT_URL).replace(/\\/+$/, '')\n + (apiKey === undefined ? '/client' : '/external')\n + '/web';\n\n this.dynamicEndpoint = `${baseEndpoint}/content`;\n this.staticEndpoint = `${baseEndpoint}/static-content`;\n this.logger = configuration.logger ?? new NullLogger();\n this.configuration = {\n appId: configuration.appId,\n apiKey: apiKey,\n defaultTimeout: configuration.defaultTimeout,\n defaultPreferredLocale: configuration.defaultPreferredLocale,\n };\n }\n\n public fetch<P extends JsonObject>(slotId: string, options: FetchOptions = {}): Promise<FetchResponse<P>> {\n if (options.static === true && this.configuration.apiKey === undefined) {\n throw new Error('The API key must be provided to fetch static content.');\n }\n\n return new Promise<FetchResponse<P>>((resolve, reject) => {\n const abortController = new AbortController();\n const timeout = options.timeout ?? this.configuration.defaultTimeout;\n\n let timer: number | NodeJS.Timeout | undefined;\n\n if (timeout !== undefined) {\n timer = setTimeout(\n () => {\n const response: ErrorResponse = {\n title: `Content could not be loaded in time for slot '${slotId}'.`,\n type: ContentErrorType.TIMEOUT,\n detail: `The content took more than ${timeout}ms to load.`,\n status: 408, // Request Timeout\n };\n\n abortController.abort();\n\n this.logHelp(response.status);\n\n reject(new ContentError(response));\n },\n timeout,\n );\n }\n\n this.load(slotId, abortController.signal, options)\n .finally(() => clearTimeout(timer))\n .then(response => {\n const region = response.headers.get('X-Croct-Region');\n const timing = response.headers.get('X-Croct-Timing');\n\n this.logger.debug(`Content for slot '${slotId}' processed by region ${region} in ${timing}.`);\n\n return response.json()\n .then(body => {\n if (response.ok) {\n return resolve(body);\n }\n\n this.logHelp(response.status);\n\n reject(new ContentError(body));\n })\n .catch(error => {\n if (!response.ok) {\n throw new Error(`Error ${response.status} - ${response.statusText}`);\n }\n\n throw error;\n });\n })\n .catch(error => {\n if (!abortController.signal.aborted) {\n reject(\n new ContentError({\n title: formatMessage(error),\n type: ContentErrorType.UNEXPECTED_ERROR,\n detail: 'Please try again or contact Croct support if the error persists.',\n status: 500, // Internal Server Error\n }),\n );\n }\n });\n });\n }\n\n private load(slotId: string, signal: AbortSignal, options: FetchOptions): Promise<Response> {\n const {apiKey, appId} = this.configuration;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n headers['X-Client-Library'] = CLIENT_LIBRARY;\n\n if (appId !== undefined) {\n headers['X-App-Id'] = appId;\n }\n\n if (apiKey !== undefined) {\n headers['X-Api-Key'] = apiKey;\n }\n\n const payload: FetchPayload = {\n slotId: slotId,\n };\n\n if (options.version !== undefined) {\n payload.version = `${options.version}`;\n }\n\n const preferredLocale = options.preferredLocale ?? this.configuration.defaultPreferredLocale;\n\n if (preferredLocale !== undefined) {\n payload.preferredLocale = preferredLocale;\n }\n\n const dynamic = ContentFetcher.isDynamicContent(options);\n\n if (dynamic) {\n if (options.clientId !== undefined) {\n headers['X-Client-Id'] = options.clientId;\n }\n\n if (options.clientIp !== undefined) {\n headers['X-Client-Ip'] = options.clientIp;\n }\n\n if (options.userToken !== undefined) {\n headers['X-Token'] = options.userToken.toString();\n }\n\n if (options.clientAgent !== undefined) {\n headers['X-Client-Agent'] = options.clientAgent;\n }\n\n if (options.context !== undefined) {\n payload.context = options.context;\n }\n\n if (options.previewToken !== undefined) {\n payload.previewToken = `${options.previewToken}`;\n }\n }\n\n return fetch(dynamic ? this.dynamicEndpoint : this.staticEndpoint, {\n // Set the request mode to 'cors' when running in the browser.\n // By default, the request mode is computed based on the referrer policy\n // and response-tainting rules applied to the script that ultimately\n // initiated the fetch, make this prone to errors due to unrelated\n // configurations on the page.\n // https://fetch.spec.whatwg.org/#origin-header\n mode: typeof window === 'undefined' ? undefined : 'cors',\n credentials: 'omit',\n ...options.extra,\n method: 'POST',\n headers: headers,\n signal: signal,\n body: JSON.stringify(payload),\n });\n }\n\n private logHelp(statusCode: number): void {\n const help = Help.forStatusCode(statusCode);\n\n if (help !== undefined) {\n this.logger.error(help);\n }\n }\n\n private static isDynamicContent(options: FetchOptions): options is DynamicContentOptions {\n return options.static !== true;\n }\n\n public toJSON(): never {\n // Prevent sensitive configuration from being serialized\n throw new Error('Unserializable value.');\n }\n}\n"],"mappings":"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","names":["ContentErrorType"]}
|
package/contentFetcher.d.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { JsonObject } from '@croct/json';
|
|
2
|
-
import { EvaluationContext } from './evaluator';
|
|
3
|
-
import { Token } from './token';
|
|
4
|
-
import { Logger } from './logging';
|
|
5
|
-
import
|
|
6
|
-
|
|
2
|
+
import { EvaluationContext } from './evaluator.js';
|
|
3
|
+
import { Token } from './token/token.js';
|
|
4
|
+
import { Logger } from './logging/logger.js';
|
|
5
|
+
import { ApiKey } from './apiKey.js';
|
|
6
|
+
import './sourceLocation.js';
|
|
7
|
+
|
|
8
|
+
type ErrorResponse = {
|
|
7
9
|
type: string;
|
|
8
10
|
title: string;
|
|
9
11
|
status: number;
|
|
10
12
|
detail?: string;
|
|
11
13
|
};
|
|
12
|
-
|
|
14
|
+
declare enum ContentErrorType {
|
|
13
15
|
TIMEOUT = "https://croct.help/api/content#timeout",
|
|
14
16
|
UNEXPECTED_ERROR = "https://croct.help/api/content#unexpected-error"
|
|
15
17
|
}
|
|
16
|
-
|
|
18
|
+
declare class ContentError<T extends ErrorResponse = ErrorResponse> extends Error {
|
|
17
19
|
readonly response: T;
|
|
18
20
|
constructor(response: T);
|
|
19
21
|
}
|
|
@@ -23,10 +25,10 @@ type BasicOptions = {
|
|
|
23
25
|
timeout?: number;
|
|
24
26
|
extra?: ExtraFetchOptions;
|
|
25
27
|
};
|
|
26
|
-
|
|
28
|
+
type StaticContentOptions = BasicOptions & {
|
|
27
29
|
static: true;
|
|
28
30
|
};
|
|
29
|
-
|
|
31
|
+
type DynamicContentOptions = BasicOptions & {
|
|
30
32
|
static?: false;
|
|
31
33
|
clientId?: string;
|
|
32
34
|
clientIp?: string;
|
|
@@ -39,11 +41,11 @@ type AllowedFetchOptions = Exclude<keyof RequestInit, 'method' | 'body' | 'heade
|
|
|
39
41
|
type ExtraFetchOptions<T extends keyof RequestInit = AllowedFetchOptions> = Pick<RequestInit, T> & {
|
|
40
42
|
[key in Exclude<keyof RequestInit, T>]?: never;
|
|
41
43
|
} & Record<string, any>;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
type FetchOptions = StaticContentOptions | DynamicContentOptions;
|
|
45
|
+
type FetchResponse<P extends JsonObject = JsonObject> = {
|
|
44
46
|
content: P;
|
|
45
47
|
};
|
|
46
|
-
|
|
48
|
+
type Configuration = {
|
|
47
49
|
appId?: string;
|
|
48
50
|
apiKey?: string | ApiKey;
|
|
49
51
|
baseEndpointUrl?: string;
|
|
@@ -51,7 +53,7 @@ export type Configuration = {
|
|
|
51
53
|
defaultTimeout?: number;
|
|
52
54
|
defaultPreferredLocale?: string;
|
|
53
55
|
};
|
|
54
|
-
|
|
56
|
+
declare class ContentFetcher {
|
|
55
57
|
private readonly configuration;
|
|
56
58
|
private readonly dynamicEndpoint;
|
|
57
59
|
private readonly staticEndpoint;
|
|
@@ -63,4 +65,5 @@ export declare class ContentFetcher {
|
|
|
63
65
|
private static isDynamicContent;
|
|
64
66
|
toJSON(): never;
|
|
65
67
|
}
|
|
66
|
-
|
|
68
|
+
|
|
69
|
+
export { type Configuration, ContentError, ContentErrorType, ContentFetcher, type DynamicContentOptions, type ErrorResponse, type FetchOptions, type FetchResponse, type StaticContentOptions };
|
package/contentFetcher.js
CHANGED
|
@@ -1,175 +1,168 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
(
|
|
10
|
-
ContentErrorType["TIMEOUT"] = "https://croct.help/api/content#timeout";
|
|
11
|
-
ContentErrorType["UNEXPECTED_ERROR"] = "https://croct.help/api/content#unexpected-error";
|
|
12
|
-
})(ContentErrorType || (exports.ContentErrorType = ContentErrorType = {}));
|
|
1
|
+
import { BASE_ENDPOINT_URL, CLIENT_LIBRARY } from "./constants";
|
|
2
|
+
import { formatMessage } from "./error";
|
|
3
|
+
import { NullLogger } from "./logging";
|
|
4
|
+
import { Help } from "./help";
|
|
5
|
+
var ContentErrorType = /* @__PURE__ */ ((ContentErrorType2) => {
|
|
6
|
+
ContentErrorType2["TIMEOUT"] = "https://croct.help/api/content#timeout";
|
|
7
|
+
ContentErrorType2["UNEXPECTED_ERROR"] = "https://croct.help/api/content#unexpected-error";
|
|
8
|
+
return ContentErrorType2;
|
|
9
|
+
})(ContentErrorType || {});
|
|
13
10
|
class ContentError extends Error {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
constructor(response) {
|
|
12
|
+
super(response.title);
|
|
13
|
+
this.response = response;
|
|
14
|
+
Object.setPrototypeOf(this, ContentError.prototype);
|
|
15
|
+
}
|
|
19
16
|
}
|
|
20
|
-
exports.ContentError = ContentError;
|
|
21
17
|
class ContentFetcher {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
throw new Error('Either the application ID or the API key must be provided.');
|
|
26
|
-
}
|
|
27
|
-
const { baseEndpointUrl } = configuration;
|
|
28
|
-
const apiKey = typeof configuration.apiKey === 'object'
|
|
29
|
-
? configuration.apiKey.getIdentifier()
|
|
30
|
-
: configuration.apiKey;
|
|
31
|
-
// eslint-disable-next-line prefer-template -- Better readability
|
|
32
|
-
const baseEndpoint = (baseEndpointUrl !== null && baseEndpointUrl !== void 0 ? baseEndpointUrl : constants_1.BASE_ENDPOINT_URL).replace(/\/+$/, '')
|
|
33
|
-
+ (apiKey === undefined ? '/client' : '/external')
|
|
34
|
-
+ '/web';
|
|
35
|
-
this.dynamicEndpoint = `${baseEndpoint}/content`;
|
|
36
|
-
this.staticEndpoint = `${baseEndpoint}/static-content`;
|
|
37
|
-
this.logger = (_a = configuration.logger) !== null && _a !== void 0 ? _a : new logging_1.NullLogger();
|
|
38
|
-
this.configuration = {
|
|
39
|
-
appId: configuration.appId,
|
|
40
|
-
apiKey: apiKey,
|
|
41
|
-
defaultTimeout: configuration.defaultTimeout,
|
|
42
|
-
defaultPreferredLocale: configuration.defaultPreferredLocale,
|
|
43
|
-
};
|
|
18
|
+
constructor(configuration) {
|
|
19
|
+
if (configuration.appId === void 0 === (configuration.apiKey === void 0)) {
|
|
20
|
+
throw new Error("Either the application ID or the API key must be provided.");
|
|
44
21
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
abortController.abort();
|
|
63
|
-
this.logHelp(response.status);
|
|
64
|
-
reject(new ContentError(response));
|
|
65
|
-
}, timeout);
|
|
66
|
-
}
|
|
67
|
-
this.load(slotId, abortController.signal, options)
|
|
68
|
-
.finally(() => clearTimeout(timer))
|
|
69
|
-
.then(response => {
|
|
70
|
-
const region = response.headers.get('X-Croct-Region');
|
|
71
|
-
const timing = response.headers.get('X-Croct-Timing');
|
|
72
|
-
this.logger.debug(`Content for slot '${slotId}' processed by region ${region} in ${timing}.`);
|
|
73
|
-
return response.json()
|
|
74
|
-
.then(body => {
|
|
75
|
-
if (response.ok) {
|
|
76
|
-
return resolve(body);
|
|
77
|
-
}
|
|
78
|
-
this.logHelp(response.status);
|
|
79
|
-
reject(new ContentError(body));
|
|
80
|
-
})
|
|
81
|
-
.catch(error => {
|
|
82
|
-
if (!response.ok) {
|
|
83
|
-
throw new Error(`Error ${response.status} - ${response.statusText}`);
|
|
84
|
-
}
|
|
85
|
-
throw error;
|
|
86
|
-
});
|
|
87
|
-
})
|
|
88
|
-
.catch(error => {
|
|
89
|
-
if (!abortController.signal.aborted) {
|
|
90
|
-
reject(new ContentError({
|
|
91
|
-
title: (0, error_1.formatMessage)(error),
|
|
92
|
-
type: ContentErrorType.UNEXPECTED_ERROR,
|
|
93
|
-
detail: 'Please try again or contact Croct support if the error persists.',
|
|
94
|
-
status: 500, // Internal Server Error
|
|
95
|
-
}));
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
});
|
|
22
|
+
const { baseEndpointUrl } = configuration;
|
|
23
|
+
const apiKey = typeof configuration.apiKey === "object" ? configuration.apiKey.getIdentifier() : configuration.apiKey;
|
|
24
|
+
const baseEndpoint = (baseEndpointUrl ?? BASE_ENDPOINT_URL).replace(/\/+$/, "") + (apiKey === void 0 ? "/client" : "/external") + "/web";
|
|
25
|
+
this.dynamicEndpoint = `${baseEndpoint}/content`;
|
|
26
|
+
this.staticEndpoint = `${baseEndpoint}/static-content`;
|
|
27
|
+
this.logger = configuration.logger ?? new NullLogger();
|
|
28
|
+
this.configuration = {
|
|
29
|
+
appId: configuration.appId,
|
|
30
|
+
apiKey,
|
|
31
|
+
defaultTimeout: configuration.defaultTimeout,
|
|
32
|
+
defaultPreferredLocale: configuration.defaultPreferredLocale
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
fetch(slotId, options = {}) {
|
|
36
|
+
if (options.static === true && this.configuration.apiKey === void 0) {
|
|
37
|
+
throw new Error("The API key must be provided to fetch static content.");
|
|
99
38
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
if (options.context !== undefined) {
|
|
138
|
-
payload.context = options.context;
|
|
139
|
-
}
|
|
140
|
-
if (options.previewToken !== undefined) {
|
|
141
|
-
payload.previewToken = `${options.previewToken}`;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return fetch(dynamic ? this.dynamicEndpoint : this.staticEndpoint, {
|
|
145
|
-
// Set the request mode to 'cors' when running in the browser.
|
|
146
|
-
// By default, the request mode is computed based on the referrer policy
|
|
147
|
-
// and response-tainting rules applied to the script that ultimately
|
|
148
|
-
// initiated the fetch, make this prone to errors due to unrelated
|
|
149
|
-
// configurations on the page.
|
|
150
|
-
// https://fetch.spec.whatwg.org/#origin-header
|
|
151
|
-
mode: typeof window === 'undefined' ? undefined : 'cors',
|
|
152
|
-
credentials: 'omit',
|
|
153
|
-
...options.extra,
|
|
154
|
-
method: 'POST',
|
|
155
|
-
headers: headers,
|
|
156
|
-
signal: signal,
|
|
157
|
-
body: JSON.stringify(payload),
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const abortController = new AbortController();
|
|
41
|
+
const timeout = options.timeout ?? this.configuration.defaultTimeout;
|
|
42
|
+
let timer;
|
|
43
|
+
if (timeout !== void 0) {
|
|
44
|
+
timer = setTimeout(
|
|
45
|
+
() => {
|
|
46
|
+
const response = {
|
|
47
|
+
title: `Content could not be loaded in time for slot '${slotId}'.`,
|
|
48
|
+
type: "https://croct.help/api/content#timeout" /* TIMEOUT */,
|
|
49
|
+
detail: `The content took more than ${timeout}ms to load.`,
|
|
50
|
+
status: 408
|
|
51
|
+
// Request Timeout
|
|
52
|
+
};
|
|
53
|
+
abortController.abort();
|
|
54
|
+
this.logHelp(response.status);
|
|
55
|
+
reject(new ContentError(response));
|
|
56
|
+
},
|
|
57
|
+
timeout
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
this.load(slotId, abortController.signal, options).finally(() => clearTimeout(timer)).then((response) => {
|
|
61
|
+
const region = response.headers.get("X-Croct-Region");
|
|
62
|
+
const timing = response.headers.get("X-Croct-Timing");
|
|
63
|
+
this.logger.debug(`Content for slot '${slotId}' processed by region ${region} in ${timing}.`);
|
|
64
|
+
return response.json().then((body) => {
|
|
65
|
+
if (response.ok) {
|
|
66
|
+
return resolve(body);
|
|
67
|
+
}
|
|
68
|
+
this.logHelp(response.status);
|
|
69
|
+
reject(new ContentError(body));
|
|
70
|
+
}).catch((error) => {
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
throw new Error(`Error ${response.status} - ${response.statusText}`);
|
|
73
|
+
}
|
|
74
|
+
throw error;
|
|
158
75
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
76
|
+
}).catch((error) => {
|
|
77
|
+
if (!abortController.signal.aborted) {
|
|
78
|
+
reject(
|
|
79
|
+
new ContentError({
|
|
80
|
+
title: formatMessage(error),
|
|
81
|
+
type: "https://croct.help/api/content#unexpected-error" /* UNEXPECTED_ERROR */,
|
|
82
|
+
detail: "Please try again or contact Croct support if the error persists.",
|
|
83
|
+
status: 500
|
|
84
|
+
// Internal Server Error
|
|
85
|
+
})
|
|
86
|
+
);
|
|
164
87
|
}
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
load(slotId, signal, options) {
|
|
92
|
+
const { apiKey, appId } = this.configuration;
|
|
93
|
+
const headers = {
|
|
94
|
+
"Content-Type": "application/json"
|
|
95
|
+
};
|
|
96
|
+
headers["X-Client-Library"] = CLIENT_LIBRARY;
|
|
97
|
+
if (appId !== void 0) {
|
|
98
|
+
headers["X-App-Id"] = appId;
|
|
99
|
+
}
|
|
100
|
+
if (apiKey !== void 0) {
|
|
101
|
+
headers["X-Api-Key"] = apiKey;
|
|
102
|
+
}
|
|
103
|
+
const payload = {
|
|
104
|
+
slotId
|
|
105
|
+
};
|
|
106
|
+
if (options.version !== void 0) {
|
|
107
|
+
payload.version = `${options.version}`;
|
|
108
|
+
}
|
|
109
|
+
const preferredLocale = options.preferredLocale ?? this.configuration.defaultPreferredLocale;
|
|
110
|
+
if (preferredLocale !== void 0) {
|
|
111
|
+
payload.preferredLocale = preferredLocale;
|
|
165
112
|
}
|
|
166
|
-
|
|
167
|
-
|
|
113
|
+
const dynamic = ContentFetcher.isDynamicContent(options);
|
|
114
|
+
if (dynamic) {
|
|
115
|
+
if (options.clientId !== void 0) {
|
|
116
|
+
headers["X-Client-Id"] = options.clientId;
|
|
117
|
+
}
|
|
118
|
+
if (options.clientIp !== void 0) {
|
|
119
|
+
headers["X-Client-Ip"] = options.clientIp;
|
|
120
|
+
}
|
|
121
|
+
if (options.userToken !== void 0) {
|
|
122
|
+
headers["X-Token"] = options.userToken.toString();
|
|
123
|
+
}
|
|
124
|
+
if (options.clientAgent !== void 0) {
|
|
125
|
+
headers["X-Client-Agent"] = options.clientAgent;
|
|
126
|
+
}
|
|
127
|
+
if (options.context !== void 0) {
|
|
128
|
+
payload.context = options.context;
|
|
129
|
+
}
|
|
130
|
+
if (options.previewToken !== void 0) {
|
|
131
|
+
payload.previewToken = `${options.previewToken}`;
|
|
132
|
+
}
|
|
168
133
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
134
|
+
return fetch(dynamic ? this.dynamicEndpoint : this.staticEndpoint, {
|
|
135
|
+
// Set the request mode to 'cors' when running in the browser.
|
|
136
|
+
// By default, the request mode is computed based on the referrer policy
|
|
137
|
+
// and response-tainting rules applied to the script that ultimately
|
|
138
|
+
// initiated the fetch, make this prone to errors due to unrelated
|
|
139
|
+
// configurations on the page.
|
|
140
|
+
// https://fetch.spec.whatwg.org/#origin-header
|
|
141
|
+
mode: typeof window === "undefined" ? void 0 : "cors",
|
|
142
|
+
credentials: "omit",
|
|
143
|
+
...options.extra,
|
|
144
|
+
method: "POST",
|
|
145
|
+
headers,
|
|
146
|
+
signal,
|
|
147
|
+
body: JSON.stringify(payload)
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
logHelp(statusCode) {
|
|
151
|
+
const help = Help.forStatusCode(statusCode);
|
|
152
|
+
if (help !== void 0) {
|
|
153
|
+
this.logger.error(help);
|
|
172
154
|
}
|
|
155
|
+
}
|
|
156
|
+
static isDynamicContent(options) {
|
|
157
|
+
return options.static !== true;
|
|
158
|
+
}
|
|
159
|
+
toJSON() {
|
|
160
|
+
throw new Error("Unserializable value.");
|
|
161
|
+
}
|
|
173
162
|
}
|
|
174
|
-
|
|
163
|
+
export {
|
|
164
|
+
ContentError,
|
|
165
|
+
ContentErrorType,
|
|
166
|
+
ContentFetcher
|
|
167
|
+
};
|
|
175
168
|
//# sourceMappingURL=contentFetcher.js.map
|
package/contentFetcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contentFetcher.js","sourceRoot":"","sources":["src/contentFetcher.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["src/contentFetcher.ts"],"sourcesContent":["import {JsonObject} from '@croct/json';\nimport {EvaluationContext} from './evaluator';\nimport {Token} from './token';\nimport {BASE_ENDPOINT_URL, CLIENT_LIBRARY} from './constants';\nimport {formatMessage} from './error';\nimport {Logger, NullLogger} from './logging';\nimport type {ApiKey} from './apiKey';\nimport {Help} from './help';\n\nexport type ErrorResponse = {\n type: string,\n title: string,\n status: number,\n detail?: string,\n};\n\nexport enum ContentErrorType {\n TIMEOUT = 'https://croct.help/api/content#timeout',\n UNEXPECTED_ERROR = 'https://croct.help/api/content#unexpected-error',\n}\n\ntype FetchPayload = {\n slotId: string,\n version?: string,\n preferredLocale?: string,\n previewToken?: string,\n context?: EvaluationContext,\n};\n\nexport class ContentError<T extends ErrorResponse = ErrorResponse> extends Error {\n public readonly response: T;\n\n public constructor(response: T) {\n super(response.title);\n\n this.response = response;\n\n Object.setPrototypeOf(this, ContentError.prototype);\n }\n}\n\ntype BasicOptions = {\n version?: `${number}` | number,\n preferredLocale?: string,\n timeout?: number,\n extra?: ExtraFetchOptions,\n};\n\nexport type StaticContentOptions = BasicOptions & {\n static: true,\n};\n\nexport type DynamicContentOptions = BasicOptions & {\n static?: false,\n clientId?: string,\n clientIp?: string,\n clientAgent?: string,\n userToken?: Token|string,\n previewToken?: Token|string,\n context?: EvaluationContext,\n};\n\ntype AllowedFetchOptions = Exclude<keyof RequestInit, 'method' | 'body' | 'headers' | 'signal'>;\n\ntype ExtraFetchOptions<T extends keyof RequestInit = AllowedFetchOptions> = Pick<RequestInit, T>\n & {[key in Exclude<keyof RequestInit, T>]?: never}\n & Record<string, any>;\n\nexport type FetchOptions = StaticContentOptions | DynamicContentOptions;\n\nexport type FetchResponse<P extends JsonObject = JsonObject> = {\n content: P,\n};\n\nexport type Configuration = {\n appId?: string,\n apiKey?: string|ApiKey,\n baseEndpointUrl?: string,\n logger?: Logger,\n defaultTimeout?: number,\n defaultPreferredLocale?: string,\n};\n\ntype InternalConfiguration = {\n appId?: string,\n apiKey?: string,\n defaultTimeout?: number,\n defaultPreferredLocale?: string,\n};\n\nexport class ContentFetcher {\n private readonly configuration: InternalConfiguration;\n\n private readonly dynamicEndpoint: string;\n\n private readonly staticEndpoint: string;\n\n private readonly logger: Logger;\n\n public constructor(configuration: Configuration) {\n if ((configuration.appId === undefined) === (configuration.apiKey === undefined)) {\n throw new Error('Either the application ID or the API key must be provided.');\n }\n\n const {baseEndpointUrl} = configuration;\n const apiKey = typeof configuration.apiKey === 'object'\n ? configuration.apiKey.getIdentifier()\n : configuration.apiKey;\n\n // eslint-disable-next-line prefer-template -- Better readability\n const baseEndpoint = (baseEndpointUrl ?? BASE_ENDPOINT_URL).replace(/\\/+$/, '')\n + (apiKey === undefined ? '/client' : '/external')\n + '/web';\n\n this.dynamicEndpoint = `${baseEndpoint}/content`;\n this.staticEndpoint = `${baseEndpoint}/static-content`;\n this.logger = configuration.logger ?? new NullLogger();\n this.configuration = {\n appId: configuration.appId,\n apiKey: apiKey,\n defaultTimeout: configuration.defaultTimeout,\n defaultPreferredLocale: configuration.defaultPreferredLocale,\n };\n }\n\n public fetch<P extends JsonObject>(slotId: string, options: FetchOptions = {}): Promise<FetchResponse<P>> {\n if (options.static === true && this.configuration.apiKey === undefined) {\n throw new Error('The API key must be provided to fetch static content.');\n }\n\n return new Promise<FetchResponse<P>>((resolve, reject) => {\n const abortController = new AbortController();\n const timeout = options.timeout ?? this.configuration.defaultTimeout;\n\n let timer: number | NodeJS.Timeout | undefined;\n\n if (timeout !== undefined) {\n timer = setTimeout(\n () => {\n const response: ErrorResponse = {\n title: `Content could not be loaded in time for slot '${slotId}'.`,\n type: ContentErrorType.TIMEOUT,\n detail: `The content took more than ${timeout}ms to load.`,\n status: 408, // Request Timeout\n };\n\n abortController.abort();\n\n this.logHelp(response.status);\n\n reject(new ContentError(response));\n },\n timeout,\n );\n }\n\n this.load(slotId, abortController.signal, options)\n .finally(() => clearTimeout(timer))\n .then(response => {\n const region = response.headers.get('X-Croct-Region');\n const timing = response.headers.get('X-Croct-Timing');\n\n this.logger.debug(`Content for slot '${slotId}' processed by region ${region} in ${timing}.`);\n\n return response.json()\n .then(body => {\n if (response.ok) {\n return resolve(body);\n }\n\n this.logHelp(response.status);\n\n reject(new ContentError(body));\n })\n .catch(error => {\n if (!response.ok) {\n throw new Error(`Error ${response.status} - ${response.statusText}`);\n }\n\n throw error;\n });\n })\n .catch(error => {\n if (!abortController.signal.aborted) {\n reject(\n new ContentError({\n title: formatMessage(error),\n type: ContentErrorType.UNEXPECTED_ERROR,\n detail: 'Please try again or contact Croct support if the error persists.',\n status: 500, // Internal Server Error\n }),\n );\n }\n });\n });\n }\n\n private load(slotId: string, signal: AbortSignal, options: FetchOptions): Promise<Response> {\n const {apiKey, appId} = this.configuration;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n headers['X-Client-Library'] = CLIENT_LIBRARY;\n\n if (appId !== undefined) {\n headers['X-App-Id'] = appId;\n }\n\n if (apiKey !== undefined) {\n headers['X-Api-Key'] = apiKey;\n }\n\n const payload: FetchPayload = {\n slotId: slotId,\n };\n\n if (options.version !== undefined) {\n payload.version = `${options.version}`;\n }\n\n const preferredLocale = options.preferredLocale ?? this.configuration.defaultPreferredLocale;\n\n if (preferredLocale !== undefined) {\n payload.preferredLocale = preferredLocale;\n }\n\n const dynamic = ContentFetcher.isDynamicContent(options);\n\n if (dynamic) {\n if (options.clientId !== undefined) {\n headers['X-Client-Id'] = options.clientId;\n }\n\n if (options.clientIp !== undefined) {\n headers['X-Client-Ip'] = options.clientIp;\n }\n\n if (options.userToken !== undefined) {\n headers['X-Token'] = options.userToken.toString();\n }\n\n if (options.clientAgent !== undefined) {\n headers['X-Client-Agent'] = options.clientAgent;\n }\n\n if (options.context !== undefined) {\n payload.context = options.context;\n }\n\n if (options.previewToken !== undefined) {\n payload.previewToken = `${options.previewToken}`;\n }\n }\n\n return fetch(dynamic ? this.dynamicEndpoint : this.staticEndpoint, {\n // Set the request mode to 'cors' when running in the browser.\n // By default, the request mode is computed based on the referrer policy\n // and response-tainting rules applied to the script that ultimately\n // initiated the fetch, make this prone to errors due to unrelated\n // configurations on the page.\n // https://fetch.spec.whatwg.org/#origin-header\n mode: typeof window === 'undefined' ? undefined : 'cors',\n credentials: 'omit',\n ...options.extra,\n method: 'POST',\n headers: headers,\n signal: signal,\n body: JSON.stringify(payload),\n });\n }\n\n private logHelp(statusCode: number): void {\n const help = Help.forStatusCode(statusCode);\n\n if (help !== undefined) {\n this.logger.error(help);\n }\n }\n\n private static isDynamicContent(options: FetchOptions): options is DynamicContentOptions {\n return options.static !== true;\n }\n\n public toJSON(): never {\n // Prevent sensitive configuration from being serialized\n throw new Error('Unserializable value.');\n }\n}\n"],"mappings":"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","names":["ContentErrorType"]}
|
package/context.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.ts"],"sourcesContent":["import {Token, TokenStore, CachedTokenStore, ReplicatedTokenStore, InMemoryTokenStore} from './token';\nimport {Tab, UrlSanitizer} from './tab';\nimport {uuid4} from './uuid';\nimport {EventDispatcher} from './eventManager';\nimport {SdkEventMap} from './sdkEvents';\nimport {Cache, ObservableCache} from './cache';\n\nexport type TokenScope = 'isolated' | 'global' | 'contextual';\n\nexport type Configuration = {\n tokenScope: TokenScope,\n urlSanitizer?: UrlSanitizer,\n eventDispatcher: ContextEventDispatcher,\n cache: {\n tabId: Cache,\n tabToken: Cache,\n browserToken: Cache,\n },\n};\n\ntype ContextEventDispatcher = EventDispatcher<Pick<SdkEventMap, 'tokenChanged'>>;\n\nfunction tokenEquals(left: Token|null, right: Token|null): boolean {\n return left === right || (left !== null && right !== null && left.toString() === right.toString());\n}\n\nexport class Context {\n private readonly tab: Tab;\n\n private readonly tokenStore: TokenStore;\n\n private readonly eventDispatcher: ContextEventDispatcher;\n\n private lastToken: Token|null;\n\n private constructor(tab: Tab, tokenStore: TokenStore, eventDispatcher: ContextEventDispatcher) {\n this.tab = tab;\n this.tokenStore = tokenStore;\n this.eventDispatcher = eventDispatcher;\n this.lastToken = tokenStore.getToken();\n this.syncToken = this.syncToken.bind(this);\n }\n\n public static load({cache, tokenScope, eventDispatcher, urlSanitizer}: Configuration): Context {\n let tabId: string | null = cache.tabId.get();\n let newTab = false;\n\n if (tabId === null) {\n tabId = uuid4(true);\n newTab = true;\n }\n\n const tab = new Tab(tabId, newTab, urlSanitizer);\n\n cache.tabId.clear();\n\n tab.addListener('unload', () => cache.tabId.put(tab.id));\n\n switch (tokenScope) {\n case 'isolated':\n return new Context(tab, new InMemoryTokenStore(), eventDispatcher);\n\n case 'global': {\n const context = new Context(tab, new CachedTokenStore(cache.browserToken), eventDispatcher);\n\n if (ObservableCache.isObservable(cache.browserToken)) {\n cache.browserToken.addListener(context.syncToken);\n }\n\n return context;\n }\n\n case 'contextual': {\n const primaryStorage = new CachedTokenStore(cache.tabToken);\n const secondaryStorage = new CachedTokenStore(cache.browserToken);\n\n if (tab.isNew) {\n primaryStorage.setToken(secondaryStorage.getToken());\n }\n\n tab.addListener('visibilityChange', event => {\n if (event.detail.visible) {\n secondaryStorage.setToken(primaryStorage.getToken());\n }\n });\n\n return new Context(tab, new ReplicatedTokenStore(primaryStorage, secondaryStorage), eventDispatcher);\n }\n }\n }\n\n public getTab(): Tab {\n return this.tab;\n }\n\n public isAnonymous(): boolean {\n const token = this.getToken();\n\n return token == null || token.isAnonymous();\n }\n\n public getUser(): string | null {\n const token = this.getToken();\n\n return token == null ? null : token.getSubject();\n }\n\n public getToken(): Token | null {\n return this.tokenStore.getToken();\n }\n\n public setToken(token: Token | null): void {\n const oldToken = this.lastToken;\n\n this.lastToken = token;\n this.tokenStore.setToken(token);\n\n if (!tokenEquals(oldToken, token)) {\n this.eventDispatcher.dispatch('tokenChanged', {\n oldToken: oldToken,\n newToken: token,\n });\n }\n }\n\n private syncToken(): void {\n const newToken = this.tokenStore.getToken();\n const oldToken = this.lastToken;\n\n if (!tokenEquals(oldToken, newToken)) {\n this.lastToken = newToken;\n\n this.eventDispatcher.dispatch('tokenChanged', {\n oldToken: oldToken,\n newToken: newToken,\n });\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4F;AAC5F,iBAAgC;AAChC,kBAAoB;AAGpB,mBAAqC;AAiBrC,SAAS,YAAY,MAAkB,OAA4B;AAC/D,SAAO,SAAS,SAAU,SAAS,QAAQ,UAAU,QAAQ,KAAK,SAAS,MAAM,MAAM,SAAS;AACpG;AAEO,MAAM,QAAQ;AAAA,EAST,YAAY,KAAU,YAAwB,iBAAyC;AAC3F,SAAK,MAAM;AACX,SAAK,aAAa;AAClB,SAAK,kBAAkB;AACvB,SAAK,YAAY,WAAW,SAAS;AACrC,SAAK,YAAY,KAAK,UAAU,KAAK,IAAI;AAAA,EAC7C;AAAA,EAEA,OAAc,KAAK,EAAC,OAAO,YAAY,iBAAiB,aAAY,GAA2B;AAC3F,QAAI,QAAuB,MAAM,MAAM,IAAI;AAC3C,QAAI,SAAS;AAEb,QAAI,UAAU,MAAM;AAChB,kBAAQ,mBAAM,IAAI;AAClB,eAAS;AAAA,IACb;AAEA,UAAM,MAAM,IAAI,eAAI,OAAO,QAAQ,YAAY;AAE/C,UAAM,MAAM,MAAM;AAElB,QAAI,YAAY,UAAU,MAAM,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;AAEvD,YAAQ,YAAY;AAAA,MAChB,KAAK;AACD,eAAO,IAAI,QAAQ,KAAK,IAAI,gCAAmB,GAAG,eAAe;AAAA,MAErE,KAAK,UAAU;AACX,cAAM,UAAU,IAAI,QAAQ,KAAK,IAAI,8BAAiB,MAAM,YAAY,GAAG,eAAe;AAE1F,YAAI,6BAAgB,aAAa,MAAM,YAAY,GAAG;AAClD,gBAAM,aAAa,YAAY,QAAQ,SAAS;AAAA,QACpD;AAEA,eAAO;AAAA,MACX;AAAA,MAEA,KAAK,cAAc;AACf,cAAM,iBAAiB,IAAI,8BAAiB,MAAM,QAAQ;AAC1D,cAAM,mBAAmB,IAAI,8BAAiB,MAAM,YAAY;AAEhE,YAAI,IAAI,OAAO;AACX,yBAAe,SAAS,iBAAiB,SAAS,CAAC;AAAA,QACvD;AAEA,YAAI,YAAY,oBAAoB,WAAS;AACzC,cAAI,MAAM,OAAO,SAAS;AACtB,6BAAiB,SAAS,eAAe,SAAS,CAAC;AAAA,UACvD;AAAA,QACJ,CAAC;AAED,eAAO,IAAI,QAAQ,KAAK,IAAI,kCAAqB,gBAAgB,gBAAgB,GAAG,eAAe;AAAA,MACvG;AAAA,IACJ;AAAA,EACJ;AAAA,EAEO,SAAc;AACjB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEO,cAAuB;AAC1B,UAAM,QAAQ,KAAK,SAAS;AAE5B,WAAO,SAAS,QAAQ,MAAM,YAAY;AAAA,EAC9C;AAAA,EAEO,UAAyB;AAC5B,UAAM,QAAQ,KAAK,SAAS;AAE5B,WAAO,SAAS,OAAO,OAAO,MAAM,WAAW;AAAA,EACnD;AAAA,EAEO,WAAyB;AAC5B,WAAO,KAAK,WAAW,SAAS;AAAA,EACpC;AAAA,EAEO,SAAS,OAA2B;AACvC,UAAM,WAAW,KAAK;AAEtB,SAAK,YAAY;AACjB,SAAK,WAAW,SAAS,KAAK;AAE9B,QAAI,CAAC,YAAY,UAAU,KAAK,GAAG;AAC/B,WAAK,gBAAgB,SAAS,gBAAgB;AAAA,QAC1C;AAAA,QACA,UAAU;AAAA,MACd,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EAEQ,YAAkB;AACtB,UAAM,WAAW,KAAK,WAAW,SAAS;AAC1C,UAAM,WAAW,KAAK;AAEtB,QAAI,CAAC,YAAY,UAAU,QAAQ,GAAG;AAClC,WAAK,YAAY;AAEjB,WAAK,gBAAgB,SAAS,gBAAgB;AAAA,QAC1C;AAAA,QACA;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AACJ;","names":[]}
|
package/context.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { Token } from './token';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Token } from './token/token.js';
|
|
2
|
+
import { Cache } from './cache/cache.js';
|
|
3
|
+
import { UrlSanitizer, Tab } from './tab.js';
|
|
4
|
+
import { EventDispatcher } from './eventManager.js';
|
|
5
|
+
import { SdkEventMap } from './sdkEvents.js';
|
|
6
|
+
import '@croct/json';
|
|
7
|
+
import './apiKey.js';
|
|
8
|
+
|
|
9
|
+
type TokenScope = 'isolated' | 'global' | 'contextual';
|
|
10
|
+
type Configuration = {
|
|
8
11
|
tokenScope: TokenScope;
|
|
9
12
|
urlSanitizer?: UrlSanitizer;
|
|
10
13
|
eventDispatcher: ContextEventDispatcher;
|
|
@@ -15,7 +18,7 @@ export type Configuration = {
|
|
|
15
18
|
};
|
|
16
19
|
};
|
|
17
20
|
type ContextEventDispatcher = EventDispatcher<Pick<SdkEventMap, 'tokenChanged'>>;
|
|
18
|
-
|
|
21
|
+
declare class Context {
|
|
19
22
|
private readonly tab;
|
|
20
23
|
private readonly tokenStore;
|
|
21
24
|
private readonly eventDispatcher;
|
|
@@ -29,4 +32,5 @@ export declare class Context {
|
|
|
29
32
|
setToken(token: Token | null): void;
|
|
30
33
|
private syncToken;
|
|
31
34
|
}
|
|
32
|
-
|
|
35
|
+
|
|
36
|
+
export { type Configuration, Context, type TokenScope };
|