Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ This file does not list v7 releases after 7.0.8, or v6 releases after 6.3.0. For
- Add `--purge-environment` to purge `production` (the default), `staging`, or both. A staging purge sends the `Fastly-Purge-Environment: staging` header.
- A failed purge shows a warning on stderr. The command still completes, because the content is already published.

- `collections delete`
- After the delete, purge the surrogate key of the collection, so that the service stops serving cached responses of the deleted collection. This has the same options and rules as the purge of `publish-content`: `--fastly-service-id`, `--purge-environment`, and the API token.

- S3-compatible storage (BETA)
- Add support for S3-compatible storage, such as Fastly Object Storage
- Store items using same keys as KV Store
Expand Down Expand Up @@ -107,6 +110,11 @@ This file does not list v7 releases after 7.0.8, or v6 releases after 6.3.0. For

- `collectionSelector.fromCookie()`: the activate and reset paths now accept only a path on the same site for `redirectTo`. Any other value redirects to `/`. The activate path returns `400` for a `collection` value with characters that a cookie value cannot have, and sets no cookie.

- S3-compatible storage: `--local` stops the command with an error before it connects to storage. Before, `publish-content`, `collections list`, `collections delete`, `collections promote`, `collections update-expiration`, and `clean` ignored `--local` for storage, and changed the bucket. There is no local simulation of S3 storage. If you used `--local` in S3 mode to skip the purge after `publish-content`, remove `--local`, and do not set a Service ID. `--help` and the README now tell that `--local` is for KV Store mode only.

- `publish-content` prepares each variant of the same content one time. Before, when several files had the same content, the files that were processed at the same time each compressed the content again, and each added the same keys to the upload. The uploaded content was correct, but the publish used more CPU time and more upload requests (in S3 mode, one `PutObject` for each duplicate). Each variant file in the working directory is now also written one time, so a file is not read while another file writes it.
- `publish-content --local` shows the number of variants to upload.

## [7.0.8] - 2026-10-14

