@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.
Files changed (102) hide show
  1. package/README.md +2 -2
  2. package/dist/app.d.ts +8 -37
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js +7 -42
  5. package/dist/app.js.map +1 -1
  6. package/dist/config.d.ts +12 -82
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +14 -82
  9. package/dist/config.js.map +1 -1
  10. package/dist/context.d.ts +37 -66
  11. package/dist/context.d.ts.map +1 -1
  12. package/dist/context.js +24 -75
  13. package/dist/context.js.map +1 -1
  14. package/dist/http.d.ts +8 -16
  15. package/dist/http.d.ts.map +1 -1
  16. package/dist/http.js +6 -13
  17. package/dist/http.js.map +1 -1
  18. package/dist/index.d.ts +13 -14
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +12 -14
  21. package/dist/index.js.map +1 -1
  22. package/dist/routes/admin-content.d.ts +4 -17
  23. package/dist/routes/admin-content.d.ts.map +1 -1
  24. package/dist/routes/admin-content.js +11 -51
  25. package/dist/routes/admin-content.js.map +1 -1
  26. package/dist/routes/admin-media.d.ts +3 -14
  27. package/dist/routes/admin-media.d.ts.map +1 -1
  28. package/dist/routes/admin-media.js +7 -29
  29. package/dist/routes/admin-media.js.map +1 -1
  30. package/dist/routes/admin-staging.d.ts +4 -9
  31. package/dist/routes/admin-staging.d.ts.map +1 -1
  32. package/dist/routes/admin-staging.js +31 -18
  33. package/dist/routes/admin-staging.js.map +1 -1
  34. package/dist/routes/admin-system.d.ts +2 -8
  35. package/dist/routes/admin-system.d.ts.map +1 -1
  36. package/dist/routes/admin-system.js +9 -44
  37. package/dist/routes/admin-system.js.map +1 -1
  38. package/dist/routes/health.d.ts +3 -10
  39. package/dist/routes/health.d.ts.map +1 -1
  40. package/dist/routes/health.js +9 -26
  41. package/dist/routes/health.js.map +1 -1
  42. package/dist/schema.d.ts +10 -38
  43. package/dist/schema.d.ts.map +1 -1
  44. package/dist/schema.js +14 -65
  45. package/dist/schema.js.map +1 -1
  46. package/dist/server.d.ts +2 -10
  47. package/dist/server.d.ts.map +1 -1
  48. package/dist/server.js +3 -9
  49. package/dist/server.js.map +1 -1
  50. package/dist/services/changes.d.ts +150 -0
  51. package/dist/services/changes.d.ts.map +1 -0
  52. package/dist/services/changes.js +339 -0
  53. package/dist/services/changes.js.map +1 -0
  54. package/dist/services/content-store.d.ts +61 -0
  55. package/dist/services/content-store.d.ts.map +1 -0
  56. package/dist/services/content-store.js +330 -0
  57. package/dist/services/content-store.js.map +1 -0
  58. package/dist/services/media.d.ts +9 -29
  59. package/dist/services/media.d.ts.map +1 -1
  60. package/dist/services/media.js +17 -57
  61. package/dist/services/media.js.map +1 -1
  62. package/dist/services/staging.d.ts +35 -167
  63. package/dist/services/staging.d.ts.map +1 -1
  64. package/dist/services/staging.js +195 -458
  65. package/dist/services/staging.js.map +1 -1
  66. package/dist/workspace/developer.d.ts +14 -0
  67. package/dist/workspace/developer.d.ts.map +1 -0
  68. package/dist/workspace/developer.js +31 -0
  69. package/dist/workspace/developer.js.map +1 -0
  70. package/dist/workspace/files.d.ts +70 -0
  71. package/dist/workspace/files.d.ts.map +1 -0
  72. package/dist/workspace/files.js +176 -0
  73. package/dist/workspace/files.js.map +1 -0
  74. package/dist/workspace/git.d.ts +45 -0
  75. package/dist/workspace/git.d.ts.map +1 -0
  76. package/dist/workspace/git.js +68 -0
  77. package/dist/workspace/git.js.map +1 -0
  78. package/dist/workspace/locks.d.ts +33 -0
  79. package/dist/workspace/locks.d.ts.map +1 -0
  80. package/dist/workspace/locks.js +76 -0
  81. package/dist/workspace/locks.js.map +1 -0
  82. package/dist/workspace/policy.d.ts +92 -0
  83. package/dist/workspace/policy.d.ts.map +1 -0
  84. package/dist/workspace/policy.js +7 -0
  85. package/dist/workspace/policy.js.map +1 -0
  86. package/dist/workspace/tree.d.ts +73 -0
  87. package/dist/workspace/tree.d.ts.map +1 -0
  88. package/dist/workspace/tree.js +229 -0
  89. package/dist/workspace/tree.js.map +1 -0
  90. package/package.json +2 -3
  91. package/dist/db/driver.d.ts +0 -35
  92. package/dist/db/driver.d.ts.map +0 -1
  93. package/dist/db/driver.js +0 -95
  94. package/dist/db/driver.js.map +0 -1
  95. package/dist/lib/git.d.ts +0 -29
  96. package/dist/lib/git.d.ts.map +0 -1
  97. package/dist/lib/git.js +0 -62
  98. package/dist/lib/git.js.map +0 -1
  99. package/dist/services/staging-local.d.ts +0 -58
  100. package/dist/services/staging-local.d.ts.map +0 -1
  101. package/dist/services/staging-local.js +0 -391
  102. package/dist/services/staging-local.js.map +0 -1
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  > **Experimental.** Pre-1.0: the API can still change without notice.
4
4
 
