@contentrail/publisher 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +137 -2
- package/dist/engine.d.ts +34 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +196 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.d.ts +28 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +35 -0
- package/dist/errors.js.map +1 -0
- package/dist/fakes/memory-git.d.ts +12 -0
- package/dist/fakes/memory-git.d.ts.map +1 -0
- package/dist/fakes/memory-git.js +56 -0
- package/dist/fakes/memory-git.js.map +1 -0
- package/dist/fakes/memory-r2.d.ts +12 -0
- package/dist/fakes/memory-r2.d.ts.map +1 -0
- package/dist/fakes/memory-r2.js +59 -0
- package/dist/fakes/memory-r2.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/paths.d.ts +4 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +43 -0
- package/dist/paths.js.map +1 -0
- package/dist/providers/git-client.d.ts +31 -0
- package/dist/providers/git-client.d.ts.map +1 -0
- package/dist/providers/git-client.js +2 -0
- package/dist/providers/git-client.js.map +1 -0
- package/dist/providers/git.d.ts +10 -0
- package/dist/providers/git.d.ts.map +1 -0
- package/dist/providers/git.js +311 -0
- package/dist/providers/git.js.map +1 -0
- package/dist/providers/r2-client.d.ts +19 -0
- package/dist/providers/r2-client.d.ts.map +1 -0
- package/dist/providers/r2-client.js +2 -0
- package/dist/providers/r2-client.js.map +1 -0
- package/dist/providers/r2.d.ts +14 -0
- package/dist/providers/r2.d.ts.map +1 -0
- package/dist/providers/r2.js +305 -0
- package/dist/providers/r2.js.map +1 -0
- package/dist/rebuild.d.ts +34 -0
- package/dist/rebuild.d.ts.map +1 -0
- package/dist/rebuild.js +51 -0
- package/dist/rebuild.js.map +1 -0
- package/dist/types.d.ts +111 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +13 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +26 -0
- package/dist/version.js.map +1 -0
- package/package.json +47 -3
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { PublishConflictError, PublishError } from "../errors.js";
|
|
3
|
+
import { assertSafeSegment } from "../paths.js";
|
|
4
|
+
function safeIdempotencySegment(key) {
|
|
5
|
+
return createHash("sha256").update(key).digest("hex").slice(0, 32);
|
|
6
|
+
}
|
|
7
|
+
function prefixKey(prefix, ...parts) {
|
|
8
|
+
const base = prefix.replaceAll(/^\/+|\/+$/g, "");
|
|
9
|
+
for (const part of parts) {
|
|
10
|
+
assertSafeSegment(part, "storage key");
|
|
11
|
+
}
|
|
12
|
+
return [base, ...parts].filter((part) => part !== "").join("/");
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* R2 / object-storage provider.
|
|
16
|
+
* Writes immutable version snapshots, then conditionally updates `current.json`.
|
|
17
|
+
*/
|
|
18
|
+
export function createR2PublishProvider(options) {
|
|
19
|
+
if (options.hasCredential === false) {
|
|
20
|
+
throw new PublishError("CREDENTIALS", "R2 publish provider requires a configured server-side credential.");
|
|
21
|
+
}
|
|
22
|
+
const { client, keyPrefix } = options;
|
|
23
|
+
const currentKey = (siteId, collection) => prefixKey(keyPrefix, siteId, "collections", collection, "current.json");
|
|
24
|
+
const versionPrefix = (siteId, collection, version) => prefixKey(keyPrefix, siteId, "collections", collection, "versions", version);
|
|
25
|
+
const idempotencyKeyPath = (siteId, collection, idempotencyKey) => prefixKey(keyPrefix, siteId, "collections", collection, "idempotency", safeIdempotencySegment(idempotencyKey));
|
|
26
|
+
return {
|
|
27
|
+
kind: "r2",
|
|
28
|
+
async getActiveVersion(siteId, collection) {
|
|
29
|
+
const current = await client.getObject(currentKey(siteId, collection));
|
|
30
|
+
if (current === null) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return JSON.parse(current.body).version;
|
|
34
|
+
},
|
|
35
|
+
async readActiveContent(siteId, collection) {
|
|
36
|
+
const currentObject = await client.getObject(currentKey(siteId, collection));
|
|
37
|
+
if (currentObject === null) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const current = JSON.parse(currentObject.body);
|
|
41
|
+
const base = versionPrefix(siteId, collection, current.version);
|
|
42
|
+
const manifestObject = await client.getObject(`${base}/manifest.json`);
|
|
43
|
+
if (manifestObject === null) {
|
|
44
|
+
throw new PublishError("NOT_FOUND", `Active version "${current.version}" is missing its manifest.`, { siteId, collection });
|
|
45
|
+
}
|
|
46
|
+
const manifest = JSON.parse(manifestObject.body);
|
|
47
|
+
const entries = [];
|
|
48
|
+
for (const entryId of manifest.entryIds) {
|
|
49
|
+
const object = await client.getObject(`${base}/entries/${entryId}.json`);
|
|
50
|
+
if (object === null) {
|
|
51
|
+
throw new PublishError("NOT_FOUND", `Active version "${current.version}" is missing entry "${entryId}".`, { siteId, collection });
|
|
52
|
+
}
|
|
53
|
+
entries.push({ id: entryId, data: JSON.parse(object.body) });
|
|
54
|
+
}
|
|
55
|
+
const snapshot = {
|
|
56
|
+
version: manifest.version,
|
|
57
|
+
publicationId: manifest.publicationId,
|
|
58
|
+
createdAt: manifest.createdAt,
|
|
59
|
+
entries,
|
|
60
|
+
};
|
|
61
|
+
return snapshot;
|
|
62
|
+
},
|
|
63
|
+
async readIdempotentResult(siteId, collection, idempotencyKey) {
|
|
64
|
+
const object = await client.getObject(idempotencyKeyPath(siteId, collection, idempotencyKey));
|
|
65
|
+
if (object === null) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return JSON.parse(object.body);
|
|
69
|
+
},
|
|
70
|
+
async recoverIdempotentPublish(input) {
|
|
71
|
+
const prior = await this.readIdempotentResult(input.siteId, input.collection, input.idempotencyKey);
|
|
72
|
+
if (prior !== null) {
|
|
73
|
+
return prior;
|
|
74
|
+
}
|
|
75
|
+
const active = await this.getActiveVersion(input.siteId, input.collection);
|
|
76
|
+
if (active !== input.version) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const manifestObject = await client.getObject(`${versionPrefix(input.siteId, input.collection, input.version)}/manifest.json`);
|
|
80
|
+
if (manifestObject === null) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const manifest = JSON.parse(manifestObject.body);
|
|
84
|
+
const current = await client.getObject(currentKey(input.siteId, input.collection));
|
|
85
|
+
const result = {
|
|
86
|
+
success: true,
|
|
87
|
+
publicationId: input.publicationId,
|
|
88
|
+
version: input.version,
|
|
89
|
+
previousVersion: manifest.previousVersion,
|
|
90
|
+
manifest,
|
|
91
|
+
provider: {
|
|
92
|
+
kind: "r2",
|
|
93
|
+
revision: current?.etag ?? input.version,
|
|
94
|
+
},
|
|
95
|
+
rebuild: { state: "not_requested" },
|
|
96
|
+
idempotentReplay: true,
|
|
97
|
+
};
|
|
98
|
+
await client.putObject(idempotencyKeyPath(input.siteId, input.collection, input.idempotencyKey), `${JSON.stringify(result, null, 2)}\n`);
|
|
99
|
+
return result;
|
|
100
|
+
},
|
|
101
|
+
async publishSnapshot(input) {
|
|
102
|
+
const currentObject = await client.getObject(currentKey(input.siteId, input.collection));
|
|
103
|
+
const current = currentObject
|
|
104
|
+
? JSON.parse(currentObject.body)
|
|
105
|
+
: null;
|
|
106
|
+
const activeVersion = current?.version ?? null;
|
|
107
|
+
if (activeVersion !== input.expectedVersion) {
|
|
108
|
+
throw new PublishConflictError("R2 current pointer does not match expectedVersion.", {
|
|
109
|
+
siteId: input.siteId,
|
|
110
|
+
collection: input.collection,
|
|
111
|
+
publicationId: input.publicationId,
|
|
112
|
+
currentVersion: activeVersion,
|
|
113
|
+
expectedVersion: input.expectedVersion,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const createdAt = new Date().toISOString();
|
|
117
|
+
const manifest = {
|
|
118
|
+
siteId: input.siteId,
|
|
119
|
+
collection: input.collection,
|
|
120
|
+
publicationId: input.publicationId,
|
|
121
|
+
version: input.version,
|
|
122
|
+
previousVersion: input.previousVersion,
|
|
123
|
+
createdAt,
|
|
124
|
+
entryIds: input.entries.map((entry) => entry.id),
|
|
125
|
+
};
|
|
126
|
+
const base = versionPrefix(input.siteId, input.collection, input.version);
|
|
127
|
+
try {
|
|
128
|
+
for (const entry of input.entries) {
|
|
129
|
+
await client.putObject(`${base}/entries/${entry.id}.json`, `${JSON.stringify(entry.data, null, 2)}\n`);
|
|
130
|
+
}
|
|
131
|
+
await client.putObject(`${base}/manifest.json`, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (isTimeout(error)) {
|
|
135
|
+
throw new PublishError("PARTIAL_FAILURE", "R2 timed out while writing version snapshot. Current pointer was not updated.", {
|
|
136
|
+
siteId: input.siteId,
|
|
137
|
+
collection: input.collection,
|
|
138
|
+
publicationId: input.publicationId,
|
|
139
|
+
cause: error,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
throw new PublishError("PARTIAL_FAILURE", "R2 failed while writing version snapshot. Current pointer was not updated.", {
|
|
143
|
+
siteId: input.siteId,
|
|
144
|
+
collection: input.collection,
|
|
145
|
+
publicationId: input.publicationId,
|
|
146
|
+
cause: error,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
const pointer = {
|
|
150
|
+
version: input.version,
|
|
151
|
+
publicationId: input.publicationId,
|
|
152
|
+
updatedAt: createdAt,
|
|
153
|
+
};
|
|
154
|
+
// Activation uses storage-level conditional writes (S3/R2 If-Match /
|
|
155
|
+
// If-None-Match mapped by the injected client). Not an unconditional put.
|
|
156
|
+
let put;
|
|
157
|
+
try {
|
|
158
|
+
put =
|
|
159
|
+
currentObject === null
|
|
160
|
+
? await client.putObject(currentKey(input.siteId, input.collection), `${JSON.stringify(pointer, null, 2)}\n`, { ifNoneMatch: "*" })
|
|
161
|
+
: await client.putObject(currentKey(input.siteId, input.collection), `${JSON.stringify(pointer, null, 2)}\n`, { ifMatch: currentObject.etag });
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
if (isConflict(error)) {
|
|
165
|
+
throw new PublishConflictError("Concurrent R2 activation detected; snapshot may remain unreferenced.", {
|
|
166
|
+
siteId: input.siteId,
|
|
167
|
+
collection: input.collection,
|
|
168
|
+
publicationId: input.publicationId,
|
|
169
|
+
cause: error,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if (isTimeout(error)) {
|
|
173
|
+
throw new PublishError("PARTIAL_FAILURE", "R2 timed out during activation. Snapshot may exist without becoming current.", {
|
|
174
|
+
siteId: input.siteId,
|
|
175
|
+
collection: input.collection,
|
|
176
|
+
publicationId: input.publicationId,
|
|
177
|
+
cause: error,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
throw new PublishError("PROVIDER", "R2 activation failed.", {
|
|
181
|
+
siteId: input.siteId,
|
|
182
|
+
collection: input.collection,
|
|
183
|
+
publicationId: input.publicationId,
|
|
184
|
+
cause: error,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const result = {
|
|
188
|
+
success: true,
|
|
189
|
+
publicationId: input.publicationId,
|
|
190
|
+
version: input.version,
|
|
191
|
+
previousVersion: input.previousVersion,
|
|
192
|
+
manifest,
|
|
193
|
+
provider: { kind: "r2", revision: put.etag },
|
|
194
|
+
rebuild: { state: "not_requested" },
|
|
195
|
+
idempotentReplay: false,
|
|
196
|
+
};
|
|
197
|
+
if (input.idempotencyKey !== undefined) {
|
|
198
|
+
try {
|
|
199
|
+
await client.putObject(idempotencyKeyPath(input.siteId, input.collection, input.idempotencyKey), `${JSON.stringify(result, null, 2)}\n`);
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// Activation already succeeded. Retries recover via recoverIdempotentPublish.
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
},
|
|
207
|
+
async listVersions(siteId, collection) {
|
|
208
|
+
const active = await this.getActiveVersion(siteId, collection);
|
|
209
|
+
const prefix = prefixKey(keyPrefix, siteId, "collections", collection, "versions");
|
|
210
|
+
const keys = await client.listKeys(`${prefix}/`);
|
|
211
|
+
const manifests = new Set();
|
|
212
|
+
for (const key of keys) {
|
|
213
|
+
if (key.endsWith("/manifest.json")) {
|
|
214
|
+
manifests.add(key);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const summaries = [];
|
|
218
|
+
for (const key of manifests) {
|
|
219
|
+
const object = await client.getObject(key);
|
|
220
|
+
if (object === null) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
const manifest = JSON.parse(object.body);
|
|
224
|
+
summaries.push({
|
|
225
|
+
version: manifest.version,
|
|
226
|
+
publicationId: manifest.publicationId,
|
|
227
|
+
createdAt: manifest.createdAt,
|
|
228
|
+
active: manifest.version === active,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return summaries.sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
232
|
+
},
|
|
233
|
+
async rollback(input) {
|
|
234
|
+
const currentObject = await client.getObject(currentKey(input.siteId, input.collection));
|
|
235
|
+
const current = currentObject
|
|
236
|
+
? JSON.parse(currentObject.body)
|
|
237
|
+
: null;
|
|
238
|
+
const activeVersion = current?.version ?? null;
|
|
239
|
+
if (activeVersion !== input.expectedVersion) {
|
|
240
|
+
throw new PublishConflictError("Rollback expectedVersion does not match R2 current pointer.", {
|
|
241
|
+
siteId: input.siteId,
|
|
242
|
+
collection: input.collection,
|
|
243
|
+
currentVersion: activeVersion,
|
|
244
|
+
expectedVersion: input.expectedVersion,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
const manifestObject = await client.getObject(`${versionPrefix(input.siteId, input.collection, input.targetVersion)}/manifest.json`);
|
|
248
|
+
if (manifestObject === null) {
|
|
249
|
+
throw new PublishError("NOT_FOUND", `Unknown publication version "${input.targetVersion}".`, { siteId: input.siteId, collection: input.collection });
|
|
250
|
+
}
|
|
251
|
+
const manifest = JSON.parse(manifestObject.body);
|
|
252
|
+
const publicationId = input.publicationId ?? manifest.publicationId;
|
|
253
|
+
const updatedAt = new Date().toISOString();
|
|
254
|
+
const pointer = {
|
|
255
|
+
version: input.targetVersion,
|
|
256
|
+
publicationId,
|
|
257
|
+
updatedAt,
|
|
258
|
+
};
|
|
259
|
+
try {
|
|
260
|
+
const put = currentObject === null
|
|
261
|
+
? await client.putObject(currentKey(input.siteId, input.collection), `${JSON.stringify(pointer, null, 2)}\n`, { ifNoneMatch: "*" })
|
|
262
|
+
: await client.putObject(currentKey(input.siteId, input.collection), `${JSON.stringify(pointer, null, 2)}\n`, { ifMatch: currentObject.etag });
|
|
263
|
+
return {
|
|
264
|
+
success: true,
|
|
265
|
+
publicationId,
|
|
266
|
+
version: input.targetVersion,
|
|
267
|
+
previousVersion: activeVersion,
|
|
268
|
+
manifest: {
|
|
269
|
+
...manifest,
|
|
270
|
+
previousVersion: activeVersion,
|
|
271
|
+
publicationId,
|
|
272
|
+
},
|
|
273
|
+
provider: { kind: "r2", revision: put.etag },
|
|
274
|
+
rebuild: { state: "not_requested" },
|
|
275
|
+
idempotentReplay: false,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
if (isConflict(error)) {
|
|
280
|
+
throw new PublishConflictError("Concurrent R2 update detected during rollback.", {
|
|
281
|
+
siteId: input.siteId,
|
|
282
|
+
collection: input.collection,
|
|
283
|
+
publicationId,
|
|
284
|
+
cause: error,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
throw new PublishError("PROVIDER", "R2 rollback failed.", {
|
|
288
|
+
siteId: input.siteId,
|
|
289
|
+
collection: input.collection,
|
|
290
|
+
publicationId,
|
|
291
|
+
cause: error,
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
function isConflict(error) {
|
|
298
|
+
return (error instanceof Error &&
|
|
299
|
+
(error.message === "CONFLICT" ||
|
|
300
|
+
/conflict|precondition/i.test(error.message)));
|
|
301
|
+
}
|
|
302
|
+
function isTimeout(error) {
|
|
303
|
+
return error instanceof Error && /timeout|timed out/i.test(error.message);
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=r2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2.js","sourceRoot":"","sources":["../../src/providers/r2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { RebuildStatus } from "./types.js";
|
|
2
|
+
export interface RebuildHookClient {
|
|
3
|
+
/**
|
|
4
|
+
* POSTs to a configured deploy hook. Must not log the secret URL.
|
|
5
|
+
* Throws Error("timeout") or Error("failed") for simulated failures.
|
|
6
|
+
*/
|
|
7
|
+
trigger(payload: {
|
|
8
|
+
siteId: string;
|
|
9
|
+
collection: string;
|
|
10
|
+
version: string;
|
|
11
|
+
publicationId: string;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
ok: true;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
detail: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
export interface RebuildHookOptions {
|
|
20
|
+
readonly client: RebuildHookClient;
|
|
21
|
+
readonly hasSecret?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Optional rebuild trigger. Publication success does not imply rebuild success.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createRebuildHook(options: RebuildHookOptions): {
|
|
27
|
+
trigger(input: {
|
|
28
|
+
siteId: string;
|
|
29
|
+
collection: string;
|
|
30
|
+
version: string;
|
|
31
|
+
publicationId: string;
|
|
32
|
+
}): Promise<RebuildStatus>;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=rebuild.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebuild.d.ts","sourceRoot":"","sources":["../src/rebuild.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG;IAC9D,OAAO,CAAC,KAAK,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC5B,CAuDA"}
|
package/dist/rebuild.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { PublishError } from "./errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Optional rebuild trigger. Publication success does not imply rebuild success.
|
|
5
|
+
*/
|
|
6
|
+
export function createRebuildHook(options) {
|
|
7
|
+
if (options.hasSecret === false) {
|
|
8
|
+
throw new PublishError("CREDENTIALS", "Rebuild hook requires a configured server-side secret.");
|
|
9
|
+
}
|
|
10
|
+
const seen = new Set();
|
|
11
|
+
return {
|
|
12
|
+
async trigger(input) {
|
|
13
|
+
const dedupe = createHash("sha256")
|
|
14
|
+
.update(`${input.siteId}:${input.collection}:${input.version}:${input.publicationId}`)
|
|
15
|
+
.digest("hex");
|
|
16
|
+
if (seen.has(dedupe)) {
|
|
17
|
+
return {
|
|
18
|
+
state: "pending",
|
|
19
|
+
triggerId: dedupe.slice(0, 12),
|
|
20
|
+
detail: "Duplicate rebuild trigger suppressed; prior request retained.",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const response = await options.client.trigger(input);
|
|
25
|
+
const triggerId = randomUUID();
|
|
26
|
+
seen.add(dedupe);
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
return {
|
|
29
|
+
state: "failed",
|
|
30
|
+
triggerId,
|
|
31
|
+
detail: response.detail,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
state: "pending",
|
|
36
|
+
triggerId,
|
|
37
|
+
detail: "Rebuild hook accepted. Content publication succeeded independently of deploy completion.",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
return {
|
|
42
|
+
state: "failed",
|
|
43
|
+
detail: error instanceof Error
|
|
44
|
+
? error.message
|
|
45
|
+
: "Rebuild hook failed after successful publication.",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=rebuild.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebuild.js","sourceRoot":"","sources":["../src/rebuild.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqB3C;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IAQ3D,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;QAChC,MAAM,IAAI,YAAY,CACpB,aAAa,EACb,wDAAwD,CACzD,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,KAAK;YACjB,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;iBAChC,MAAM,CACL,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,aAAa,EAAE,CAC9E;iBACA,MAAM,CAAC,KAAK,CAAC,CAAC;YAEjB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrB,OAAO;oBACL,KAAK,EAAE,SAAS;oBAChB,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;oBAC9B,MAAM,EACJ,+DAA+D;iBAClE,CAAC;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACrD,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;gBAC/B,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACjB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBACjB,OAAO;wBACL,KAAK,EAAE,QAAQ;wBACf,SAAS;wBACT,MAAM,EAAE,QAAQ,CAAC,MAAM;qBACxB,CAAC;gBACJ,CAAC;gBACD,OAAO;oBACL,KAAK,EAAE,SAAS;oBAChB,SAAS;oBACT,MAAM,EACJ,0FAA0F;iBAC7F,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO;oBACL,KAAK,EAAE,QAAQ;oBACf,MAAM,EACJ,KAAK,YAAY,KAAK;wBACpB,CAAC,CAAC,KAAK,CAAC,OAAO;wBACf,CAAC,CAAC,mDAAmD;iBAC1D,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { ContentCollection, InferEntry } from "@contentrail/core";
|
|
2
|
+
export type RebuildState = "not_requested" | "pending" | "succeeded" | "failed";
|
|
3
|
+
export interface PublishEntryInput {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly data: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface PublishRequest<TCollection extends ContentCollection = ContentCollection> {
|
|
8
|
+
readonly siteId: string;
|
|
9
|
+
readonly collection: TCollection;
|
|
10
|
+
readonly entries: ReadonlyArray<PublishEntryInput>;
|
|
11
|
+
/**
|
|
12
|
+
* Required previous version. Use `null` when publishing the first version.
|
|
13
|
+
* Omit only when the provider allows force (not supported in Phase 3).
|
|
14
|
+
*/
|
|
15
|
+
readonly expectedVersion: string | null;
|
|
16
|
+
readonly publicationId?: string;
|
|
17
|
+
readonly idempotencyKey?: string;
|
|
18
|
+
readonly message?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface PublicationManifest {
|
|
21
|
+
readonly siteId: string;
|
|
22
|
+
readonly collection: string;
|
|
23
|
+
readonly publicationId: string;
|
|
24
|
+
readonly version: string;
|
|
25
|
+
readonly previousVersion: string | null;
|
|
26
|
+
readonly createdAt: string;
|
|
27
|
+
readonly entryIds: readonly string[];
|
|
28
|
+
}
|
|
29
|
+
export interface RebuildStatus {
|
|
30
|
+
readonly state: RebuildState;
|
|
31
|
+
readonly triggerId?: string;
|
|
32
|
+
readonly detail?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface PublishSuccess {
|
|
35
|
+
readonly success: true;
|
|
36
|
+
readonly publicationId: string;
|
|
37
|
+
readonly version: string;
|
|
38
|
+
readonly previousVersion: string | null;
|
|
39
|
+
readonly manifest: PublicationManifest;
|
|
40
|
+
readonly provider: {
|
|
41
|
+
readonly kind: "git" | "r2";
|
|
42
|
+
readonly revision: string;
|
|
43
|
+
};
|
|
44
|
+
readonly rebuild: RebuildStatus;
|
|
45
|
+
readonly idempotentReplay: boolean;
|
|
46
|
+
}
|
|
47
|
+
export type PublishResult = PublishSuccess;
|
|
48
|
+
export interface PublicationSummary {
|
|
49
|
+
readonly version: string;
|
|
50
|
+
readonly publicationId: string;
|
|
51
|
+
readonly createdAt: string;
|
|
52
|
+
readonly active: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** Active published snapshot for editor/API reads (ADR 018). */
|
|
55
|
+
export interface ActiveContentSnapshot {
|
|
56
|
+
readonly version: string;
|
|
57
|
+
readonly publicationId: string;
|
|
58
|
+
readonly createdAt: string;
|
|
59
|
+
readonly entries: ReadonlyArray<{
|
|
60
|
+
id: string;
|
|
61
|
+
data: unknown;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
export interface PublishProvider {
|
|
65
|
+
readonly kind: "git" | "r2";
|
|
66
|
+
getActiveVersion(siteId: string, collection: string): Promise<string | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Load entry bodies for the currently active publication.
|
|
69
|
+
* Returns `null` when no version is active.
|
|
70
|
+
*/
|
|
71
|
+
readActiveContent(siteId: string, collection: string): Promise<ActiveContentSnapshot | null>;
|
|
72
|
+
readIdempotentResult(siteId: string, collection: string, idempotencyKey: string): Promise<PublishSuccess | null>;
|
|
73
|
+
/**
|
|
74
|
+
* After a conflict or partial failure on a keyed request, return a completed
|
|
75
|
+
* result when this operation already activated (or was recorded).
|
|
76
|
+
*/
|
|
77
|
+
recoverIdempotentPublish(input: {
|
|
78
|
+
siteId: string;
|
|
79
|
+
collection: string;
|
|
80
|
+
idempotencyKey: string;
|
|
81
|
+
publicationId: string;
|
|
82
|
+
version: string;
|
|
83
|
+
}): Promise<PublishSuccess | null>;
|
|
84
|
+
publishSnapshot(input: {
|
|
85
|
+
siteId: string;
|
|
86
|
+
collection: string;
|
|
87
|
+
publicationId: string;
|
|
88
|
+
version: string;
|
|
89
|
+
previousVersion: string | null;
|
|
90
|
+
expectedVersion: string | null;
|
|
91
|
+
entries: ReadonlyArray<{
|
|
92
|
+
id: string;
|
|
93
|
+
data: unknown;
|
|
94
|
+
}>;
|
|
95
|
+
message?: string;
|
|
96
|
+
idempotencyKey?: string;
|
|
97
|
+
}): Promise<PublishSuccess>;
|
|
98
|
+
listVersions(siteId: string, collection: string): Promise<PublicationSummary[]>;
|
|
99
|
+
rollback(input: {
|
|
100
|
+
siteId: string;
|
|
101
|
+
collection: string;
|
|
102
|
+
targetVersion: string;
|
|
103
|
+
expectedVersion: string | null;
|
|
104
|
+
publicationId?: string;
|
|
105
|
+
}): Promise<PublishSuccess>;
|
|
106
|
+
}
|
|
107
|
+
export type ValidatedEntries<TCollection extends ContentCollection> = Array<{
|
|
108
|
+
id: string;
|
|
109
|
+
data: InferEntry<TCollection>;
|
|
110
|
+
}>;
|
|
111
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function createPublicationId(explicit?: string): string;
|
|
2
|
+
/** Stable publication id derived from an idempotency key so retries share one operation. */
|
|
3
|
+
export declare function publicationIdFromIdempotencyKey(idempotencyKey: string): string;
|
|
4
|
+
export declare function createContentVersion(input: {
|
|
5
|
+
siteId: string;
|
|
6
|
+
collection: string;
|
|
7
|
+
publicationId: string;
|
|
8
|
+
entries: ReadonlyArray<{
|
|
9
|
+
id: string;
|
|
10
|
+
data: unknown;
|
|
11
|
+
}>;
|
|
12
|
+
}): string;
|
|
13
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED,4FAA4F;AAC5F,wBAAgB,+BAA+B,CAC7C,cAAc,EAAE,MAAM,GACrB,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACvD,GAAG,MAAM,CAUT"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
export function createPublicationId(explicit) {
|
|
3
|
+
if (explicit !== undefined) {
|
|
4
|
+
if (explicit.trim() === "") {
|
|
5
|
+
throw new Error("publicationId must be a non-empty string when provided.");
|
|
6
|
+
}
|
|
7
|
+
return explicit;
|
|
8
|
+
}
|
|
9
|
+
return randomUUID();
|
|
10
|
+
}
|
|
11
|
+
/** Stable publication id derived from an idempotency key so retries share one operation. */
|
|
12
|
+
export function publicationIdFromIdempotencyKey(idempotencyKey) {
|
|
13
|
+
return `idem-${createHash("sha256").update(idempotencyKey).digest("hex").slice(0, 32)}`;
|
|
14
|
+
}
|
|
15
|
+
export function createContentVersion(input) {
|
|
16
|
+
const canonical = JSON.stringify({
|
|
17
|
+
siteId: input.siteId,
|
|
18
|
+
collection: input.collection,
|
|
19
|
+
publicationId: input.publicationId,
|
|
20
|
+
entries: [...input.entries]
|
|
21
|
+
.map((entry) => ({ id: entry.id, data: entry.data }))
|
|
22
|
+
.sort((a, b) => a.id.localeCompare(b.id)),
|
|
23
|
+
});
|
|
24
|
+
return createHash("sha256").update(canonical).digest("hex").slice(0, 32);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,UAAU,mBAAmB,CAAC,QAAiB;IACnD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,+BAA+B,CAC7C,cAAsB;IAEtB,OAAO,QAAQ,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAKpC;IACC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC/B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;aACxB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;aACpD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC5C,CAAC,CAAC;IACH,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentrail/publisher",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Server-only ContentRail publishing contracts, Git and R2 providers, and rebuild hooks.",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=22"
|
|
10
|
+
},
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"node": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@contentrail/core": "0.2.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^22.20.5",
|
|
30
|
+
"typescript": "5.9.3",
|
|
31
|
+
"zod": "4.6.7"
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/Hridhin-k/contentrail.git",
|
|
36
|
+
"directory": "packages/publisher"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/Hridhin-k/contentrail/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/Hridhin-k/contentrail#readme",
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc -p tsconfig.json",
|
|
47
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
48
|
+
"test": "pnpm run build && tsc -p tsconfig.test.json && node --test test-dist/**/*.test.js"
|
|
49
|
+
}
|
|
6
50
|
}
|