@prismicio/e2e-tests-utils 1.4.0-alpha.2 → 1.4.1

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.
Files changed (58) hide show
  1. package/README.md +16 -9
  2. package/dist/clients/apiClient.cjs +39 -0
  3. package/dist/clients/apiClient.cjs.map +1 -0
  4. package/dist/clients/apiClient.d.ts +30 -0
  5. package/dist/clients/apiClient.js +39 -0
  6. package/dist/clients/apiClient.js.map +1 -0
  7. package/dist/clients/authenticationApi.cjs +54 -34
  8. package/dist/clients/authenticationApi.cjs.map +1 -1
  9. package/dist/clients/authenticationApi.d.ts +13 -5
  10. package/dist/clients/authenticationApi.js +55 -35
  11. package/dist/clients/authenticationApi.js.map +1 -1
  12. package/dist/clients/contentApi.cjs +20 -50
  13. package/dist/clients/contentApi.cjs.map +1 -1
  14. package/dist/clients/contentApi.d.ts +27 -37
  15. package/dist/clients/contentApi.js +20 -50
  16. package/dist/clients/contentApi.js.map +1 -1
  17. package/dist/clients/coreApi.cjs +36 -31
  18. package/dist/clients/coreApi.cjs.map +1 -1
  19. package/dist/clients/coreApi.d.ts +21 -3
  20. package/dist/clients/coreApi.js +37 -32
  21. package/dist/clients/coreApi.js.map +1 -1
  22. package/dist/clients/customTypesApi.cjs +48 -42
  23. package/dist/clients/customTypesApi.cjs.map +1 -1
  24. package/dist/clients/customTypesApi.d.ts +34 -6
  25. package/dist/clients/customTypesApi.js +49 -43
  26. package/dist/clients/customTypesApi.js.map +1 -1
  27. package/dist/clients/migrationApi.cjs +30 -29
  28. package/dist/clients/migrationApi.cjs.map +1 -1
  29. package/dist/clients/migrationApi.d.ts +27 -5
  30. package/dist/clients/migrationApi.js +31 -30
  31. package/dist/clients/migrationApi.js.map +1 -1
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.js +2 -2
  34. package/dist/managers/repositories.cjs +19 -9
  35. package/dist/managers/repositories.cjs.map +1 -1
  36. package/dist/managers/repositories.d.ts +2 -2
  37. package/dist/managers/repositories.js +23 -13
  38. package/dist/managers/repositories.js.map +1 -1
  39. package/dist/managers/repository.cjs +9 -1
  40. package/dist/managers/repository.cjs.map +1 -1
  41. package/dist/managers/repository.d.ts +6 -4
  42. package/dist/managers/repository.js +9 -1
  43. package/dist/managers/repository.js.map +1 -1
  44. package/dist/utils/log.cjs +4 -0
  45. package/dist/utils/log.cjs.map +1 -1
  46. package/dist/utils/log.d.ts +2 -0
  47. package/dist/utils/log.js +4 -0
  48. package/dist/utils/log.js.map +1 -1
  49. package/package.json +3 -1
  50. package/src/clients/apiClient.ts +48 -0
  51. package/src/clients/authenticationApi.ts +52 -50
  52. package/src/clients/contentApi.ts +54 -45
  53. package/src/clients/coreApi.ts +36 -42
  54. package/src/clients/customTypesApi.ts +34 -59
  55. package/src/clients/migrationApi.ts +36 -45
  56. package/src/managers/repositories.ts +26 -20
  57. package/src/managers/repository.ts +21 -8
  58. package/src/utils/log.ts +11 -0
package/README.md CHANGED
@@ -26,9 +26,9 @@ const config: RepositoryConfig = {
26
26
  defaultLocale: "en-gb",
27
27
  // ... see RepositoryConfig for other options
28
28
  };
29
- const credentials = { email, password };
29
+ const authConfig = { email, password };
30
30
 
31
- const testUtils = createRepositoriesManager("https://prismic.io", credentials);
31
+ const testUtils = createRepositoriesManager({ urlConfig :"https://prismic.io", authConfig});
32
32
  const repository = await testUtils.createRepository(config);
33
33
 
34
34
  // A repository is now available with a unique name and configured as required
@@ -93,6 +93,18 @@ await testUtils.createRepository(config);
93
93
  const token = await testUtils.getUserApiToken();
94
94
  ```
95
95
 
96
+ ### Get API clients
97
+
98
+ The library provides a few api clients for Prismic services. For example the Content Api.
99
+
100
+ ```typescript
101
+ const contentApi = repository.getContentApiClient();
102
+ const document = await contentApi.getDocumentByID(documentId);
103
+ ```
104
+
105
+ The `@prismicio/client` package could have been used but had too many abstractions (caching, error handling) that we don't necessarly want for test execution.
106
+
107
+
96
108
  ### Retrieve a RepositoryManager of an existing repository
97
109
 
98
110
  ```typescript
@@ -107,8 +119,8 @@ await repository.createRelease("next release");
107
119
 
108
120
  When you create the manager, you have 2 options:
109
121
 
110
- - Provide the base Prismic url, like `createRepositoriesManager("https://prismic.io", credentials)`. The library infers the service urls from the base URL like `http://authentication.prismic.io`
111
- - One a dev environment, you might want to have control over each service url. Use `createRepositoriesManager({ baseURL: "https://...", customTypesApi : "https://...", authenticationApi : "https://..."}, credentials)`
122
+ - Provide the base Prismic url, like `createRepositoriesManager({ urlConfig: "https://prismic.io", authConfig: credentials })`. The library infers the service urls from the base URL like `http://authentication.prismic.io`
123
+ - One a dev environment, you might want to have control over each service url. Use `createRepositoriesManager({ urlConfig: { baseURL: "https://...", customTypesApi : "https://...", authenticationApi : "https://..."}, authConfig })`
112
124
 
113
125
  #### Customise the log level
114
126
 
@@ -116,8 +128,3 @@ By default, the library logs each operation, this can be changed:
116
128
 
117
129
  - Set the environment variable to `prismic_e2e_tests_utils_silent` to `true` to remove all logs.
118
130
  - Set the environment variable to `prismic_e2e_tests_utils_log_level` to `info` or `debug`.