5
- The single-site Mica runtime: the Hono API, application services and staging
6
- orchestration, deliberately **authentication-neutral**. It answers "who is
5
+ The single-site Mica runtime: the Hono API, application services, the content
6
+ files and the Git working-tree code (Git runner, locks, owner policy), deliberately **authentication-neutral**. It answers "who is
7
7
  this request?" with whatever `AuthSurface` the composing app hands in, and
8
8
  never imports an auth implementation — that direction is what keeps
9
9
  `npx @micacms/editor` free of authentication code.
package/dist/app.d.ts CHANGED
@@ -1,28 +1,7 @@
1
1
  /**
2
- * Application assembly.
3
- *
4
- * cms.example.com
5
- * │
6
- * ▼
7
- * Hono
8
- * ┌──────┴───┬──────────┐
9
- * │ │ │
10
- * /api/* /admin/* /health /ready
11
- * │ │
12
- * connector Vue SPA
13
- * │
14
- * content repository
15
- *
16
- * There is no public content API and no `/media/*`. A website is built from the
17
- * repository, not from this server, so nothing here has to be reachable for a
18
- * site to deploy — or to stay up.
19
- *
20
- * Authentication is not assembled here — it is *received*. The composing app
21
- * hands in an `AuthSurface`: routes for `/api/auth`, and the gate applied in
22
- * front of every admin route. The self-hosted app passes the OIDC surface
23
- * from `@micacms/auth-oidc`; the local editor passes nothing and gets the
24
- * unauthenticated surface below, which is a statement of fact — on your own
25
- * machine there is nobody to be — not a bypass of anything.
2
+ * Assembles the app: health, the admin API and the admin SPA. There is no
3
+ * public content API and no `/media/*`; a website builds from the repository,
4
+ * not from this server. Authentication comes from the composing app.
26
5
  */
27
6
  import { Hono } from "hono";
28
7
  import type { MiddlewareHandler } from "hono";
@@ -32,30 +11,22 @@ import type { Env } from "./http.js";
32
11
  export interface AuthSurface {
33
12
  /** Mounted at `/api/auth`: sign-in, callback, logout, whatever auth needs. */
34
13
  routes: Hono<Env>;
35
- /**
36
- * Applied before every `/api/admin` route, in order. Must either set the
37
- * `access` variable or refuse the request — nothing behind it runs without
38
- * an `AccessContext`.
39
- */
14
+ /** Applied before every `/api/admin` route. Must set `access` or refuse the request. */
40
15
  gate: MiddlewareHandler<Env>[];
41
16
  }
42
17
  /**
43
- * The unauthenticated surface: every request is allowed, and none is anybody.
44
- *
45
- * An authorization policy, not authentication code. It exists so action
46
- * checks stay uniform without inventing a user, and it is safe only because
47
- * the local editor is loopback-bound and Host-guarded by construction.
18
+ * Allows every request with no identity. Safe only because the local editor is
19
+ * loopback-bound and Host-guarded.
48
20
  */
49
21
  export declare function allowAll(): MiddlewareHandler<Env>;
