blogwright-core 0.4.0-beta.2 → 0.4.0-beta.4
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/dist/aws/logs.d.ts +6 -0
- package/dist/aws/logs.js +15 -0
- package/dist/config.d.ts +6 -3
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.js +1 -1
- package/dist/state.d.ts +1 -0
- package/dist/state.js +41 -1
- package/package.json +1 -1
package/dist/aws/logs.d.ts
CHANGED
|
@@ -35,6 +35,12 @@ export declare class LogsClient {
|
|
|
35
35
|
constructor(client: SigningClient);
|
|
36
36
|
private call;
|
|
37
37
|
ensureLogGroup(name: string, tags?: ResourceTags): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Create a log stream inside a log group, treating an existing stream as success.
|
|
40
|
+
* `CreateLogStream` takes no tags, so this carries none: a stream is tagged only
|
|
41
|
+
* through the group that holds it.
|
|
42
|
+
*/
|
|
43
|
+
ensureLogStream(logGroupName: string, logStreamName: string): Promise<void>;
|
|
38
44
|
putRetentionPolicy(name: string, retentionInDays: number): Promise<void>;
|
|
39
45
|
logGroupExists(name: string): Promise<boolean>;
|
|
40
46
|
deleteLogGroup(name: string): Promise<void>;
|
package/dist/aws/logs.js
CHANGED
|
@@ -33,6 +33,21 @@ export class LogsClient {
|
|
|
33
33
|
throw err;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Create a log stream inside a log group, treating an existing stream as success.
|
|
38
|
+
* `CreateLogStream` takes no tags, so this carries none: a stream is tagged only
|
|
39
|
+
* through the group that holds it.
|
|
40
|
+
*/
|
|
41
|
+
async ensureLogStream(logGroupName, logStreamName) {
|
|
42
|
+
try {
|
|
43
|
+
await this.call('CreateLogStream', { logGroupName, logStreamName });
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
if (err instanceof AwsError && err.isAlreadyExists)
|
|
47
|
+
return;
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
36
51
|
async putRetentionPolicy(name, retentionInDays) {
|
|
37
52
|
await this.call('PutRetentionPolicy', { logGroupName: name, retentionInDays });
|
|
38
53
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -30,9 +30,12 @@ export interface SeoConfig {
|
|
|
30
30
|
* A *shape*, not a contract core enforces: `blogwright-pds` owns this key end
|
|
31
31
|
* to end - it validates the block (`validatePdsConfig`) and derives the
|
|
32
32
|
* `<siteName>/atproto` default `secretName` (`resolvePdsSecretName`). Core
|
|
33
|
-
* parses the block through untouched. The
|
|
34
|
-
*
|
|
35
|
-
*
|
|
33
|
+
* parses the block through untouched. The CLI's own resource graph no longer
|
|
34
|
+
* reads the block at all: its deploy-role statement for the secret is gone,
|
|
35
|
+
* and that grant is now the plugin's own named inline policy
|
|
36
|
+
* (`buildPdsNodes`, `packages/pds/src/nodes.ts`). The type stays here because
|
|
37
|
+
* `OpsConfig.pds` is still a declared member, and it is through
|
|
38
|
+
* `ctx.config.pds` that the plugin itself reads the block.
|
|
36
39
|
*/
|
|
37
40
|
export interface PdsConfig {
|
|
38
41
|
/** Publication display name (site.standard.publication `name`). */
|
package/dist/plugin.d.ts
CHANGED
|
@@ -272,7 +272,7 @@ export interface ConfigBlockEntry {
|
|
|
272
272
|
/**
|
|
273
273
|
* Namespace pattern shared by `Plugin.name` and {@link PluginManifest}'s
|
|
274
274
|
* `plugin` field, so the JSON Schema fragment
|
|
275
|
-
* (`.specs/changes/2026-07-26-cli_plugin_system.md` §Type changes) and this
|
|
275
|
+
* (`.specs/changes/merged/2026-07-26-cli_plugin_system.md` §Type changes) and this
|
|
276
276
|
* runtime check cannot drift apart. Lowercase alphanumerics and dashes.
|
|
277
277
|
*/
|
|
278
278
|
export declare const PLUGIN_NAME_PATTERN: RegExp;
|
package/dist/plugin.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
/**
|
|
15
15
|
* Namespace pattern shared by `Plugin.name` and {@link PluginManifest}'s
|
|
16
16
|
* `plugin` field, so the JSON Schema fragment
|
|
17
|
-
* (`.specs/changes/2026-07-26-cli_plugin_system.md` §Type changes) and this
|
|
17
|
+
* (`.specs/changes/merged/2026-07-26-cli_plugin_system.md` §Type changes) and this
|
|
18
18
|
* runtime check cannot drift apart. Lowercase alphanumerics and dashes.
|
|
19
19
|
*/
|
|
20
20
|
export const PLUGIN_NAME_PATTERN = /^[a-z0-9-]+$/;
|
package/dist/state.d.ts
CHANGED
package/dist/state.js
CHANGED
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
export function emptyState(env) {
|
|
2
2
|
return { version: 1, env, updatedAt: undefined, resources: {} };
|
|
3
3
|
}
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function isOutputValue(value) {
|
|
8
|
+
return (typeof value === 'string' ||
|
|
9
|
+
typeof value === 'number' ||
|
|
10
|
+
typeof value === 'boolean' ||
|
|
11
|
+
(Array.isArray(value) && value.every((item) => typeof item === 'string')));
|
|
12
|
+
}
|
|
13
|
+
function invalidStateField(value) {
|
|
14
|
+
if (!isRecord(value))
|
|
15
|
+
return 'state';
|
|
16
|
+
if (typeof value.version !== 'number')
|
|
17
|
+
return 'version';
|
|
18
|
+
if (typeof value.env !== 'string')
|
|
19
|
+
return 'env';
|
|
20
|
+
if (value.updatedAt !== undefined && typeof value.updatedAt !== 'string')
|
|
21
|
+
return 'updatedAt';
|
|
22
|
+
if (!isRecord(value.resources))
|
|
23
|
+
return 'resources';
|
|
24
|
+
for (const [nodeId, outputs] of Object.entries(value.resources)) {
|
|
25
|
+
const field = `resources[${JSON.stringify(nodeId)}]`;
|
|
26
|
+
if (!isRecord(outputs))
|
|
27
|
+
return field;
|
|
28
|
+
for (const [name, output] of Object.entries(outputs)) {
|
|
29
|
+
if (!isOutputValue(output))
|
|
30
|
+
return `${field}[${JSON.stringify(name)}]`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
function validateState(value, location) {
|
|
36
|
+
const field = invalidStateField(value);
|
|
37
|
+
if (field !== undefined) {
|
|
38
|
+
throw new Error(`${location} has invalid state field ${field} - refusing to proceed with empty state`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
4
41
|
/** Namespace shape a plugin manifest declares - reused here so a scope can't smuggle a `/` or `..` into the key. */
|
|
5
42
|
const SCOPE_PATTERN = /^[a-z0-9-]+$/;
|
|
6
43
|
function stateKey(env, scope) {
|
|
@@ -53,12 +90,15 @@ export class StateStore {
|
|
|
53
90
|
// corruption, not a fresh environment, and must hit the guard below.
|
|
54
91
|
if (text === undefined)
|
|
55
92
|
return emptyState(this.env);
|
|
93
|
+
let state;
|
|
56
94
|
try {
|
|
57
|
-
|
|
95
|
+
state = JSON.parse(text);
|
|
58
96
|
}
|
|
59
97
|
catch (err) {
|
|
60
98
|
throw new Error(`${this.key} in s3://${this.bucket} is not valid JSON - refusing to proceed with empty state`, { cause: err });
|
|
61
99
|
}
|
|
100
|
+
validateState(state, `${this.key} in s3://${this.bucket}`);
|
|
101
|
+
return state;
|
|
62
102
|
}
|
|
63
103
|
async save(state) {
|
|
64
104
|
state.updatedAt = new Date().toISOString();
|