canopycms 0.0.68-int.108 → 0.0.68-int.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api/branch-status.js +2 -3
- package/dist/api/content.d.ts +2 -2
- package/dist/api/content.js +6 -5
- package/dist/api/guards.js +19 -3
- package/dist/api/types.d.ts +3 -2
- package/dist/authorization/protected-branch.d.ts +5 -4
- package/dist/authorization/protected-branch.js +5 -4
- package/dist/branch-health.js +5 -4
- package/dist/branch-metadata-error.d.ts +27 -0
- package/dist/branch-metadata-error.js +23 -0
- package/dist/branch-metadata-file.d.ts +199 -24
- package/dist/branch-metadata-file.js +124 -25
- package/dist/branch-metadata.d.ts +6 -0
- package/dist/branch-metadata.js +10 -12
- package/dist/branch-registry.d.ts +8 -0
- package/dist/branch-registry.js +61 -9
- package/dist/branch-workspace.d.ts +1 -1
- package/dist/branch-workspace.js +1 -1
- package/dist/cli/cli.js +1472 -648
- package/dist/cli/generate-ai-content.js +659 -230
- package/dist/cli/init.js +149 -3
- package/dist/config/helpers.js +2 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schemas/config.d.ts +3 -0
- package/dist/config/schemas/config.js +2 -0
- package/dist/config/schemas/field.d.ts +3 -0
- package/dist/config/schemas/field.js +45 -2
- package/dist/config/types.d.ts +29 -1
- package/dist/config/validation.d.ts +12 -1
- package/dist/config/validation.js +55 -0
- package/dist/editor/CanopyEditor.d.ts +1 -1
- package/dist/editor/CanopyEditor.js +1 -1
- package/dist/editor/Editor.d.ts +3 -1
- package/dist/editor/Editor.js +18 -17
- package/dist/editor/FormRenderer.d.ts +3 -1
- package/dist/editor/FormRenderer.js +11 -3
- package/dist/editor/PreviewFrame.d.ts +11 -3
- package/dist/editor/PreviewFrame.js +9 -6
- package/dist/editor/admin/SystemHealthPanel.js +3 -1
- package/dist/editor/canopy-path.d.ts +9 -6
- package/dist/editor/canopy-path.js +8 -11
- package/dist/editor/components/EditorSidebar.d.ts +4 -5
- package/dist/editor/components/EditorSidebar.js +19 -3
- package/dist/editor/context/SiteMdxAllowContext.d.ts +4 -0
- package/dist/editor/context/SiteMdxAllowContext.js +7 -0
- package/dist/editor/context/index.d.ts +1 -0
- package/dist/editor/context/index.js +1 -0
- package/dist/editor/field-props.d.ts +83 -0
- package/dist/editor/field-props.js +27 -0
- package/dist/editor/fields/MarkdownField.d.ts +3 -0
- package/dist/editor/fields/MarkdownField.js +43 -6
- package/dist/editor/hooks/useCommentSystem.js +3 -2
- package/dist/editor/hooks/usePreviewMarks.d.ts +21 -0
- package/dist/editor/hooks/usePreviewMarks.js +33 -0
- package/dist/editor/preview-bridge.d.ts +10 -5
- package/dist/editor/preview-bridge.js +41 -14
- package/dist/editor/preview-marks.d.ts +15 -0
- package/dist/editor/preview-marks.js +74 -0
- package/dist/entry-schema-registry.d.ts +2 -2
- package/dist/entry-schema-registry.js +5 -3
- package/dist/git-manager.d.ts +11 -2
- package/dist/git-manager.js +29 -13
- package/dist/http/handler.js +15 -2
- package/dist/http/worker-not-ready.d.ts +8 -4
- package/dist/http/worker-not-ready.js +40 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/static/index.d.ts +4 -3
- package/dist/static/index.js +11 -11
- package/dist/task-queue/worker-status.d.ts +26 -0
- package/dist/task-queue/worker-status.js +54 -0
- package/dist/types.d.ts +5 -0
- package/dist/validation/markdown-safety.d.ts +18 -18
- package/dist/validation/markdown-safety.js +150 -179
- package/dist/validation/mdx-allowlist.d.ts +55 -0
- package/dist/validation/mdx-allowlist.js +183 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/cms-worker.d.ts +47 -10
- package/dist/worker/cms-worker.js +179 -34
- package/dist/worker/git-sync.js +2 -0
- package/dist/worker/task-runner.js +3 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -442,7 +442,7 @@ export function PostView({ data }: { data: PostContent }) {
|
|
|
442
442
|
- `data`: The current content data (initial data on first render, then live updates from editor)
|
|
443
443
|
- `isLoading`: Object mirroring your data structure with boolean loading states for reference fields
|
|
444
444
|
- `highlightEnabled`: Boolean indicating if field highlighting is active in the editor
|
|
445
|
-
- `fieldProps`:
|
|
445
|
+
- `fieldProps`: marks the element rendering a field (`data-canopy-path`), with the path typed against your content; `fieldAttrs` and `scopeFieldProps` from `canopycms` thread it through section components (see the root README's Live Preview)
|
|
446
446
|
|
|
447
447
|
**Reference fields and loading states:**
|
|
448
448
|
|
|
@@ -39,9 +39,8 @@ const submitBranchForMergeHandler = async (gc, ctx, req, _params) => {
|
|
|
39
39
|
// (merged) branch could be re-submitted by its creator, re-stamping it
|
|
40
40
|
// 'submitted' and overwriting the merged PR's title/body.
|
|
41
41
|
//
|
|
42
|
-
// Fails closed on a missing status
|
|
43
|
-
//
|
|
44
|
-
// `undefined`) -- same as runWritableBranchGuard's unreadable-status arm.
|
|
42
|
+
// Fails closed on a missing status, same as runWritableBranchGuard's
|
|
43
|
+
// unreadable-status arm.
|
|
45
44
|
const status = branchContext.branch.status;
|
|
46
45
|
if (status !== 'editing') {
|
|
47
46
|
return {
|
package/dist/api/content.d.ts
CHANGED
|
@@ -104,14 +104,14 @@ export declare const CONTENT_ROUTES: {
|
|
|
104
104
|
expectedVersion: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
105
105
|
}, "strip", z.ZodTypeAny, {
|
|
106
106
|
format: "mdx" | "md" | "json" | "yaml";
|
|
107
|
+
data?: Record<string, unknown> | undefined;
|
|
107
108
|
expectedVersion?: number | null | undefined;
|
|
108
109
|
body?: string | undefined;
|
|
109
|
-
data?: Record<string, unknown> | undefined;
|
|
110
110
|
}, {
|
|
111
111
|
format: "mdx" | "md" | "json" | "yaml";
|
|
112
|
+
data?: Record<string, unknown> | undefined;
|
|
112
113
|
expectedVersion?: number | null | undefined;
|
|
113
114
|
body?: string | undefined;
|
|
114
|
-
data?: Record<string, unknown> | undefined;
|
|
115
115
|
}>, ContentWriteResponse>;
|
|
116
116
|
readonly validateReferences: import("./route-builder.js").RouteDefinition<z.ZodObject<{
|
|
117
117
|
branch: z.ZodType<import("../paths/index.js").BranchName, z.ZodTypeDef, import("../paths/index.js").BranchName>;
|
package/dist/api/content.js
CHANGED
|
@@ -132,7 +132,7 @@ function withoutKey(record, key) {
|
|
|
132
132
|
return rest;
|
|
133
133
|
}
|
|
134
134
|
/** The policy's issues in the stored entry, which a save may keep. */
|
|
135
|
-
const storedMarkdownSafetyIssues = async (store, collectionPath, slug, fields) => {
|
|
135
|
+
const storedMarkdownSafetyIssues = async (store, collectionPath, slug, fields, siteAllow) => {
|
|
136
136
|
// A stored file that does not read keeps nothing, so the save's code is refused, not a 500.
|
|
137
137
|
const doc = await store
|
|
138
138
|
.read(collectionPath, slug, { resolveReferences: false })
|
|
@@ -140,7 +140,7 @@ const storedMarkdownSafetyIssues = async (store, collectionPath, slug, fields) =
|
|
|
140
140
|
if (doc === undefined)
|
|
141
141
|
return [];
|
|
142
142
|
const data = 'body' in doc ? mergeBodyIntoData(fields, doc.data, doc.body) : doc.data;
|
|
143
|
-
return findMarkdownSafetyIssues(fields, doc.format, data);
|
|
143
|
+
return findMarkdownSafetyIssues(fields, doc.format, data, siteAllow);
|
|
144
144
|
};
|
|
145
145
|
const writeContentHandler = async (gc, ctx, req, params, body) => {
|
|
146
146
|
const { branchContext } = gc;
|
|
@@ -302,10 +302,11 @@ const writeContentHandler = async (gc, ctx, req, params, body) => {
|
|
|
302
302
|
const fieldErrors = validateEntryData(fields, dataForValidation);
|
|
303
303
|
// Code in markdown or MDX (validation/markdown-safety.ts). A field the stored entry held
|
|
304
304
|
// with code is kept, with a warning, when saved unchanged; any other code is refused.
|
|
305
|
-
const
|
|
305
|
+
const { mdxAllow } = ctx.services.config;
|
|
306
|
+
const unsafe = findMarkdownSafetyIssues(fields, body.format, dataForValidation, mdxAllow);
|
|
306
307
|
if (unsafe.length > 0) {
|
|
307
308
|
const stored = exists
|
|
308
|
-
? await storedMarkdownSafetyIssues(store, schemaItem.logicalPath, slug, fields)
|
|
309
|
+
? await storedMarkdownSafetyIssues(store, schemaItem.logicalPath, slug, fields, mdxAllow)
|
|
309
310
|
: [];
|
|
310
311
|
const { refused, kept } = splitByStored(unsafe, stored);
|
|
311
312
|
fieldErrors.push(...refused);
|
|
@@ -313,7 +314,7 @@ const writeContentHandler = async (gc, ctx, req, params, body) => {
|
|
|
313
314
|
keptWarnings.push({
|
|
314
315
|
level: 'warning',
|
|
315
316
|
fieldPath: e.fieldPath,
|
|
316
|
-
message: `holds
|
|
317
|
+
message: `holds content this field refuses, kept because the saved entry already had it: ${e.message}. Ask a developer to move it into a component, or to allow it.`,
|
|
317
318
|
});
|
|
318
319
|
}
|
|
319
320
|
}
|
package/dist/api/guards.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* error response (404/403/500) to short-circuit, or produce a guard context (e.g. branch context
|
|
4
4
|
* with schema) for the handler. See api/AGENTS.md for the full guard reference.
|
|
5
5
|
*/
|
|
6
|
+
import { BRANCH_METADATA_CORRUPT_MESSAGE, BranchMetadataCorruptError, } from '../branch-metadata-error.js';
|
|
7
|
+
import { canopyLogError } from '../utils/logger.js';
|
|
6
8
|
import { isAdmin, isReviewer, isPrivileged } from '../authorization/helpers.js';
|
|
7
9
|
import { getBranchProtection, getBranchWriteProtection } from '../authorization/protected-branch.js';
|
|
8
10
|
function extractBranchName(params) {
|
|
@@ -117,8 +119,8 @@ const runWritableBranchGuard = async (ctx, _req, params, accumulated) => {
|
|
|
117
119
|
const branchStatus = context.branch.status;
|
|
118
120
|
const error = branchStatus === 'submitted'
|
|
119
121
|
? `Branch "${context.branch.name}" is submitted for review and cannot be edited. Withdraw it or request changes to resume editing.`
|
|
120
|
-
: //
|
|
121
|
-
//
|
|
122
|
+
: // A branch.json without a status is refused as corrupt before this
|
|
123
|
+
// point; a context built elsewhere can still lack one. Refuse rather than guess.
|
|
122
124
|
branchStatus === undefined
|
|
123
125
|
? `Branch "${context.branch.name}" has no readable workflow status and cannot be edited until its metadata is repaired.`
|
|
124
126
|
: `Branch "${context.branch.name}" is ${branchStatus} and cannot be edited.`;
|
|
@@ -196,7 +198,21 @@ export async function executeGuards(guards, ctx, req, params) {
|
|
|
196
198
|
const accumulated = {};
|
|
197
199
|
for (const guardId of guards) {
|
|
198
200
|
const runner = GUARD_RUNNERS[guardId];
|
|
199
|
-
|
|
201
|
+
let result;
|
|
202
|
+
try {
|
|
203
|
+
result = await runner(ctx, req, params, accumulated);
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
// Every branch guard resolves the branch from its branch.json, and a
|
|
207
|
+
// corrupt one has no status or ACL anyone can trust: deny, whatever the guard.
|
|
208
|
+
if (!(err instanceof BranchMetadataCorruptError))
|
|
209
|
+
throw err;
|
|
210
|
+
canopyLogError(`CanopyCMS: ${err.message}`);
|
|
211
|
+
return {
|
|
212
|
+
ok: false,
|
|
213
|
+
response: { ok: false, status: 500, error: BRANCH_METADATA_CORRUPT_MESSAGE },
|
|
214
|
+
};
|
|
215
|
+
}
|
|
200
216
|
if (!result.ok) {
|
|
201
217
|
return { ok: false, response: result.response };
|
|
202
218
|
}
|
package/dist/api/types.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export interface ApiResponse<TData = unknown> {
|
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* `SCHEMA_UNAVAILABLE`: the entry's type names an entry schema the running code lacks (a 503,
|
|
56
|
-
* see `SchemaUnavailableError`).
|
|
56
|
+
* see `SchemaUnavailableError`). `WORKER_FAILED`: the CMS worker recorded that its latest start
|
|
57
|
+
* failed, so a retry will not help until an admin fixes it (a 503 with no `Retry-After`).
|
|
57
58
|
*/
|
|
58
|
-
export type ApiErrorCode = 'SCHEMA_UNAVAILABLE';
|
|
59
|
+
export type ApiErrorCode = 'SCHEMA_UNAVAILABLE' | 'WORKER_FAILED';
|
|
@@ -76,9 +76,10 @@ export declare function getBranchProtection(config: Pick<CanopyConfig, 'mode' |
|
|
|
76
76
|
* branches-list wire flag and the editor.
|
|
77
77
|
*
|
|
78
78
|
* `status` is REQUIRED and admits `undefined` because a missing status must
|
|
79
|
-
* FAIL CLOSED
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
79
|
+
* FAIL CLOSED. A branch.json without one never gets this far (its read
|
|
80
|
+
* boundary, branch-metadata-file.ts, rejects it as corrupt), but a status can
|
|
81
|
+
* still arrive unset from a context built anywhere else. Required, not
|
|
82
|
+
* optional, so "argument omitted" and "status unknown" stay distinguishable --
|
|
83
|
+
* the safe answer differs.
|
|
83
84
|
*/
|
|
84
85
|
export declare function getBranchWriteProtection(config: Pick<CanopyConfig, 'mode' | 'defaultBaseBranch'>, branchName: string, recordedBaseBranch: string | undefined, status: BranchStatus | undefined): BranchWriteProtection;
|
|
@@ -47,10 +47,11 @@ export function getBranchProtection(config, branchName, recordedBaseBranch) {
|
|
|
47
47
|
* branches-list wire flag and the editor.
|
|
48
48
|
*
|
|
49
49
|
* `status` is REQUIRED and admits `undefined` because a missing status must
|
|
50
|
-
* FAIL CLOSED
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
50
|
+
* FAIL CLOSED. A branch.json without one never gets this far (its read
|
|
51
|
+
* boundary, branch-metadata-file.ts, rejects it as corrupt), but a status can
|
|
52
|
+
* still arrive unset from a context built anywhere else. Required, not
|
|
53
|
+
* optional, so "argument omitted" and "status unknown" stay distinguishable --
|
|
54
|
+
* the safe answer differs.
|
|
54
55
|
*/
|
|
55
56
|
export function getBranchWriteProtection(config, branchName, recordedBaseBranch, status) {
|
|
56
57
|
const protection = getBranchProtection(config, branchName, recordedBaseBranch);
|
package/dist/branch-health.js
CHANGED
|
@@ -100,13 +100,14 @@ export async function scanBranchHealth(baseRoot, opts) {
|
|
|
100
100
|
}
|
|
101
101
|
if (loadErr) {
|
|
102
102
|
// Every loadOnly failure lands here — BranchMetadataCorruptError for bad
|
|
103
|
-
// JSON, EACCES/EISDIR and the rest for
|
|
104
|
-
// them need admin attention and none may
|
|
103
|
+
// JSON or a failed schema check, EACCES/EISDIR and the rest for
|
|
104
|
+
// everything else — since all of them need admin attention and none may
|
|
105
|
+
// throw out of the scan.
|
|
105
106
|
//
|
|
106
107
|
// [REDACT] parseError reaches the browser through the admin branch-health
|
|
107
108
|
// endpoint, so it must never carry the absolute workspace path.
|
|
108
|
-
// BranchMetadataCorruptError's `parseCause` is the path-free
|
|
109
|
-
//
|
|
109
|
+
// BranchMetadataCorruptError's `parseCause` is the path-free cause
|
|
110
|
+
// for exactly this, while its `message` embeds branchRoot and is
|
|
110
111
|
// for server logs only. Node errors embed the path in `message` too, so
|
|
111
112
|
// only their `code` is safe to surface.
|
|
112
113
|
const parseError = loadErr instanceof BranchMetadataCorruptError
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The corrupt-`branch.json` error and what the API says about it. Free of
|
|
3
|
+
* node built-ins, so the API guards, which the client bundle reaches, can
|
|
4
|
+
* recognize the error without pulling in the reader (branch-metadata-file.ts).
|
|
5
|
+
*/
|
|
6
|
+
/** What the editor API answers for a branch whose branch.json is corrupt. */
|
|
7
|
+
export declare const BRANCH_METADATA_CORRUPT_MESSAGE = "This branch's metadata file is damaged, so the branch can't be opened or edited. An admin can repair it in System health.";
|
|
8
|
+
/**
|
|
9
|
+
* branch.json exists but is not valid JSON, or fails the schema in branch-metadata-file.ts.
|
|
10
|
+
* Distinguished from provisioning and IO failures so callers can degrade instead
|
|
11
|
+
* of failing hard: the registry scan quarantines the branch, the API answers
|
|
12
|
+
* {@link BRANCH_METADATA_CORRUPT_MESSAGE}, and the request handler keeps serving
|
|
13
|
+
* (with empty internal groups) when the BASE branch is the corrupt one —
|
|
14
|
+
* otherwise the admin recovery surface is unreachable exactly when it is needed.
|
|
15
|
+
*/
|
|
16
|
+
export declare class BranchMetadataCorruptError extends Error {
|
|
17
|
+
readonly branchRoot: string;
|
|
18
|
+
/**
|
|
19
|
+
* [REDACT] What is wrong with the file, with no embedded path: the JSON.parse
|
|
20
|
+
* failure, or the fields that failed the schema.
|
|
21
|
+
* `message` above keeps the `branchRoot`-qualified text for server logs;
|
|
22
|
+
* `parseCause` is the one callers surface to clients (branch-health.ts's
|
|
23
|
+
* `parseError`), so no scan leaks the absolute workspace path.
|
|
24
|
+
*/
|
|
25
|
+
readonly parseCause: string;
|
|
26
|
+
constructor(branchRoot: string, cause: string);
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The corrupt-`branch.json` error and what the API says about it. Free of
|
|
3
|
+
* node built-ins, so the API guards, which the client bundle reaches, can
|
|
4
|
+
* recognize the error without pulling in the reader (branch-metadata-file.ts).
|
|
5
|
+
*/
|
|
6
|
+
/** What the editor API answers for a branch whose branch.json is corrupt. */
|
|
7
|
+
export const BRANCH_METADATA_CORRUPT_MESSAGE = "This branch's metadata file is damaged, so the branch can't be opened or edited. An admin can repair it in System health.";
|
|
8
|
+
/**
|
|
9
|
+
* branch.json exists but is not valid JSON, or fails the schema in branch-metadata-file.ts.
|
|
10
|
+
* Distinguished from provisioning and IO failures so callers can degrade instead
|
|
11
|
+
* of failing hard: the registry scan quarantines the branch, the API answers
|
|
12
|
+
* {@link BRANCH_METADATA_CORRUPT_MESSAGE}, and the request handler keeps serving
|
|
13
|
+
* (with empty internal groups) when the BASE branch is the corrupt one —
|
|
14
|
+
* otherwise the admin recovery surface is unreachable exactly when it is needed.
|
|
15
|
+
*/
|
|
16
|
+
export class BranchMetadataCorruptError extends Error {
|
|
17
|
+
constructor(branchRoot, cause) {
|
|
18
|
+
super(`Corrupt branch metadata in '${branchRoot}': ${cause}`);
|
|
19
|
+
this.name = 'BranchMetadataCorruptError';
|
|
20
|
+
this.branchRoot = branchRoot;
|
|
21
|
+
this.parseCause = cause;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Reading `branch.json` — the file format, nothing else.
|
|
3
3
|
*
|
|
4
|
-
* Deliberately a LEAF, importing only node built-ins,
|
|
5
|
-
*
|
|
4
|
+
* Deliberately a LEAF, importing only node built-ins, zod, types, and the error
|
|
5
|
+
* modules. That is what keeps `branch-registry.ts` (which reads every branch's
|
|
6
6
|
* `branch.json`) out of a runtime import cycle with `branch-metadata.ts` (which
|
|
7
7
|
* writes it and then invalidates the registry cache).
|
|
8
8
|
*/
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import type { ContentId } from './paths/types.js';
|
|
9
11
|
import type { BranchMetadata } from './types.js';
|
|
12
|
+
import { BranchMetadataCorruptError } from './branch-metadata-error.js';
|
|
13
|
+
export { BranchMetadataCorruptError };
|
|
10
14
|
export declare const BRANCH_META_DIR = ".canopy-meta";
|
|
11
15
|
export declare const BRANCH_META_FILE = "branch.json";
|
|
12
16
|
export interface BranchMetadataFile {
|
|
@@ -15,28 +19,199 @@ export interface BranchMetadataFile {
|
|
|
15
19
|
writeId?: string;
|
|
16
20
|
branch: BranchMetadata;
|
|
17
21
|
}
|
|
22
|
+
/** The `branch` object, also embedded in the registry snapshot (branch-registry.ts). */
|
|
23
|
+
export declare const branchMetadataSchema: z.ZodObject<{
|
|
24
|
+
name: z.ZodString;
|
|
25
|
+
title: z.ZodOptional<z.ZodString>;
|
|
26
|
+
description: z.ZodOptional<z.ZodString>;
|
|
27
|
+
status: z.ZodNativeEnum<{
|
|
28
|
+
editing: "editing";
|
|
29
|
+
submitted: "submitted";
|
|
30
|
+
approved: "approved";
|
|
31
|
+
archived: "archived";
|
|
32
|
+
}>;
|
|
33
|
+
access: z.ZodObject<{
|
|
34
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
35
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
36
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
37
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
38
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
39
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
40
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
42
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
43
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
44
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
45
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
46
|
+
createdBy: z.ZodDefault<z.ZodString>;
|
|
47
|
+
createdAt: z.ZodDefault<z.ZodString>;
|
|
48
|
+
updatedAt: z.ZodDefault<z.ZodString>;
|
|
49
|
+
baseBranch: z.ZodOptional<z.ZodString>;
|
|
50
|
+
pullRequestUrl: z.ZodOptional<z.ZodString>;
|
|
51
|
+
pullRequestNumber: z.ZodOptional<z.ZodNumber>;
|
|
52
|
+
submittedAt: z.ZodOptional<z.ZodString>;
|
|
53
|
+
pushedToGitHubAt: z.ZodOptional<z.ZodString>;
|
|
54
|
+
syncStatus: z.ZodOptional<z.ZodNativeEnum<{
|
|
55
|
+
synced: "synced";
|
|
56
|
+
"pending-sync": "pending-sync";
|
|
57
|
+
"sync-failed": "sync-failed";
|
|
58
|
+
}>>;
|
|
59
|
+
conflictStatus: z.ZodOptional<z.ZodNativeEnum<{
|
|
60
|
+
clean: "clean";
|
|
61
|
+
"conflicts-detected": "conflicts-detected";
|
|
62
|
+
}>>;
|
|
63
|
+
conflictFiles: z.ZodOptional<z.ZodArray<z.ZodType<ContentId, z.ZodTypeDef, ContentId>, "many">>;
|
|
64
|
+
pullRequestState: z.ZodOptional<z.ZodNativeEnum<{
|
|
65
|
+
open: "open";
|
|
66
|
+
closed: "closed";
|
|
67
|
+
merged: "merged";
|
|
68
|
+
}>>;
|
|
69
|
+
mergedAt: z.ZodOptional<z.ZodString>;
|
|
70
|
+
rebaseFailure: z.ZodOptional<z.ZodObject<{
|
|
71
|
+
message: z.ZodString;
|
|
72
|
+
firstAt: z.ZodString;
|
|
73
|
+
lastAt: z.ZodString;
|
|
74
|
+
}, "strip", z.ZodTypeAny, {
|
|
75
|
+
message: string;
|
|
76
|
+
firstAt: string;
|
|
77
|
+
lastAt: string;
|
|
78
|
+
}, {
|
|
79
|
+
message: string;
|
|
80
|
+
firstAt: string;
|
|
81
|
+
lastAt: string;
|
|
82
|
+
}>>;
|
|
83
|
+
historyRewrittenFrom: z.ZodOptional<z.ZodString>;
|
|
84
|
+
syncFailureReason: z.ZodOptional<z.ZodString>;
|
|
85
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
86
|
+
name: z.ZodString;
|
|
87
|
+
title: z.ZodOptional<z.ZodString>;
|
|
88
|
+
description: z.ZodOptional<z.ZodString>;
|
|
89
|
+
status: z.ZodNativeEnum<{
|
|
90
|
+
editing: "editing";
|
|
91
|
+
submitted: "submitted";
|
|
92
|
+
approved: "approved";
|
|
93
|
+
archived: "archived";
|
|
94
|
+
}>;
|
|
95
|
+
access: z.ZodObject<{
|
|
96
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
97
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
98
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
99
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
100
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
101
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
102
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
103
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
104
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
105
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
106
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
107
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
108
|
+
createdBy: z.ZodDefault<z.ZodString>;
|
|
109
|
+
createdAt: z.ZodDefault<z.ZodString>;
|
|
110
|
+
updatedAt: z.ZodDefault<z.ZodString>;
|
|
111
|
+
baseBranch: z.ZodOptional<z.ZodString>;
|
|
112
|
+
pullRequestUrl: z.ZodOptional<z.ZodString>;
|
|
113
|
+
pullRequestNumber: z.ZodOptional<z.ZodNumber>;
|
|
114
|
+
submittedAt: z.ZodOptional<z.ZodString>;
|
|
115
|
+
pushedToGitHubAt: z.ZodOptional<z.ZodString>;
|
|
116
|
+
syncStatus: z.ZodOptional<z.ZodNativeEnum<{
|
|
117
|
+
synced: "synced";
|
|
118
|
+
"pending-sync": "pending-sync";
|
|
119
|
+
"sync-failed": "sync-failed";
|
|
120
|
+
}>>;
|
|
121
|
+
conflictStatus: z.ZodOptional<z.ZodNativeEnum<{
|
|
122
|
+
clean: "clean";
|
|
123
|
+
"conflicts-detected": "conflicts-detected";
|
|
124
|
+
}>>;
|
|
125
|
+
conflictFiles: z.ZodOptional<z.ZodArray<z.ZodType<ContentId, z.ZodTypeDef, ContentId>, "many">>;
|
|
126
|
+
pullRequestState: z.ZodOptional<z.ZodNativeEnum<{
|
|
127
|
+
open: "open";
|
|
128
|
+
closed: "closed";
|
|
129
|
+
merged: "merged";
|
|
130
|
+
}>>;
|
|
131
|
+
mergedAt: z.ZodOptional<z.ZodString>;
|
|
132
|
+
rebaseFailure: z.ZodOptional<z.ZodObject<{
|
|
133
|
+
message: z.ZodString;
|
|
134
|
+
firstAt: z.ZodString;
|
|
135
|
+
lastAt: z.ZodString;
|
|
136
|
+
}, "strip", z.ZodTypeAny, {
|
|
137
|
+
message: string;
|
|
138
|
+
firstAt: string;
|
|
139
|
+
lastAt: string;
|
|
140
|
+
}, {
|
|
141
|
+
message: string;
|
|
142
|
+
firstAt: string;
|
|
143
|
+
lastAt: string;
|
|
144
|
+
}>>;
|
|
145
|
+
historyRewrittenFrom: z.ZodOptional<z.ZodString>;
|
|
146
|
+
syncFailureReason: z.ZodOptional<z.ZodString>;
|
|
147
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
148
|
+
name: z.ZodString;
|
|
149
|
+
title: z.ZodOptional<z.ZodString>;
|
|
150
|
+
description: z.ZodOptional<z.ZodString>;
|
|
151
|
+
status: z.ZodNativeEnum<{
|
|
152
|
+
editing: "editing";
|
|
153
|
+
submitted: "submitted";
|
|
154
|
+
approved: "approved";
|
|
155
|
+
archived: "archived";
|
|
156
|
+
}>;
|
|
157
|
+
access: z.ZodObject<{
|
|
158
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
159
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
160
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
161
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
162
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
163
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
164
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
165
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
166
|
+
allowedUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
167
|
+
allowedGroups: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
168
|
+
managerOrAdminAllowed: z.ZodOptional<z.ZodBoolean>;
|
|
169
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
170
|
+
createdBy: z.ZodDefault<z.ZodString>;
|
|
171
|
+
createdAt: z.ZodDefault<z.ZodString>;
|
|
172
|
+
updatedAt: z.ZodDefault<z.ZodString>;
|
|
173
|
+
baseBranch: z.ZodOptional<z.ZodString>;
|
|
174
|
+
pullRequestUrl: z.ZodOptional<z.ZodString>;
|
|
175
|
+
pullRequestNumber: z.ZodOptional<z.ZodNumber>;
|
|
176
|
+
submittedAt: z.ZodOptional<z.ZodString>;
|
|
177
|
+
pushedToGitHubAt: z.ZodOptional<z.ZodString>;
|
|
178
|
+
syncStatus: z.ZodOptional<z.ZodNativeEnum<{
|
|
179
|
+
synced: "synced";
|
|
180
|
+
"pending-sync": "pending-sync";
|
|
181
|
+
"sync-failed": "sync-failed";
|
|
182
|
+
}>>;
|
|
183
|
+
conflictStatus: z.ZodOptional<z.ZodNativeEnum<{
|
|
184
|
+
clean: "clean";
|
|
185
|
+
"conflicts-detected": "conflicts-detected";
|
|
186
|
+
}>>;
|
|
187
|
+
conflictFiles: z.ZodOptional<z.ZodArray<z.ZodType<ContentId, z.ZodTypeDef, ContentId>, "many">>;
|
|
188
|
+
pullRequestState: z.ZodOptional<z.ZodNativeEnum<{
|
|
189
|
+
open: "open";
|
|
190
|
+
closed: "closed";
|
|
191
|
+
merged: "merged";
|
|
192
|
+
}>>;
|
|
193
|
+
mergedAt: z.ZodOptional<z.ZodString>;
|
|
194
|
+
rebaseFailure: z.ZodOptional<z.ZodObject<{
|
|
195
|
+
message: z.ZodString;
|
|
196
|
+
firstAt: z.ZodString;
|
|
197
|
+
lastAt: z.ZodString;
|
|
198
|
+
}, "strip", z.ZodTypeAny, {
|
|
199
|
+
message: string;
|
|
200
|
+
firstAt: string;
|
|
201
|
+
lastAt: string;
|
|
202
|
+
}, {
|
|
203
|
+
message: string;
|
|
204
|
+
firstAt: string;
|
|
205
|
+
lastAt: string;
|
|
206
|
+
}>>;
|
|
207
|
+
historyRewrittenFrom: z.ZodOptional<z.ZodString>;
|
|
208
|
+
syncFailureReason: z.ZodOptional<z.ZodString>;
|
|
209
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
18
210
|
/**
|
|
19
|
-
* branch.json
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*/
|
|
25
|
-
export declare class BranchMetadataCorruptError extends Error {
|
|
26
|
-
readonly branchRoot: string;
|
|
27
|
-
/**
|
|
28
|
-
* [REDACT] The raw JSON.parse failure message, with no embedded path.
|
|
29
|
-
* `message` above keeps the `branchRoot`-qualified text for server logs;
|
|
30
|
-
* `parseCause` is the one callers surface to clients (branch-health.ts's
|
|
31
|
-
* `parseError`), so no scan leaks the absolute workspace path.
|
|
32
|
-
*/
|
|
33
|
-
readonly parseCause: string;
|
|
34
|
-
constructor(branchRoot: string, cause: string);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Read and parse `branch.json`, with no locking, no OCC and no side effects.
|
|
38
|
-
* Callers distinguish three outcomes: `null` when the file does not exist (an
|
|
39
|
-
* un-provisioned or non-branch directory), `BranchMetadataCorruptError` on
|
|
40
|
-
* malformed JSON, and every other IO failure rethrown unchanged.
|
|
211
|
+
* Read, parse and validate `branch.json`, with no locking, no OCC and no side
|
|
212
|
+
* effects. Callers distinguish three outcomes: `null` when the file does not
|
|
213
|
+
* exist (an un-provisioned or non-branch directory),
|
|
214
|
+
* `BranchMetadataCorruptError` on malformed JSON or a failed schema check, and
|
|
215
|
+
* every other IO failure rethrown unchanged.
|
|
41
216
|
*/
|
|
42
217
|
export declare function readBranchMetadataFile(branchRoot: string): Promise<BranchMetadataFile | null>;
|