50
22
  export interface CreateAppOptions {
51
23
  /** Absent means the unauthenticated local surface. */
52
24
  auth?: AuthSurface;
53
25
  /**
54
- * Extra middleware in front of everything — the local editor's Host
55
- * allowlist goes here, so even the health endpoints answer only to this machine.
26
+ * Middleware in front of everything, so the local editor's Host allowlist
27
+ * also guards the health endpoints.
56
28
  */
57
29
  guards?: MiddlewareHandler<Env>[];
58
- /** Where the built admin SPA is served from. */
59
30
  adminDir?: string;
60
31
  }
61
32
  export declare function createApp(ctx: RuntimeContext, options?: CreateAppOptions): Hono<Env>;
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAiBrC,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB;;;;OAIG;IACH,IAAI,EAAE,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAKjD;AASD,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,GAAE,gBAAqB,GAAG,IAAI,CAAC,GAAG,CAAC,CA6ExF"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAiBrC,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,wFAAwF;IACxF,IAAI,EAAE,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAKjD;AASD,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,GAAE,gBAAqB,GAAG,IAAI,CAAC,GAAG,CAAC,CA6DxF"}
package/dist/app.js CHANGED
@@ -1,28 +1,7 @@
1
1
  /**
2
- * Application assembly.
3
- *
4
- * cms.example.com
5
- * │
6
- * ▼
7
- * Hono
8
- * ┌──────┴───┬──────────┐
9
- * │ │ │
10
- * /api/* /admin/* /health /ready
11
- * │ │
12
- * connector Vue SPA
13
- * │
14
- * content repository
15
- *
16
- * There is no public content API and no `/media/*`. A website is built from the
17
- * repository, not from this server, so nothing here has to be reachable for a
18
- * site to deploy — or to stay up.
19
- *
20
- * Authentication is not assembled here — it is *received*. The composing app
21
- * hands in an `AuthSurface`: routes for `/api/auth`, and the gate applied in
22
- * front of every admin route. The self-hosted app passes the OIDC surface
23
- * from `@micacms/auth-oidc`; the local editor passes nothing and gets the
24
- * unauthenticated surface below, which is a statement of fact — on your own
25
- * machine there is nobody to be — not a bypass of anything.
2
+ * Assembles the app: health, the admin API and the admin SPA. There is no
3
+ * public content API and no `/media/*`; a website builds from the repository,
4
+ * not from this server. Authentication comes from the composing app.
26
5
  */
27
6
  import { Hono } from "hono";
28
7
  import { cors } from "hono/cors";
@@ -34,11 +13,8 @@ import { adminStagingRoutes } from "./routes/admin-staging.js";
34
13
  import { adminSystemRoutes } from "./routes/admin-system.js";
35
14
  import { healthRoutes } from "./routes/health.js";
36
15
  /**
37
- * The unauthenticated surface: every request is allowed, and none is anybody.
38
- *
39
- * An authorization policy, not authentication code. It exists so action
40
- * checks stay uniform without inventing a user, and it is safe only because
41
- * the local editor is loopback-bound and Host-guarded by construction.
16
+ * Allows every request with no identity. Safe only because the local editor is
17
+ * loopback-bound and Host-guarded.
42
18
  */
