@micacms/runtime 0.4.0 → 0.5.0-rc.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/README.md +2 -2
- package/dist/app.d.ts +8 -37
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +7 -42
- package/dist/app.js.map +1 -1
- package/dist/config.d.ts +12 -82
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -82
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +37 -66
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +24 -75
- package/dist/context.js.map +1 -1
- package/dist/http.d.ts +8 -16
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +6 -13
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +13 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -14
- package/dist/index.js.map +1 -1
- package/dist/routes/admin-content.d.ts +4 -17
- package/dist/routes/admin-content.d.ts.map +1 -1
- package/dist/routes/admin-content.js +11 -51
- package/dist/routes/admin-content.js.map +1 -1
- package/dist/routes/admin-media.d.ts +3 -14
- package/dist/routes/admin-media.d.ts.map +1 -1
- package/dist/routes/admin-media.js +7 -29
- package/dist/routes/admin-media.js.map +1 -1
- package/dist/routes/admin-staging.d.ts +4 -9
- package/dist/routes/admin-staging.d.ts.map +1 -1
- package/dist/routes/admin-staging.js +31 -18
- package/dist/routes/admin-staging.js.map +1 -1
- package/dist/routes/admin-system.d.ts +2 -8
- package/dist/routes/admin-system.d.ts.map +1 -1
- package/dist/routes/admin-system.js +9 -44
- package/dist/routes/admin-system.js.map +1 -1
- package/dist/routes/health.d.ts +3 -10
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +9 -26
- package/dist/routes/health.js.map +1 -1
- package/dist/schema.d.ts +10 -38
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +14 -65
- package/dist/schema.js.map +1 -1
- package/dist/server.d.ts +2 -10
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -9
- package/dist/server.js.map +1 -1
- package/dist/services/changes.d.ts +150 -0
- package/dist/services/changes.d.ts.map +1 -0
- package/dist/services/changes.js +339 -0
- package/dist/services/changes.js.map +1 -0
- package/dist/services/content-store.d.ts +61 -0
- package/dist/services/content-store.d.ts.map +1 -0
- package/dist/services/content-store.js +330 -0
- package/dist/services/content-store.js.map +1 -0
- package/dist/services/media.d.ts +9 -29
- package/dist/services/media.d.ts.map +1 -1
- package/dist/services/media.js +17 -57
- package/dist/services/media.js.map +1 -1
- package/dist/services/staging.d.ts +35 -167
- package/dist/services/staging.d.ts.map +1 -1
- package/dist/services/staging.js +195 -458
- package/dist/services/staging.js.map +1 -1
- package/dist/workspace/developer.d.ts +14 -0
- package/dist/workspace/developer.d.ts.map +1 -0
- package/dist/workspace/developer.js +31 -0
- package/dist/workspace/developer.js.map +1 -0
- package/dist/workspace/files.d.ts +70 -0
- package/dist/workspace/files.d.ts.map +1 -0
- package/dist/workspace/files.js +176 -0
- package/dist/workspace/files.js.map +1 -0
- package/dist/workspace/git.d.ts +45 -0
- package/dist/workspace/git.d.ts.map +1 -0
- package/dist/workspace/git.js +68 -0
- package/dist/workspace/git.js.map +1 -0
- package/dist/workspace/locks.d.ts +33 -0
- package/dist/workspace/locks.d.ts.map +1 -0
- package/dist/workspace/locks.js +76 -0
- package/dist/workspace/locks.js.map +1 -0
- package/dist/workspace/policy.d.ts +92 -0
- package/dist/workspace/policy.d.ts.map +1 -0
- package/dist/workspace/policy.js +7 -0
- package/dist/workspace/policy.js.map +1 -0
- package/dist/workspace/tree.d.ts +73 -0
- package/dist/workspace/tree.d.ts.map +1 -0
- package/dist/workspace/tree.js +229 -0
- package/dist/workspace/tree.js.map +1 -0
- package/package.json +2 -3
- package/dist/db/driver.d.ts +0 -35
- package/dist/db/driver.d.ts.map +0 -1
- package/dist/db/driver.js +0 -95
- package/dist/db/driver.js.map +0 -1
- package/dist/lib/git.d.ts +0 -29
- package/dist/lib/git.d.ts.map +0 -1
- package/dist/lib/git.js +0 -62
- package/dist/lib/git.js.map +0 -1
- package/dist/services/staging-local.d.ts +0 -58
- package/dist/services/staging-local.d.ts.map +0 -1
- package/dist/services/staging-local.js +0 -391
- package/dist/services/staging-local.js.map +0 -1
package/dist/routes/health.d.ts
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* a container that would not be any better for it.
|
|
6
|
-
* /ready the database, where the composition has one, and the content
|
|
7
|
-
* repository. Cached, because each probe spends one call of the
|
|
8
|
-
* repository token's quota and anybody can ask.
|
|
9
|
-
*
|
|
10
|
-
* Neither answer names the repository or the uptime: the endpoints are public,
|
|
11
|
-
* and the System view shows both to editors (#79).
|
|
2
|
+
* `/health` does no I/O, so a repository outage does not restart the container.
|
|
3
|
+
* `/ready` checks the content repository and is cached because it is public.
|
|
4
|
+
* Neither names the repository or the uptime.
|
|
12
5
|
*/
|
|
13
6
|
import { Hono } from "hono";
|
|
14
7
|
import type { Env } from "../http.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAE1C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAWtC,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAmBnE"}
|
package/dist/routes/health.js
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* a container that would not be any better for it.
|
|
6
|
-
* /ready the database, where the composition has one, and the content
|
|
7
|
-
* repository. Cached, because each probe spends one call of the
|
|
8
|
-
* repository token's quota and anybody can ask.
|
|
9
|
-
*
|
|
10
|
-
* Neither answer names the repository or the uptime: the endpoints are public,
|
|
11
|
-
* and the System view shows both to editors (#79).
|
|
2
|
+
* `/health` does no I/O, so a repository outage does not restart the container.
|
|
3
|
+
* `/ready` checks the content repository and is cached because it is public.
|
|
4
|
+
* Neither names the repository or the uptime.
|
|
12
5
|
*/
|
|
13
6
|
import { Hono } from "hono";
|
|
14
7
|
export function healthRoutes(options = {}) {
|
|
@@ -30,21 +23,12 @@ export function healthRoutes(options = {}) {
|
|
|
30
23
|
async function probe(c) {
|
|
31
24
|
const ctx = c.get("ctx");
|
|
32
25
|
const logger = c.get("logger");
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
ctx.health.database();
|
|
39
|
-
database = "ok";
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
logger.error("Health check failed", { error: String(error) });
|
|
43
|
-
database = "unavailable";
|
|
44
|
-
}
|
|
26
|
+
// A managed clone knows whether it can be edited without asking the remote.
|
|
27
|
+
if (ctx.health.ready) {
|
|
28
|
+
const { ok, reasons } = ctx.health.ready();
|
|
29
|
+
return { status: ok ? "ok" : "error", repository: ok ? "ok" : "unavailable", reasons };
|
|
45
30
|
}
|
|
46
|
-
// `list` on a missing root returns an empty array
|
|
47
|
-
// this proves reachability, not that anyone has written content yet.
|
|
31
|
+
// `list` on a missing root returns an empty array, so this proves reachability only.
|
|
48
32
|
let repository = "ok";
|
|
49
33
|
try {
|
|
50
34
|
await ctx.site.contentRepository.list("");
|
|
@@ -53,7 +37,6 @@ async function probe(c) {
|
|
|
53
37
|
logger.error("Content repository is unreachable", { error: String(error) });
|
|
54
38
|
repository = "unavailable";
|
|
55
39
|
}
|
|
56
|
-
|
|
57
|
-
return { status: ok ? "ok" : "error", ...(database ? { database } : {}), repository };
|
|
40
|
+
return { status: repository === "ok" ? "ok" : "error", repository };
|
|
58
41
|
}
|
|
59
42
|
//# sourceMappingURL=health.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAmB1C,MAAM,UAAU,YAAY,CAAC,UAAyB,EAAE;IACtD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,6EAA6E;IAC7E,IAAI,MAAM,GAAsD,IAAI,CAAC;IAErE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAO,CAAC;IAE5B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEpD,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5B,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,OAAO,EAAE,CAAC;YAC5C,MAAM,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,CAAe;IAClC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE/B,4EAA4E;IAC5E,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC3C,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,OAAO,EAAE,CAAC;IACzF,CAAC;IAED,qFAAqF;IACrF,IAAI,UAAU,GAAU,IAAI,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5E,UAAU,GAAG,aAAa,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC;AACtE,CAAC"}
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* repository, at `.mica/schema.json`, through the same connector it reads
|
|
6
|
-
* entries with. The Astro project writes that file and the developer commits
|
|
7
|
-
* it, so the model reaches the server the way content does — no artifact to
|
|
8
|
-
* mount, no second channel to keep in step, and a model change that is
|
|
9
|
-
* reviewable in a diff.
|
|
10
|
-
*
|
|
11
|
-
* That is what lets one published image serve any project: the model is plain
|
|
12
|
-
* data (field descriptors hold no functions, so `JSON.stringify(site)`
|
|
13
|
-
* round-trips), and every consumer downstream — form generation, payload
|
|
14
|
-
* validation, the admin — already reads it out of the request context.
|
|
15
|
-
*
|
|
16
|
-
* Whatever arrives is re-validated as if it had just been written by hand. A
|
|
17
|
-
* manifest from a repository is untrusted input: it may have been produced by a
|
|
18
|
-
* different version of `@micacms/core`, hand-edited, or truncated.
|
|
2
|
+
* Reads the content model from `.mica/schema.json` in the content repository.
|
|
3
|
+
* The Astro project writes it. The manifest is untrusted input (another core
|
|
4
|
+
* version, hand-edited or truncated), so it is validated again here.
|
|
19
5
|
*/
|
|
20
6
|
import { type ContentSource, type Site } from "@micacms/core";
|
|
21
7
|
export declare class SchemaError extends Error {
|
|
@@ -24,33 +10,19 @@ export declare class SchemaError extends Error {
|
|
|
24
10
|
/** Where a model came from, for logs and the system screen. */
|
|
25
11
|
export declare function schemaOrigin(source: ContentSource): string;
|
|
26
12
|
/**
|
|
27
|
-
* Reads the model the content repository
|
|
28
|
-
*
|
|
29
|
-
* A missing file is the interesting failure and gets the long message: it is
|
|
30
|
-
* what a first deployment hits, and the fix — build the Astro project, commit
|
|
31
|
-
* the result — is not guessable from "not found".
|
|
13
|
+
* Reads the model from the content repository. A missing file gets a long
|
|
14
|
+
* message because a first deployment hits it.
|
|
32
15
|
*/
|
|
33
16
|
export declare function loadSchema(source: ContentSource): Promise<Site>;
|
|
34
17
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* `defineSite` assumes its input came from the typed builders, so it never
|
|
39
|
-
* questions a `kind`. Field kinds reach a `switch` with no default when a form
|
|
40
|
-
* is rendered and when a payload is validated, so an unknown one surfaces as an
|
|
41
|
-
* incoherent failure much later, on an editor's screen. Catching it here turns
|
|
42
|
-
* a version mismatch between the project's `@micacms/core` and the image's
|
|
43
|
-
* into a startup error that names the field.
|
|
18
|
+
* Runs the `defineSite` checks, and also refuses an unknown field `kind`, which
|
|
19
|
+
* `defineSite` does not check. This turns a core version mismatch into a
|
|
20
|
+
* startup error, not a later failure on an editor's screen.
|
|
44
21
|
*/
|
|
45
22
|
export declare function checkSchema(raw: unknown, origin?: string): Site;
|
|
46
23
|
/**
|
|
47
|
-
* A
|
|
48
|
-
*
|
|
49
|
-
* Logged at startup and returned by the schema endpoint so that a website built
|
|
50
|
-
* against one model and a CMS serving another is a visible mismatch rather than
|
|
51
|
-
* a puzzling absence of fields. Key order follows the model's own declaration
|
|
52
|
-
* order, which is meaningful here — reordering fields reorders the admin form,
|
|
53
|
-
* so it is a real change and should produce a different digest.
|
|
24
|
+
* A short digest of a model, to show drift. Field order counts, because it is
|
|
25
|
+
* the order of the admin form.
|
|
54
26
|
*/
|
|
55
27
|
export declare function schemaFingerprint(site: Site): Promise<string>;
|
|
56
28
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAQL,KAAK,aAAa,EAGlB,KAAK,IAAI,EACV,MAAM,eAAe,CAAC;AAEvB,qBAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,SAAiB;CAC/B;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BrE;AAWD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,SAAe,GAAG,IAAI,CAiDrE;AA0BD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAGnE"}
|
package/dist/schema.js
CHANGED
|
@@ -1,21 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* repository, at `.mica/schema.json`, through the same connector it reads
|
|
6
|
-
* entries with. The Astro project writes that file and the developer commits
|
|
7
|
-
* it, so the model reaches the server the way content does — no artifact to
|
|
8
|
-
* mount, no second channel to keep in step, and a model change that is
|
|
9
|
-
* reviewable in a diff.
|
|
10
|
-
*
|
|
11
|
-
* That is what lets one published image serve any project: the model is plain
|
|
12
|
-
* data (field descriptors hold no functions, so `JSON.stringify(site)`
|
|
13
|
-
* round-trips), and every consumer downstream — form generation, payload
|
|
14
|
-
* validation, the admin — already reads it out of the request context.
|
|
15
|
-
*
|
|
16
|
-
* Whatever arrives is re-validated as if it had just been written by hand. A
|
|
17
|
-
* manifest from a repository is untrusted input: it may have been produced by a
|
|
18
|
-
* different version of `@micacms/core`, hand-edited, or truncated.
|
|
2
|
+
* Reads the content model from `.mica/schema.json` in the content repository.
|
|
3
|
+
* The Astro project writes it. The manifest is untrusted input (another core
|
|
4
|
+
* version, hand-edited or truncated), so it is validated again here.
|
|
19
5
|
*/
|
|
20
6
|
import { checkCompatibility, defineSite, isFieldKind, isProtocolManifest, MANIFEST_PATH, PROTOCOL_VERSION, } from "@micacms/core";
|
|
21
7
|
export class SchemaError extends Error {
|
|
@@ -26,11 +12,8 @@ export function schemaOrigin(source) {
|
|
|
26
12
|
return `${source.origin}/${MANIFEST_PATH}`;
|
|
27
13
|
}
|
|
28
14
|
/**
|
|
29
|
-
* Reads the model the content repository
|
|
30
|
-
*
|
|
31
|
-
* A missing file is the interesting failure and gets the long message: it is
|
|
32
|
-
* what a first deployment hits, and the fix — build the Astro project, commit
|
|
33
|
-
* the result — is not guessable from "not found".
|
|
15
|
+
* Reads the model from the content repository. A missing file gets a long
|
|
16
|
+
* message because a first deployment hits it.
|
|
34
17
|
*/
|
|
35
18
|
export async function loadSchema(source) {
|
|
36
19
|
const origin = schemaOrigin(source);
|
|
@@ -39,8 +22,7 @@ export async function loadSchema(source) {
|
|
|
39
22
|
text = await source.read(MANIFEST_PATH);
|
|
40
23
|
}
|
|
41
24
|
catch (error) {
|
|
42
|
-
//
|
|
43
|
-
// because the two have completely different fixes.
|
|
25
|
+
// An unreachable repository is not a bad model; the fixes are different.
|
|
44
26
|
throw new SchemaError(`Could not read the content model from ${source.origin}.\n` +
|
|
45
27
|
` ${error.message}\n` +
|
|
46
28
|
` The repository has to be reachable before Mica can start: the model\n` +
|
|
@@ -64,23 +46,15 @@ function describeMissing(origin) {
|
|
|
64
46
|
` then commit ${MANIFEST_PATH} and push it to the branch Mica is reading.`);
|
|
65
47
|
}
|
|
66
48
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* `defineSite` assumes its input came from the typed builders, so it never
|
|
71
|
-
* questions a `kind`. Field kinds reach a `switch` with no default when a form
|
|
72
|
-
* is rendered and when a payload is validated, so an unknown one surfaces as an
|
|
73
|
-
* incoherent failure much later, on an editor's screen. Catching it here turns
|
|
74
|
-
* a version mismatch between the project's `@micacms/core` and the image's
|
|
75
|
-
* into a startup error that names the field.
|
|
49
|
+
* Runs the `defineSite` checks, and also refuses an unknown field `kind`, which
|
|
50
|
+
* `defineSite` does not check. This turns a core version mismatch into a
|
|
51
|
+
* startup error, not a later failure on an editor's screen.
|
|
76
52
|
*/
|
|
77
53
|
export function checkSchema(raw, origin = "the schema") {
|
|
78
54
|
if (raw === null || typeof raw !== "object") {
|
|
79
55
|
throw new SchemaError(`${origin} is ${raw === null ? "null" : typeof raw}, expected an object.`);
|
|
80
56
|
}
|
|
81
|
-
//
|
|
82
|
-
// the protocol version is a backstop for changes that cannot be detected by
|
|
83
|
-
// looking, not an admission ticket.
|
|
57
|
+
// A bare `{ collections }` without the protocol envelope is also accepted.
|
|
84
58
|
if (isProtocolManifest(raw)) {
|
|
85
59
|
const compatibility = checkCompatibility(raw);
|
|
86
60
|
if (!compatibility.ok && compatibility.reason === "newer") {
|
|
@@ -93,10 +67,7 @@ export function checkSchema(raw, origin = "the schema") {
|
|
|
93
67
|
if (candidate.collections === null || typeof candidate.collections !== "object") {
|
|
94
68
|
throw new SchemaError(`${origin} has no \`collections\`. Expected defineSite({ collections: { ... } }).`);
|
|
95
69
|
}
|
|
96
|
-
|
|
97
|
-
// outlives the release that produced it, so both spellings are read here;
|
|
98
|
-
// only the new one is written anywhere.
|
|
99
|
-
const rawSingletons = candidate.singletons ?? candidate.globals;
|
|
70
|
+
const rawSingletons = candidate.singletons;
|
|
100
71
|
if (rawSingletons !== undefined && (rawSingletons === null || typeof rawSingletons !== "object")) {
|
|
101
72
|
throw new SchemaError(`${origin} has a \`singletons\` that is not an object.`);
|
|
102
73
|
}
|
|
@@ -108,29 +79,12 @@ export function checkSchema(raw, origin = "the schema") {
|
|
|
108
79
|
for (const [name, def] of Object.entries(singletons)) {
|
|
109
80
|
assertFieldMap(def?.fields, `singletons.${name}`, origin);
|
|
110
81
|
}
|
|
111
|
-
|
|
112
|
-
* A default sort naming a field the collection does not declare is dropped
|
|
113
|
-
* here rather than refused.
|
|
114
|
-
*
|
|
115
|
-
* `defineSite` rejects it, which is right when somebody is writing the model
|
|
116
|
-
* and can fix the line they are looking at. By the time it reaches Mica the
|
|
117
|
-
* model is committed and a site is starting against it: the entries are
|
|
118
|
-
* intact, the fields are intact, and the only casualty is the order of a
|
|
119
|
-
* list. Refusing to serve the site over that would be out of proportion —
|
|
120
|
-
* and models written before the check existed contain exactly this, because
|
|
121
|
-
* the old fixed list of sort fields offered names no collection had.
|
|
122
|
-
*
|
|
123
|
-
* So the option is dropped, the list falls back to the order editors
|
|
124
|
-
* arranged by hand, and the project's next build reports it properly.
|
|
125
|
-
*/
|
|
82
|
+
// Drop, do not refuse, a default sort on an undeclared field: only the list order is affected.
|
|
126
83
|
for (const def of Object.values(collections)) {
|
|
127
84
|
const field = def?.defaultSort?.field;
|
|
128
85
|
if (field && field !== "position" && !def.fields?.[field])
|
|
129
86
|
delete def.defaultSort;
|
|
130
87
|
}
|
|
131
|
-
// Name injection and every cross-reference check — unknown relation targets,
|
|
132
|
-
// slugs derived from absent siblings, reserved collection names — come from
|
|
133
|
-
// the same function a hand-written model goes through.
|
|
134
88
|
try {
|
|
135
89
|
return defineSite({ collections, singletons });
|
|
136
90
|
}
|
|
@@ -158,13 +112,8 @@ function assertFieldMap(fields, at, origin) {
|
|
|
158
112
|
}
|
|
159
113
|
}
|
|
160
114
|
/**
|
|
161
|
-
* A
|
|
162
|
-
*
|
|
163
|
-
* Logged at startup and returned by the schema endpoint so that a website built
|
|
164
|
-
* against one model and a CMS serving another is a visible mismatch rather than
|
|
165
|
-
* a puzzling absence of fields. Key order follows the model's own declaration
|
|
166
|
-
* order, which is meaningful here — reordering fields reorders the admin form,
|
|
167
|
-
* so it is a real change and should produce a different digest.
|
|
115
|
+
* A short digest of a model, to show drift. Field order counts, because it is
|
|
116
|
+
* the order of the admin form.
|
|
168
117
|
*/
|
|
169
118
|
export async function schemaFingerprint(site) {
|
|
170
119
|
const { createHash } = await import("node:crypto");
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* The shared half of every app's entry point: bind the Hono app to a socket,
|
|
5
|
-
* shut down cleanly on SIGTERM/SIGINT, and turn the one most likely first-run
|
|
6
|
-
* failure — a busy port — into a message instead of a stack trace. What the
|
|
7
|
-
* apps keep for themselves is what to *say* when the server is up, because
|
|
8
|
-
* that is where a laptop and a container genuinely differ.
|
|
2
|
+
* Binds the app to a socket and shuts down cleanly on SIGTERM and SIGINT. Each
|
|
3
|
+
* app keeps its own startup message.
|
|
9
4
|
*/
|
|
10
5
|
import type { Hono } from "hono";
|
|
11
6
|
import type { Env } from "./http.js";
|
|
@@ -15,13 +10,10 @@ export interface StartServerOptions {
|
|
|
15
10
|
host: string;
|
|
16
11
|
port: number;
|
|
17
12
|
logger: Logger;
|
|
18
|
-
/** Called once the socket is listening — the banner or the log line. */
|
|
19
13
|
onListening(info: {
|
|
20
14
|
port: number;
|
|
21
15
|
}): void;
|
|
22
|
-
/** The message for a busy port. Defaults to a plain sentence. */
|
|
23
16
|
portInUseMessage?(): string;
|
|
24
|
-
/** Releases what the composition holds — timers, the database. */
|
|
25
17
|
shutdown(): Promise<void>;
|
|
26
18
|
}
|
|
27
19
|
export declare function startServer(options: StartServerOptions): void;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1C,gBAAgB,CAAC,IAAI,MAAM,CAAC;IAC5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,CA8C7D"}
|
package/dist/server.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* The shared half of every app's entry point: bind the Hono app to a socket,
|
|
5
|
-
* shut down cleanly on SIGTERM/SIGINT, and turn the one most likely first-run
|
|
6
|
-
* failure — a busy port — into a message instead of a stack trace. What the
|
|
7
|
-
* apps keep for themselves is what to *say* when the server is up, because
|
|
8
|
-
* that is where a laptop and a container genuinely differ.
|
|
2
|
+
* Binds the app to a socket and shuts down cleanly on SIGTERM and SIGINT. Each
|
|
3
|
+
* app keeps its own startup message.
|
|
9
4
|
*/
|
|
10
5
|
import { serve } from "@hono/node-server";
|
|
11
6
|
export function startServer(options) {
|
|
@@ -25,14 +20,13 @@ export function startServer(options) {
|
|
|
25
20
|
return;
|
|
26
21
|
shuttingDown = true;
|
|
27
22
|
logger.info("Shutting down", { signal });
|
|
28
|
-
// Stop accepting connections, then release whatever the app holds.
|
|
29
23
|
server.close(() => {
|
|
30
24
|
void options.shutdown().then(() => {
|
|
31
25
|
logger.info("Shutdown complete");
|
|
32
26
|
process.exit(0);
|
|
33
27
|
});
|
|
34
28
|
});
|
|
35
|
-
//
|
|
29
|
+
// A hung connection must not block a container restart.
|
|
36
30
|
setTimeout(() => {
|
|
37
31
|
logger.warn("Forcing exit after shutdown timeout");
|
|
38
32
|
process.exit(1);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAgB1C,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE3B,MAAM,MAAM,GAAG,KAAK,CAClB,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EACxE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CACnD,CAAC;IAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;QAClD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAAE,MAAM,KAAK,CAAC;QAE7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,OAAO,CAAC,gBAAgB,EAAE,EAAE;YAC1B,QAAQ,OAAO,CAAC,IAAI,OAAO,OAAO,CAAC,IAAI,qCAAqC;gBAC1E,yBAAyB,CAC9B,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAQ,EAAE;QACxC,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QACpB,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAEzC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;YAChB,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;gBAChC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,wDAAwD;QACxD,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE/C,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/** The staging API types, the before/after comparison and the analysis of a pending change set. */
|
|
2
|
+
import type { Author } from "../workspace/files.js";
|
|
3
|
+
import { type ContentChange, type ContentSource, type FieldIssue, type PublishResult, type Site } from "@micacms/core";
|
|
4
|
+
import type { SyncStatus } from "../workspace/policy.js";
|
|
5
|
+
/** Where the change happened, in words an editor recognises. */
|
|
6
|
+
export type ChangeOwner = {
|
|
7
|
+
kind: "entry";
|
|
8
|
+
collection: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
label: string;
|
|
11
|
+
/** The slug before a pending rename. Set on the files of both slugs. */
|
|
12
|
+
renamedFrom?: string;
|
|
13
|
+
} | {
|
|
14
|
+
kind: "singleton";
|
|
15
|
+
name: string;
|
|
16
|
+
label: string;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "order";
|
|
19
|
+
collection: string;
|
|
20
|
+
label: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: "media";
|
|
23
|
+
label: string;
|
|
24
|
+
} | {
|
|
25
|
+
kind: "other";
|
|
26
|
+
label: string;
|
|
27
|
+
};
|
|
28
|
+
export interface AnnotatedChange extends ContentChange {
|
|
29
|
+
owner: ChangeOwner;
|
|
30
|
+
/**
|
|
31
|
+
* The file's revision, null for a deletion. Publish sends it back, so a file
|
|
32
|
+
* saved after the review is not published unseen.
|
|
33
|
+
*/
|
|
34
|
+
revision?: string | null;
|
|
35
|
+
}
|
|
36
|
+
/** One thing that would make the staged result unpublishable. */
|
|
37
|
+
export interface StagingProblem {
|
|
38
|
+
/** The file the problem is about, relative to the content root. */
|
|
39
|
+
path: string;
|
|
40
|
+
label: string;
|
|
41
|
+
issues: FieldIssue[];
|
|
42
|
+
}
|
|
43
|
+
export interface StagingValidation {
|
|
44
|
+
ok: boolean;
|
|
45
|
+
problems: StagingProblem[];
|
|
46
|
+
}
|
|
47
|
+
export interface StagingStatus {
|
|
48
|
+
/** Whose working tree it is. The UI wording changes with it. */
|
|
49
|
+
owner: "developer" | "managed";
|
|
50
|
+
publish: {
|
|
51
|
+
enabled: boolean;
|
|
52
|
+
reason?: string;
|
|
53
|
+
};
|
|
54
|
+
/** The commit the pending changes sit on. */
|
|
55
|
+
head: string | null;
|
|
56
|
+
/** The branch a publication lands on, where the workspace knows it. */
|
|
57
|
+
branch: string | null;
|
|
58
|
+
/** Commits created and not yet pushed. */
|
|
59
|
+
ahead: number | null;
|
|
60
|
+
changes: AnnotatedChange[];
|
|
61
|
+
validation: StagingValidation;
|
|
62
|
+
/** Where a clone that Mica keeps stands against its remote. Null for the developer's checkout. */
|
|
63
|
+
sync: SyncStatus | null;
|
|
64
|
+
}
|
|
65
|
+
export interface PublishInput {
|
|
66
|
+
/** Subject line of the commit. */
|
|
67
|
+
message: string;
|
|
68
|
+
/**
|
|
69
|
+
* The reviewed paths, with the revision each had in the review. Only these
|
|
70
|
+
* are published; a file saved again since, or another file of the same entry,
|
|
71
|
+
* makes Publish refuse.
|
|
72
|
+
*/
|
|
73
|
+
paths: Record<string, string | null>;
|
|
74
|
+
author?: Author;
|
|
75
|
+
}
|
|
76
|
+
/** What the System page shows about the repository. */
|
|
77
|
+
export interface RepositoryInfo {
|
|
78
|
+
owner: "developer" | "managed";
|
|
79
|
+
branch: string | null;
|
|
80
|
+
head: string | null;
|
|
81
|
+
/** The remote, for a clone that Mica keeps. */
|
|
82
|
+
url: string | null;
|
|
83
|
+
cloneBytes: number | null;
|
|
84
|
+
sync: SyncStatus | null;
|
|
85
|
+
}
|
|
86
|
+
export interface ContentStagingService {
|
|
87
|
+
status(): Promise<StagingStatus>;
|
|
88
|
+
publish(input: PublishInput): Promise<PublishResult>;
|
|
89
|
+
discard(paths: string[]): Promise<{
|
|
90
|
+
discarded: string[];
|
|
91
|
+
}>;
|
|
92
|
+
/** Retries the push after `committed-pending-push`. */
|
|
93
|
+
push(): Promise<PublishResult>;
|
|
94
|
+
/**
|
|
95
|
+
* A document before and after a pending change. `origin` compares against the
|
|
96
|
+
* website's version, not the last commit.
|
|
97
|
+
*/
|
|
98
|
+
compare(target: CompareTarget, against?: "head" | "origin"): Promise<Comparison>;
|
|
99
|
+
/** Brings a clone that Mica keeps up to date now. Refused for the developer's checkout. */
|
|
100
|
+
sync(): Promise<void>;
|
|
101
|
+
resolve(group: string, choice: "mine" | "website"): Promise<void>;
|
|
102
|
+
repository(): Promise<RepositoryInfo>;
|
|
103
|
+
}
|
|
104
|
+
/** What to compare on the Publish page. */
|
|
105
|
+
export type CompareTarget =
|
|
106
|
+
/** `from` names the published slug of a renamed entry. */
|
|
107
|
+
{
|
|
108
|
+
kind: "entry";
|
|
109
|
+
collection: string;
|
|
110
|
+
slug: string;
|
|
111
|
+
from?: string;
|
|
112
|
+
} | {
|
|
113
|
+
kind: "singleton";
|
|
114
|
+
name: string;
|
|
115
|
+
} | {
|
|
116
|
+
kind: "order";
|
|
117
|
+
collection: string;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Raw field data on both sides of a pending change. The editor renders the
|
|
121
|
+
* comparison from the model.
|
|
122
|
+
*/
|
|
123
|
+
export interface Comparison {
|
|
124
|
+
/** As the repository has it — null when the change creates the document. */
|
|
125
|
+
before: Record<string, unknown> | null;
|
|
126
|
+
/** As staged for publication — null when the change deletes it. */
|
|
127
|
+
after: Record<string, unknown> | null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Reads one document from `published` and from `staged`. An order target
|
|
131
|
+
* becomes `{ order: [{ slug, title }] }` on each side, in position order.
|
|
132
|
+
*/
|
|
133
|
+
export declare function compareSources(model: Site, published: ContentSource, staged: ContentSource, target: CompareTarget): Promise<Comparison>;
|
|
134
|
+
/**
|
|
135
|
+
* Annotates a change set with owners and validates the entries it touches, in
|
|
136
|
+
* one read of the affected collections. Only changed documents are validated: a
|
|
137
|
+
* broken entry committed earlier must not block an unrelated publication.
|
|
138
|
+
*/
|
|
139
|
+
export declare function analyseChanges(model: Site, source: ContentSource, changes: ContentChange[],
|
|
140
|
+
/** The repository's side. When given, renamed entries are detected. */
|
|
141
|
+
published?: ContentSource): Promise<{
|
|
142
|
+
changes: AnnotatedChange[];
|
|
143
|
+
validation: StagingValidation;
|
|
144
|
+
}>;
|
|
145
|
+
/** Which piece of content a file belongs to, read from the model's path layout. */
|
|
146
|
+
export declare function classifyPath(model: Site, path: string): ChangeOwner;
|
|
147
|
+
export declare function describeProblems(problems: StagingProblem[]): string;
|
|
148
|
+
/** Field issues with the file path folded in, for the flat API envelope. */
|
|
149
|
+
export declare function flattenProblems(problems: StagingProblem[]): FieldIssue[];
|
|
150
|
+
//# sourceMappingURL=changes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../src/services/changes.ts"],"names":[],"mappings":"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"}
|