@croct/sdk 0.19.1 → 0.20.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/constants.cjs CHANGED
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
  const BASE_ENDPOINT_URL = "https://api.croct.io";
27
27
  const MAX_QUERY_LENGTH = parseInt("<@maxQueryLength@>", 10);
28
- const VERSION = "0.19.1";
28
+ const VERSION = "0.20.0";
29
29
  const CLIENT_LIBRARY = `Croct SDK JS v${VERSION}`;
30
30
  // Annotate the CommonJS export names for ESM import in node:
31
31
  0 && (module.exports = {
package/constants.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  declare const BASE_ENDPOINT_URL = "https://api.croct.io";
2
2
  declare const MAX_QUERY_LENGTH: number;
3
- declare const VERSION = "0.19.1";
4
- declare const CLIENT_LIBRARY = "Croct SDK JS v0.19.1";
3
+ declare const VERSION = "0.20.0";
4
+ declare const CLIENT_LIBRARY = "Croct SDK JS v0.20.0";
5
5
 
6
6
  export { BASE_ENDPOINT_URL, CLIENT_LIBRARY, MAX_QUERY_LENGTH, VERSION };
package/constants.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  declare const BASE_ENDPOINT_URL = "https://api.croct.io";
2
2
  declare const MAX_QUERY_LENGTH: number;
3
- declare const VERSION = "0.19.1";
4
- declare const CLIENT_LIBRARY = "Croct SDK JS v0.19.1";
3
+ declare const VERSION = "0.20.0";
4
+ declare const CLIENT_LIBRARY = "Croct SDK JS v0.20.0";
5
5
 
6
6
  export { BASE_ENDPOINT_URL, CLIENT_LIBRARY, MAX_QUERY_LENGTH, VERSION };
package/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const BASE_ENDPOINT_URL = "https://api.croct.io";
2
2
  const MAX_QUERY_LENGTH = parseInt("<@maxQueryLength@>", 10);
3
- const VERSION = "0.19.1";
3
+ const VERSION = "0.20.0";
4
4
  const CLIENT_LIBRARY = `Croct SDK JS v${VERSION}`;
5
5
  export {
6
6
  BASE_ENDPOINT_URL,
package/container.d.cts CHANGED
@@ -20,6 +20,7 @@ import './trackingEvents.cjs';
20
20
  import './patch.cjs';
21
21
  import './utilityTypes.cjs';
22
22
  import './sourceLocation.cjs';
23
+ import '@croct/content-model/definition';
23
24
 
24
25
  type DependencyResolver<T> = (container: Container) => T;
25
26
  type Configuration = {
package/container.d.ts CHANGED
@@ -20,6 +20,7 @@ import './trackingEvents.js';
20
20
  import './patch.js';
21
21
  import './utilityTypes.js';
22
22
  import './sourceLocation.js';
23
+ import '@croct/content-model/definition';
23
24
 
24
25
  type DependencyResolver<T> = (container: Container) => T;
25
26
  type Configuration = {
@@ -57,13 +57,13 @@ class ContentFetcher {
57
57
  defaultPreferredLocale: configuration.defaultPreferredLocale
58
58
  };
59
59
  }
60
- fetch(slotId, options = {}) {
61
- if (options.static === true && this.configuration.apiKey === void 0) {
60
+ fetch(slotId, options) {
61
+ if (options?.static === true && this.configuration.apiKey === void 0) {
62
62
  throw new Error("The API key must be provided to fetch static content.");
63
63
  }
64
64
  return new Promise((resolve, reject) => {
65
65
  const abortController = new AbortController();
66
- const timeout = options.timeout ?? this.configuration.defaultTimeout;
66
+ const timeout = options?.timeout ?? this.configuration.defaultTimeout;
67
67
  let timer;
68
68
  if (timeout !== void 0) {
69
69
  timer = setTimeout(
@@ -82,7 +82,7 @@ class ContentFetcher {
82
82
  timeout
83
83
  );
84
84
  }
85
- this.load(slotId, abortController.signal, options).finally(() => clearTimeout(timer)).then((response) => {
85
+ this.load(slotId, abortController.signal, options ?? {}).finally(() => clearTimeout(timer)).then((response) => {
86
86
  const region = response.headers.get("X-Croct-Region");
87
87
  const timing = response.headers.get("X-Croct-Timing");
88
88
  this.logger.debug(`Content for slot '${slotId}' processed by region ${region} in ${timing}.`);
@@ -136,6 +136,9 @@ class ContentFetcher {
136
136
  const payload = {
137
137
  slotId
138
138
  };
139
+ if (options.includeSchema === true) {
140
+ payload.includeSchema = true;
141
+ }
139
142
  if (options.version !== void 0) {
140
143
  payload.version = `${options.version}`;
141
144
  }
@@ -1,4 +1,5 @@
1
1
  import { JsonObject } from '@croct/json';
2
+ import { ContentDefinitionBundle } from '@croct/content-model/definition';
2
3
  import { EvaluationContext } from './evaluator.cjs';
3
4
  import { Token } from './token/token.cjs';
4
5
  import { Logger } from './logging/logger.cjs';
@@ -20,7 +21,10 @@ declare class ContentError<T extends ErrorResponse = ErrorResponse> extends Erro
20
21
  readonly response: T;
21
22
  constructor(response: T);
22
23
  }
23
- type BasicOptions = {
24
+ type FetchResponseOptions = {
25
+ includeSchema?: boolean;
26
+ };
27
+ type BasicOptions = FetchResponseOptions & {
24
28
  version?: `${number}` | number;
25
29
  preferredLocale?: string;
26
30
  timeout?: number;
@@ -43,7 +47,25 @@ type ExtraFetchOptions<T extends keyof RequestInit = AllowedFetchOptions> = Pick
43
47
  [key in Exclude<keyof RequestInit, T>]?: never;
44
48
  } & Record<string, any>;
45
49
  type FetchOptions = StaticContentOptions | DynamicContentOptions;
46
- type FetchResponse<P extends JsonObject = JsonObject> = {
50
+ type With<T, K extends keyof T> = T & {
51
+ [P in K]-?: T[P];
52
+ };
53
+ type SlotMetadata = {
54
+ version: string;
55
+ schema?: ContentDefinitionBundle;
56
+ experience?: {
57
+ experienceId: string;
58
+ audienceId: string;
59
+ experiment?: {
60
+ experimentId: string;
61
+ variantId: string;
62
+ };
63
+ };
64
+ };
65
+ type FetchResponse<P = JsonObject, O = FetchResponseOptions> = {
66
+ metadata: With<SlotMetadata, O extends {
67
+ includeSchema: true;
68
+ } ? 'schema' : never>;
47
69
  content: P;
48
70
  };
49
71
  type Configuration = {
@@ -60,11 +82,11 @@ declare class ContentFetcher {
60
82
  private readonly staticEndpoint;
61
83
  private readonly logger;
62
84
  constructor(configuration: Configuration);
63
- fetch<P extends JsonObject>(slotId: string, options?: FetchOptions): Promise<FetchResponse<P>>;
85
+ fetch<P extends JsonObject, O extends FetchResponseOptions>(slotId: string, options?: O & FetchOptions): Promise<FetchResponse<P, O>>;
64
86
  private load;
65
87
  private logHelp;
66
88
  private static isDynamicContent;
67
89
  toJSON(): never;
68
90
  }
69
91
 
70
- export { type Configuration, ContentError, ContentErrorType, ContentFetcher, type DynamicContentOptions, type ErrorResponse, type FetchOptions, type FetchResponse, type StaticContentOptions };
92
+ export { type Configuration, ContentError, ContentErrorType, ContentFetcher, type DynamicContentOptions, type ErrorResponse, type FetchOptions, type FetchResponse, type FetchResponseOptions, type SlotMetadata, type StaticContentOptions };
@@ -1,4 +1,5 @@
1
1
  import { JsonObject } from '@croct/json';
2
+ import { ContentDefinitionBundle } from '@croct/content-model/definition';
2
3
  import { EvaluationContext } from './evaluator.js';
3
4
  import { Token } from './token/token.js';
4
5
  import { Logger } from './logging/logger.js';
@@ -20,7 +21,10 @@ declare class ContentError<T extends ErrorResponse = ErrorResponse> extends Erro
20
21
  readonly response: T;
21
22
  constructor(response: T);
22
23
  }
23
- type BasicOptions = {
24
+ type FetchResponseOptions = {
25
+ includeSchema?: boolean;
26
+ };
27
+ type BasicOptions = FetchResponseOptions & {
24
28
  version?: `${number}` | number;
25
29
  preferredLocale?: string;
26
30
  timeout?: number;
@@ -43,7 +47,25 @@ type ExtraFetchOptions<T extends keyof RequestInit = AllowedFetchOptions> = Pick
43
47
  [key in Exclude<keyof RequestInit, T>]?: never;
44
48
  } & Record<string, any>;
45
49
  type FetchOptions = StaticContentOptions | DynamicContentOptions;
46
- type FetchResponse<P extends JsonObject = JsonObject> = {
50
+ type With<T, K extends keyof T> = T & {
51
+ [P in K]-?: T[P];
52
+ };
53
+ type SlotMetadata = {
54
+ version: string;
55
+ schema?: ContentDefinitionBundle;
56
+ experience?: {
57
+ experienceId: string;
58
+ audienceId: string;
59
+ experiment?: {
60
+ experimentId: string;
61
+ variantId: string;
62
+ };
63
+ };
64
+ };
65
+ type FetchResponse<P = JsonObject, O = FetchResponseOptions> = {
66
+ metadata: With<SlotMetadata, O extends {
67
+ includeSchema: true;
68
+ } ? 'schema' : never>;
47
69
  content: P;
48
70
  };
49
71
  type Configuration = {
@@ -60,11 +82,11 @@ declare class ContentFetcher {
60
82
  private readonly staticEndpoint;
61
83
  private readonly logger;
62
84
  constructor(configuration: Configuration);
63
- fetch<P extends JsonObject>(slotId: string, options?: FetchOptions): Promise<FetchResponse<P>>;
85
+ fetch<P extends JsonObject, O extends FetchResponseOptions>(slotId: string, options?: O & FetchOptions): Promise<FetchResponse<P, O>>;
64
86
  private load;
65
87
  private logHelp;
66
88
  private static isDynamicContent;
67
89
  toJSON(): never;
68
90
  }
69
91
 
70
- export { type Configuration, ContentError, ContentErrorType, ContentFetcher, type DynamicContentOptions, type ErrorResponse, type FetchOptions, type FetchResponse, type StaticContentOptions };
92
+ export { type Configuration, ContentError, ContentErrorType, ContentFetcher, type DynamicContentOptions, type ErrorResponse, type FetchOptions, type FetchResponse, type FetchResponseOptions, type SlotMetadata, type StaticContentOptions };
package/contentFetcher.js CHANGED
@@ -33,13 +33,13 @@ class ContentFetcher {
33
33
  defaultPreferredLocale: configuration.defaultPreferredLocale
34
34
  };
35
35
  }
36
- fetch(slotId, options = {}) {
37
- if (options.static === true && this.configuration.apiKey === void 0) {
36
+ fetch(slotId, options) {
37
+ if (options?.static === true && this.configuration.apiKey === void 0) {
38
38
  throw new Error("The API key must be provided to fetch static content.");
39
39
  }
40
40
  return new Promise((resolve, reject) => {
41
41
  const abortController = new AbortController();
42
- const timeout = options.timeout ?? this.configuration.defaultTimeout;
42
+ const timeout = options?.timeout ?? this.configuration.defaultTimeout;
43
43
  let timer;
44
44
  if (timeout !== void 0) {
45
45
  timer = setTimeout(
@@ -58,7 +58,7 @@ class ContentFetcher {
58
58
  timeout
59
59
  );
60
60
  }
61
- this.load(slotId, abortController.signal, options).finally(() => clearTimeout(timer)).then((response) => {
61
+ this.load(slotId, abortController.signal, options ?? {}).finally(() => clearTimeout(timer)).then((response) => {
62
62
  const region = response.headers.get("X-Croct-Region");
63
63
  const timing = response.headers.get("X-Croct-Timing");
64
64
  this.logger.debug(`Content for slot '${slotId}' processed by region ${region} in ${timing}.`);
@@ -112,6 +112,9 @@ class ContentFetcher {
112
112
  const payload = {
113
113
  slotId
114
114
  };
115
+ if (options.includeSchema === true) {
116
+ payload.includeSchema = true;
117
+ }
115
118
  if (options.version !== void 0) {
116
119
  payload.version = `${options.version}`;
117
120
  }
@@ -37,20 +37,23 @@ class ContentFetcherFacade {
37
37
  this.cidAssigner = configuration.cidAssigner;
38
38
  this.contextFactory = configuration.contextFactory;
39
39
  }
40
- async fetch(slotId, options = {}) {
40
+ async fetch(slotId, options) {
41
41
  if (typeof slotId !== "string" || slotId.length === 0) {
42
42
  throw new Error("The slot ID must be a non-empty string.");
43
43
  }
44
- validate(options);
44
+ if (options !== void 0) {
45
+ validate(options);
46
+ }
45
47
  return this.fetcher.fetch(slotId, {
46
48
  static: false,
47
49
  clientId: await this.cidAssigner.assignCid(),
48
50
  userToken: this.userTokenProvider.getToken() ?? void 0,
49
51
  previewToken: this.previewTokenProvider.getToken() ?? void 0,
50
- version: options.version,
51
- context: this.contextFactory.createContext(options.attributes),
52
- timeout: options.timeout,
53
- preferredLocale: options.preferredLocale
52
+ version: options?.version,
53
+ context: this.contextFactory.createContext(options?.attributes),
54
+ timeout: options?.timeout,
55
+ preferredLocale: options?.preferredLocale,
56
+ includeSchema: options?.includeSchema
54
57
  });
55
58
  }
56
59
  }
@@ -1,8 +1,9 @@
1
1
  import { JsonObject } from '@croct/json';
2
- import { ContentFetcher, FetchResponse } from '../contentFetcher.cjs';
2
+ import { FetchResponseOptions, ContentFetcher, FetchResponse } from '../contentFetcher.cjs';
3
3
  import { ContextFactory } from './evaluatorFacade.cjs';
4
4
  import { TokenProvider } from '../token/token.cjs';
5
5
  import { CidAssigner } from '../cid/assigner.cjs';
6
+ import '@croct/content-model/definition';
6
7
  import '../evaluator.cjs';
7
8
  import '../sourceLocation.cjs';
8
9
  import '../logging/logger.cjs';
@@ -10,7 +11,7 @@ import '../apiKey.cjs';
10
11
  import '../tab.cjs';
11
12
  import '../eventManager.cjs';
12
13
 
13
- type FetchOptions = {
14
+ type FetchOptions = FetchResponseOptions & {
14
15
  version?: `${number}` | number;
15
16
  preferredLocale?: string;
16
17
  timeout?: number;
@@ -30,7 +31,7 @@ declare class ContentFetcherFacade {
30
31
  private readonly userTokenProvider;
31
32
  private readonly cidAssigner;
32
33
  constructor(configuration: Configuration);
33
- fetch<P extends JsonObject>(slotId: string, options?: FetchOptions): Promise<FetchResponse<P>>;
34
+ fetch<P extends JsonObject, O extends FetchResponseOptions>(slotId: string, options?: O & FetchOptions): Promise<FetchResponse<P, O>>;
34
35
  }
35
36
 
36
37
  export { type Configuration, ContentFetcherFacade, type FetchOptions };
@@ -1,8 +1,9 @@
1
1
  import { JsonObject } from '@croct/json';
2
- import { ContentFetcher, FetchResponse } from '../contentFetcher.js';
2
+ import { FetchResponseOptions, ContentFetcher, FetchResponse } from '../contentFetcher.js';
3
3
  import { ContextFactory } from './evaluatorFacade.js';
4
4
  import { TokenProvider } from '../token/token.js';
5
5
  import { CidAssigner } from '../cid/assigner.js';
6
+ import '@croct/content-model/definition';
6
7
  import '../evaluator.js';
7
8
  import '../sourceLocation.js';
8
9
  import '../logging/logger.js';
@@ -10,7 +11,7 @@ import '../apiKey.js';
10
11
  import '../tab.js';
11
12
  import '../eventManager.js';
12
13
 
13
- type FetchOptions = {
14
+ type FetchOptions = FetchResponseOptions & {
14
15
  version?: `${number}` | number;
15
16
  preferredLocale?: string;
16
17
  timeout?: number;
@@ -30,7 +31,7 @@ declare class ContentFetcherFacade {
30
31
  private readonly userTokenProvider;
31
32
  private readonly cidAssigner;
32
33
  constructor(configuration: Configuration);
33
- fetch<P extends JsonObject>(slotId: string, options?: FetchOptions): Promise<FetchResponse<P>>;
34
+ fetch<P extends JsonObject, O extends FetchResponseOptions>(slotId: string, options?: O & FetchOptions): Promise<FetchResponse<P, O>>;
34
35
  }
35
36
 
36
37
  export { type Configuration, ContentFetcherFacade, type FetchOptions };
@@ -15,20 +15,23 @@ class ContentFetcherFacade {
15
15
  this.cidAssigner = configuration.cidAssigner;
16
16
  this.contextFactory = configuration.contextFactory;
17
17
  }
18
- async fetch(slotId, options = {}) {
18
+ async fetch(slotId, options) {
19
19
  if (typeof slotId !== "string" || slotId.length === 0) {
20
20
  throw new Error("The slot ID must be a non-empty string.");
21
21
  }
22
- validate(options);
22
+ if (options !== void 0) {
23
+ validate(options);
24
+ }
23
25
  return this.fetcher.fetch(slotId, {
24
26
  static: false,
25
27
  clientId: await this.cidAssigner.assignCid(),
26
28
  userToken: this.userTokenProvider.getToken() ?? void 0,
27
29
  previewToken: this.previewTokenProvider.getToken() ?? void 0,
28
- version: options.version,
29
- context: this.contextFactory.createContext(options.attributes),
30
- timeout: options.timeout,
31
- preferredLocale: options.preferredLocale
30
+ version: options?.version,
31
+ context: this.contextFactory.createContext(options?.attributes),
32
+ timeout: options?.timeout,
33
+ preferredLocale: options?.preferredLocale,
34
+ includeSchema: options?.includeSchema
32
35
  });
33
36
  }
34
37
  }
@@ -19,6 +19,7 @@ import '../cache/cache.cjs';
19
19
  import '../sdkEvents.cjs';
20
20
  import './contentFetcherFacade.cjs';
21
21
  import '../contentFetcher.cjs';
22
+ import '@croct/content-model/definition';
22
23
  import '../cache/cookieCache.cjs';
23
24
  import '../trackingEvents.cjs';
24
25
  import '../patch.cjs';
package/facade/index.d.ts CHANGED
@@ -19,6 +19,7 @@ import '../cache/cache.js';
19
19
  import '../sdkEvents.js';
20
20
  import './contentFetcherFacade.js';
21
21
  import '../contentFetcher.js';
22
+ import '@croct/content-model/definition';
22
23
  import '../cache/cookieCache.js';
23
24
  import '../trackingEvents.js';
24
25
  import '../patch.js';
@@ -26,6 +26,7 @@ import '../retry/policy.cjs';
26
26
  import '../cache/cache.cjs';
27
27
  import '../activeRecord.cjs';
28
28
  import '../contentFetcher.cjs';
29
+ import '@croct/content-model/definition';
29
30
 
30
31
  type Configuration = {
31
32
  appId: string;
@@ -26,6 +26,7 @@ import '../retry/policy.js';
26
26
  import '../cache/cache.js';
27
27
  import '../activeRecord.js';
28
28
  import '../contentFetcher.js';
29
+ import '@croct/content-model/definition';
29
30
 
30
31
  type Configuration = {
31
32
  appId: string;
package/index.d.cts CHANGED
@@ -22,4 +22,5 @@ import './evaluator.cjs';
22
22
  import './sourceLocation.cjs';
23
23
  import './cid/assigner.cjs';
24
24
  import './contentFetcher.cjs';
25
+ import '@croct/content-model/definition';
25
26
  import './cache/cookieCache.cjs';
package/index.d.ts CHANGED
@@ -22,4 +22,5 @@ import './evaluator.js';
22
22
  import './sourceLocation.js';
23
23
  import './cid/assigner.js';
24
24
  import './contentFetcher.js';
25
+ import '@croct/content-model/definition';
25
26
  import './cache/cookieCache.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@croct/sdk",
3
- "version": "0.19.1",
3
+ "version": "0.20.0",
4
4
  "description": "Croct SDK for JavaScript.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -81,6 +81,7 @@
81
81
  },
82
82
  "dependencies": {
83
83
  "@croct/json": "^2.0.1",
84
+ "@croct/content-model": "^0.21.1",
84
85
  "tslib": "^2.5.0"
85
86
  },
86
87
  "devDependencies": {
@@ -39,6 +39,7 @@ const fetchOptionsSchema = new import_validation.ObjectType({
39
39
  preferredLocale: new import_validation.StringType({
40
40
  pattern: /^[a-z]{2,3}([-_][a-z]{2,3})?$/i
41
41
  }),
42
+ includeSchema: new import_validation.BooleanType(),
42
43
  attributes: new import_validation.JsonObjectType()
43
44
  }
44
45
  });
@@ -1,4 +1,4 @@
1
- import { ObjectType, NumberType, JsonObjectType, StringType, UnionType } from "../validation/index.js";
1
+ import { ObjectType, NumberType, JsonObjectType, StringType, UnionType, BooleanType } from "../validation/index.js";
2
2
  const fetchOptionsSchema = new ObjectType({
3
3
  properties: {
4
4
  timeout: new NumberType({
@@ -17,6 +17,7 @@ const fetchOptionsSchema = new ObjectType({
17
17
  preferredLocale: new StringType({
18
18
  pattern: /^[a-z]{2,3}([-_][a-z]{2,3})?$/i
19
19
  }),
20
+ includeSchema: new BooleanType(),
20
21
  attributes: new JsonObjectType()
21
22
  }
22
23
  });
package/sdk.d.cts CHANGED
@@ -21,6 +21,7 @@ import '@croct/json';
21
21
  import './utilityTypes.cjs';
22
22
  import './sourceLocation.cjs';
23
23
  import './apiKey.cjs';
24
+ import '@croct/content-model/definition';
24
25
 
25
26
  type Configuration = {
26
27
  appId: string;
package/sdk.d.ts CHANGED
@@ -21,6 +21,7 @@ import '@croct/json';
21
21
  import './utilityTypes.js';
22
22
  import './sourceLocation.js';
23
23
  import './apiKey.js';
24
+ import '@croct/content-model/definition';
24
25
 
25
26
  type Configuration = {
26
27
  appId: string;