### Added
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Both parts use a registry of builder functions. Each entry point calls `register
- `kv-store-provider` uses the Fastly API.
- `kv-store-local-provider` is for the `--local` flag. It writes `static-publisher/kvstore.json` and the prepared files, so that `fastly compute serve` can simulate the KV Store.
- `s3-storage-provider` uses the AWS SDK.
- The CLI interface has list, get, submit, delete, batch, and chunking. The purge after publishing is not part of it: `publish-content` does it with `util/purge.ts`, because it is the same for every storage mode.
- The CLI interface has list, get, submit, delete, batch, and chunking. The purge after a change to a collection is not part of it: `publish-content` and `collections delete` do it with `util/purge.ts`, because it is the same for every storage mode.
- The Fastly API token comes only from `--fastly-api-token` or `FASTLY_API_TOKEN` (`util/api-token.ts`). As of v8, the CLI does not run `fastly profile token`, and the package does not depend on `@fastly/cli`. (The scaffolder still adds `@fastly/cli` to the generated app.)
- Server (`src/server/storage/`): `kv-store-provider` and `s3-storage-provider`. Both use a small `getEntry(key, tags)` interface. S3 credentials come from a Secret Store. `src/server/index.ts` exports the setters.
- The server's `s3-storage-provider` does not use the AWS SDK. It signs a `GET` with `@smithy/signature-v4` and reads the status code, the body, and the `x-amz-meta-*` headers. The SDK's browser build, which js-compute bundles, parses XML with `DOMParser` (since `@aws-sdk/xml-builder` 3.894.0), and Compute does not have `DOMParser`. Do not import `@aws-sdk/*` in `src/server`.
Expand All @@ -56,7 +56,7 @@ All keys start with `publishId` (default `'default'`):
- `<publishId>_settings_<collection>`: The normalized `server` section of `publish-content.config.js`. The CLI saves it when it publishes.
- `<publishId>_files_sha256_<hash>[_<variant>]`: The file content, with `br`/`gzip` variants. The key is the hash of the content. Large files are split into chunks.

All collections share the files, because the key is the hash of the content. `clean` removes expired collections and the `_files_` keys that no index uses. After a publish, the CLI purges the surrogate key `<publishId>-<collection>`. The server adds this tag when it reads, and to the responses in the response cache. The purge runs in KV Store and S3 modes (not with `--local`), only if the CLI finds a Service ID (`--fastly-service-id`, then `FASTLY_SERVICE_ID`, then `service_id` in `fastly.toml`, the same order as the Fastly CLI; see `util/service-id.ts`). `loadPurgeTarget()` checks this before the upload, and fails if there is a Service ID but no API token. It is a soft purge. A purge without the `Fastly-Purge-Environment: staging` header does not clear the cache of a staged service version: `--purge-environment` selects `production` (the default, no header), `staging`, or both, and `publish-content` sends one purge for each. A failed purge is only a warning, because the content is already published.
All collections share the files, because the key is the hash of the content. `clean` removes expired collections and the `_files_` keys that no index uses. After a publish or a `collections delete`, the CLI purges the surrogate key `<publishId>-<collection>` (`purgeCollection()`). The server adds this tag when it reads, and to the responses in the response cache. The purge runs in KV Store and S3 modes (not with `--local`), only if the CLI finds a Service ID (`--fastly-service-id`, then `FASTLY_SERVICE_ID`, then `service_id` in `fastly.toml`, the same order as the Fastly CLI; see `util/service-id.ts`). `loadPurgeTarget()` checks this before the upload or the delete, and fails if there is a Service ID but no API token. It is a soft purge. A purge without the `Fastly-Purge-Environment: staging` header does not clear the cache of a staged service version: `--purge-environment` selects `production` (the default, no header), `staging`, or both, and the CLI sends one purge for each. A failed purge is only a warning, because the change to storage is already done.

### `publish-content` flow

Expand Down
3 changes: 2 additions & 1 deletion MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ To upgrade an app that uses the KV Store:
in KV Store mode too. It finds the Service ID from `--fastly-service-id`, then the `FASTLY_SERVICE_ID`
environment variable, then `service_id` in `fastly.toml`. If it finds a Service ID, the API token must have permission to purge
that service. If you do not want a purge, make sure that the CLI does not find a Service ID. If the purge fails,
the CLI shows a warning, and the publish is complete.
the CLI shows a warning, and the publish is complete. `collections delete` purges the same way after it deletes a
collection.
- **`kvStoreAssetInclusionTest` has a new name.** In `publish-content.config.js`, use `assetInclusionTest`. The old
name continues to work, but it is deprecated.
- **Some types have new names.** `KVAssetEntry` is now `AssetEntry`, and `KVAssetEntryMap` is now `AssetEntryMap`.
Expand Down
18 changes: 12 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ After this process is complete, the PublisherServer object in the Compute applic

**KV Store Options:**

- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment.
- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment. KV Store mode only. In S3 mode, `--local` is an error, because there is no local simulation of S3 storage.

- `--fastly-api-token`: API token to use when publishing. If not set, the tool uses the **`FASTLY_API_TOKEN` environment variable**.

Expand All @@ -962,7 +962,7 @@ This can include expired collection indexes and orphaned content assets.

**KV Store Options:**

- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment.
- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment. KV Store mode only. In S3 mode, `--local` is an error, because there is no local simulation of S3 storage.

- `--fastly-api-token`: API token to use when publishing. If not set, the tool uses the **`FASTLY_API_TOKEN` environment variable**.

Expand All @@ -981,7 +981,7 @@ Lists all collections currently published in storage.

**KV Store Options:**

- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment.
- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment. KV Store mode only. In S3 mode, `--local` is an error, because there is no local simulation of S3 storage.

- `--fastly-api-token`: API token to use when publishing. If not set, the tool uses the **`FASTLY_API_TOKEN` environment variable**.

Expand Down Expand Up @@ -1014,7 +1014,7 @@ Copies an existing collection (content + config) to a new collection name.

**KV Store Options:**

- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment.
- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment. KV Store mode only. In S3 mode, `--local` is an error, because there is no local simulation of S3 storage.

- `--fastly-api-token`: API token to use when publishing. If not set, the tool uses the **`FASTLY_API_TOKEN` environment variable**.

Expand Down Expand Up @@ -1044,7 +1044,7 @@ Sets or updates the expiration time of an existing collection.

**KV Store Options:**

- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment.
- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment. KV Store mode only. In S3 mode, `--local` is an error, because there is no local simulation of S3 storage.

- `--fastly-api-token`: API token to use when publishing. If not set, the tool uses the **`FASTLY_API_TOKEN` environment variable**.

Expand All @@ -1063,13 +1063,19 @@ Deletes a collection index from storage. The content files will remain as they m

Use the `npx @fastly/compute-js-static-publish clean` command afterward to remove content files that are no longer referenced by any collection.

If a Service ID is found, the command then purges the surrogate key `<publishId>-<collectionName>`, so that the service stops serving cached responses of the deleted collection. This uses the same options as [`publish-content`](#publish-content).

##### Options:

- `--collection-name`: The name of the collection to delete (required)

- `--fastly-service-id`: The Fastly Service ID to purge after deleting. If not set, the tool checks the `FASTLY_SERVICE_ID` environment variable, then `service_id` in `fastly.toml`. If none is found, the command skips the purge. The purge also needs an API token (see `--fastly-api-token`). With `--local`, there is no purge. If the purge fails, the command shows a warning and completes, because the collection is already deleted.

- `--purge-environment`: The environments to purge: `production` (the default), `staging`, or both, as a comma-separated list. You can also repeat the option.

**KV Store Options:**

- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment.
- `--local`: Instead of working with the Fastly KV Store, operate on local files that will be used to simulate the KV Store with the local development environment. KV Store mode only. In S3 mode, `--local` is an error, because there is no local simulation of S3 storage.

- `--fastly-api-token`: API token to use when publishing. If not set, the tool uses the **`FASTLY_API_TOKEN` environment variable**.

Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/manage/clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ KV Store Options:
--local Instead of working with the Fastly KV Store, operate on
local files that will be used to simulate the KV Store
with the local development environment.
KV Store mode only. In S3 mode, --local is an error.

--fastly-api-token=<token> Fastly API token for KV Store access.
If not set, the tool uses the FASTLY_API_TOKEN
Expand Down
42 changes: 41 additions & 1 deletion src/cli/commands/manage/collections/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { type OptionDefinition } from 'command-line-args';
import { parseCommandLine } from '../../../util/args.js';
import { LoadConfigError, loadStaticPublisherRcFile } from '../../../util/config.js';
import { loadStorageProviderFromStaticPublishRc } from '../../../storage/storage-provider.js';
import { type PurgeTarget, loadPurgeTarget, purgeCollection } from '../../../util/purge.js';

function help() {
console.log(`\
Expand All @@ -24,18 +25,33 @@ Description:
Use the 'npx @fastly/compute-js-static-publish clean' command afterward to remove content
files that are no longer referenced by any collection.

If a Service ID is found, the tool then purges the cached responses of the collection
from that service.

Required:
--collection-name=<name> The name of the collection to delete

KV Store Options:
--local Instead of working with the Fastly KV Store, operate on
local files that will be used to simulate the KV Store
with the local development environment.
KV Store mode only. In S3 mode, --local is an error.

--fastly-api-token=<token> Fastly API token for KV Store access.
--fastly-api-token=<token> Fastly API token for KV Store or cache access.
If not set, the tool uses the FASTLY_API_TOKEN
environment variable.

Purge Options:
--fastly-service-id=<id> Fastly Service ID to purge after deleting (not with --local).
If not set, the tool will check:
1. FASTLY_SERVICE_ID environment variable
2. service_id in fastly.toml
If none is found, the purge is skipped.

--purge-environment=<env> Environment to purge: production, staging, or a
comma-separated list of both. Can be repeated.
Default: production

S3 Storage Options (BETA):
--s3-access-key-id=<id> Access Key ID and Secret Access Key used to
--s3-secret-access-key=<key> interface with S3 or compatible storage.
Expand All @@ -56,6 +72,8 @@ export async function action(actionArgs: string[]) {

{ name: 'local', type: Boolean },
{ name: 'fastly-api-token', type: String, },
{ name: 'fastly-service-id', type: String, },
{ name: 'purge-environment', type: String, multiple: true, },

{ name: 's3-access-key-id', type: String, },
{ name: 's3-secret-access-key', type: String, },
Expand All @@ -77,6 +95,8 @@ export async function action(actionArgs: string[]) {
verbose,
['collection-name']: collectionNameValue,
['fastly-api-token']: fastlyApiToken,
['fastly-service-id']: fastlyServiceId,
['purge-environment']: purgeEnvironmentValues,
local: localMode,
['s3-access-key-id']: s3AccessKeyId,
['s3-secret-access-key']: s3SecretAccessKey,
Expand Down Expand Up @@ -145,6 +165,22 @@ export async function action(actionArgs: string[]) {

console.log(`✔️ Collection to delete: ${collectionName}`);

// Purge target: checked now, so that a missing API token fails before anything is deleted.
let purgeTarget: PurgeTarget | null;
try {
purgeTarget = loadPurgeTarget({
localMode: localMode ?? false,
computeAppDir,
fastlyServiceId,
fastlyApiToken,
purgeEnvironments: purgeEnvironmentValues,
});
} catch (err: unknown) {
console.error(String(err));
process.exitCode = 1;
return;
}

// ### Asset Keys to delete
const assetKeysToDelete = new Set<string>();

Expand Down Expand Up @@ -181,5 +217,9 @@ export async function action(actionArgs: string[]) {
true,
)

if (purgeTarget != null) {
await purgeCollection(purgeTarget, publishId, collectionName);
}

console.log("✅ Completed.")
}
1 change: 1 addition & 0 deletions src/cli/commands/manage/collections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ KV Store Options:
--local Instead of working with the Fastly KV Store, operate on
local files that will be used to simulate the KV Store
with the local development environment.
KV Store mode only. In S3 mode, --local is an error.

--fastly-api-token=<token> Fastly API token for KV Store access.
If not set, the tool uses the FASTLY_API_TOKEN
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/manage/collections/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ KV Store Options:
--local Instead of working with the Fastly KV Store, operate on
local files that will be used to simulate the KV Store
with the local development environment.
KV Store mode only. In S3 mode, --local is an error.

--fastly-api-token=<token> Fastly API token for KV Store access.
If not set, the tool uses the FASTLY_API_TOKEN
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/manage/collections/promote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ KV Store Options:
--local Instead of working with the Fastly KV Store, operate on
local files that will be used to simulate the KV Store
with the local development environment.
KV Store mode only. In S3 mode, --local is an error.

--fastly-api-token=<token> Fastly API token for KV Store access.
If not set, the tool uses the FASTLY_API_TOKEN
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/manage/collections/update-expiration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ KV Store Options:
--local Instead of working with the Fastly KV Store, operate on
local files that will be used to simulate the KV Store
with the local development environment.
KV Store mode only. In S3 mode, --local is an error.

--fastly-api-token=<token> Fastly API token for KV Store access.
If not set, the tool uses the FASTLY_API_TOKEN
Expand Down
1 change: 1 addition & 0 deletions src/cli/commands/manage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ KV Store Options:
--local Instead of working with the Fastly KV Store, operate on
local files that will be used to simulate the KV Store
with the local development environment.
KV Store mode only. In S3 mode, --local is an error.

--fastly-api-token=<token> Fastly API token for KV Store access.
If not set, the tool uses the FASTLY_API_TOKEN
Expand Down
Loading
Loading