@adobe/spacecat-shared-tokowaka-client 1.0.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/.mocha-multi.json +7 -0
- package/.nycrc.json +15 -0
- package/.releaserc.cjs +17 -0
- package/CHANGELOG.md +24 -0
- package/CODE_OF_CONDUCT.md +75 -0
- package/CONTRIBUTING.md +74 -0
- package/LICENSE.txt +203 -0
- package/README.md +101 -0
- package/package.json +53 -0
- package/src/cdn/base-cdn-client.js +50 -0
- package/src/cdn/cdn-client-registry.js +87 -0
- package/src/cdn/cloudfront-cdn-client.js +128 -0
- package/src/constants.js +17 -0
- package/src/index.d.ts +289 -0
- package/src/index.js +447 -0
- package/src/mappers/base-mapper.js +86 -0
- package/src/mappers/content-summarization-mapper.js +106 -0
- package/src/mappers/headings-mapper.js +118 -0
- package/src/mappers/mapper-registry.js +87 -0
- package/test/cdn/base-cdn-client.test.js +52 -0
- package/test/cdn/cdn-client-registry.test.js +179 -0
- package/test/cdn/cloudfront-cdn-client.test.js +330 -0
- package/test/index.test.js +1142 -0
- package/test/mappers/base-mapper.test.js +110 -0
- package/test/mappers/content-mapper.test.js +355 -0
- package/test/mappers/headings-mapper.test.js +428 -0
- package/test/mappers/mapper-registry.test.js +197 -0
- package/test/setup-env.js +18 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import CloudFrontCdnClient from './cloudfront-cdn-client.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Registry for CDN clients
|
|
17
|
+
* Manages different CDN provider implementations
|
|
18
|
+
*/
|
|
19
|
+
export default class CdnClientRegistry {
|
|
20
|
+
constructor(env, log) {
|
|
21
|
+
this.env = env;
|
|
22
|
+
this.log = log;
|
|
23
|
+
this.clients = new Map();
|
|
24
|
+
this.#registerDefaultClients();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Registers default CDN clients
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
#registerDefaultClients() {
|
|
32
|
+
this.registerClient('cloudfront', CloudFrontCdnClient);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Registers a CDN client class
|
|
37
|
+
* @param {string} provider - CDN provider name
|
|
38
|
+
* @param {Class} ClientClass - CDN client class
|
|
39
|
+
*/
|
|
40
|
+
registerClient(provider, ClientClass) {
|
|
41
|
+
this.clients.set(provider.toLowerCase(), ClientClass);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gets a CDN client instance for the specified provider
|
|
46
|
+
* @param {string} provider - CDN provider name
|
|
47
|
+
* @param {Object} config - CDN configuration
|
|
48
|
+
* @returns {BaseCdnClient|null} CDN client instance or null if not found
|
|
49
|
+
*/
|
|
50
|
+
getClient(provider) {
|
|
51
|
+
if (!provider) {
|
|
52
|
+
this.log.warn('No CDN provider specified');
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const ClientClass = this.clients.get(provider.toLowerCase());
|
|
57
|
+
|
|
58
|
+
if (!ClientClass) {
|
|
59
|
+
this.log.warn(`No CDN client found for provider: ${provider}`);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
return new ClientClass(this.env, this.log);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
this.log.error(`Failed to create CDN client for ${provider}: ${error.message}`, error);
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Gets list of supported CDN providers
|
|
73
|
+
* @returns {Array<string>} List of provider names
|
|
74
|
+
*/
|
|
75
|
+
getSupportedProviders() {
|
|
76
|
+
return Array.from(this.clients.keys());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Checks if a provider is supported
|
|
81
|
+
* @param {string} provider - CDN provider name
|
|
82
|
+
* @returns {boolean} True if provider is supported
|
|
83
|
+
*/
|
|
84
|
+
isProviderSupported(provider) {
|
|
85
|
+
return this.clients.has(provider?.toLowerCase());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
CloudFrontClient,
|
|
15
|
+
CreateInvalidationCommand,
|
|
16
|
+
} from '@aws-sdk/client-cloudfront';
|
|
17
|
+
import BaseCdnClient from './base-cdn-client.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* CloudFront CDN client implementation
|
|
21
|
+
* Handles cache invalidation for AWS CloudFront
|
|
22
|
+
*/
|
|
23
|
+
export default class CloudFrontCdnClient extends BaseCdnClient {
|
|
24
|
+
constructor(env, log) {
|
|
25
|
+
super(env, log);
|
|
26
|
+
let parsedConfig = {};
|
|
27
|
+
try {
|
|
28
|
+
parsedConfig = JSON.parse(env.TOKOWAKA_CDN_CONFIG);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
throw new Error('Invalid TOKOWAKA_CDN_CONFIG: must be valid JSON');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!parsedConfig.cloudfront) {
|
|
34
|
+
throw new Error("Missing 'cloudfront' config in TOKOWAKA_CDN_CONFIG");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.cdnConfig = parsedConfig.cloudfront;
|
|
38
|
+
this.client = null;
|
|
39
|
+
this.providerName = 'cloudfront';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getProviderName() {
|
|
43
|
+
return this.providerName;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
validateConfig() {
|
|
47
|
+
// Only distributionId is required - credentials are optional when running on Lambda
|
|
48
|
+
if (!this.cdnConfig.distributionId || !this.cdnConfig.region) {
|
|
49
|
+
this.log.error('CloudFront CDN config missing required fields: distributionId and region');
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Initializes the CloudFront client
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
#initializeClient() {
|
|
61
|
+
if (!this.client) {
|
|
62
|
+
this.client = new CloudFrontClient({
|
|
63
|
+
region: this.cdnConfig.region,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Invalidates CloudFront CDN cache for given paths
|
|
70
|
+
* @param {Array<string>} paths - Array of URL paths to invalidate
|
|
71
|
+
* @returns {Promise<Object>} Result of the invalidation request
|
|
72
|
+
*/
|
|
73
|
+
async invalidateCache(paths) {
|
|
74
|
+
if (!this.validateConfig()) {
|
|
75
|
+
throw new Error('Invalid CloudFront CDN configuration');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
79
|
+
this.log.warn('No paths provided for cache invalidation');
|
|
80
|
+
return { status: 'skipped', message: 'No paths to invalidate' };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.#initializeClient();
|
|
84
|
+
|
|
85
|
+
// CloudFront requires paths to start with '/'
|
|
86
|
+
const formattedPaths = paths.map((path) => {
|
|
87
|
+
if (!path.startsWith('/')) {
|
|
88
|
+
return `/${path}`;
|
|
89
|
+
}
|
|
90
|
+
return path;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const callerReference = `tokowaka-${Date.now()}`;
|
|
94
|
+
|
|
95
|
+
const command = new CreateInvalidationCommand({
|
|
96
|
+
DistributionId: this.cdnConfig.distributionId,
|
|
97
|
+
InvalidationBatch: {
|
|
98
|
+
CallerReference: callerReference,
|
|
99
|
+
Paths: {
|
|
100
|
+
Quantity: formattedPaths.length,
|
|
101
|
+
Items: formattedPaths,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
this.log.debug(`Initiating CloudFront cache invalidation for ${JSON.stringify(formattedPaths)} paths`);
|
|
107
|
+
const startTime = Date.now();
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
const response = await this.client.send(command);
|
|
111
|
+
const invalidation = response.Invalidation;
|
|
112
|
+
|
|
113
|
+
this.log.info(`CloudFront cache invalidation initiated: ${invalidation.Id} (took ${Date.now() - startTime}ms)`);
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
status: 'success',
|
|
117
|
+
provider: 'cloudfront',
|
|
118
|
+
invalidationId: invalidation.Id,
|
|
119
|
+
invalidationStatus: invalidation.Status,
|
|
120
|
+
createTime: invalidation.CreateTime,
|
|
121
|
+
paths: formattedPaths.length,
|
|
122
|
+
};
|
|
123
|
+
} catch (error) {
|
|
124
|
+
this.log.error(`Failed to invalidate CloudFront cache after ${Date.now() - startTime}ms: ${error.message}`, error);
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const TARGET_USER_AGENTS_CATEGORIES = {
|
|
14
|
+
AI_BOTS: 'ai-bots',
|
|
15
|
+
BOTS: 'bots',
|
|
16
|
+
ALL: 'all',
|
|
17
|
+
};
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
14
|
+
|
|
15
|
+
export interface TokawakaPatch {
|
|
16
|
+
op: 'replace' | 'insertAfter' | 'insertBefore' | 'appendChild';
|
|
17
|
+
selector: string;
|
|
18
|
+
value: string | object;
|
|
19
|
+
valueFormat: 'text' | 'hast';
|
|
20
|
+
tag?: string;
|
|
21
|
+
currValue?: string;
|
|
22
|
+
target: 'ai-bots' | 'bots' | 'all';
|
|
23
|
+
opportunityId: string;
|
|
24
|
+
suggestionId: string;
|
|
25
|
+
prerenderRequired: boolean;
|
|
26
|
+
lastUpdated: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const TARGET_USER_AGENTS_CATEGORIES: {
|
|
30
|
+
AI_BOTS: 'ai-bots';
|
|
31
|
+
BOTS: 'bots';
|
|
32
|
+
ALL: 'all';
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export interface TokowakaUrlOptimization {
|
|
36
|
+
prerender: boolean;
|
|
37
|
+
patches: TokawakaPatch[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface TokowakaConfig {
|
|
41
|
+
siteId: string;
|
|
42
|
+
baseURL: string;
|
|
43
|
+
version: string;
|
|
44
|
+
tokowakaForceFail: boolean;
|
|
45
|
+
tokowakaOptimizations: Record<string, TokowakaUrlOptimization>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface CdnInvalidationResult {
|
|
49
|
+
status: string;
|
|
50
|
+
provider?: string;
|
|
51
|
+
purgeId?: string;
|
|
52
|
+
estimatedSeconds?: number;
|
|
53
|
+
paths?: number;
|
|
54
|
+
message?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface DeploymentResult {
|
|
58
|
+
s3Path: string;
|
|
59
|
+
cdnInvalidation: CdnInvalidationResult | null;
|
|
60
|
+
succeededSuggestions: Array<any>;
|
|
61
|
+
failedSuggestions: Array<{ suggestion: any; reason: string }>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface SiteConfig {
|
|
65
|
+
getTokowakaConfig(): {
|
|
66
|
+
apiKey: string;
|
|
67
|
+
cdnProvider?: string;
|
|
68
|
+
};
|
|
69
|
+
getFetchConfig?(): {
|
|
70
|
+
overrideBaseURL?: string;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface Site {
|
|
75
|
+
getId(): string;
|
|
76
|
+
getBaseURL(): string;
|
|
77
|
+
getConfig(): SiteConfig;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface Opportunity {
|
|
81
|
+
getId(): string;
|
|
82
|
+
getType(): string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface Suggestion {
|
|
86
|
+
getId(): string;
|
|
87
|
+
getData(): Record<string, any>;
|
|
88
|
+
getUpdatedAt(): string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Base class for opportunity mappers
|
|
93
|
+
* Extend this class to create custom mappers for new opportunity types
|
|
94
|
+
*/
|
|
95
|
+
export abstract class BaseOpportunityMapper {
|
|
96
|
+
protected log: any;
|
|
97
|
+
|
|
98
|
+
constructor(log: any);
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Returns the opportunity type this mapper handles
|
|
102
|
+
*/
|
|
103
|
+
abstract getOpportunityType(): string;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Determines if prerendering is required for this opportunity type
|
|
107
|
+
*/
|
|
108
|
+
abstract requiresPrerender(): boolean;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Converts a suggestion to a Tokowaka patch
|
|
112
|
+
*/
|
|
113
|
+
abstract suggestionToPatch(
|
|
114
|
+
suggestion: Suggestion,
|
|
115
|
+
opportunityId: string
|
|
116
|
+
): TokawakaPatch | null;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Checks if a suggestion can be deployed for this opportunity type
|
|
120
|
+
* This method should validate all eligibility and data requirements
|
|
121
|
+
*/
|
|
122
|
+
abstract canDeploy(suggestion: Suggestion): {
|
|
123
|
+
eligible: boolean;
|
|
124
|
+
reason?: string;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Helper method to create base patch structure
|
|
129
|
+
*/
|
|
130
|
+
protected createBasePatch(
|
|
131
|
+
suggestion: Suggestion,
|
|
132
|
+
opportunityId: string
|
|
133
|
+
): Partial<TokawakaPatch>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Headings opportunity mapper
|
|
138
|
+
* Handles conversion of heading suggestions (heading-empty, heading-missing-h1, heading-h1-length) to Tokowaka patches
|
|
139
|
+
*/
|
|
140
|
+
export class HeadingsMapper extends BaseOpportunityMapper {
|
|
141
|
+
constructor(log: any);
|
|
142
|
+
|
|
143
|
+
getOpportunityType(): string;
|
|
144
|
+
requiresPrerender(): boolean;
|
|
145
|
+
suggestionToPatch(suggestion: Suggestion, opportunityId: string): TokawakaPatch | null;
|
|
146
|
+
canDeploy(suggestion: Suggestion): { eligible: boolean; reason?: string };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Content summarization opportunity mapper
|
|
151
|
+
* Handles conversion of content summarization suggestions to Tokowaka patches with HAST format
|
|
152
|
+
*/
|
|
153
|
+
export class ContentSummarizationMapper extends BaseOpportunityMapper {
|
|
154
|
+
constructor(log: any);
|
|
155
|
+
|
|
156
|
+
getOpportunityType(): string;
|
|
157
|
+
requiresPrerender(): boolean;
|
|
158
|
+
suggestionToPatch(suggestion: Suggestion, opportunityId: string): TokawakaPatch | null;
|
|
159
|
+
canDeploy(suggestion: Suggestion): { eligible: boolean; reason?: string };
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Converts markdown text to HAST (Hypertext Abstract Syntax Tree) format
|
|
163
|
+
*/
|
|
164
|
+
markdownToHast(markdown: string): object;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Registry for opportunity mappers
|
|
169
|
+
*/
|
|
170
|
+
export class MapperRegistry {
|
|
171
|
+
constructor(log: any);
|
|
172
|
+
|
|
173
|
+
registerMapper(MapperClass: typeof BaseOpportunityMapper): void;
|
|
174
|
+
getMapper(opportunityType: string): BaseOpportunityMapper | null;
|
|
175
|
+
getSupportedOpportunityTypes(): string[];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Base class for CDN clients
|
|
180
|
+
* Extend this class to create custom CDN clients for different providers
|
|
181
|
+
*/
|
|
182
|
+
export abstract class BaseCdnClient {
|
|
183
|
+
protected env: any;
|
|
184
|
+
protected log: any;
|
|
185
|
+
|
|
186
|
+
constructor(env: any, log: any);
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Returns the CDN provider name
|
|
190
|
+
*/
|
|
191
|
+
abstract getProviderName(): string;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Validates the CDN configuration
|
|
195
|
+
*/
|
|
196
|
+
abstract validateConfig(): boolean;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Invalidates the CDN cache for the given paths
|
|
200
|
+
*/
|
|
201
|
+
abstract invalidateCache(paths: string[]): Promise<CdnInvalidationResult>;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* CloudFront CDN client implementation
|
|
206
|
+
*/
|
|
207
|
+
export class CloudFrontCdnClient extends BaseCdnClient {
|
|
208
|
+
constructor(env: {
|
|
209
|
+
TOKOWAKA_CDN_CONFIG: string; // JSON string with cloudfront config
|
|
210
|
+
}, log: any);
|
|
211
|
+
|
|
212
|
+
getProviderName(): string;
|
|
213
|
+
validateConfig(): boolean;
|
|
214
|
+
invalidateCache(paths: string[]): Promise<CdnInvalidationResult>;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Registry for CDN clients
|
|
219
|
+
*/
|
|
220
|
+
export class CdnClientRegistry {
|
|
221
|
+
constructor(log: any);
|
|
222
|
+
|
|
223
|
+
registerClient(provider: string, ClientClass: typeof BaseCdnClient): void;
|
|
224
|
+
getClient(provider: string, config: Record<string, any>): BaseCdnClient | null;
|
|
225
|
+
getSupportedProviders(): string[];
|
|
226
|
+
isProviderSupported(provider: string): boolean;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Main Tokowaka Client for managing edge optimization configurations
|
|
231
|
+
*/
|
|
232
|
+
export default class TokowakaClient {
|
|
233
|
+
constructor(config: {
|
|
234
|
+
bucketName: string;
|
|
235
|
+
s3Client: S3Client;
|
|
236
|
+
env?: Record<string, any>;
|
|
237
|
+
}, log: any);
|
|
238
|
+
|
|
239
|
+
static createFrom(context: {
|
|
240
|
+
env: {
|
|
241
|
+
TOKOWAKA_SITE_CONFIG_BUCKET: string;
|
|
242
|
+
TOKOWAKA_CDN_PROVIDER?: string;
|
|
243
|
+
TOKOWAKA_CDN_CONFIG?: string;
|
|
244
|
+
};
|
|
245
|
+
log?: any;
|
|
246
|
+
s3: { s3Client: S3Client };
|
|
247
|
+
tokowakaClient?: TokowakaClient;
|
|
248
|
+
}): TokowakaClient;
|
|
249
|
+
|
|
250
|
+
generateConfig(
|
|
251
|
+
site: Site,
|
|
252
|
+
opportunity: Opportunity,
|
|
253
|
+
suggestions: Suggestion[]
|
|
254
|
+
): TokowakaConfig;
|
|
255
|
+
|
|
256
|
+
uploadConfig(apiKey: string, config: TokowakaConfig): Promise<string>;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Fetches existing Tokowaka configuration from S3
|
|
260
|
+
*/
|
|
261
|
+
fetchConfig(apiKey: string): Promise<TokowakaConfig | null>;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Merges existing configuration with new configuration
|
|
265
|
+
*/
|
|
266
|
+
mergeConfigs(existingConfig: TokowakaConfig, newConfig: TokowakaConfig): TokowakaConfig;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Invalidates CDN cache
|
|
270
|
+
*/
|
|
271
|
+
invalidateCdnCache(apiKey: string, cdnProvider?: string): Promise<CdnInvalidationResult | null>;
|
|
272
|
+
|
|
273
|
+
deploySuggestions(
|
|
274
|
+
site: Site,
|
|
275
|
+
opportunity: Opportunity,
|
|
276
|
+
suggestions: Suggestion[]
|
|
277
|
+
): Promise<DeploymentResult>;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Registers a custom mapper for an opportunity type
|
|
281
|
+
*/
|
|
282
|
+
registerMapper(mapper: BaseOpportunityMapper): void;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Gets list of supported opportunity types
|
|
286
|
+
*/
|
|
287
|
+
getSupportedOpportunityTypes(): string[];
|
|
288
|
+
}
|
|
289
|
+
|