@adobe/spacecat-shared-tokowaka-client 1.4.0 → 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.
- package/CHANGELOG.md +7 -0
- package/README.md +107 -7
- package/package.json +1 -1
- package/src/cdn/cdn-client-registry.js +2 -0
- package/src/cdn/fastly-cdn-client.js +156 -0
- package/src/index.d.ts +47 -11
- package/src/index.js +138 -81
- package/src/mappers/generic-mapper.js +5 -1
- package/test/cdn/fastly-cdn-client.test.js +484 -0
- package/test/index.test.js +313 -113
- package/test/mappers/generic-mapper.test.js +82 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-tokowaka-client-v1.4.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tokowaka-client-v1.4.0...@adobe/spacecat-shared-tokowaka-client-v1.4.1) (2025-12-12)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* fastly CDN cache invalidation ([#1240](https://github.com/adobe/spacecat-shared/issues/1240)) ([fbb43e4](https://github.com/adobe/spacecat-shared/commit/fbb43e411053c6dc71255fc3883255785c301659))
|
|
7
|
+
|
|
1
8
|
# [@adobe/spacecat-shared-tokowaka-client-v1.4.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tokowaka-client-v1.3.2...@adobe/spacecat-shared-tokowaka-client-v1.4.0) (2025-12-11)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -28,8 +28,8 @@ Creates a client instance from a context object.
|
|
|
28
28
|
- `context.log` (Object, optional): Logger instance
|
|
29
29
|
- `context.env.TOKOWAKA_SITE_CONFIG_BUCKET` (string): S3 bucket name for deployed configurations
|
|
30
30
|
- `context.env.TOKOWAKA_PREVIEW_BUCKET` (string): S3 bucket name for preview configurations
|
|
31
|
-
- `context.env.TOKOWAKA_CDN_PROVIDER` (string): CDN provider for cache invalidation
|
|
32
|
-
- `context.env.TOKOWAKA_CDN_CONFIG` (string): JSON configuration for CDN
|
|
31
|
+
- `context.env.TOKOWAKA_CDN_PROVIDER` (string | string[]): CDN provider(s) for cache invalidation
|
|
32
|
+
- `context.env.TOKOWAKA_CDN_CONFIG` (string): JSON configuration for CDN clients
|
|
33
33
|
- `context.env.TOKOWAKA_EDGE_URL` (string): Tokowaka edge URL for preview HTML fetching
|
|
34
34
|
|
|
35
35
|
## Environment Variables
|
|
@@ -39,8 +39,23 @@ Creates a client instance from a context object.
|
|
|
39
39
|
- `TOKOWAKA_PREVIEW_BUCKET` - S3 bucket name for storing preview configurations
|
|
40
40
|
|
|
41
41
|
**Optional (for CDN invalidation):**
|
|
42
|
-
- `TOKOWAKA_CDN_PROVIDER` - CDN provider name (e.g., "cloudfront")
|
|
43
|
-
- `TOKOWAKA_CDN_CONFIG` - JSON string with CDN-specific configuration
|
|
42
|
+
- `TOKOWAKA_CDN_PROVIDER` - CDN provider name(s). Can be a single provider (e.g., "cloudfront") or multiple providers as comma-separated string (e.g., "cloudfront,fastly") or array
|
|
43
|
+
- `TOKOWAKA_CDN_CONFIG` - JSON string with CDN-specific configuration for all providers:
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"cloudfront": {
|
|
47
|
+
"distributionId": "<distribution-id>",
|
|
48
|
+
"region": "us-east-1"
|
|
49
|
+
},
|
|
50
|
+
"fastly": {
|
|
51
|
+
"serviceId": "<service-id>",
|
|
52
|
+
"apiToken": "<api-token>",
|
|
53
|
+
"distributionUrl": "https://<cloudfront-distribution>.cloudfront.net"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Note for Fastly**: The `distributionUrl` is required and should be the full CloudFront distribution URL (e.g., `https://deftbrsarcsf4.cloudfront.net`). Fastly uses this to construct full URLs as surrogate keys for cache purging.
|
|
44
59
|
|
|
45
60
|
**Optional (for preview functionality):**
|
|
46
61
|
- `TOKOWAKA_EDGE_URL` - Tokowaka edge URL for fetching HTML content during preview
|
|
@@ -55,7 +70,7 @@ Generates configuration and uploads to S3 **per URL**. **Automatically fetches e
|
|
|
55
70
|
|
|
56
71
|
**Returns:** `Promise<DeploymentResult>` with:
|
|
57
72
|
- `s3Paths` - Array of S3 keys where configs were uploaded (one per URL)
|
|
58
|
-
- `cdnInvalidations` - Array of CDN invalidation results (one per URL)
|
|
73
|
+
- `cdnInvalidations` - Array of CDN invalidation results (one per URL per provider)
|
|
59
74
|
- `succeededSuggestions` - Array of deployed suggestions
|
|
60
75
|
- `failedSuggestions` - Array of `{suggestion, reason}` objects for ineligible suggestions
|
|
61
76
|
|
|
@@ -72,7 +87,7 @@ Rolls back previously deployed suggestions by removing their patches from the co
|
|
|
72
87
|
|
|
73
88
|
**Returns:** `Promise<RollbackResult>` with:
|
|
74
89
|
- `s3Paths` - Array of S3 keys where configs were uploaded (one per URL)
|
|
75
|
-
- `cdnInvalidations` - Array of CDN invalidation results (one per URL)
|
|
90
|
+
- `cdnInvalidations` - Array of CDN invalidation results (one per URL per provider)
|
|
76
91
|
- `succeededSuggestions` - Array of rolled back suggestions
|
|
77
92
|
- `failedSuggestions` - Array of `{suggestion, reason}` objects for ineligible suggestions
|
|
78
93
|
- `removedPatchesCount` - Total number of patches removed across all URLs
|
|
@@ -84,7 +99,7 @@ Previews suggestions by uploading to preview S3 path and fetching HTML compariso
|
|
|
84
99
|
**Returns:** `Promise<PreviewResult>` with:
|
|
85
100
|
- `s3Path` - S3 key where preview config was uploaded
|
|
86
101
|
- `config` - Preview configuration object
|
|
87
|
-
- `
|
|
102
|
+
- `cdnInvalidations` - Array of CDN invalidation results (one per provider)
|
|
88
103
|
- `succeededSuggestions` - Array of previewed suggestions
|
|
89
104
|
- `failedSuggestions` - Array of `{suggestion, reason}` objects for ineligible suggestions
|
|
90
105
|
- `html` - Object with `url`, `originalHtml`, and `optimizedHtml`
|
|
@@ -235,6 +250,91 @@ Per-URL configuration (flat structure):
|
|
|
235
250
|
- The `tokowakaOptimizations` nested structure has been removed
|
|
236
251
|
- The `tokowakaForceFail` field has been renamed to `forceFail`
|
|
237
252
|
|
|
253
|
+
## CDN Cache Invalidation
|
|
254
|
+
|
|
255
|
+
The client supports multiple CDN providers for cache invalidation with **intelligent batching** for optimal performance.
|
|
256
|
+
|
|
257
|
+
### Batch Optimization
|
|
258
|
+
|
|
259
|
+
When deploying or rolling back multiple URLs:
|
|
260
|
+
- **Before**: Each URL triggered separate CDN invalidation calls (N URLs = N×2 API calls for 2 providers)
|
|
261
|
+
- **After**: All URLs are collected and invalidated in a single batch call per provider (N URLs = 2 API calls for 2 providers)
|
|
262
|
+
|
|
263
|
+
**Example Performance Improvement:**
|
|
264
|
+
- 10 URLs with CloudFront + Fastly
|
|
265
|
+
- Old: 20 API calls (10 per provider)
|
|
266
|
+
- New: **2 API calls** (1 per provider)
|
|
267
|
+
- **90% reduction in API calls!**
|
|
268
|
+
|
|
269
|
+
### Supported CDN Providers
|
|
270
|
+
|
|
271
|
+
#### CloudFront
|
|
272
|
+
AWS CloudFront CDN invalidation using the AWS SDK.
|
|
273
|
+
|
|
274
|
+
**Configuration:**
|
|
275
|
+
```json
|
|
276
|
+
{
|
|
277
|
+
"cloudfront": {
|
|
278
|
+
"distributionId": "E1234567890ABC",
|
|
279
|
+
"region": "us-east-1"
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### Fastly
|
|
285
|
+
Fastly CDN purging using surrogate key purging.
|
|
286
|
+
|
|
287
|
+
**Configuration:**
|
|
288
|
+
```json
|
|
289
|
+
{
|
|
290
|
+
"fastly": {
|
|
291
|
+
"serviceId": "abc123xyz",
|
|
292
|
+
"apiToken": "your-fastly-api-token"
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Multiple CDN Providers
|
|
298
|
+
|
|
299
|
+
To invalidate cache on multiple CDNs simultaneously:
|
|
300
|
+
|
|
301
|
+
**Environment Variable:**
|
|
302
|
+
```bash
|
|
303
|
+
TOKOWAKA_CDN_PROVIDER="cloudfront,fastly"
|
|
304
|
+
# or as array in code: ["cloudfront", "fastly"]
|
|
305
|
+
|
|
306
|
+
TOKOWAKA_CDN_CONFIG='{"cloudfront":{"distributionId":"...","region":"us-east-1"},"fastly":{"serviceId":"...","apiToken":"...","distributionUrl":"https://xxx.cloudfront.net"}}'
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Behavior:**
|
|
310
|
+
- All URLs are batched into a single invalidation request per provider
|
|
311
|
+
- All CDN providers are invalidated in parallel using `Promise.all()`
|
|
312
|
+
- Failures in one CDN don't block others
|
|
313
|
+
- Each CDN returns its own result in the `cdnInvalidations` array
|
|
314
|
+
- Results include status, provider name, and provider-specific details
|
|
315
|
+
|
|
316
|
+
### Fastly Batch Purging
|
|
317
|
+
|
|
318
|
+
The Fastly client uses surrogate key purging with full CloudFront URLs:
|
|
319
|
+
- **Surrogate Keys**: Constructed as full CloudFront URLs (e.g., `https://xxx.cloudfront.net/opportunities/adobe.com/config`)
|
|
320
|
+
- **Batch Purging**: All paths are sent in a single API call using the `Surrogate-Key` header (space-separated URLs)
|
|
321
|
+
- **Configuration**: Requires `distributionUrl` in the Fastly config to construct full URLs
|
|
322
|
+
- Significantly reduces API calls and improves performance for bulk operations
|
|
323
|
+
|
|
324
|
+
**Example Fastly Configuration:**
|
|
325
|
+
```json
|
|
326
|
+
{
|
|
327
|
+
"serviceId": "abc123xyz",
|
|
328
|
+
"apiToken": "your-fastly-api-token",
|
|
329
|
+
"distributionUrl": "https://deftbrsarcsf4.cloudfront.net"
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
This configuration allows Fastly to purge cache entries using URLs like:
|
|
334
|
+
```
|
|
335
|
+
fastly purge --key https://deftbrsarcsf4.cloudfront.net/opportunities/adobe.com/config
|
|
336
|
+
```
|
|
337
|
+
|
|
238
338
|
## Reference Material
|
|
239
339
|
|
|
240
340
|
https://wiki.corp.adobe.com/display/AEMSites/Tokowaka+-+Spacecat+Integration
|
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import CloudFrontCdnClient from './cloudfront-cdn-client.js';
|
|
14
|
+
import FastlyCdnClient from './fastly-cdn-client.js';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Registry for CDN clients
|
|
@@ -30,6 +31,7 @@ export default class CdnClientRegistry {
|
|
|
30
31
|
*/
|
|
31
32
|
#registerDefaultClients() {
|
|
32
33
|
this.registerClient('cloudfront', CloudFrontCdnClient);
|
|
34
|
+
this.registerClient('fastly', FastlyCdnClient);
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -0,0 +1,156 @@
|
|
|
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 BaseCdnClient from './base-cdn-client.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Fastly CDN client implementation
|
|
17
|
+
* Handles cache invalidation for Fastly CDN using surrogate key purging
|
|
18
|
+
*/
|
|
19
|
+
export default class FastlyCdnClient extends BaseCdnClient {
|
|
20
|
+
constructor(env, log) {
|
|
21
|
+
super(env, log);
|
|
22
|
+
let parsedConfig = {};
|
|
23
|
+
try {
|
|
24
|
+
parsedConfig = JSON.parse(env.TOKOWAKA_CDN_CONFIG);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
throw new Error('Invalid TOKOWAKA_CDN_CONFIG: must be valid JSON');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!parsedConfig.fastly) {
|
|
30
|
+
throw new Error("Missing 'fastly' config in TOKOWAKA_CDN_CONFIG");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
this.cdnConfig = parsedConfig.fastly;
|
|
34
|
+
this.providerName = 'fastly';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
getProviderName() {
|
|
38
|
+
return this.providerName;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
validateConfig() {
|
|
42
|
+
// serviceId, apiToken, and distributionUrl are required for Fastly API
|
|
43
|
+
if (!this.cdnConfig.serviceId || !this.cdnConfig.apiToken) {
|
|
44
|
+
this.log.error('Fastly CDN config missing required fields: serviceId and apiToken');
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!this.cdnConfig.distributionUrl) {
|
|
49
|
+
this.log.error('Fastly CDN config missing distributionUrl (CloudFront distribution URL)');
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Invalidates Fastly CDN cache for given paths using surrogate key purging
|
|
58
|
+
* Constructs full CloudFront URLs as surrogate keys for Fastly purge
|
|
59
|
+
* Works efficiently for both single and multiple paths
|
|
60
|
+
* @param {Array<string>} paths - Array of URL paths to invalidate
|
|
61
|
+
* (e.g., '/opportunities/adobe.com/config')
|
|
62
|
+
* @returns {Promise<Object>} Result of the invalidation request
|
|
63
|
+
*/
|
|
64
|
+
async invalidateCache(paths) {
|
|
65
|
+
if (!this.validateConfig()) {
|
|
66
|
+
throw new Error('Invalid Fastly CDN configuration');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
70
|
+
this.log.warn('No paths provided for cache invalidation');
|
|
71
|
+
return { status: 'skipped', message: 'No paths to invalidate' };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.log.info(`Starting Fastly cache invalidation for ${paths.length} path(s)`);
|
|
75
|
+
|
|
76
|
+
// Construct full CloudFront URLs as surrogate keys
|
|
77
|
+
// Example: "https://deftbrsarcsf4.cloudfront.net/opportunities/adobe.com/config"
|
|
78
|
+
const surrogateKeys = paths.map((path) => {
|
|
79
|
+
// Ensure path starts with /
|
|
80
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
81
|
+
// Combine CloudFront distribution URL with path
|
|
82
|
+
const fullUrl = `${this.cdnConfig.distributionUrl}${normalizedPath}`;
|
|
83
|
+
return fullUrl;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
this.log.debug(`Generated ${surrogateKeys.length} surrogate key(s) for purge`);
|
|
87
|
+
this.log.debug(`Surrogate keys: ${surrogateKeys.join(', ')}`);
|
|
88
|
+
|
|
89
|
+
const startTime = Date.now();
|
|
90
|
+
const apiEndpoint = `https://api.fastly.com/service/${this.cdnConfig.serviceId}/purge`;
|
|
91
|
+
this.log.debug(`Calling Fastly API: POST ${apiEndpoint}`);
|
|
92
|
+
try {
|
|
93
|
+
// Fastly batch purge using Surrogate-Key header (space-separated)
|
|
94
|
+
// Works for both single and multiple keys
|
|
95
|
+
const response = await fetch(
|
|
96
|
+
`https://api.fastly.com/service/${this.cdnConfig.serviceId}/purge`,
|
|
97
|
+
{
|
|
98
|
+
method: 'POST',
|
|
99
|
+
headers: {
|
|
100
|
+
'Fastly-Key': this.cdnConfig.apiToken,
|
|
101
|
+
'Surrogate-Key': surrogateKeys.join(' '),
|
|
102
|
+
Accept: 'application/json',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
const errorText = await response.text();
|
|
109
|
+
this.log.error(`Failed to purge Fastly cache: ${response.status} - ${errorText}`);
|
|
110
|
+
return {
|
|
111
|
+
status: 'failed',
|
|
112
|
+
provider: 'fastly',
|
|
113
|
+
serviceId: this.cdnConfig.serviceId,
|
|
114
|
+
totalPaths: paths.length,
|
|
115
|
+
totalKeys: surrogateKeys.length,
|
|
116
|
+
successCount: 0,
|
|
117
|
+
failedCount: surrogateKeys.length,
|
|
118
|
+
error: errorText,
|
|
119
|
+
duration: Date.now() - startTime,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const result = await response.json();
|
|
124
|
+
const duration = Date.now() - startTime;
|
|
125
|
+
this.log.info(
|
|
126
|
+
`Successfully purged ${surrogateKeys.length} Fastly cache key(s) `
|
|
127
|
+
+ `for service ${this.cdnConfig.serviceId} (took ${duration}ms)`,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
status: 'success',
|
|
132
|
+
provider: 'fastly',
|
|
133
|
+
serviceId: this.cdnConfig.serviceId,
|
|
134
|
+
totalPaths: paths.length,
|
|
135
|
+
totalKeys: surrogateKeys.length,
|
|
136
|
+
successCount: surrogateKeys.length,
|
|
137
|
+
failedCount: 0,
|
|
138
|
+
purgeId: result.id,
|
|
139
|
+
duration,
|
|
140
|
+
};
|
|
141
|
+
} catch (error) {
|
|
142
|
+
this.log.error(`Error purging Fastly cache: ${error.message}`, error);
|
|
143
|
+
return {
|
|
144
|
+
status: 'error',
|
|
145
|
+
provider: 'fastly',
|
|
146
|
+
serviceId: this.cdnConfig.serviceId,
|
|
147
|
+
totalPaths: paths.length,
|
|
148
|
+
totalKeys: surrogateKeys.length,
|
|
149
|
+
successCount: 0,
|
|
150
|
+
failedCount: surrogateKeys.length,
|
|
151
|
+
error: error.message,
|
|
152
|
+
duration: Date.now() - startTime,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -49,23 +49,39 @@ export interface TokowakaConfig {
|
|
|
49
49
|
|
|
50
50
|
export interface CdnInvalidationResult {
|
|
51
51
|
status: string;
|
|
52
|
-
provider
|
|
52
|
+
provider: string;
|
|
53
53
|
purgeId?: string;
|
|
54
|
+
invalidationId?: string;
|
|
55
|
+
invalidationStatus?: string;
|
|
56
|
+
createTime?: string;
|
|
54
57
|
estimatedSeconds?: number;
|
|
55
58
|
paths?: number;
|
|
59
|
+
totalPaths?: number;
|
|
60
|
+
totalKeys?: number;
|
|
61
|
+
successCount?: number;
|
|
62
|
+
failedCount?: number;
|
|
63
|
+
serviceId?: string;
|
|
64
|
+
duration?: number;
|
|
65
|
+
results?: Array<{
|
|
66
|
+
key: string;
|
|
67
|
+
status: string;
|
|
68
|
+
statusCode?: number;
|
|
69
|
+
error?: string;
|
|
70
|
+
}>;
|
|
56
71
|
message?: string;
|
|
72
|
+
error?: string;
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
export interface DeploymentResult {
|
|
60
76
|
s3Paths: string[];
|
|
61
|
-
cdnInvalidations:
|
|
77
|
+
cdnInvalidations: CdnInvalidationResult[];
|
|
62
78
|
succeededSuggestions: Array<any>;
|
|
63
79
|
failedSuggestions: Array<{ suggestion: any; reason: string }>;
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
export interface RollbackResult {
|
|
67
83
|
s3Paths: string[];
|
|
68
|
-
cdnInvalidations:
|
|
84
|
+
cdnInvalidations: CdnInvalidationResult[];
|
|
69
85
|
succeededSuggestions: Array<any>;
|
|
70
86
|
failedSuggestions: Array<{ suggestion: any; reason: string }>;
|
|
71
87
|
removedPatchesCount: number;
|
|
@@ -74,7 +90,7 @@ export interface RollbackResult {
|
|
|
74
90
|
export interface PreviewResult {
|
|
75
91
|
s3Path: string;
|
|
76
92
|
config: TokowakaConfig;
|
|
77
|
-
|
|
93
|
+
cdnInvalidations: CdnInvalidationResult[];
|
|
78
94
|
succeededSuggestions: Array<any>;
|
|
79
95
|
failedSuggestions: Array<{ suggestion: any; reason: string }>;
|
|
80
96
|
html: {
|
|
@@ -300,14 +316,27 @@ export class CloudFrontCdnClient extends BaseCdnClient {
|
|
|
300
316
|
invalidateCache(paths: string[]): Promise<CdnInvalidationResult>;
|
|
301
317
|
}
|
|
302
318
|
|
|
319
|
+
/**
|
|
320
|
+
* Fastly CDN client implementation
|
|
321
|
+
*/
|
|
322
|
+
export class FastlyCdnClient extends BaseCdnClient {
|
|
323
|
+
constructor(env: {
|
|
324
|
+
TOKOWAKA_CDN_CONFIG: string; // JSON string with fastly config
|
|
325
|
+
}, log: any);
|
|
326
|
+
|
|
327
|
+
getProviderName(): string;
|
|
328
|
+
validateConfig(): boolean;
|
|
329
|
+
invalidateCache(paths: string[]): Promise<CdnInvalidationResult>;
|
|
330
|
+
}
|
|
331
|
+
|
|
303
332
|
/**
|
|
304
333
|
* Registry for CDN clients
|
|
305
334
|
*/
|
|
306
335
|
export class CdnClientRegistry {
|
|
307
|
-
constructor(log: any);
|
|
336
|
+
constructor(env: Record<string, any>, log: any);
|
|
308
337
|
|
|
309
338
|
registerClient(provider: string, ClientClass: typeof BaseCdnClient): void;
|
|
310
|
-
getClient(provider: string
|
|
339
|
+
getClient(provider: string): BaseCdnClient | null;
|
|
311
340
|
getSupportedProviders(): string[];
|
|
312
341
|
isProviderSupported(provider: string): boolean;
|
|
313
342
|
}
|
|
@@ -327,8 +356,8 @@ export default class TokowakaClient {
|
|
|
327
356
|
env: {
|
|
328
357
|
TOKOWAKA_SITE_CONFIG_BUCKET: string;
|
|
329
358
|
TOKOWAKA_PREVIEW_BUCKET?: string;
|
|
330
|
-
TOKOWAKA_CDN_PROVIDER?: string;
|
|
331
|
-
TOKOWAKA_CDN_CONFIG?: string;
|
|
359
|
+
TOKOWAKA_CDN_PROVIDER?: string | string[]; // Single provider or comma-separated list
|
|
360
|
+
TOKOWAKA_CDN_CONFIG?: string; // JSON with cloudfront and/or fastly config
|
|
332
361
|
TOKOWAKA_EDGE_URL?: string;
|
|
333
362
|
};
|
|
334
363
|
log?: any;
|
|
@@ -358,12 +387,12 @@ export default class TokowakaClient {
|
|
|
358
387
|
/**
|
|
359
388
|
* Fetches domain-level metaconfig from S3
|
|
360
389
|
*/
|
|
361
|
-
fetchMetaconfig(url: string
|
|
390
|
+
fetchMetaconfig(url: string): Promise<TokowakaMetaconfig | null>;
|
|
362
391
|
|
|
363
392
|
/**
|
|
364
393
|
* Uploads domain-level metaconfig to S3
|
|
365
394
|
*/
|
|
366
|
-
uploadMetaconfig(url: string, metaconfig: TokowakaMetaconfig
|
|
395
|
+
uploadMetaconfig(url: string, metaconfig: TokowakaMetaconfig): Promise<string>;
|
|
367
396
|
|
|
368
397
|
/**
|
|
369
398
|
* Merges existing configuration with new configuration
|
|
@@ -372,8 +401,15 @@ export default class TokowakaClient {
|
|
|
372
401
|
|
|
373
402
|
/**
|
|
374
403
|
* Invalidates CDN cache for a specific URL
|
|
404
|
+
* Supports multiple CDN providers in parallel
|
|
405
|
+
*/
|
|
406
|
+
invalidateCdnCache(url: string, providers?: string | string[], isPreview?: boolean): Promise<CdnInvalidationResult[]>;
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Batch invalidates CDN cache for multiple URLs at once
|
|
410
|
+
* More efficient than individual invalidations when processing multiple URLs
|
|
375
411
|
*/
|
|
376
|
-
|
|
412
|
+
batchInvalidateCdnCache(urls: string[], providers?: string | string[], isPreview?: boolean): Promise<CdnInvalidationResult[]>;
|
|
377
413
|
|
|
378
414
|
/**
|
|
379
415
|
* Deploys suggestions to Tokowaka edge
|