43
19
  export function allowAll() {
44
20
  return async (c, next) => {
@@ -55,18 +31,13 @@ function unauthenticatedSurface() {
55
31
  export function createApp(ctx, options = {}) {
56
32
  const app = new Hono();
57
33
  const auth = options.auth ?? unauthenticatedSurface();
58
- /* ---------------------------------------------------------- baseline */
59
34
  app.use("*", requestContext(ctx));
60
35
  for (const guard of options.guards ?? [])
61
36
  app.use("*", guard);
62
37
  app.use("*", securityHeaders());
63
38
  app.onError(errorHandler());
64
- /* ------------------------------------------------------------ health */
65
39
  app.route("/", healthRoutes());
66
- /* --------------------------------------------------------------- API */
67
- // In development the SPA is served by Vite on another origin, so the API has
68
- // to accept credentialed cross-origin calls from it. In production the SPA is
69
- // same-origin and ADMIN_ORIGINS is normally empty.
40
+ // Only for the Vite dev server on another origin; in production the SPA is same-origin.
70
41
  if (ctx.config.adminOrigins.length > 0) {
71
42
  app.use("/api/*", cors({
72
43
  origin: allowedOrigins(ctx.config),
@@ -79,10 +50,7 @@ export function createApp(ctx, options = {}) {
79
50
  app.use("/api/*", originGuard());
80
51
  app.use("/api/*", requestSizeLimit());
81
52
  app.route("/api/auth", auth.routes);
82
- /* ------------------------------------------------------- admin API */
83
- // One gate, and no second one behind it: whoever the surface admits is an
84
- // editor of this site. There are no roles, because there are no accounts to
85
- // hang them on.
53
+ // One gate and no roles: whoever the surface admits is an editor of this site.
86
54
  for (const middleware of auth.gate)
87
55
  app.use("/api/admin/*", middleware);
88
56
  app.route("/api/admin", adminSystemRoutes());
@@ -90,14 +58,11 @@ export function createApp(ctx, options = {}) {
90
58
  app.route("/api/admin", adminStagingRoutes());
91
59
  app.route("/api/admin/media", adminMediaRoutes());
92
60
  app.all("/api/*", (c) => c.json({ error: { code: "not_found", message: "No such endpoint." } }, 404));
93
- /* --------------------------------------------------------- admin SPA */
94
61
  const adminDir = options.adminDir ?? ctx.config.ADMIN_DIR;
95
62
  if (adminDir && adminAssetsExist(adminDir)) {
96
63
  app.route("/admin", adminSpaRoutes(adminDir));
97
64
  }
98
65
  else {
99
- // Running from source with only the API built: point at the Vite server
100
- // rather than returning a blank 404.
101
66
  app.get("/admin/*", (c) => c.text("The admin interface has not been built.\n" +
102
67
  "Run `rush build`, or use `rush dev` and open the Vite dev server.", 503));
103
68
  }
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,27 +1,17 @@
1
1
  /**
2
- * The runtime's slice of the environment, as a fragment.
3
- *
4
- * There is no `loadConfig` here, deliberately. The runtime is composed by an
5
- * app — the local editor, the self-hosted container — and which variables
6
- * exist, which are refused and what the defaults are is exactly what makes
7
- * one app not the other. Each app builds its own Zod schema from this shape,
8
- * adds its own variables, and derives a `RuntimeConfig` with `deriveRuntime`;
9
- * this module only states what the runtime itself reads.
10
- *
11
- * `MICA_MODE` is gone. The mode is which app you run.
2
+ * The environment variables the runtime reads. There is no `loadConfig`: each
3
+ * app builds its own schema from `runtimeEnv`, because the variables and
4
+ * defaults are what make one app different from another.
12
5
  */
13
6
  import { z } from "zod";
14
- /**
15
- * `.default` takes the *output* value in Zod 4, and short-circuits: an absent
16
- * variable returns the boolean without going through the transform.
17
- */
7
+ /** In Zod 4, `.default` takes the output value and skips the transform. */
18
8
  export declare const bool: (fallback: boolean) => z.ZodDefault<z.ZodPipe<z.ZodEnum<{
19
9
  0: "0";
20
10
  1: "1";
21
11
  true: "true";
22
12
  false: "false";
23
13
  }>, z.ZodTransform<boolean, "0" | "1" | "true" | "false">>>;
24
- /** `a, b , c` and `a,b,c` are the same list, and an empty entry is not one. */
14
+ /** Splits a comma-separated list, trims entries and drops empty ones. */
25
15
  export declare const list: (value: string | undefined) => string[];
26
16
  export declare class ConfigError extends Error {
27
17
  name: string;
@@ -42,42 +32,14 @@ export declare const runtimeEnv: {
42
32
  error: "error";
43
33
  silent: "silent";
44
34
  }>>;
45
- /** The address to listen on. Defaulted by the app: loopback for the local
46
- * editor (which refuses anything else), every interface for a container. */
35
+ /** The listen address. The app sets the default. */
47
36
  HOST: z.ZodOptional<z.ZodString>;
48
37
  PORT: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
49
38
  /** Public origin of the CMS itself. Used for cookies, CORS and media URLs. */
50
39
  MICA_PUBLIC_URL: z.ZodDefault<z.ZodString>;
51
- /**
52
- * The content repository this Mica serves, when it reaches it as a working
53
- * tree on disk. Ignored for a provider connector, which is given
54
- * REPOSITORY_ROOT inside the remote repository instead.
55
- */
40
+ /** The content root this Mica serves: a directory in a Git working tree. */
56
41
  CONTENT_ROOT: z.ZodDefault<z.ZodString>;
57
- /**
58
- * How Mica reaches that repository. `local` is a working tree beside the
59
- * server — and the working tree is then the draft workspace. `github` and
60
- * `gitlab` publish through the provider's API, with saves staged in the
61
- * draft store until an editor publishes.
62
- */
63
- REPOSITORY: z.ZodDefault<z.ZodEnum<{
64
- local: "local";
65
- github: "github";
66
- gitlab: "gitlab";
67
- }>>;
68
- /** Where the content root sits *inside* the remote repository. */
69
- REPOSITORY_ROOT: z.ZodDefault<z.ZodString>;
70
- REPOSITORY_BRANCH: z.ZodDefault<z.ZodString>;
71
- /** Token with write access to the content repository. */
72
- REPOSITORY_TOKEN: z.ZodOptional<z.ZodString>;
73
- /** `owner/repo` for GitHub, `group/project` or a numeric id for GitLab. */
74
- REPOSITORY_PROJECT: z.ZodOptional<z.ZodString>;
75
- /** For GitHub Enterprise or self-managed GitLab. */
76
- REPOSITORY_API_BASE: z.ZodOptional<z.ZodString>;
77
- /**
78
- * Whether working-tree staging may commit and push. `false` reduces Publish
79
- * to autosave plus a read-only view of the pending changes.
80
- */
42
+ /** `false` disables commit and push: Publish shows the pending changes read-only. */
81
43
  MICA_LOCAL_PUBLISH: z.ZodDefault<z.ZodPipe<z.ZodEnum<{
82
44
  0: "0";
83
45
  1: "1";
@@ -114,16 +76,6 @@ declare const runtimeSchema: z.ZodObject<{
114
76
  PORT: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
115
77
  MICA_PUBLIC_URL: z.ZodDefault<z.ZodString>;
116
78
  CONTENT_ROOT: z.ZodDefault<z.ZodString>;
117
- REPOSITORY: z.ZodDefault<z.ZodEnum<{
118
- local: "local";
119
- github: "github";
120
- gitlab: "gitlab";
121
- }>>;
122
- REPOSITORY_ROOT: z.ZodDefault<z.ZodString>;
123
- REPOSITORY_BRANCH: z.ZodDefault<z.ZodString>;
124
- REPOSITORY_TOKEN: z.ZodOptional<z.ZodString>;
125
- REPOSITORY_PROJECT: z.ZodOptional<z.ZodString>;
126
- REPOSITORY_API_BASE: z.ZodOptional<z.ZodString>;
127
79
  MICA_LOCAL_PUBLISH: z.ZodDefault<z.ZodPipe<z.ZodEnum<{
128
80
  0: "0";
129
81
  1: "1";
@@ -142,10 +94,8 @@ declare const runtimeSchema: z.ZodObject<{
142
94
  }, z.core.$strip>;
143
95
  export type RuntimeEnv = z.infer<typeof runtimeSchema>;
144
96
  /**
145
- * The derived values the runtime reads, on top of the parsed environment.
146
- *
147
- * Called from each app's own `transform`, so every composition derives them
148
- * the same way and none forgets one.
97
+ * Adds the derived values to the parsed environment. Each app calls it from its
98
+ * own `transform`.
149
99
  */
150
100
  export declare function deriveRuntime<T extends RuntimeEnv>(env: T): T & {
151
101
  isProduction: boolean;
@@ -157,29 +107,9 @@ export type RuntimeConfig = ReturnType<typeof deriveRuntime<RuntimeEnv>> & {
157
107
  /** Resolved by the app: the runtime never guesses an address. */
158
108
  HOST: string;
159
109
  };
160
- /**
161
- * A remote repository needs to be told which one, and with what.
162
- *
163
- * Checked at startup rather than at the first save: a Mica that starts, shows
164
- * the editor their content, and only fails when they press Save has already
165
- * wasted their work.
166
- */
167
- export declare function requireRepositoryConfig(config: RuntimeConfig): void;
168
- /**
169
- * Folds `./.env` into the ambient environment.
170
- *
171
- * `process.loadEnvFile` leaves already-set variables alone, so a container's
172
- * `environment:` block still beats a file that happened to be copied into the
173
- * image.
174
- */
110
+ /** Loads `./.env` into `process.env`. Variables that are already set win. */
175
111
  export declare function loadEnvFile(): void;
176
- /**
177
- * An unset variable and one set to the empty string mean the same thing.
178
- *
179
- * `.env.example` ships blanks for the operator to fill in, and the docs say to
180
- * copy it verbatim; without this, doing so reads as "the secret is a
181
- * zero-length string" and the server refuses on the documented happy path.
182
- */
112
+ /** Treats a blank variable as unset, so a verbatim copy of `.env.example` with blanks is valid. */
183
113
  export declare function withoutBlanks(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
184
114
  /** Formats a Zod refusal the way a person at a terminal reads it. */
185
115
  export declare function describeConfigIssues(error: z.ZodError): string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;GAGG;AACH,eAAO,MAAM,IAAI,GAAI,UAAU,OAAO;;;;;2DAIhB,CAAC;AAEvB,+EAA+E;AAC/E,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAAM,EAInC,CAAC;AAErB,qBAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,SAAiB;CAC/B;AAED,yDAAyD;AACzD,eAAO,MAAM,QAAQ,aAAyE,CAAC;AAE/F,kFAAkF;AAClF,eAAO,MAAM,UAAU;;;;;;;;;;;;;IAIrB;iFAC6E;;;IAI7E,8EAA8E;;IAG9E;;;;OAIG;;IAGH;;;;;OAKG;;;;;;IAEH,kEAAkE;;;IAGlE,yDAAyD;;IAEzD,2EAA2E;;IAE3E,oDAAoD;;IAGpD;;;OAGG;;;;;;;;IASH,2EAA2E;;;;;;;IAE3E,6EAA6E;;IAE7E,0DAA0D;;CAE3D,CAAC;AAEF,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAuB,CAAC;AAC3C,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEvD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAAE,GAAG,EAAE,CAAC;;;;EAOzD;AAED,6DAA6D;AAC7D,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,UAAU,CAAC,CAAC,GAAG;IACzE,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAgBnE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAWlC;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAIvE;AAED,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,MAAM,CAK9D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,2EAA2E;AAC3E,eAAO,MAAM,IAAI,GAAI,UAAU,OAAO;;;;;2DAIhB,CAAC;AAEvB,yEAAyE;AACzE,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,GAAG,SAAS,KAAG,MAAM,EAInC,CAAC;AAErB,qBAAa,WAAY,SAAQ,KAAK;IAC3B,IAAI,SAAiB;CAC/B;AAED,yDAAyD;AACzD,eAAO,MAAM,QAAQ,aAAyE,CAAC;AAE/F,kFAAkF;AAClF,eAAO,MAAM,UAAU;;;;;;;;;;;;;IAIrB,oDAAoD;;;IAIpD,8EAA8E;;IAG9E,4EAA4E;;IAG5E,qFAAqF;;;;;;;;IASrF,2EAA2E;;;;;;;IAE3E,6EAA6E;;IAE7E,0DAA0D;;CAE3D,CAAC;AAEF,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAuB,CAAC;AAC3C,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,UAAU,EAAE,GAAG,EAAE,CAAC;;;;EAOzD;AAED,6DAA6D;AAC7D,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,UAAU,CAAC,CAAC,GAAG;IACzE,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,WAAW,IAAI,IAAI,CAUlC;AAED,mGAAmG;AACnG,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAIvE;AAED,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,MAAM,CAK9D"}
package/dist/config.js CHANGED
@@ -1,27 +1,17 @@
1
1
  /**
2
- * The runtime's slice of the environment, as a fragment.
3
- *
4
- * There is no `loadConfig` here, deliberately. The runtime is composed by an
5
- * app — the local editor, the self-hosted container — and which variables
6
- * exist, which are refused and what the defaults are is exactly what makes
7
- * one app not the other. Each app builds its own Zod schema from this shape,
8
- * adds its own variables, and derives a `RuntimeConfig` with `deriveRuntime`;
9
- * this module only states what the runtime itself reads.
10
- *
11
- * `MICA_MODE` is gone. The mode is which app you run.
2
+ * The environment variables the runtime reads. There is no `loadConfig`: each
3
+ * app builds its own schema from `runtimeEnv`, because the variables and
4
+ * defaults are what make one app different from another.
12
5
  */
13
6
  import path from "node:path";
14
7
  import { z } from "zod";
15
8
  import { DEFAULT_BASE_URL, DEFAULT_PORT } from "./lib/ports.js";
16
- /**
17
- * `.default` takes the *output* value in Zod 4, and short-circuits: an absent
18
- * variable returns the boolean without going through the transform.
19
- */
9
+ /** In Zod 4, `.default` takes the output value and skips the transform. */
20
10
  export const bool = (fallback) => z
21
11
  .enum(["true", "false", "1", "0"])
22
12
  .transform((value) => value === "true" || value === "1")
23
13
  .default(fallback);
24
- /** `a, b , c` and `a,b,c` are the same list, and an empty entry is not one. */
14
+ /** Splits a comma-separated list, trims entries and drops empty ones. */
25
15
  export const list = (value) => (value ?? "")
26
16
  .split(",")
27
17
  .map((entry) => entry.trim())
@@ -35,38 +25,14 @@ export const LOOPBACK = new Set(["localhost", "127.0.0.1", "[::1]", "::1", "0:0:
35
25
  export const runtimeEnv = {
36
26
  NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
37
27
  LOG_LEVEL: z.enum(["debug", "info", "warn", "error", "silent"]).default("info"),
38
- /** The address to listen on. Defaulted by the app: loopback for the local
39
- * editor (which refuses anything else), every interface for a container. */
28
+ /** The listen address. The app sets the default. */
40
29
  HOST: z.string().optional(),
41
30
  PORT: z.coerce.number().int().min(1).max(65535).default(DEFAULT_PORT),
42
31
  /** Public origin of the CMS itself. Used for cookies, CORS and media URLs. */
43
32
  MICA_PUBLIC_URL: z.string().url().default(DEFAULT_BASE_URL),
44
- /**
45
- * The content repository this Mica serves, when it reaches it as a working
46
- * tree on disk. Ignored for a provider connector, which is given
47
- * REPOSITORY_ROOT inside the remote repository instead.
48
- */
33
+ /** The content root this Mica serves: a directory in a Git working tree. */
49
34
  CONTENT_ROOT: z.string().default("../../examples/muster-consulting/content"),
50
- /**
51
- * How Mica reaches that repository. `local` is a working tree beside the
52
- * server — and the working tree is then the draft workspace. `github` and
53
- * `gitlab` publish through the provider's API, with saves staged in the
54
- * draft store until an editor publishes.
55
- */
56
- REPOSITORY: z.enum(["local", "github", "gitlab"]).default("local"),
57
- /** Where the content root sits *inside* the remote repository. */
58
- REPOSITORY_ROOT: z.string().default("content"),
59
- REPOSITORY_BRANCH: z.string().default("main"),
60
- /** Token with write access to the content repository. */
61
- REPOSITORY_TOKEN: z.string().optional(),
62
- /** `owner/repo` for GitHub, `group/project` or a numeric id for GitLab. */
63
- REPOSITORY_PROJECT: z.string().optional(),
64
- /** For GitHub Enterprise or self-managed GitLab. */
65
- REPOSITORY_API_BASE: z.string().url().optional(),
66
- /**
67
- * Whether working-tree staging may commit and push. `false` reduces Publish
68
- * to autosave plus a read-only view of the pending changes.
69
- */
35
+ /** `false` disables commit and push: Publish shows the pending changes read-only. */
70
36
  MICA_LOCAL_PUBLISH: bool(true),
71
37
  MAX_UPLOAD_BYTES: z.coerce
72
38
  .number()
@@ -82,10 +48,8 @@ export const runtimeEnv = {
82
48
  };
83
49
  const runtimeSchema = z.object(runtimeEnv);
84
50
  /**
85
- * The derived values the runtime reads, on top of the parsed environment.
86
- *
87
- * Called from each app's own `transform`, so every composition derives them
88
- * the same way and none forgets one.
51
+ * Adds the derived values to the parsed environment. Each app calls it from its
52
+ * own `transform`.
89
53
  */
90
54
  export function deriveRuntime(env) {
91
55
  return {
@@ -95,52 +59,20 @@ export function deriveRuntime(env) {
95
59
  adminOrigins: list(env.ADMIN_ORIGINS),
96
60
  };
97
61
  }
98
- /**
99
- * A remote repository needs to be told which one, and with what.
100
- *
101
- * Checked at startup rather than at the first save: a Mica that starts, shows
102
- * the editor their content, and only fails when they press Save has already
103
- * wasted their work.
104
- */
105
- export function requireRepositoryConfig(config) {
106
- if (config.REPOSITORY === "local")
107
- return;
108
- const needed = ["REPOSITORY_PROJECT", "REPOSITORY_TOKEN"].filter((key) => !config[key]);
109
- if (needed.length > 0) {
110
- throw new ConfigError(`REPOSITORY is "${config.REPOSITORY}", so ${needed.join(" and ")} must be set.\n` +
111
- (config.REPOSITORY === "github"
112
- ? " REPOSITORY_PROJECT is owner/repo, and the token needs contents: write."
113
- : " REPOSITORY_PROJECT is group/project or a numeric id, and the token needs\n" +
114
- " the write_repository scope."));
115
- }
116
- }
117
- /**
118
- * Folds `./.env` into the ambient environment.
119
- *
120
- * `process.loadEnvFile` leaves already-set variables alone, so a container's
121
- * `environment:` block still beats a file that happened to be copied into the
122
- * image.
123
- */
62
+ /** Loads `./.env` into `process.env`. Variables that are already set win. */
124
63
  export function loadEnvFile() {
125
64
  try {
126
65
  process.loadEnvFile();
127
66
  }
128
67
  catch (error) {
129
- // No `.env` is the normal case in production. Anything else — unreadable,
130
- // malformed — is a real misconfiguration, and silently starting with
131
- // default secrets is exactly the failure config exists to prevent.
68
+ // A missing `.env` is normal; an unreadable or malformed one must not start
69
+ // the server with defaults.
132
70
  if (error.code !== "ENOENT") {
133
71
  throw new ConfigError(`Could not read .env: ${error.message}`);
134
72
  }
135
73
  }
136
74
  }
137
- /**
138
- * An unset variable and one set to the empty string mean the same thing.
139
- *
140
- * `.env.example` ships blanks for the operator to fill in, and the docs say to
141
- * copy it verbatim; without this, doing so reads as "the secret is a
142
- * zero-length string" and the server refuses on the documented happy path.
143
- */
75
+ /** Treats a blank variable as unset, so a verbatim copy of `.env.example` with blanks is valid. */
144
76
  export function withoutBlanks(env) {
145
77
  return Object.fromEntries(Object.entries(env).filter(([, value]) => value !== undefined && value.trim() !== ""));
146
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,QAAiB,EAAE,EAAE,CACxC,CAAC;KACE,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;KACjC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,CAAC;KACvD,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvB,+EAA+E;AAC/E,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAyB,EAAY,EAAE,CAC1D,CAAC,KAAK,IAAI,EAAE,CAAC;KACV,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;KAC5B,MAAM,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,GAAG,aAAa,CAAC;CAC/B;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAE/F,kFAAkF;AAClF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAC9E,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAE/E;iFAC6E;IAC7E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;IAErE,8EAA8E;IAC9E,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC;IAE3D;;;;OAIG;IACH,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC;IAE5E;;;;;OAKG;IACH,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IAClE,kEAAkE;IAClE,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;IAC9C,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7C,yDAAyD;IACzD,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,2EAA2E;IAC3E,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzC,oDAAoD;IACpD,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAEhD;;;OAGG;IACH,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC;IAE9B,gBAAgB,EAAE,CAAC,CAAC,MAAM;SACvB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,OAAO,CAAC,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;IAE5B,2EAA2E;IAC3E,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC;IACxB,6EAA6E;IAC7E,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,0DAA0D;IAC1D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAG3C;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAuB,GAAM;IACxD,OAAO;QACL,GAAG,GAAG;QACN,YAAY,EAAE,GAAG,CAAC,QAAQ,KAAK,YAAY;QAC3C,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QAC3C,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;KACtC,CAAC;AACJ,CAAC;AAQD;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAqB;IAC3D,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO;QAAE,OAAO;IAE1C,MAAM,MAAM,GAAI,CAAC,oBAAoB,EAAE,kBAAkB,CAAW,CAAC,MAAM,CACzE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACtB,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,WAAW,CACnB,kBAAkB,MAAM,CAAC,UAAU,SAAS,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB;YAC/E,CAAC,MAAM,CAAC,UAAU,KAAK,QAAQ;gBAC7B,CAAC,CAAC,0EAA0E;gBAC5E,CAAC,CAAC,8EAA8E;oBAC9E,+BAA+B,CAAC,CACvC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC;QACH,OAAO,CAAC,WAAW,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0EAA0E;QAC1E,qEAAqE;QACrE,mEAAmE;QACnE,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,IAAI,WAAW,CAAC,wBAAyB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAsB;IAClD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CACtF,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,oBAAoB,CAAC,KAAiB;IACpD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM;SACzB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;SACzE,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,uCAAuC,OAAO,EAAE,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}