blogwright-core 0.3.3 → 0.4.0-beta.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/README.md +1 -1
- package/dist/adapters/node-terminal.d.ts +2 -2
- package/dist/adapters/node-terminal.js +1 -1
- package/dist/aws/cloudfront.d.ts +4 -4
- package/dist/aws/cloudfront.js +6 -6
- package/dist/aws/credentials.d.ts +1 -1
- package/dist/aws/credentials.js +1 -1
- package/dist/aws/endpoint.d.ts +22 -2
- package/dist/aws/endpoint.js +21 -2
- package/dist/aws/errors.js +1 -1
- package/dist/aws/iam.d.ts +1 -1
- package/dist/aws/iam.js +1 -1
- package/dist/aws/logs.d.ts +24 -4
- package/dist/aws/logs.js +19 -9
- package/dist/aws/microvms.d.ts +1 -1
- package/dist/aws/microvms.js +2 -2
- package/dist/aws/route53.d.ts +1 -1
- package/dist/aws/route53.js +2 -2
- package/dist/aws/signer.d.ts +2 -2
- package/dist/aws/signer.js +7 -6
- package/dist/aws/sts.d.ts +1 -1
- package/dist/aws/sts.js +1 -1
- package/dist/aws/xml.d.ts +2 -2
- package/dist/aws/xml.js +2 -2
- package/dist/clients.d.ts +11 -1
- package/dist/clients.js +3 -1
- package/dist/colors.js +1 -1
- package/dist/config.d.ts +47 -4
- package/dist/config.js +29 -28
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/plugin.d.ts +360 -0
- package/dist/plugin.js +85 -0
- package/dist/repo-root.d.ts +3 -0
- package/dist/repo-root.js +7 -1
- package/dist/state.d.ts +24 -3
- package/dist/state.js +38 -11
- package/dist/util.d.ts +23 -0
- package/dist/util.js +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
SigV4 transport, per-service AWS HTTP clients, config parsing, and the S3 state store
|
|
4
4
|
used by [blogwright](https://www.npmjs.com/package/blogwright). Not useful on its
|
|
5
|
-
own
|
|
5
|
+
own - install `blogwright` instead.
|
|
6
6
|
|
|
7
7
|
Full documentation: https://github.com/antstanley/blogwright
|
|
@@ -13,7 +13,7 @@ export interface TerminalStreams {
|
|
|
13
13
|
export interface NodeTerminalOptions extends Partial<TerminalStreams> {
|
|
14
14
|
/**
|
|
15
15
|
* Force the minimal, machine-friendly presentation (`--plain`): the terminal
|
|
16
|
-
* reports non-interactive, so output is plain durable lines
|
|
16
|
+
* reports non-interactive, so output is plain durable lines - no colour, no
|
|
17
17
|
* transient status, no prompts left hanging for automation.
|
|
18
18
|
*/
|
|
19
19
|
plain?: boolean | undefined;
|
|
@@ -22,7 +22,7 @@ export interface NodeTerminalOptions extends Partial<TerminalStreams> {
|
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Build the real Terminal adapter over the process's standard streams. TTY
|
|
25
|
-
* state is read once, at construction
|
|
25
|
+
* state is read once, at construction - never at module load or per call.
|
|
26
26
|
* The transient status line exists only on an interactive TTY; `write`/`error`
|
|
27
27
|
* clear it first so durable lines never interleave with a stale status.
|
|
28
28
|
*/
|
|
@@ -4,7 +4,7 @@ import { stripColors } from '../colors.js';
|
|
|
4
4
|
const CLEAR_LINE = '\r\u001B[2K';
|
|
5
5
|
/**
|
|
6
6
|
* Build the real Terminal adapter over the process's standard streams. TTY
|
|
7
|
-
* state is read once, at construction
|
|
7
|
+
* state is read once, at construction - never at module load or per call.
|
|
8
8
|
* The transient status line exists only on an interactive TTY; `write`/`error`
|
|
9
9
|
* clear it first so durable lines never interleave with a stale status.
|
|
10
10
|
*/
|
package/dist/aws/cloudfront.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { SigningClient } from './signer.js';
|
|
|
2
2
|
import type { ResourceTags } from '../tags.js';
|
|
3
3
|
/** AWS managed "CachingOptimized" cache policy. */
|
|
4
4
|
export declare const CACHING_OPTIMIZED = "658327ea-f89d-4fab-a63d-7e88639e58f6";
|
|
5
|
-
/** AWS managed "CachingDisabled" cache policy (used for previews
|
|
5
|
+
/** AWS managed "CachingDisabled" cache policy (used for previews - no CDN caching). */
|
|
6
6
|
export declare const CACHING_DISABLED = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad";
|
|
7
7
|
export interface DistributionSummary {
|
|
8
8
|
id: string;
|
|
@@ -11,7 +11,7 @@ export interface DistributionSummary {
|
|
|
11
11
|
status: string;
|
|
12
12
|
etag: string | undefined;
|
|
13
13
|
}
|
|
14
|
-
/** One entry from ListDistributions
|
|
14
|
+
/** One entry from ListDistributions - enough to identify a distribution for adoption. */
|
|
15
15
|
export interface DistributionListItem {
|
|
16
16
|
id: string;
|
|
17
17
|
arn: string;
|
|
@@ -62,7 +62,7 @@ export declare class CloudFrontClient {
|
|
|
62
62
|
etag: string;
|
|
63
63
|
} | undefined>;
|
|
64
64
|
/**
|
|
65
|
-
* Reconcile the distribution's aliases and viewer certificate in place
|
|
65
|
+
* Reconcile the distribution's aliases and viewer certificate in place - the
|
|
66
66
|
* path taken when a domain is added (or changed) after the distribution was
|
|
67
67
|
* first created. Compares semantically (CNAME set + certificate ARN), since
|
|
68
68
|
* the returned config carries legacy elements our builder never emits.
|
|
@@ -72,7 +72,7 @@ export declare class CloudFrontClient {
|
|
|
72
72
|
/**
|
|
73
73
|
* Disable a distribution by flipping its top-level `<Enabled>` to false. The config
|
|
74
74
|
* also contains `<Enabled>false</Enabled>` inside TrustedSigners/Logging, so the
|
|
75
|
-
* distribution-level flag must be matched specifically
|
|
75
|
+
* distribution-level flag must be matched specifically - it is the one immediately
|
|
76
76
|
* followed by `<ViewerCertificate>` in the schema.
|
|
77
77
|
*/
|
|
78
78
|
disableDistribution(id: string): Promise<void>;
|
package/dist/aws/cloudfront.js
CHANGED
|
@@ -4,7 +4,7 @@ const API = '/2020-05-31';
|
|
|
4
4
|
const XMLNS = 'http://cloudfront.amazonaws.com/doc/2020-05-31/';
|
|
5
5
|
/** AWS managed "CachingOptimized" cache policy. */
|
|
6
6
|
export const CACHING_OPTIMIZED = '658327ea-f89d-4fab-a63d-7e88639e58f6';
|
|
7
|
-
/** AWS managed "CachingDisabled" cache policy (used for previews
|
|
7
|
+
/** AWS managed "CachingDisabled" cache policy (used for previews - no CDN caching). */
|
|
8
8
|
export const CACHING_DISABLED = '4135ea2d-6df8-44a3-9df3-4b5a84be39ad';
|
|
9
9
|
/** CloudFront client (REST-XML). Global service, signed in us-east-1. */
|
|
10
10
|
export class CloudFrontClient {
|
|
@@ -116,7 +116,7 @@ export class CloudFrontClient {
|
|
|
116
116
|
service: 'cloudfront',
|
|
117
117
|
method: 'POST',
|
|
118
118
|
path: `${API}/tagging`,
|
|
119
|
-
// Operation=Tag is required
|
|
119
|
+
// Operation=Tag is required - the tagging path is shared with UntagResource
|
|
120
120
|
// (Operation=Untag) and CloudFront routes on it; without it: InvalidAction.
|
|
121
121
|
query: { Operation: 'Tag', Resource: resourceArn },
|
|
122
122
|
headers: { 'content-type': 'application/xml' },
|
|
@@ -140,7 +140,7 @@ export class CloudFrontClient {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
/**
|
|
143
|
-
* Reconcile the distribution's aliases and viewer certificate in place
|
|
143
|
+
* Reconcile the distribution's aliases and viewer certificate in place - the
|
|
144
144
|
* path taken when a domain is added (or changed) after the distribution was
|
|
145
145
|
* first created. Compares semantically (CNAME set + certificate ARN), since
|
|
146
146
|
* the returned config carries legacy elements our builder never emits.
|
|
@@ -171,7 +171,7 @@ export class CloudFrontClient {
|
|
|
171
171
|
/**
|
|
172
172
|
* Disable a distribution by flipping its top-level `<Enabled>` to false. The config
|
|
173
173
|
* also contains `<Enabled>false</Enabled>` inside TrustedSigners/Logging, so the
|
|
174
|
-
* distribution-level flag must be matched specifically
|
|
174
|
+
* distribution-level flag must be matched specifically - it is the one immediately
|
|
175
175
|
* followed by `<ViewerCertificate>` in the schema.
|
|
176
176
|
*/
|
|
177
177
|
async disableDistribution(id) {
|
|
@@ -240,7 +240,7 @@ export class CloudFrontClient {
|
|
|
240
240
|
async describeFunction(name) {
|
|
241
241
|
// DescribeFunction is GET …/function/{name}/describe (XML summary). The
|
|
242
242
|
// bare GET …/function/{name} is GetFunction, whose body is the raw code
|
|
243
|
-
// bytes
|
|
243
|
+
// bytes - no FunctionARN to parse.
|
|
244
244
|
try {
|
|
245
245
|
const res = await this.client.send({
|
|
246
246
|
service: 'cloudfront',
|
|
@@ -277,7 +277,7 @@ export class CloudFrontClient {
|
|
|
277
277
|
});
|
|
278
278
|
}
|
|
279
279
|
// Re-read the current ETag before publishing. Create/update return a fresh ETag, but
|
|
280
|
-
// it isn't reliably surfaced from the response headers
|
|
280
|
+
// it isn't reliably surfaced from the response headers - publishing the DEVELOPMENT
|
|
281
281
|
// stage with a stale ETag fails the precondition (HTTP 412), which is what broke
|
|
282
282
|
// reconciling an already-existing function.
|
|
283
283
|
const current = await this.describeFunction(name);
|
|
@@ -10,7 +10,7 @@ export type CredentialProvider = () => Promise<AwsCredentials>;
|
|
|
10
10
|
*
|
|
11
11
|
* When an endpoint override is in play (floci/localstack) and no real credentials
|
|
12
12
|
* are configured, fall back to the emulator's dummy `test/test` pair so signing
|
|
13
|
-
* still succeeds
|
|
13
|
+
* still succeeds - floci does not validate signatures.
|
|
14
14
|
*/
|
|
15
15
|
export declare function createCredentialProvider(opts: {
|
|
16
16
|
override?: boolean | undefined;
|
package/dist/aws/credentials.js
CHANGED
|
@@ -5,7 +5,7 @@ import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
|
5
5
|
*
|
|
6
6
|
* When an endpoint override is in play (floci/localstack) and no real credentials
|
|
7
7
|
* are configured, fall back to the emulator's dummy `test/test` pair so signing
|
|
8
|
-
* still succeeds
|
|
8
|
+
* still succeeds - floci does not validate signatures.
|
|
9
9
|
*/
|
|
10
10
|
export function createCredentialProvider(opts) {
|
|
11
11
|
const chain = fromNodeProviderChain();
|
package/dist/aws/endpoint.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
export interface ResolvedEndpoint {
|
|
9
9
|
protocol: 'http:' | 'https:';
|
|
10
10
|
host: string;
|
|
11
|
-
/** Signing region
|
|
11
|
+
/** Signing region - some services (iam, cloudfront) are global and sign as us-east-1. */
|
|
12
12
|
signingRegion: string;
|
|
13
13
|
/** True when talking to an override origin (floci/localstack); forces S3 path-style. */
|
|
14
14
|
override: boolean;
|
|
@@ -26,4 +26,24 @@ export declare const SIGNING_NAMES: {
|
|
|
26
26
|
readonly secretsmanager: "secretsmanager";
|
|
27
27
|
};
|
|
28
28
|
export type ServiceKey = keyof typeof SIGNING_NAMES;
|
|
29
|
-
|
|
29
|
+
/**
|
|
30
|
+
* A plugin-supplied AWS service - core does not enumerate it, so the plugin names
|
|
31
|
+
* its own SigV4 signing name and whether it is global (signs in us-east-1).
|
|
32
|
+
*/
|
|
33
|
+
export interface ServiceDescriptor {
|
|
34
|
+
service: string;
|
|
35
|
+
signingName: string;
|
|
36
|
+
global?: boolean | undefined;
|
|
37
|
+
}
|
|
38
|
+
/** What every `service`-keyed site actually needs, whichever form `service` arrived in. */
|
|
39
|
+
export interface ResolvedService {
|
|
40
|
+
name: string;
|
|
41
|
+
signingName: string;
|
|
42
|
+
global: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Turns a core `ServiceKey` or a plugin-supplied `ServiceDescriptor` into one shape.
|
|
46
|
+
* The single resolution helper every `service`-keyed site reads.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveService(service: ServiceKey | ServiceDescriptor): ResolvedService;
|
|
49
|
+
export declare function resolveEndpoint(service: ServiceKey | ServiceDescriptor, region: string, override: string | undefined): ResolvedEndpoint;
|
package/dist/aws/endpoint.js
CHANGED
|
@@ -21,8 +21,27 @@ export const SIGNING_NAMES = {
|
|
|
21
21
|
};
|
|
22
22
|
/** Services that are global; they always sign in us-east-1. */
|
|
23
23
|
const GLOBAL_SERVICES = new Set(['iam', 'cloudfront', 'route53']);
|
|
24
|
+
/**
|
|
25
|
+
* Turns a core `ServiceKey` or a plugin-supplied `ServiceDescriptor` into one shape.
|
|
26
|
+
* The single resolution helper every `service`-keyed site reads.
|
|
27
|
+
*/
|
|
28
|
+
export function resolveService(service) {
|
|
29
|
+
if (typeof service === 'string') {
|
|
30
|
+
return {
|
|
31
|
+
name: service,
|
|
32
|
+
signingName: SIGNING_NAMES[service],
|
|
33
|
+
global: GLOBAL_SERVICES.has(service),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
name: service.service,
|
|
38
|
+
signingName: service.signingName,
|
|
39
|
+
global: service.global ?? false,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
24
42
|
export function resolveEndpoint(service, region, override) {
|
|
25
|
-
const
|
|
43
|
+
const resolved = resolveService(service);
|
|
44
|
+
const signingRegion = resolved.global ? 'us-east-1' : region;
|
|
26
45
|
if (override) {
|
|
27
46
|
const url = new URL(override);
|
|
28
47
|
return {
|
|
@@ -34,7 +53,7 @@ export function resolveEndpoint(service, region, override) {
|
|
|
34
53
|
}
|
|
35
54
|
return {
|
|
36
55
|
protocol: 'https:',
|
|
37
|
-
host: canonicalHost(
|
|
56
|
+
host: canonicalHost(resolved.name, region),
|
|
38
57
|
signingRegion,
|
|
39
58
|
override: false,
|
|
40
59
|
};
|
package/dist/aws/errors.js
CHANGED
|
@@ -5,7 +5,7 @@ export class AwsError extends Error {
|
|
|
5
5
|
requestId;
|
|
6
6
|
service;
|
|
7
7
|
constructor(opts) {
|
|
8
|
-
super(`${opts.service}: ${opts.code}
|
|
8
|
+
super(`${opts.service}: ${opts.code} - ${opts.message} (HTTP ${opts.statusCode})`);
|
|
9
9
|
this.name = 'AwsError';
|
|
10
10
|
this.service = opts.service;
|
|
11
11
|
this.code = opts.code;
|
package/dist/aws/iam.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ResourceTags } from '../tags.js';
|
|
2
2
|
import type { SigningClient } from './signer.js';
|
|
3
|
-
/** IAM client (query protocol)
|
|
3
|
+
/** IAM client (query protocol) - roles with inline policies. */
|
|
4
4
|
export declare class IamClient {
|
|
5
5
|
private readonly client;
|
|
6
6
|
constructor(client: SigningClient);
|
package/dist/aws/iam.js
CHANGED
|
@@ -2,7 +2,7 @@ import { AwsError } from './errors.js';
|
|
|
2
2
|
import { formEncode } from './form.js';
|
|
3
3
|
import { allTags, textTag } from './xml.js';
|
|
4
4
|
const VERSION = '2010-05-08';
|
|
5
|
-
/** IAM client (query protocol)
|
|
5
|
+
/** IAM client (query protocol) - roles with inline policies. */
|
|
6
6
|
export class IamClient {
|
|
7
7
|
client;
|
|
8
8
|
constructor(client) {
|
package/dist/aws/logs.d.ts
CHANGED
|
@@ -9,6 +9,26 @@ export interface FilterEventsOptions {
|
|
|
9
9
|
startTime?: number | undefined;
|
|
10
10
|
endTime?: number | undefined;
|
|
11
11
|
}
|
|
12
|
+
/** The format CloudWatch Logs writes records in for a vended log delivery. */
|
|
13
|
+
export type DeliveryOutputFormat = 'json' | 'plain' | 'w3c' | 'raw' | 'parquet';
|
|
14
|
+
export interface DeliveryDestinationOptions {
|
|
15
|
+
outputFormat?: DeliveryOutputFormat | undefined;
|
|
16
|
+
}
|
|
17
|
+
export interface DeliveryOptions {
|
|
18
|
+
recordFields?: readonly string[] | undefined;
|
|
19
|
+
fieldDelimiter?: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* One delivery attached to a delivery source. The destination ARN travels with
|
|
23
|
+
* the id because a delivery source is shared - AWS permits exactly one per
|
|
24
|
+
* distribution - so a caller tearing its own wiring down has to tell its
|
|
25
|
+
* delivery from someone else's, and the destination it feeds is the only thing
|
|
26
|
+
* that distinguishes them. `DescribeDeliveries` already returns the field.
|
|
27
|
+
*/
|
|
28
|
+
export interface DeliverySummary {
|
|
29
|
+
id: string;
|
|
30
|
+
deliveryDestinationArn: string;
|
|
31
|
+
}
|
|
12
32
|
/** CloudWatch Logs client (AWS JSON 1.1). */
|
|
13
33
|
export declare class LogsClient {
|
|
14
34
|
private readonly client;
|
|
@@ -21,12 +41,12 @@ export declare class LogsClient {
|
|
|
21
41
|
/** Fetch events across a log group within an optional time window. */
|
|
22
42
|
filterEvents(logGroupName: string, opts?: FilterEventsOptions): Promise<LogEvent[]>;
|
|
23
43
|
putDeliverySource(name: string, resourceArn: string, logType: string, tags?: ResourceTags): Promise<string>;
|
|
24
|
-
putDeliveryDestination(name: string, logGroupArn: string): Promise<string>;
|
|
25
|
-
createDelivery(deliverySourceName: string, deliveryDestinationArn: string): Promise<void>;
|
|
44
|
+
putDeliveryDestination(name: string, logGroupArn: string, opts?: DeliveryDestinationOptions): Promise<string>;
|
|
45
|
+
createDelivery(deliverySourceName: string, deliveryDestinationArn: string, opts?: DeliveryOptions): Promise<void>;
|
|
26
46
|
/** The delivery id linking a given source (needed to delete it), or undefined if none. */
|
|
27
47
|
findDeliveryIdBySource(deliverySourceName: string): Promise<string | undefined>;
|
|
28
|
-
/**
|
|
29
|
-
deliveriesForSource(sourceName: string): Promise<
|
|
48
|
+
/** Every delivery attached to a delivery source, each paired with the destination it feeds. */
|
|
49
|
+
deliveriesForSource(sourceName: string): Promise<DeliverySummary[]>;
|
|
30
50
|
deleteDelivery(id: string): Promise<void>;
|
|
31
51
|
deleteDeliverySource(name: string): Promise<void>;
|
|
32
52
|
deleteDeliveryDestination(name: string): Promise<void>;
|
package/dist/aws/logs.js
CHANGED
|
@@ -78,13 +78,22 @@ export class LogsClient {
|
|
|
78
78
|
});
|
|
79
79
|
return out.deliverySource?.arn ?? '';
|
|
80
80
|
}
|
|
81
|
-
async putDeliveryDestination(name, logGroupArn) {
|
|
82
|
-
const out = await this.call('PutDeliveryDestination', {
|
|
81
|
+
async putDeliveryDestination(name, logGroupArn, opts = {}) {
|
|
82
|
+
const out = await this.call('PutDeliveryDestination', {
|
|
83
|
+
name,
|
|
84
|
+
deliveryDestinationConfiguration: { destinationResourceArn: logGroupArn },
|
|
85
|
+
...(opts.outputFormat !== undefined ? { outputFormat: opts.outputFormat } : {}),
|
|
86
|
+
});
|
|
83
87
|
return out.deliveryDestination?.arn ?? '';
|
|
84
88
|
}
|
|
85
|
-
async createDelivery(deliverySourceName, deliveryDestinationArn) {
|
|
89
|
+
async createDelivery(deliverySourceName, deliveryDestinationArn, opts = {}) {
|
|
86
90
|
try {
|
|
87
|
-
await this.call('CreateDelivery', {
|
|
91
|
+
await this.call('CreateDelivery', {
|
|
92
|
+
deliverySourceName,
|
|
93
|
+
deliveryDestinationArn,
|
|
94
|
+
...(opts.recordFields !== undefined ? { recordFields: opts.recordFields } : {}),
|
|
95
|
+
...(opts.fieldDelimiter !== undefined ? { fieldDelimiter: opts.fieldDelimiter } : {}),
|
|
96
|
+
});
|
|
88
97
|
}
|
|
89
98
|
catch (err) {
|
|
90
99
|
if (err instanceof AwsError && err.isAlreadyExists)
|
|
@@ -104,19 +113,20 @@ export class LogsClient {
|
|
|
104
113
|
} while (nextToken);
|
|
105
114
|
return undefined;
|
|
106
115
|
}
|
|
107
|
-
/**
|
|
116
|
+
/** Every delivery attached to a delivery source, each paired with the destination it feeds. */
|
|
108
117
|
async deliveriesForSource(sourceName) {
|
|
109
|
-
const
|
|
118
|
+
const deliveries = [];
|
|
110
119
|
let nextToken;
|
|
111
120
|
do {
|
|
112
121
|
const out = await this.call('DescribeDeliveries', nextToken ? { nextToken } : {});
|
|
113
122
|
for (const d of out.deliveries ?? []) {
|
|
114
|
-
if (d.deliverySourceName === sourceName)
|
|
115
|
-
|
|
123
|
+
if (d.deliverySourceName === sourceName) {
|
|
124
|
+
deliveries.push({ id: d.id, deliveryDestinationArn: d.deliveryDestinationArn ?? '' });
|
|
125
|
+
}
|
|
116
126
|
}
|
|
117
127
|
nextToken = out.nextToken;
|
|
118
128
|
} while (nextToken);
|
|
119
|
-
return
|
|
129
|
+
return deliveries;
|
|
120
130
|
}
|
|
121
131
|
async deleteDelivery(id) {
|
|
122
132
|
try {
|
package/dist/aws/microvms.d.ts
CHANGED
|
@@ -73,7 +73,7 @@ export declare class MicrovmsClient {
|
|
|
73
73
|
*
|
|
74
74
|
* `maxResults` is always sent: the ListMicrovms operation defines it as a defaulted
|
|
75
75
|
* query parameter, and the service normalizes a missing default into the request before
|
|
76
|
-
* validating the SigV4 signature
|
|
76
|
+
* validating the SigV4 signature - so omitting it produces an intermittent
|
|
77
77
|
* SignatureDoesNotMatch that GetMicrovm/DeleteMicrovm (no query params) never hit.
|
|
78
78
|
*/
|
|
79
79
|
listMicrovms(opts?: {
|
package/dist/aws/microvms.js
CHANGED
|
@@ -84,7 +84,7 @@ export class MicrovmsClient {
|
|
|
84
84
|
return normalizeImage(await this.call('POST', PATHS.images, body));
|
|
85
85
|
}
|
|
86
86
|
async updateImage(id, input) {
|
|
87
|
-
// A PUT is idempotent on the image itself, so no clientToken is needed
|
|
87
|
+
// A PUT is idempotent on the image itself, so no clientToken is needed - and reusing one
|
|
88
88
|
// across separate update attempts triggers "clientToken used with different parameters".
|
|
89
89
|
const { clientToken, ...body } = this.imageBody(input);
|
|
90
90
|
void clientToken;
|
|
@@ -140,7 +140,7 @@ export class MicrovmsClient {
|
|
|
140
140
|
*
|
|
141
141
|
* `maxResults` is always sent: the ListMicrovms operation defines it as a defaulted
|
|
142
142
|
* query parameter, and the service normalizes a missing default into the request before
|
|
143
|
-
* validating the SigV4 signature
|
|
143
|
+
* validating the SigV4 signature - so omitting it produces an intermittent
|
|
144
144
|
* SignatureDoesNotMatch that GetMicrovm/DeleteMicrovm (no query params) never hit.
|
|
145
145
|
*/
|
|
146
146
|
async listMicrovms(opts = {}) {
|
package/dist/aws/route53.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface DnsRecord {
|
|
|
8
8
|
/** When set, emit an AliasTarget (no TTL/ResourceRecords) pointing at `value`. */
|
|
9
9
|
aliasZoneId?: string | undefined;
|
|
10
10
|
}
|
|
11
|
-
/** CloudFront's fixed alias hosted zone id
|
|
11
|
+
/** CloudFront's fixed alias hosted zone id - the same for every distribution. */
|
|
12
12
|
export declare const CLOUDFRONT_ALIAS_ZONE_ID = "Z2FDTNDATAQYW2";
|
|
13
13
|
/** Route53 client (REST-XML). Global service, signed in us-east-1. */
|
|
14
14
|
export declare class Route53Client {
|
package/dist/aws/route53.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AwsError } from './errors.js';
|
|
2
2
|
import { encodeEntities, textTag } from './xml.js';
|
|
3
3
|
const API = '/2013-04-01';
|
|
4
|
-
/** CloudFront's fixed alias hosted zone id
|
|
4
|
+
/** CloudFront's fixed alias hosted zone id - the same for every distribution. */
|
|
5
5
|
export const CLOUDFRONT_ALIAS_ZONE_ID = 'Z2FDTNDATAQYW2';
|
|
6
6
|
/** Route53 client (REST-XML). Global service, signed in us-east-1. */
|
|
7
7
|
export class Route53Client {
|
|
@@ -63,7 +63,7 @@ export class Route53Client {
|
|
|
63
63
|
await this.change(zoneId, 'DELETE', record);
|
|
64
64
|
}
|
|
65
65
|
catch (err) {
|
|
66
|
-
// Route53 rejects a DELETE whose record doesn't exactly match/exist
|
|
66
|
+
// Route53 rejects a DELETE whose record doesn't exactly match/exist -
|
|
67
67
|
// that (and only that) means "already gone". Throttling, auth, and other
|
|
68
68
|
// failures must surface, or a teardown leaves the record dangling while
|
|
69
69
|
// reporting success.
|
package/dist/aws/signer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CredentialProvider } from './credentials.js';
|
|
2
|
-
import { type ServiceKey } from './endpoint.js';
|
|
2
|
+
import { type ServiceDescriptor, type ServiceKey } from './endpoint.js';
|
|
3
3
|
export interface RawResponse {
|
|
4
4
|
statusCode: number;
|
|
5
5
|
headers: Record<string, string>;
|
|
@@ -14,7 +14,7 @@ export type Transport = (req: {
|
|
|
14
14
|
body: string | Uint8Array | undefined;
|
|
15
15
|
}) => Promise<RawResponse>;
|
|
16
16
|
export interface SendOptions {
|
|
17
|
-
service: ServiceKey;
|
|
17
|
+
service: ServiceKey | ServiceDescriptor;
|
|
18
18
|
method: string;
|
|
19
19
|
/** Path starting with '/'. For S3 pass an already-percent-encoded path. */
|
|
20
20
|
path: string;
|
package/dist/aws/signer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Sha256 } from '@aws-crypto/sha256-js';
|
|
2
2
|
import { HttpRequest } from '@smithy/protocol-http';
|
|
3
3
|
import { SignatureV4 } from '@smithy/signature-v4';
|
|
4
|
-
import { resolveEndpoint,
|
|
4
|
+
import { resolveEndpoint, resolveService, } from './endpoint.js';
|
|
5
5
|
import { AwsError, isRetryable } from './errors.js';
|
|
6
6
|
import { withRetry } from '../util.js';
|
|
7
7
|
import { textTag } from './xml.js';
|
|
@@ -51,6 +51,7 @@ export class SigningClient {
|
|
|
51
51
|
this.transport = opts.transport ?? fetchTransport;
|
|
52
52
|
}
|
|
53
53
|
async send(opts) {
|
|
54
|
+
const resolved = resolveService(opts.service);
|
|
54
55
|
const ep = resolveEndpoint(opts.service, this.region, this.endpointOverride);
|
|
55
56
|
const [hostname, portStr] = ep.host.split(':');
|
|
56
57
|
const port = portStr ? Number(portStr) : undefined;
|
|
@@ -76,7 +77,7 @@ export class SigningClient {
|
|
|
76
77
|
...(opts.body !== undefined ? { body: opts.body } : {}),
|
|
77
78
|
});
|
|
78
79
|
const signer = new SignatureV4({
|
|
79
|
-
service:
|
|
80
|
+
service: resolved.signingName,
|
|
80
81
|
region: ep.signingRegion,
|
|
81
82
|
credentials: async () => {
|
|
82
83
|
const c = await this.credentials();
|
|
@@ -87,7 +88,7 @@ export class SigningClient {
|
|
|
87
88
|
};
|
|
88
89
|
},
|
|
89
90
|
sha256: Sha256,
|
|
90
|
-
uriEscapePath:
|
|
91
|
+
uriEscapePath: resolved.name !== 's3',
|
|
91
92
|
});
|
|
92
93
|
const signed = await signer.sign(request);
|
|
93
94
|
const qs = Object.keys(query)
|
|
@@ -96,7 +97,7 @@ export class SigningClient {
|
|
|
96
97
|
const url = `${ep.protocol}//${ep.host}${opts.path}${qs ? `?${qs}` : ''}`;
|
|
97
98
|
// Retry transient failures with backoff. For idempotent methods, retry on network
|
|
98
99
|
// errors and 5xx/429. For non-idempotent POSTs, retry ONLY on network errors (the
|
|
99
|
-
// request never reached the server)
|
|
100
|
+
// request never reached the server) - never on a 5xx, which may mean the mutation
|
|
100
101
|
// was applied and a retry would double-execute (e.g. launch a second MicroVM).
|
|
101
102
|
const idempotent = ['GET', 'HEAD', 'PUT', 'DELETE'].includes(opts.method);
|
|
102
103
|
const retryable = idempotent ? isRetryable : (err) => err instanceof TypeError;
|
|
@@ -109,10 +110,10 @@ export class SigningClient {
|
|
|
109
110
|
});
|
|
110
111
|
// Anything outside 2xx is a failure. 3xx matters: S3's region-mismatch
|
|
111
112
|
// PermanentRedirect is a 301 with no Location header, which fetch
|
|
112
|
-
// returns as final
|
|
113
|
+
// returns as final - treating it as success would report writes as
|
|
113
114
|
// stored and listings as empty against the wrong endpoint.
|
|
114
115
|
if (response.statusCode >= 300)
|
|
115
|
-
throw parseError(
|
|
116
|
+
throw parseError(resolved.name, response);
|
|
116
117
|
return response;
|
|
117
118
|
}, { retryable });
|
|
118
119
|
}
|
package/dist/aws/sts.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SigningClient } from './signer.js';
|
|
2
|
-
/** STS client
|
|
2
|
+
/** STS client - only GetCallerIdentity, used to derive the account id. */
|
|
3
3
|
export declare class StsClient {
|
|
4
4
|
private readonly client;
|
|
5
5
|
constructor(client: SigningClient);
|
package/dist/aws/sts.js
CHANGED
package/dist/aws/xml.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Minimal XML helpers for the handful of AWS REST-XML / query responses this CLI
|
|
3
|
-
* reads (S3, STS, IAM, CloudFront). Not a general XML parser
|
|
3
|
+
* reads (S3, STS, IAM, CloudFront). Not a general XML parser - it extracts tag
|
|
4
4
|
* contents by name, which is sufficient for the flat response shapes we consume.
|
|
5
5
|
*/
|
|
6
6
|
export declare function decodeEntities(value: string): string;
|
|
@@ -10,7 +10,7 @@ export declare function firstTag(xml: string, name: string): string | undefined;
|
|
|
10
10
|
/** Return the decoded text value of the first `<name>` element. */
|
|
11
11
|
export declare function textTag(xml: string, name: string): string | undefined;
|
|
12
12
|
/**
|
|
13
|
-
* Like {@link textTag} but verbatim
|
|
13
|
+
* Like {@link textTag} but verbatim - no trimming. For values where whitespace
|
|
14
14
|
* is data, like S3 object keys (a trimmed key would target a different object).
|
|
15
15
|
*/
|
|
16
16
|
export declare function rawTextTag(xml: string, name: string): string | undefined;
|
package/dist/aws/xml.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Minimal XML helpers for the handful of AWS REST-XML / query responses this CLI
|
|
3
|
-
* reads (S3, STS, IAM, CloudFront). Not a general XML parser
|
|
3
|
+
* reads (S3, STS, IAM, CloudFront). Not a general XML parser - it extracts tag
|
|
4
4
|
* contents by name, which is sufficient for the flat response shapes we consume.
|
|
5
5
|
*/
|
|
6
6
|
const ENTITIES = {
|
|
@@ -41,7 +41,7 @@ export function textTag(xml, name) {
|
|
|
41
41
|
return inner === undefined ? undefined : decodeEntities(inner.trim());
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Like {@link textTag} but verbatim
|
|
44
|
+
* Like {@link textTag} but verbatim - no trimming. For values where whitespace
|
|
45
45
|
* is data, like S3 object keys (a trimmed key would target a different object).
|
|
46
46
|
*/
|
|
47
47
|
export function rawTextTag(xml, name) {
|
package/dist/clients.d.ts
CHANGED
|
@@ -19,12 +19,22 @@ export interface ClientBundleOptions {
|
|
|
19
19
|
export interface AwsClients {
|
|
20
20
|
region: string;
|
|
21
21
|
signing: SigningClient;
|
|
22
|
+
/**
|
|
23
|
+
* The us-east-1 signer, exposed so a plugin can build clients for services
|
|
24
|
+
* core does not enumerate over the credentials, endpoint override and
|
|
25
|
+
* transport the host already resolved - a `SigningClient`'s region is fixed
|
|
26
|
+
* at construction and both of those are private, so a hand-built one would
|
|
27
|
+
* re-resolve credentials and ignore a transport a test injected. Core builds
|
|
28
|
+
* no additional client from it: `logsUsEast1`, `acm`, `cloudfront` and
|
|
29
|
+
* `route53` below are the only ones it signs for.
|
|
30
|
+
*/
|
|
31
|
+
signingUsEast1: SigningClient;
|
|
22
32
|
s3: S3Client;
|
|
23
33
|
sts: StsClient;
|
|
24
34
|
iam: IamClient;
|
|
25
35
|
logs: LogsClient;
|
|
26
36
|
/**
|
|
27
|
-
* Logs client pinned to us-east-1 for CloudFront vended log delivery
|
|
37
|
+
* Logs client pinned to us-east-1 for CloudFront vended log delivery -
|
|
28
38
|
* PutDeliverySource with the CloudFront LogType exists only there, the same
|
|
29
39
|
* global-service quirk as CloudFront's ACM certificates.
|
|
30
40
|
*/
|
package/dist/clients.js
CHANGED
|
@@ -19,11 +19,13 @@ export function createClients(opts) {
|
|
|
19
19
|
...(opts.transport ? { transport: opts.transport } : {}),
|
|
20
20
|
};
|
|
21
21
|
const signing = new SigningClient({ region: opts.region, ...base });
|
|
22
|
-
// ACM for CloudFront must be us-east-1 regardless of the primary region
|
|
22
|
+
// ACM for CloudFront must be us-east-1 regardless of the primary region; the
|
|
23
|
+
// same signer is handed out as `signingUsEast1` for plugin-supplied services.
|
|
23
24
|
const usEast1 = new SigningClient({ region: 'us-east-1', ...base });
|
|
24
25
|
return {
|
|
25
26
|
region: opts.region,
|
|
26
27
|
signing,
|
|
28
|
+
signingUsEast1: usEast1,
|
|
27
29
|
s3: new S3Client(signing),
|
|
28
30
|
sts: new StsClient(signing),
|
|
29
31
|
iam: new IamClient(signing),
|
package/dist/colors.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* ANSI colour helpers shared by the CLI and feature packages. Pure string
|
|
3
|
-
* composition
|
|
3
|
+
* composition - writing (and stripping for non-interactive sessions) is the
|
|
4
4
|
* logger's job.
|
|
5
5
|
*/
|
|
6
6
|
const ESCAPE = '\u001B';
|