119
-
120
-
121
- ---
122
-
123
- _Note: Make sure to replace placeholders like `email`, `password` and other specific values with your actual configuration._
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => {
5
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+ return value;
7
+ };
8
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
9
+ const test = require("@playwright/test");
10
+ class AuthenticatedApiClient {
11
+ constructor(baseURL, token, headers) {
12
+ __publicField(this, "baseURL");
13
+ __publicField(this, "token");
14
+ __publicField(this, "headers");
15
+ __publicField(this, "_context");
16
+ this.baseURL = baseURL;
17
+ this.token = token;
18
+ this.headers = headers;
19
+ }
20
+ /**
21
+ * Returns a Playwright ApiRequestContext instance with the necessary
22
+ * authorization headers.
23
+ */
24
+ async getContext() {
25
+ if (!this._context) {
26
+ const token = typeof this.token === "string" ? this.token : await this.token();
27
+ this._context = await test.request.newContext({
28
+ baseURL: this.baseURL,
29
+ extraHTTPHeaders: {
30
+ Authorization: `Bearer ${token}`,
31
+ ...this.headers
32
+ }
33
+ });
34
+ }
35
+ return this._context;
36
+ }
37
+ }
38
+ exports.AuthenticatedApiClient = AuthenticatedApiClient;
39
+ //# sourceMappingURL=apiClient.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiClient.cjs","sources":["../../../src/clients/apiClient.ts"],"sourcesContent":["import { APIRequestContext, request } from \"@playwright/test\";\n\n/**\n * The authentication token. Can be a string or a function that returns a\n * promise resolving to the token.\n */\nexport type AuthServerToken = string | (() => Promise<string>);\n\n/**\n * Abstract class for Prismic api clients that use the Prismic authentication\n * server. This class takes care or creating the Playwright context with the\n * necessary authorization headers.\n *\n * This class performs requests with Playwright instead of a library like Axios\n * which has the advantage of tracing all the network details in the Playwright\n * reports making test failures investigation easier for projects that use\n * Playwright.\n */\nexport abstract class AuthenticatedApiClient {\n\tprivate _context?: APIRequestContext;\n\n\tconstructor(\n\t\tprivate readonly baseURL: string,\n\t\tprivate readonly token: AuthServerToken,\n\t\tprivate readonly headers?: { [key: string]: string } | undefined,\n\t) {}\n\n\t/**\n\t * Returns a Playwright ApiRequestContext instance with the necessary\n\t * authorization headers.\n\t */\n\tprotected async getContext(): Promise<APIRequestContext> {\n\t\tif (!this._context) {\n\t\t\tconst token =\n\t\t\t\ttypeof this.token === \"string\" ? this.token : await this.token();\n\n\t\t\tthis._context = await request.newContext({\n\t\t\t\tbaseURL: this.baseURL,\n\t\t\t\textraHTTPHeaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...this.headers,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\treturn this._context;\n\t}\n}\n"],"names":["request"],"mappings":";;;;;;;;;MAkBsB,uBAAsB;AAAA,EAG3C,YACkB,SACA,OACA,SAA+C;AAF/C;AACA;AACA;AALV;AAGU,SAAO,UAAP;AACA,SAAK,QAAL;AACA,SAAO,UAAP;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,MAAM,aAAU;AACrB,QAAA,CAAC,KAAK,UAAU;AACb,YAAA,QACL,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,MAAM,KAAK;AAErD,WAAA,WAAW,MAAMA,KAAA,QAAQ,WAAW;AAAA,QACxC,SAAS,KAAK;AAAA,QACd,kBAAkB;AAAA,UACjB,eAAe,UAAU,KAAK;AAAA,UAC9B,GAAG,KAAK;AAAA,QACR;AAAA,MAAA,CACD;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACb;AACA;;"}
@@ -0,0 +1,30 @@
1
+ import { APIRequestContext } from "@playwright/test";
2
+ /**
3
+ * The authentication token. Can be a string or a function that returns a
4
+ * promise resolving to the token.
5
+ */
6
+ export type AuthServerToken = string | (() => Promise<string>);
7
+ /**
8
+ * Abstract class for Prismic api clients that use the Prismic authentication
9
+ * server. This class takes care or creating the Playwright context with the
10
+ * necessary authorization headers.
11
+ *
12
+ * This class performs requests with Playwright instead of a library like Axios
13
+ * which has the advantage of tracing all the network details in the Playwright
14
+ * reports making test failures investigation easier for projects that use
15
+ * Playwright.
16
+ */
17
+ export declare abstract class AuthenticatedApiClient {
18
+ private readonly baseURL;
19
+ private readonly token;
20
+ private readonly headers?;
21
+ private _context?;
22
+ constructor(baseURL: string, token: AuthServerToken, headers?: {
23
+ [key: string]: string;
24
+ } | undefined);
25
+ /**
26
+ * Returns a Playwright ApiRequestContext instance with the necessary
27
+ * authorization headers.
28
+ */
29
+ protected getContext(): Promise<APIRequestContext>;
30
+ }
@@ -0,0 +1,39 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+ import { request } from "@playwright/test";
8
+ class AuthenticatedApiClient {
9
+ constructor(baseURL, token, headers) {
10
+ __publicField(this, "baseURL");
11
+ __publicField(this, "token");
12
+ __publicField(this, "headers");
13
+ __publicField(this, "_context");
14
+ this.baseURL = baseURL;
15
+ this.token = token;
16
+ this.headers = headers;
17
+ }
18
+ /**
19
+ * Returns a Playwright ApiRequestContext instance with the necessary
20
+ * authorization headers.
21
+ */
22
+ async getContext() {
23
+ if (!this._context) {
24
+ const token = typeof this.token === "string" ? this.token : await this.token();
25
+ this._context = await request.newContext({
26
+ baseURL: this.baseURL,
27
+ extraHTTPHeaders: {
28
+ Authorization: `Bearer ${token}`,
29
+ ...this.headers
30
+ }
31
+ });
32
+ }
33
+ return this._context;
34
+ }
35
+ }
36
+ export {
37
+ AuthenticatedApiClient
38
+ };
39
+ //# sourceMappingURL=apiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiClient.js","sources":["../../../src/clients/apiClient.ts"],"sourcesContent":["import { APIRequestContext, request } from \"@playwright/test\";\n\n/**\n * The authentication token. Can be a string or a function that returns a\n * promise resolving to the token.\n */\nexport type AuthServerToken = string | (() => Promise<string>);\n\n/**\n * Abstract class for Prismic api clients that use the Prismic authentication\n * server. This class takes care or creating the Playwright context with the\n * necessary authorization headers.\n *\n * This class performs requests with Playwright instead of a library like Axios\n * which has the advantage of tracing all the network details in the Playwright\n * reports making test failures investigation easier for projects that use\n * Playwright.\n */\nexport abstract class AuthenticatedApiClient {\n\tprivate _context?: APIRequestContext;\n\n\tconstructor(\n\t\tprivate readonly baseURL: string,\n\t\tprivate readonly token: AuthServerToken,\n\t\tprivate readonly headers?: { [key: string]: string } | undefined,\n\t) {}\n\n\t/**\n\t * Returns a Playwright ApiRequestContext instance with the necessary\n\t * authorization headers.\n\t */\n\tprotected async getContext(): Promise<APIRequestContext> {\n\t\tif (!this._context) {\n\t\t\tconst token =\n\t\t\t\ttypeof this.token === \"string\" ? this.token : await this.token();\n\n\t\t\tthis._context = await request.newContext({\n\t\t\t\tbaseURL: this.baseURL,\n\t\t\t\textraHTTPHeaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\t...this.headers,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\treturn this._context;\n\t}\n}\n"],"names":[],"mappings":";;;;;;;MAkBsB,uBAAsB;AAAA,EAG3C,YACkB,SACA,OACA,SAA+C;AAF/C;AACA;AACA;AALV;AAGU,SAAO,UAAP;AACA,SAAK,QAAL;AACA,SAAO,UAAP;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,MAAM,aAAU;AACrB,QAAA,CAAC,KAAK,UAAU;AACb,YAAA,QACL,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,MAAM,KAAK;AAErD,WAAA,WAAW,MAAM,QAAQ,WAAW;AAAA,QACxC,SAAS,KAAK;AAAA,QACd,kBAAkB;AAAA,UACjB,eAAe,UAAU,KAAK;AAAA,UAC9B,GAAG,KAAK;AAAA,QACR;AAAA,MAAA,CACD;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACb;AACA;"}
@@ -1,55 +1,75 @@
1
1
  "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => {
5
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+ return value;
7
+ };
2
8
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const axios = require("axios");
9
+ const test = require("@playwright/test");
4
10
  const log = require("../utils/log.cjs");
5
- const createAuthenticationApiClient = (baseURL, auth) => {
6
- let authToken;
7
- const client = axios.create({
8
- baseURL,
9
- validateStatus: () => true
10
- // Don't throw on 4XX errors
11
- });
12
- async function login() {
11
+ class AuthenticationApiClient {
12
+ constructor(baseURL, auth) {
13
+ __publicField(this, "baseURL");
14
+ __publicField(this, "auth");
15
+ __publicField(this, "authToken");
16
+ __publicField(this, "_context");
17
+ this.baseURL = baseURL;
18
+ this.auth = auth;
19
+ }
20
+ async getContext() {
21
+ if (!this._context) {
22
+ this._context = await test.request.newContext({
23
+ baseURL: this.baseURL
24
+ });
25
+ }
26
+ return this._context;
27
+ }
28
+ async login() {
13
29
  const profiler = log.logger.startTimer();
14
- const result = await client.post("login", {
15
- email: auth.email,
16
- password: auth.password
30
+ const context = await this.getContext();
31
+ const result = await context.post("login", {
32
+ data: {
33
+ email: this.auth.email,
34
+ password: this.auth.password
35
+ }
17
36
  });
18
- if (!result.data || typeof result.data !== "string") {
19
- log.logHttpResponse(result);
37
+ const token = await result.text();
38
+ if (!result.ok() || !token) {
39
+ log.logPlaywrightApiResponse(result);
20
40
  throw new Error("Authentication failed, no token received.");
21
41
  }
22
42
  profiler.done({
23
- message: `generated user token for ${auth.email} from auth service`
43
+ message: `generated user token for ${this.auth.email} from auth service`
24
44
  });
25
- return result.data;
45
+ return token;
26
46
  }
27
- async function getToken() {
28
- if (!authToken) {
29
- authToken = await login();
47
+ /** Return an api user token. Creates one if needed. */
48
+ async getToken() {
49
+ if (!this.authToken) {
50
+ this.authToken = await this.login();
30
51
  }
31
- return authToken;
52
+ return this.authToken;
32
53
  }
33
- async function getMachine2MachineToken(repository) {
34
- if (!authToken) {
35
- authToken = await login();
54
+ /** Return an api user token. Creates one if needed. */
55
+ async getMachine2MachineToken(repository) {
56
+ if (!this.authToken) {
57
+ this.authToken = await this.login();
36
58
  }
37
- const result = await client.get("machine2machine", {
59
+ const context = await this.getContext();
60
+ const result = await context.get("machine2machine", {
38
61
  headers: {
39
- Authorization: `Bearer ${authToken}`,
62
+ Authorization: `Bearer ${this.authToken}`,
40
63
  repository
41
64
  }
42
65
  });
43
- if (![200].includes(result.status) || !result.data.token) {
44
- log.logHttpResponse(result);
66
+ if (!result.ok()) {
67
+ log.logPlaywrightApiResponse(result);
45
68
  throw new Error("Machine2Machine token generation failed, no token received.");
46
69
  }
47
- return result.data.token;
70
+ const token = (await result.json()).token;
71
+ return token;
48
72
  }
49
- return {
50
- getToken,
51
- getMachine2MachineToken
52
- };
53
- };
54
- exports.createAuthenticationApiClient = createAuthenticationApiClient;
73
+ }
74
+ exports.AuthenticationApiClient = AuthenticationApiClient;
55
75
  //# sourceMappingURL=authenticationApi.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"authenticationApi.cjs","sources":["../../../src/clients/authenticationApi.ts"],"sourcesContent":["import axios, { AxiosInstance } from \"axios\";\n\nimport { AuthConfig } from \"../types\";\n\nimport { logHttpResponse, logger } from \"../utils/log\";\n\nexport type AuthenticationClient = {\n\tgetToken: () => Promise<string>;\n\tgetMachine2MachineToken: (repository: string) => Promise<string>;\n};\n\n/** Client for interacting with the authentication service to manage tokens */\nexport const createAuthenticationApiClient = (\n\tbaseURL: string,\n\tauth: AuthConfig,\n): AuthenticationClient => {\n\tlet authToken: string;\n\n\tconst client: AxiosInstance = axios.create({\n\t\tbaseURL,\n\t\tvalidateStatus: () => true, // Don't throw on 4XX errors\n\t});\n\n\tasync function login(): Promise<string> {\n\t\tconst profiler = logger.startTimer();\n\n\t\tconst result = await client.post(\"login\", {\n\t\t\temail: auth.email,\n\t\t\tpassword: auth.password,\n\t\t});\n\n\t\tif (!result.data || typeof result.data !== \"string\") {\n\t\t\tlogHttpResponse(result);\n\t\t\tthrow new Error(\"Authentication failed, no token received.\");\n\t\t}\n\n\t\tprofiler.done({\n\t\t\tmessage: `generated user token for ${auth.email} from auth service`,\n\t\t});\n\n\t\treturn result.data;\n\t}\n\n\t/** Return an api user token. Creates one if needed. */\n\tasync function getToken(): Promise<string> {\n\t\tif (!authToken) {\n\t\t\tauthToken = await login();\n\t\t}\n\n\t\treturn authToken;\n\t}\n\n\t/** Return an api user token. Creates one if needed. */\n\tasync function getMachine2MachineToken(repository: string): Promise<string> {\n\t\tif (!authToken) {\n\t\t\tauthToken = await login();\n\t\t}\n\t\tconst result = await client.get<{ token: string; timestamp: number }>(\n\t\t\t\"machine2machine\",\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${authToken}`,\n\t\t\t\t\trepository,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tif (![200].includes(result.status) || !result.data.token) {\n\t\t\tlogHttpResponse(result);\n\t\t\tthrow new Error(\n\t\t\t\t\"Machine2Machine token generation failed, no token received.\",\n\t\t\t);\n\t\t}\n\n\t\treturn result.data.token;\n\t}\n\n\treturn {\n\t\tgetToken,\n\t\tgetMachine2MachineToken,\n\t};\n};\n"],"names":["logger","logHttpResponse"],"mappings":";;;;AAYa,MAAA,gCAAgC,CAC5C,SACA,SACyB;AACrB,MAAA;AAEE,QAAA,SAAwB,MAAM,OAAO;AAAA,IAC1C;AAAA,IACA,gBAAgB,MAAM;AAAA;AAAA,EAAA,CACtB;AAED,iBAAe,QAAK;AACb,UAAA,WAAWA,WAAO;AAExB,UAAM,SAAS,MAAM,OAAO,KAAK,SAAS;AAAA,MACzC,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,IAAA,CACf;AAED,QAAI,CAAC,OAAO,QAAQ,OAAO,OAAO,SAAS,UAAU;AACpDC,UAAA,gBAAgB,MAAM;AAChB,YAAA,IAAI,MAAM,2CAA2C;AAAA,IAC5D;AAEA,aAAS,KAAK;AAAA,MACb,SAAS,4BAA4B,KAAK,KAAK;AAAA,IAAA,CAC/C;AAED,WAAO,OAAO;AAAA,EACf;AAGA,iBAAe,WAAQ;AACtB,QAAI,CAAC,WAAW;AACf,kBAAY,MAAM;IACnB;AAEO,WAAA;AAAA,EACR;AAGA,iBAAe,wBAAwB,YAAkB;AACxD,QAAI,CAAC,WAAW;AACf,kBAAY,MAAM;IACnB;AACA,UAAM,SAAS,MAAM,OAAO,IAC3B,mBACA;AAAA,MACC,SAAS;AAAA,QACR,eAAe,UAAU,SAAS;AAAA,QAClC;AAAA,MACA;AAAA,IAAA,CACD;AAGE,QAAA,CAAC,CAAC,GAAG,EAAE,SAAS,OAAO,MAAM,KAAK,CAAC,OAAO,KAAK,OAAO;AACzDA,UAAA,gBAAgB,MAAM;AAChB,YAAA,IAAI,MACT,6DAA6D;AAAA,IAE/D;AAEA,WAAO,OAAO,KAAK;AAAA,EACpB;AAEO,SAAA;AAAA,IACN;AAAA,IACA;AAAA,EAAA;AAEF;;"}
1
+ {"version":3,"file":"authenticationApi.cjs","sources":["../../../src/clients/authenticationApi.ts"],"sourcesContent":["import { APIRequestContext, request } from \"@playwright/test\";\n\nimport { AuthConfig } from \"../types\";\n\nimport { logPlaywrightApiResponse, logger } from \"../utils/log\";\n\n/** Client for interacting with the authentication service to manage tokens */\nexport class AuthenticationApiClient {\n\tprivate authToken?: string;\n\tprivate _context?: APIRequestContext;\n\n\tconstructor(\n\t\tprivate readonly baseURL: string,\n\t\tprivate readonly auth: AuthConfig,\n\t) {}\n\n\tprivate async getContext(): Promise<APIRequestContext> {\n\t\tif (!this._context) {\n\t\t\tthis._context = await request.newContext({\n\t\t\t\tbaseURL: this.baseURL,\n\t\t\t});\n\t\t}\n\n\t\treturn this._context;\n\t}\n\n\tprivate async login(): Promise<string> {\n\t\tconst profiler = logger.startTimer();\n\n\t\tconst context = await this.getContext();\n\t\tconst result = await context.post(\"login\", {\n\t\t\tdata: {\n\t\t\t\temail: this.auth.email,\n\t\t\t\tpassword: this.auth.password,\n\t\t\t},\n\t\t});\n\n\t\tconst token = await result.text();\n\t\tif (!result.ok() || !token) {\n\t\t\tlogPlaywrightApiResponse(result);\n\t\t\tthrow new Error(\"Authentication failed, no token received.\");\n\t\t}\n\n\t\tprofiler.done({\n\t\t\tmessage: `generated user token for ${this.auth.email} from auth service`,\n\t\t});\n\n\t\treturn token;\n\t}\n\n\t/** Return an api user token. Creates one if needed. */\n\tasync getToken(): Promise<string> {\n\t\tif (!this.authToken) {\n\t\t\tthis.authToken = await this.login();\n\t\t}\n\n\t\treturn this.authToken;\n\t}\n\n\t/** Return an api user token. Creates one if needed. */\n\tasync getMachine2MachineToken(repository: string): Promise<string> {\n\t\tif (!this.authToken) {\n\t\t\tthis.authToken = await this.login();\n\t\t}\n\n\t\tconst context = await this.getContext();\n\t\tconst result = await context.get(\"machine2machine\", {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${this.authToken}`,\n\t\t\t\trepository,\n\t\t\t},\n\t\t});\n\n\t\tif (!result.ok()) {\n\t\t\tlogPlaywrightApiResponse(result);\n\t\t\tthrow new Error(\n\t\t\t\t\"Machine2Machine token generation failed, no token received.\",\n\t\t\t);\n\t\t}\n\t\tconst token = (await result.json()).token;\n\n\t\treturn token;\n\t}\n}\n"],"names":["request","logger","logPlaywrightApiResponse"],"mappings":";;;;;;;;;;MAOa,wBAAuB;AAAA,EAInC,YACkB,SACA,MAAgB;AADhB;AACA;AALV;AACA;AAGU,SAAO,UAAP;AACA,SAAI,OAAJ;AAAA,EACf;AAAA,EAEK,MAAM,aAAU;AACnB,QAAA,CAAC,KAAK,UAAU;AACd,WAAA,WAAW,MAAMA,KAAA,QAAQ,WAAW;AAAA,QACxC,SAAS,KAAK;AAAA,MAAA,CACd;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACb;AAAA,EAEQ,MAAM,QAAK;AACZ,UAAA,WAAWC,WAAO;AAElB,UAAA,UAAU,MAAM,KAAK;AAC3B,UAAM,SAAS,MAAM,QAAQ,KAAK,SAAS;AAAA,MAC1C,MAAM;AAAA,QACL,OAAO,KAAK,KAAK;AAAA,QACjB,UAAU,KAAK,KAAK;AAAA,MACpB;AAAA,IAAA,CACD;AAEK,UAAA,QAAQ,MAAM,OAAO;AAC3B,QAAI,CAAC,OAAO,QAAQ,CAAC,OAAO;AAC3BC,UAAA,yBAAyB,MAAM;AACzB,YAAA,IAAI,MAAM,2CAA2C;AAAA,IAC5D;AAEA,aAAS,KAAK;AAAA,MACb,SAAS,4BAA4B,KAAK,KAAK,KAAK;AAAA,IAAA,CACpD;AAEM,WAAA;AAAA,EACR;AAAA;AAAA,EAGA,MAAM,WAAQ;AACT,QAAA,CAAC,KAAK,WAAW;AACf,WAAA,YAAY,MAAM,KAAK;IAC7B;AAEA,WAAO,KAAK;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,wBAAwB,YAAkB;AAC3C,QAAA,CAAC,KAAK,WAAW;AACf,WAAA,YAAY,MAAM,KAAK;IAC7B;AAEM,UAAA,UAAU,MAAM,KAAK;AAC3B,UAAM,SAAS,MAAM,QAAQ,IAAI,mBAAmB;AAAA,MACnD,SAAS;AAAA,QACR,eAAe,UAAU,KAAK,SAAS;AAAA,QACvC;AAAA,MACA;AAAA,IAAA,CACD;AAEG,QAAA,CAAC,OAAO,MAAM;AACjBA,UAAA,yBAAyB,MAAM;AACzB,YAAA,IAAI,MACT,6DAA6D;AAAA,IAE/D;AACA,UAAM,SAAS,MAAM,OAAO,KAAA,GAAQ;AAE7B,WAAA;AAAA,EACR;AACA;;"}
@@ -1,7 +1,15 @@
1
1
  import { AuthConfig } from "../types";
2
- export type AuthenticationClient = {
3
- getToken: () => Promise<string>;
4
- getMachine2MachineToken: (repository: string) => Promise<string>;
5
- };
6
2
  /** Client for interacting with the authentication service to manage tokens */
7
- export declare const createAuthenticationApiClient: (baseURL: string, auth: AuthConfig) => AuthenticationClient;
3
+ export declare class AuthenticationApiClient {
4
+ private readonly baseURL;
5
+ private readonly auth;
6
+ private authToken?;
7
+ private _context?;
8
+ constructor(baseURL: string, auth: AuthConfig);
9
+ private getContext;
10
+ private login;
11
+ /** Return an api user token. Creates one if needed. */
12
+ getToken(): Promise<string>;
13
+ /** Return an api user token. Creates one if needed. */
14
+ getMachine2MachineToken(repository: string): Promise<string>;
15
+ }
@@ -1,55 +1,75 @@
1
- import axios from "axios";
2
- import { logHttpResponse, logger } from "../utils/log.js";
3
- const createAuthenticationApiClient = (baseURL, auth) => {
4
- let authToken;
5
- const client = axios.create({
6
- baseURL,
7
- validateStatus: () => true
8
- // Don't throw on 4XX errors
9
- });
10
- async function login() {
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+ import { request } from "@playwright/test";
8
+ import { logger, logPlaywrightApiResponse } from "../utils/log.js";
9
+ class AuthenticationApiClient {
10
+ constructor(baseURL, auth) {
11
+ __publicField(this, "baseURL");
12
+ __publicField(this, "auth");
13
+ __publicField(this, "authToken");
14
+ __publicField(this, "_context");
15
+ this.baseURL = baseURL;
16
+ this.auth = auth;
17
+ }
18
+ async getContext() {
19
+ if (!this._context) {
20
+ this._context = await request.newContext({
21
+ baseURL: this.baseURL
22
+ });
23
+ }
24
+ return this._context;
25
+ }
26
+ async login() {
11
27
  const profiler = logger.startTimer();
12
- const result = await client.post("login", {
13
- email: auth.email,
14
- password: auth.password
28
+ const context = await this.getContext();
29
+ const result = await context.post("login", {
30
+ data: {
31
+ email: this.auth.email,
32
+ password: this.auth.password
33
+ }
15
34
  });
16
- if (!result.data || typeof result.data !== "string") {
17
- logHttpResponse(result);
35
+ const token = await result.text();
36
+ if (!result.ok() || !token) {
37
+ logPlaywrightApiResponse(result);
18
38
  throw new Error("Authentication failed, no token received.");
19
39
  }
20
40
  profiler.done({
21
- message: `generated user token for ${auth.email} from auth service`
41
+ message: `generated user token for ${this.auth.email} from auth service`
22
42
  });
23
- return result.data;
43
+ return token;
24
44
  }
25
- async function getToken() {
26
- if (!authToken) {
27
- authToken = await login();
45
+ /** Return an api user token. Creates one if needed. */
46
+ async getToken() {
47
+ if (!this.authToken) {
48
+ this.authToken = await this.login();
28
49
  }
29
- return authToken;
50
+ return this.authToken;
30
51
  }
31
- async function getMachine2MachineToken(repository) {
32
- if (!authToken) {
33
- authToken = await login();
52
+ /** Return an api user token. Creates one if needed. */
53
+ async getMachine2MachineToken(repository) {
54
+ if (!this.authToken) {
55
+ this.authToken = await this.login();
34
56
  }
35
- const result = await client.get("machine2machine", {
57
+ const context = await this.getContext();
58
+ const result = await context.get("machine2machine", {
36
59
  headers: {
37
- Authorization: `Bearer ${authToken}`,
60
+ Authorization: `Bearer ${this.authToken}`,
38
61
  repository
39
62
  }
40
63
  });
41
- if (![200].includes(result.status) || !result.data.token) {
42
- logHttpResponse(result);
64
+ if (!result.ok()) {
65
+ logPlaywrightApiResponse(result);
43
66
  throw new Error("Machine2Machine token generation failed, no token received.");
44
67
  }
45
- return result.data.token;
68
+ const token = (await result.json()).token;
69
+ return token;
46
70
  }
47
- return {
48
- getToken,
49
- getMachine2MachineToken
50
- };
51
- };
71
+ }
52
72
  export {
53
- createAuthenticationApiClient
73
+ AuthenticationApiClient
54
74
  };
55
75
  //# sourceMappingURL=authenticationApi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authenticationApi.js","sources":["../../../src/clients/authenticationApi.ts"],"sourcesContent":["import axios, { AxiosInstance } from \"axios\";\n\nimport { AuthConfig } from \"../types\";\n\nimport { logHttpResponse, logger } from \"../utils/log\";\n\nexport type AuthenticationClient = {\n\tgetToken: () => Promise<string>;\n\tgetMachine2MachineToken: (repository: string) => Promise<string>;\n};\n\n/** Client for interacting with the authentication service to manage tokens */\nexport const createAuthenticationApiClient = (\n\tbaseURL: string,\n\tauth: AuthConfig,\n): AuthenticationClient => {\n\tlet authToken: string;\n\n\tconst client: AxiosInstance = axios.create({\n\t\tbaseURL,\n\t\tvalidateStatus: () => true, // Don't throw on 4XX errors\n\t});\n\n\tasync function login(): Promise<string> {\n\t\tconst profiler = logger.startTimer();\n\n\t\tconst result = await client.post(\"login\", {\n\t\t\temail: auth.email,\n\t\t\tpassword: auth.password,\n\t\t});\n\n\t\tif (!result.data || typeof result.data !== \"string\") {\n\t\t\tlogHttpResponse(result);\n\t\t\tthrow new Error(\"Authentication failed, no token received.\");\n\t\t}\n\n\t\tprofiler.done({\n\t\t\tmessage: `generated user token for ${auth.email} from auth service`,\n\t\t});\n\n\t\treturn result.data;\n\t}\n\n\t/** Return an api user token. Creates one if needed. */\n\tasync function getToken(): Promise<string> {\n\t\tif (!authToken) {\n\t\t\tauthToken = await login();\n\t\t}\n\n\t\treturn authToken;\n\t}\n\n\t/** Return an api user token. Creates one if needed. */\n\tasync function getMachine2MachineToken(repository: string): Promise<string> {\n\t\tif (!authToken) {\n\t\t\tauthToken = await login();\n\t\t}\n\t\tconst result = await client.get<{ token: string; timestamp: number }>(\n\t\t\t\"machine2machine\",\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${authToken}`,\n\t\t\t\t\trepository,\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tif (![200].includes(result.status) || !result.data.token) {\n\t\t\tlogHttpResponse(result);\n\t\t\tthrow new Error(\n\t\t\t\t\"Machine2Machine token generation failed, no token received.\",\n\t\t\t);\n\t\t}\n\n\t\treturn result.data.token;\n\t}\n\n\treturn {\n\t\tgetToken,\n\t\tgetMachine2MachineToken,\n\t};\n};\n"],"names":[],"mappings":";;AAYa,MAAA,gCAAgC,CAC5C,SACA,SACyB;AACrB,MAAA;AAEE,QAAA,SAAwB,MAAM,OAAO;AAAA,IAC1C;AAAA,IACA,gBAAgB,MAAM;AAAA;AAAA,EAAA,CACtB;AAED,iBAAe,QAAK;AACb,UAAA,WAAW,OAAO;AAExB,UAAM,SAAS,MAAM,OAAO,KAAK,SAAS;AAAA,MACzC,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,IAAA,CACf;AAED,QAAI,CAAC,OAAO,QAAQ,OAAO,OAAO,SAAS,UAAU;AACpD,sBAAgB,MAAM;AAChB,YAAA,IAAI,MAAM,2CAA2C;AAAA,IAC5D;AAEA,aAAS,KAAK;AAAA,MACb,SAAS,4BAA4B,KAAK,KAAK;AAAA,IAAA,CAC/C;AAED,WAAO,OAAO;AAAA,EACf;AAGA,iBAAe,WAAQ;AACtB,QAAI,CAAC,WAAW;AACf,kBAAY,MAAM;IACnB;AAEO,WAAA;AAAA,EACR;AAGA,iBAAe,wBAAwB,YAAkB;AACxD,QAAI,CAAC,WAAW;AACf,kBAAY,MAAM;IACnB;AACA,UAAM,SAAS,MAAM,OAAO,IAC3B,mBACA;AAAA,MACC,SAAS;AAAA,QACR,eAAe,UAAU,SAAS;AAAA,QAClC;AAAA,MACA;AAAA,IAAA,CACD;AAGE,QAAA,CAAC,CAAC,GAAG,EAAE,SAAS,OAAO,MAAM,KAAK,CAAC,OAAO,KAAK,OAAO;AACzD,sBAAgB,MAAM;AAChB,YAAA,IAAI,MACT,6DAA6D;AAAA,IAE/D;AAEA,WAAO,OAAO,KAAK;AAAA,EACpB;AAEO,SAAA;AAAA,IACN;AAAA,IACA;AAAA,EAAA;AAEF;"}
1
+ {"version":3,"file":"authenticationApi.js","sources":["../../../src/clients/authenticationApi.ts"],"sourcesContent":["import { APIRequestContext, request } from \"@playwright/test\";\n\nimport { AuthConfig } from \"../types\";\n\nimport { logPlaywrightApiResponse, logger } from \"../utils/log\";\n\n/** Client for interacting with the authentication service to manage tokens */\nexport class AuthenticationApiClient {\n\tprivate authToken?: string;\n\tprivate _context?: APIRequestContext;\n\n\tconstructor(\n\t\tprivate readonly baseURL: string,\n\t\tprivate readonly auth: AuthConfig,\n\t) {}\n\n\tprivate async getContext(): Promise<APIRequestContext> {\n\t\tif (!this._context) {\n\t\t\tthis._context = await request.newContext({\n\t\t\t\tbaseURL: this.baseURL,\n\t\t\t});\n\t\t}\n\n\t\treturn this._context;\n\t}\n\n\tprivate async login(): Promise<string> {\n\t\tconst profiler = logger.startTimer();\n\n\t\tconst context = await this.getContext();\n\t\tconst result = await context.post(\"login\", {\n\t\t\tdata: {\n\t\t\t\temail: this.auth.email,\n\t\t\t\tpassword: this.auth.password,\n\t\t\t},\n\t\t});\n\n\t\tconst token = await result.text();\n\t\tif (!result.ok() || !token) {\n\t\t\tlogPlaywrightApiResponse(result);\n\t\t\tthrow new Error(\"Authentication failed, no token received.\");\n\t\t}\n\n\t\tprofiler.done({\n\t\t\tmessage: `generated user token for ${this.auth.email} from auth service`,\n\t\t});\n\n\t\treturn token;\n\t}\n\n\t/** Return an api user token. Creates one if needed. */\n\tasync getToken(): Promise<string> {\n\t\tif (!this.authToken) {\n\t\t\tthis.authToken = await this.login();\n\t\t}\n\n\t\treturn this.authToken;\n\t}\n\n\t/** Return an api user token. Creates one if needed. */\n\tasync getMachine2MachineToken(repository: string): Promise<string> {\n\t\tif (!this.authToken) {\n\t\t\tthis.authToken = await this.login();\n\t\t}\n\n\t\tconst context = await this.getContext();\n\t\tconst result = await context.get(\"machine2machine\", {\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${this.authToken}`,\n\t\t\t\trepository,\n\t\t\t},\n\t\t});\n\n\t\tif (!result.ok()) {\n\t\t\tlogPlaywrightApiResponse(result);\n\t\t\tthrow new Error(\n\t\t\t\t\"Machine2Machine token generation failed, no token received.\",\n\t\t\t);\n\t\t}\n\t\tconst token = (await result.json()).token;\n\n\t\treturn token;\n\t}\n}\n"],"names":[],"mappings":";;;;;;;;MAOa,wBAAuB;AAAA,EAInC,YACkB,SACA,MAAgB;AADhB;AACA;AALV;AACA;AAGU,SAAO,UAAP;AACA,SAAI,OAAJ;AAAA,EACf;AAAA,EAEK,MAAM,aAAU;AACnB,QAAA,CAAC,KAAK,UAAU;AACd,WAAA,WAAW,MAAM,QAAQ,WAAW;AAAA,QACxC,SAAS,KAAK;AAAA,MAAA,CACd;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACb;AAAA,EAEQ,MAAM,QAAK;AACZ,UAAA,WAAW,OAAO;AAElB,UAAA,UAAU,MAAM,KAAK;AAC3B,UAAM,SAAS,MAAM,QAAQ,KAAK,SAAS;AAAA,MAC1C,MAAM;AAAA,QACL,OAAO,KAAK,KAAK;AAAA,QACjB,UAAU,KAAK,KAAK;AAAA,MACpB;AAAA,IAAA,CACD;AAEK,UAAA,QAAQ,MAAM,OAAO;AAC3B,QAAI,CAAC,OAAO,QAAQ,CAAC,OAAO;AAC3B,+BAAyB,MAAM;AACzB,YAAA,IAAI,MAAM,2CAA2C;AAAA,IAC5D;AAEA,aAAS,KAAK;AAAA,MACb,SAAS,4BAA4B,KAAK,KAAK,KAAK;AAAA,IAAA,CACpD;AAEM,WAAA;AAAA,EACR;AAAA;AAAA,EAGA,MAAM,WAAQ;AACT,QAAA,CAAC,KAAK,WAAW;AACf,WAAA,YAAY,MAAM,KAAK;IAC7B;AAEA,WAAO,KAAK;AAAA,EACb;AAAA;AAAA,EAGA,MAAM,wBAAwB,YAAkB;AAC3C,QAAA,CAAC,KAAK,WAAW;AACf,WAAA,YAAY,MAAM,KAAK;IAC7B;AAEM,UAAA,UAAU,MAAM,KAAK;AAC3B,UAAM,SAAS,MAAM,QAAQ,IAAI,mBAAmB;AAAA,MACnD,SAAS;AAAA,QACR,eAAe,UAAU,KAAK,SAAS;AAAA,QACvC;AAAA,MACA;AAAA,IAAA,CACD;AAEG,QAAA,CAAC,OAAO,MAAM;AACjB,+BAAyB,MAAM;AACzB,YAAA,IAAI,MACT,6DAA6D;AAAA,IAE/D;AACA,UAAM,SAAS,MAAM,OAAO,KAAA,GAAQ;AAE7B,WAAA;AAAA,EACR;AACA;"}
@@ -5,35 +5,18 @@ var __publicField = (obj, key, value) => {
5
5
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
6
  return value;
7
7
  };
8
- var __accessCheck = (obj, member, msg) => {
9
- if (!member.has(obj))
10
- throw TypeError("Cannot " + msg);
11
- };
12
- var __privateGet = (obj, member, getter) => {
13
- __accessCheck(obj, member, "read from private field");
14
- return getter ? getter.call(obj) : member.get(obj);
15
- };
16
- var __privateAdd = (obj, member, value) => {
17
- if (member.has(obj))
18
- throw TypeError("Cannot add the same private member more than once");
19
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
20
- };
21
- var __privateSet = (obj, member, value, setter) => {
22
- __accessCheck(obj, member, "write to private field");
23
- setter ? setter.call(obj, value) : member.set(obj, value);
24
- return value;
25
- };
26
- var __privateMethod = (obj, member, method) => {
27
- __accessCheck(obj, member, "access private method");
28
- return method;
29
- };
30
- var _version, _accessToken, _context, context_fn;
31
8
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
32
- const test = require("@playwright/test");
33
- class ContentApiClient {
9
+ const apiClient = require("./apiClient.cjs");
10
+ class ContentApiClient extends apiClient.AuthenticatedApiClient {
34
11
  /**
35
- * @example new ContentApiClient("https://my-repo.cdn.prismic.io" { version :
36
- * "v2", accessToken: "my-secret-token" })
12
+ * @example To instantiate the class:
13
+ *
14
+ * ```js
15
+ * new ContentApiClient("https://my-repo.cdn.prismic.io", {
16
+ * version: "v2",
17
+ * accessToken: "my-secret-token",
18
+ * });
19
+ * ```
37
20
  *
38
21
  * @param baseURL - the api base URL like https://my-repo.cdn.prismic.io
39
22
  * @param config - Optional configuration
@@ -43,18 +26,16 @@ class ContentApiClient {
43
26
  * https://prismic.io/docs/access-token
44
27
  */
45
28
  constructor(baseURL, config = {}) {
46
- __privateAdd(this, _context);
47
- __publicField(this, "baseURL");
48
- __privateAdd(this, _version, void 0);
49
- __privateAdd(this, _accessToken, void 0);
50
- this.baseURL = baseURL;
51
- __privateSet(this, _version, config.version || "v2");
52
- __privateSet(this, _accessToken, config.accessToken);
29
+ super(baseURL, config.accessToken || "");
30
+ __publicField(this, "version");
31
+ __publicField(this, "accessToken");
32
+ this.version = config.version || "v2";
33
+ this.accessToken = config.accessToken;
53
34
  }
54
35
  async get(path, params, headers) {
55
- const context = await __privateMethod(this, _context, context_fn).call(this);
36
+ const context = await this.getContext();
56
37
  const securityParams = {
57
- ...__privateGet(this, _accessToken) ? { access_token: __privateGet(this, _accessToken) } : {}
38
+ ...this.accessToken ? { access_token: this.accessToken } : {}
58
39
  };
59
40
  return context.get(path, {
60
41
  params: { ...securityParams, ...params },
@@ -67,10 +48,10 @@ class ContentApiClient {
67
48
  }
68
49
  /** Query the graphql api - https://prismic.io/docs/graphql-technical-reference */
69
50
  async graphql(ref, query) {
70
- return this.getAsJson("/graphql", { query }, { "Prismic-ref": ref });
51
+ return this.getAsJson("graphql", { query }, { "Prismic-ref": ref });
71
52
  }
72
53
  async getRefs() {
73
- const data = await this.getAsJson(`/api/${__privateGet(this, _version)}`);
54
+ const data = await this.getAsJson(`api/${this.version}`);
74
55
  return data.refs;
75
56
  }
76
57
  async getMasterRef() {
@@ -95,7 +76,7 @@ class ContentApiClient {
95
76
  if (!ref) {
96
77
  ref = await this.getMasterRef();
97
78
  }
98
- return this.getAsJson(`/api/${__privateGet(this, _version)}/documents/search`, {
79
+ return this.getAsJson(`api/${this.version}/documents/search`, {
99
80
  ...filters,
100
81
  ref
101
82
  });
@@ -120,16 +101,5 @@ class ContentApiClient {
120
101
  }
121
102
  }
122
103
  }
123
- _version = new WeakMap();
124
- _accessToken = new WeakMap();
125
- _context = new WeakSet();
126
- context_fn = function() {
127
- return test.request.newContext({
128
- baseURL: this.baseURL,
129
- // reset any Authorization header set globally with Playwright
130
- // didn't find a way to delete it
131
- extraHTTPHeaders: { Authorization: "" }
132
- });
133
- };
134
104
  exports.ContentApiClient = ContentApiClient;
135
105
  //# sourceMappingURL=contentApi.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"contentApi.cjs","sources":["../../../src/clients/contentApi.ts"],"sourcesContent":["import { APIResponse, request } from \"@playwright/test\";\n\nexport interface Error {\n\ttype: string;\n\tmessage: string;\n}\nexport interface SearchResponse {\n\tpage: number;\n\tresults_per_page: number;\n\tresults_size: number;\n\ttotal_results_size: number;\n\ttotal_pages: number;\n\tnext_page: string | null;\n\tprev_page: string | null;\n\tresults: Document[];\n}\n\nexport interface Document {\n\tid: string;\n\tuid: string | null;\n\turl: string | null;\n\ttype: string;\n\thref: string;\n\ttags: string[];\n\tfirst_publication_date: string;\n\tlast_publication_date: string;\n\tslugs: string[];\n\tlinked_documents: unknown[];\n\tlang: string;\n\talternate_languages: string[];\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdata: Record<string, any>;\n}\n\nexport interface GraphQLResponse {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdata: Record<string, any>;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\terrors?: { message: string; locations: any }[];\n}\n\nexport interface Ref {\n\tid: string;\n\tref: string;\n\tlabel: string;\n\tisMasterRef?: boolean;\n}\n\nexport interface RepoConfig {\n\trefs: Ref[];\n\tbookmarks: Record<string, unknown>;\n\ttypes: Record<string, string>;\n\tlanguages: {\n\t\tid: string;\n\t\tname: string;\n\t\tis_master: boolean;\n\t}[];\n\toauth_initiate: string;\n\toauth_token: string;\n\ttags: string[];\n\tlicense: string;\n\tversion: string;\n}\n\nexport type QueryParams = {\n\tref?: string;\n\tquery?: string;\n\tq?: string;\n\tgraphQuery?: string;\n\tfetchLinks?: string;\n\torderings?: string;\n\tpageSize?: number;\n\tpage?: number;\n\tlang?: string;\n\tafter?: string;\n\troutes?: string;\n};\n\ntype ApiVersions = \"v1\" | \"v2\";\n\n/**\n * Client to query the Prismic content api. Uses Playwright to benefit from\n * network request traces in your reports. The @prismicio/client could have been\n * used but had too many abstractions (caching, error handling) that we didn't\n * want for test execution. See api docs:\n * https://prismic.io/docs/rest-api-technical-reference\n */\nexport class ContentApiClient {\n\t#version: ApiVersions;\n\t#accessToken: string | undefined;\n\n\t/**\n\t * @example new ContentApiClient(\"https://my-repo.cdn.prismic.io\" { version :\n\t * \"v2\", accessToken: \"my-secret-token\" })\n\t *\n\t * @param baseURL - the api base URL like https://my-repo.cdn.prismic.io\n\t * @param config - Optional configuration\n\t *\n\t * - {@link config.version}: Api version, default is \"v2\"\n\t * - {@link config.accessToken}: Access token for the content api -\n\t * https://prismic.io/docs/access-token\n\t */\n\tconstructor(\n\t\tprivate readonly baseURL: string,\n\t\tconfig: { version?: ApiVersions; accessToken?: string } = {},\n\t) {\n\t\tthis.#version = config.version || \"v2\";\n\t\tthis.#accessToken = config.accessToken;\n\t}\n\n\t#context() {\n\t\treturn request.newContext({\n\t\t\tbaseURL: this.baseURL,\n\t\t\t// reset any Authorization header set globally with Playwright\n\t\t\t// didn't find a way to delete it\n\t\t\textraHTTPHeaders: { Authorization: \"\" },\n\t\t});\n\t}\n\n\tasync get(\n\t\tpath: string,\n\t\tparams?: QueryParams,\n\t\theaders?: Record<string, string>,\n\t): Promise<APIResponse> {\n\t\tconst context = await this.#context();\n\t\tconst securityParams = {\n\t\t\t...(this.#accessToken ? { access_token: this.#accessToken } : {}),\n\t\t};\n\n\t\treturn context.get(path, {\n\t\t\tparams: { ...securityParams, ...params },\n\t\t\theaders,\n\t\t});\n\t}\n\n\tasync getAsJson<T>(\n\t\turl: string,\n\t\tparams?: QueryParams,\n\t\theaders?: Record<string, string>,\n\t): Promise<T> {\n\t\tconst response = await this.get(url, params, headers);\n\n\t\treturn response.json() as T;\n\t}\n\n\t/** Query the graphql api - https://prismic.io/docs/graphql-technical-reference */\n\tasync graphql(ref: string, query: string): Promise<GraphQLResponse> {\n\t\treturn this.getAsJson<GraphQLResponse>(\n\t\t\t\"/graphql\",\n\t\t\t{ query },\n\t\t\t{ \"Prismic-ref\": ref },\n\t\t);\n\t}\n\n\tasync getRefs(): Promise<Ref[]> {\n\t\tconst data = await this.getAsJson<RepoConfig>(`/api/${this.#version}`);\n\n\t\treturn data.refs;\n\t}\n\n\tasync getMasterRef(): Promise<string> {\n\t\tconst refs = await this.getRefs();\n\n\t\tconst masterRef = refs.find(({ isMasterRef }) => isMasterRef === true);\n\t\tif (!masterRef) {\n\t\t\tthrow \"No master ref found\";\n\t\t}\n\n\t\treturn masterRef.ref;\n\t}\n\n\tasync getRefByReleaseID(releaseID: string): Promise<string> {\n\t\tconst refs = await this.getRefs();\n\t\tconst release = refs.find(({ id }) => id === releaseID);\n\t\tif (!release) {\n\t\t\tthrow `No ref found for release ${releaseID}`;\n\t\t}\n\n\t\treturn release.ref;\n\t}\n\n\t/** Search documents from the `/api/v<version>/documents/search` endpoint. */\n\tasync search(filters?: QueryParams): Promise<SearchResponse> {\n\t\tlet ref = filters?.ref;\n\t\tif (!ref) {\n\t\t\tref = await this.getMasterRef();\n\t\t}\n\n\t\treturn this.getAsJson<SearchResponse>(\n\t\t\t`/api/${this.#version}/documents/search`,\n\t\t\t{\n\t\t\t\t...filters,\n\t\t\t\tref,\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Search for a single document by its it, using the\n\t * `/api/v<version>/documents/search` endpoint and a default filter.\n\t */\n\tasync searchByID(id: string, filters?: QueryParams): Promise<SearchResponse> {\n\t\treturn this.search({ ...filters, q: `[[at(document.id, \"${id}\")]]` });\n\t}\n\n\t/** Retrieve a single document or undefined if not found. */\n\tasync getDocumentByID(\n\t\tid: string,\n\t\tfilters?: QueryParams,\n\t): Promise<Document | undefined> {\n\t\tconst data = await this.searchByID(id, filters);\n\t\tswitch (data.results_size) {\n\t\t\tcase 0:\n\t\t\t\treturn;\n\t\t\tcase 1:\n\t\t\t\treturn data.results[0];\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Too many documents returned with the same id ${id}`);\n\t\t}\n\t}\n}\n"],"names":["request"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuFa,iBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAe5B,YACkB,SACjB,SAA0D,IAAE;AAM7D;AAPkB;AAflB;AACA;AAckB,SAAO,UAAP;AAGZ,uBAAA,UAAW,OAAO,WAAW;AAClC,uBAAK,cAAe,OAAO;AAAA,EAC5B;AAAA,EAWA,MAAM,IACL,MACA,QACA,SAAgC;AAE1B,UAAA,UAAU,MAAM,sBAAK,sBAAL;AACtB,UAAM,iBAAiB;AAAA,MACtB,GAAI,mBAAK,gBAAe,EAAE,cAAc,mBAAK,cAAA,IAAiB;;AAGxD,WAAA,QAAQ,IAAI,MAAM;AAAA,MACxB,QAAQ,EAAE,GAAG,gBAAgB,GAAG,OAAQ;AAAA,MACxC;AAAA,IAAA,CACA;AAAA,EACF;AAAA,EAEA,MAAM,UACL,KACA,QACA,SAAgC;AAEhC,UAAM,WAAW,MAAM,KAAK,IAAI,KAAK,QAAQ,OAAO;AAEpD,WAAO,SAAS;EACjB;AAAA;AAAA,EAGA,MAAM,QAAQ,KAAa,OAAa;AAChC,WAAA,KAAK,UACX,YACA,EAAE,SACF,EAAE,eAAe,IAAA,CAAK;AAAA,EAExB;AAAA,EAEA,MAAM,UAAO;AACZ,UAAM,OAAO,MAAM,KAAK,UAAsB,QAAQ,mBAAK,SAAQ,EAAE;AAErE,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,MAAM,eAAY;AACX,UAAA,OAAO,MAAM,KAAK;AAElB,UAAA,YAAY,KAAK,KAAK,CAAC,EAAE,kBAAkB,gBAAgB,IAAI;AACrE,QAAI,CAAC,WAAW;AACT,YAAA;AAAA,IACP;AAEA,WAAO,UAAU;AAAA,EAClB;AAAA,EAEA,MAAM,kBAAkB,WAAiB;AAClC,UAAA,OAAO,MAAM,KAAK;AAClB,UAAA,UAAU,KAAK,KAAK,CAAC,EAAE,SAAS,OAAO,SAAS;AACtD,QAAI,CAAC,SAAS;AACb,YAAM,4BAA4B,SAAS;AAAA,IAC5C;AAEA,WAAO,QAAQ;AAAA,EAChB;AAAA;AAAA,EAGA,MAAM,OAAO,SAAqB;AACjC,QAAI,MAAM,mCAAS;AACnB,QAAI,CAAC,KAAK;AACH,YAAA,MAAM,KAAK;IAClB;AAEA,WAAO,KAAK,UACX,QAAQ,mBAAK,SAAQ,qBACrB;AAAA,MACC,GAAG;AAAA,MACH;AAAA,IAAA,CACA;AAAA,EAEH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,IAAY,SAAqB;AAC1C,WAAA,KAAK,OAAO,EAAE,GAAG,SAAS,GAAG,sBAAsB,EAAE,OAAA,CAAQ;AAAA,EACrE;AAAA;AAAA,EAGA,MAAM,gBACL,IACA,SAAqB;AAErB,UAAM,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO;AAC9C,YAAQ,KAAK,cAAc;AAAA,MAC1B,KAAK;AACJ;AAAA,MACD,KAAK;AACG,eAAA,KAAK,QAAQ,CAAC;AAAA,MACtB;AACC,cAAM,IAAI,MAAM,gDAAgD,EAAE,EAAE;AAAA,IACtE;AAAA,EACD;AACA;AApIA;AACA;AAqBA;AAAA,aAAQ,WAAA;AACP,SAAOA,KAAAA,QAAQ,WAAW;AAAA,IACzB,SAAS,KAAK;AAAA;AAAA;AAAA,IAGd,kBAAkB,EAAE,eAAe,GAAI;AAAA,EAAA,CACvC;AACF;;"}
1
+ {"version":3,"file":"contentApi.cjs","sources":["../../../src/clients/contentApi.ts"],"sourcesContent":["import { APIResponse } from \"@playwright/test\";\n\nimport { AuthenticatedApiClient } from \"./apiClient\";\n\nexport interface ContentApiError {\n\ttype: string;\n\tmessage: string;\n}\nexport interface ContentApiSearchResponse {\n\tpage: number;\n\tresults_per_page: number;\n\tresults_size: number;\n\ttotal_results_size: number;\n\ttotal_pages: number;\n\tnext_page: string | null;\n\tprev_page: string | null;\n\tresults: ContentApiDocument[];\n}\n\nexport interface ContentApiDocument {\n\tid: string;\n\tuid: string | null;\n\turl: string | null;\n\ttype: string;\n\thref: string;\n\ttags: string[];\n\tfirst_publication_date: string;\n\tlast_publication_date: string;\n\tslugs: string[];\n\tlinked_documents: unknown[];\n\tlang: string;\n\talternate_languages: string[];\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdata: Record<string, any>;\n}\n\nexport interface ContentApiGraphQLResponse {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdata: Record<string, any>;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\terrors?: { message: string; locations: any }[];\n}\n\nexport interface ContentApiRef {\n\tid: string;\n\tref: string;\n\tlabel: string;\n\tisMasterRef?: boolean;\n}\n\ninterface ContentApiRepoConfigResponse {\n\trefs: ContentApiRef[];\n\tbookmarks: Record<string, unknown>;\n\ttypes: Record<string, string>;\n\tlanguages: {\n\t\tid: string;\n\t\tname: string;\n\t\tis_master: boolean;\n\t}[];\n\toauth_initiate: string;\n\toauth_token: string;\n\ttags: string[];\n\tlicense: string;\n\tversion: string;\n}\n\ntype SearchQueryParams = {\n\tref?: string;\n\tquery?: string;\n\tq?: string;\n\tgraphQuery?: string;\n\tfetchLinks?: string;\n\torderings?: string;\n\tpageSize?: number;\n\tpage?: number;\n\tlang?: string;\n\tafter?: string;\n\troutes?: string;\n};\n\ntype ApiVersions = \"v1\" | \"v2\";\n\n/**\n * Client to query the Prismic content api. Uses Playwright to benefit from\n * network request traces in your reports. See api docs:\n * https://prismic.io/docs/rest-api-technical-reference\n */\nexport class ContentApiClient extends AuthenticatedApiClient {\n\tprivate version: ApiVersions;\n\tprivate accessToken: string | undefined;\n\n\t/**\n\t * @example To instantiate the class:\n\t *\n\t * ```js\n\t * new ContentApiClient(\"https://my-repo.cdn.prismic.io\", {\n\t * \tversion: \"v2\",\n\t * \taccessToken: \"my-secret-token\",\n\t * });\n\t * ```\n\t *\n\t * @param baseURL - the api base URL like https://my-repo.cdn.prismic.io\n\t * @param config - Optional configuration\n\t *\n\t * - {@link config.version}: Api version, default is \"v2\"\n\t * - {@link config.accessToken}: Access token for the content api -\n\t * https://prismic.io/docs/access-token\n\t */\n\tconstructor(\n\t\tbaseURL: string,\n\t\tconfig: { version?: ApiVersions; accessToken?: string } = {},\n\t) {\n\t\t// Use an empty string as Authorization header in case it is already set globally in the project Playwright config file.\n\t\t// This is because the content api returns an error in case it gets an non-empty invalid Authorization\n\t\t// even though it actually checks authorization from the access_token query parameter.\n\t\tsuper(baseURL, config.accessToken || \"\");\n\t\tthis.version = config.version || \"v2\";\n\t\tthis.accessToken = config.accessToken;\n\t}\n\n\tasync get(\n\t\tpath: string,\n\t\tparams?: SearchQueryParams,\n\t\theaders?: Record<string, string>,\n\t): Promise<APIResponse> {\n\t\tconst context = await this.getContext();\n\t\tconst securityParams = {\n\t\t\t...(this.accessToken ? { access_token: this.accessToken } : {}),\n\t\t};\n\n\t\treturn context.get(path, {\n\t\t\tparams: { ...securityParams, ...params },\n\t\t\theaders,\n\t\t});\n\t}\n\n\tasync getAsJson<T>(\n\t\turl: string,\n\t\tparams?: SearchQueryParams,\n\t\theaders?: Record<string, string>,\n\t): Promise<T> {\n\t\tconst response = await this.get(url, params, headers);\n\n\t\treturn response.json() as T;\n\t}\n\n\t/** Query the graphql api - https://prismic.io/docs/graphql-technical-reference */\n\tasync graphql(\n\t\tref: string,\n\t\tquery: string,\n\t): Promise<ContentApiGraphQLResponse> {\n\t\treturn this.getAsJson<ContentApiGraphQLResponse>(\n\t\t\t\"graphql\",\n\t\t\t{ query },\n\t\t\t{ \"Prismic-ref\": ref },\n\t\t);\n\t}\n\n\tasync getRefs(): Promise<ContentApiRef[]> {\n\t\tconst data = await this.getAsJson<ContentApiRepoConfigResponse>(\n\t\t\t`api/${this.version}`,\n\t\t);\n\n\t\treturn data.refs;\n\t}\n\n\tasync getMasterRef(): Promise<string> {\n\t\tconst refs = await this.getRefs();\n\n\t\tconst masterRef = refs.find(({ isMasterRef }) => isMasterRef === true);\n\t\tif (!masterRef) {\n\t\t\tthrow \"No master ref found\";\n\t\t}\n\n\t\treturn masterRef.ref;\n\t}\n\n\tasync getRefByReleaseID(releaseID: string): Promise<string> {\n\t\tconst refs = await this.getRefs();\n\t\tconst release = refs.find(({ id }) => id === releaseID);\n\t\tif (!release) {\n\t\t\tthrow `No ref found for release ${releaseID}`;\n\t\t}\n\n\t\treturn release.ref;\n\t}\n\n\t/** Search documents from the `/api/v<version>/documents/search` endpoint. */\n\tasync search(filters?: SearchQueryParams): Promise<ContentApiSearchResponse> {\n\t\tlet ref = filters?.ref;\n\t\tif (!ref) {\n\t\t\tref = await this.getMasterRef();\n\t\t}\n\n\t\treturn this.getAsJson<ContentApiSearchResponse>(\n\t\t\t`api/${this.version}/documents/search`,\n\t\t\t{\n\t\t\t\t...filters,\n\t\t\t\tref,\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Search for a single document by its it, using the\n\t * `/api/v<version>/documents/search` endpoint and a default filter.\n\t */\n\tasync searchByID(\n\t\tid: string,\n\t\tfilters?: SearchQueryParams,\n\t): Promise<ContentApiSearchResponse> {\n\t\treturn this.search({ ...filters, q: `[[at(document.id, \"${id}\")]]` });\n\t}\n\n\t/** Retrieve a single document or undefined if not found. */\n\tasync getDocumentByID(\n\t\tid: string,\n\t\tfilters?: SearchQueryParams,\n\t): Promise<ContentApiDocument | undefined> {\n\t\tconst data = await this.searchByID(id, filters);\n\t\tswitch (data.results_size) {\n\t\t\tcase 0:\n\t\t\t\treturn;\n\t\t\tcase 1:\n\t\t\t\treturn data.results[0];\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Too many documents returned with the same id ${id}`);\n\t\t}\n\t}\n}\n"],"names":["AuthenticatedApiClient"],"mappings":";;;;;;;;;AAuFM,MAAO,yBAAyBA,UAAAA,uBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqB3D,YACC,SACA,SAA0D,IAAE;AAKtD,UAAA,SAAS,OAAO,eAAe,EAAE;AA3BhC;AACA;AA2BF,SAAA,UAAU,OAAO,WAAW;AACjC,SAAK,cAAc,OAAO;AAAA,EAC3B;AAAA,EAEA,MAAM,IACL,MACA,QACA,SAAgC;AAE1B,UAAA,UAAU,MAAM,KAAK;AAC3B,UAAM,iBAAiB;AAAA,MACtB,GAAI,KAAK,cAAc,EAAE,cAAc,KAAK,YAAA,IAAgB;;AAGtD,WAAA,QAAQ,IAAI,MAAM;AAAA,MACxB,QAAQ,EAAE,GAAG,gBAAgB,GAAG,OAAQ;AAAA,MACxC;AAAA,IAAA,CACA;AAAA,EACF;AAAA,EAEA,MAAM,UACL,KACA,QACA,SAAgC;AAEhC,UAAM,WAAW,MAAM,KAAK,IAAI,KAAK,QAAQ,OAAO;AAEpD,WAAO,SAAS;EACjB;AAAA;AAAA,EAGA,MAAM,QACL,KACA,OAAa;AAEN,WAAA,KAAK,UACX,WACA,EAAE,SACF,EAAE,eAAe,IAAA,CAAK;AAAA,EAExB;AAAA,EAEA,MAAM,UAAO;AACZ,UAAM,OAAO,MAAM,KAAK,UACvB,OAAO,KAAK,OAAO,EAAE;AAGtB,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,MAAM,eAAY;AACX,UAAA,OAAO,MAAM,KAAK;AAElB,UAAA,YAAY,KAAK,KAAK,CAAC,EAAE,kBAAkB,gBAAgB,IAAI;AACrE,QAAI,CAAC,WAAW;AACT,YAAA;AAAA,IACP;AAEA,WAAO,UAAU;AAAA,EAClB;AAAA,EAEA,MAAM,kBAAkB,WAAiB;AAClC,UAAA,OAAO,MAAM,KAAK;AAClB,UAAA,UAAU,KAAK,KAAK,CAAC,EAAE,SAAS,OAAO,SAAS;AACtD,QAAI,CAAC,SAAS;AACb,YAAM,4BAA4B,SAAS;AAAA,IAC5C;AAEA,WAAO,QAAQ;AAAA,EAChB;AAAA;AAAA,EAGA,MAAM,OAAO,SAA2B;AACvC,QAAI,MAAM,mCAAS;AACnB,QAAI,CAAC,KAAK;AACH,YAAA,MAAM,KAAK;IAClB;AAEA,WAAO,KAAK,UACX,OAAO,KAAK,OAAO,qBACnB;AAAA,MACC,GAAG;AAAA,MACH;AAAA,IAAA,CACA;AAAA,EAEH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WACL,IACA,SAA2B;AAEpB,WAAA,KAAK,OAAO,EAAE,GAAG,SAAS,GAAG,sBAAsB,EAAE,OAAA,CAAQ;AAAA,EACrE;AAAA;AAAA,EAGA,MAAM,gBACL,IACA,SAA2B;AAE3B,UAAM,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO;AAC9C,YAAQ,KAAK,cAAc;AAAA,MAC1B,KAAK;AACJ;AAAA,MACD,KAAK;AACG,eAAA,KAAK,QAAQ,CAAC;AAAA,MACtB;AACC,cAAM,IAAI,MAAM,gDAAgD,EAAE,EAAE;AAAA,IACtE;AAAA,EACD;AACA;;"}