canopycms 0.0.68-int.113 → 0.0.68-int.114
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/generate.d.ts +4 -4
- package/dist/ai/generate.js +75 -14
- package/dist/ai/types.d.ts +12 -0
- package/dist/api/branch.js +13 -13
- package/dist/auth/cache.d.ts +1 -1
- package/dist/auth/cache.js +1 -1
- package/dist/auth/file-based-auth-cache.d.ts +8 -0
- package/dist/auth/file-based-auth-cache.js +11 -0
- package/dist/authorization/branch.d.ts +1 -1
- package/dist/authorization/branch.js +2 -1
- package/dist/cli/cli.js +160 -28
- package/dist/cli/generate-ai-content.js +156 -24
- package/dist/content-reader.js +2 -1
- package/dist/context.js +2 -1
- package/dist/editor/BranchManager.js +13 -17
- package/dist/editor/CommentsPanel.js +7 -6
- package/dist/editor/Editor.js +152 -30
- package/dist/editor/EditorAuthGate.js +2 -2
- package/dist/editor/EditorPanes.d.ts +10 -0
- package/dist/editor/EditorPanes.js +32 -8
- package/dist/editor/FormRenderer.d.ts +10 -0
- package/dist/editor/FormRenderer.js +92 -73
- package/dist/editor/PreviewFrame.d.ts +3 -1
- package/dist/editor/PreviewFrame.js +72 -9
- package/dist/editor/admin/SystemHealthPanel.js +27 -24
- package/dist/editor/branch-status.d.ts +16 -0
- package/dist/editor/branch-status.js +28 -0
- package/dist/editor/comments/BranchComments.js +1 -1
- package/dist/editor/comments/EntryComments.d.ts +3 -0
- package/dist/editor/comments/EntryComments.js +3 -3
- package/dist/editor/comments/FieldWrapper.d.ts +3 -0
- package/dist/editor/comments/FieldWrapper.js +2 -2
- package/dist/editor/comments/InlineCommentThread.js +2 -1
- package/dist/editor/comments/ThreadCarousel.js +2 -2
- package/dist/editor/components/ConfirmDeleteModal.js +1 -1
- package/dist/editor/components/EditorCrashScreen.js +1 -1
- package/dist/editor/components/EditorHeader.d.ts +2 -0
- package/dist/editor/components/EditorHeader.js +15 -36
- package/dist/editor/components/EditorSidebar.d.ts +5 -6
- package/dist/editor/components/EditorSidebar.js +2 -2
- package/dist/editor/components/EntryCreateModal.js +1 -1
- package/dist/editor/components/NoEditPermissionNotice.d.ts +3 -2
- package/dist/editor/components/NoEditPermissionNotice.js +3 -2
- package/dist/editor/components/ReadOnlyDraftNotice.d.ts +11 -0
- package/dist/editor/components/ReadOnlyDraftNotice.js +12 -0
- package/dist/editor/components/RenameEntryModal.js +1 -1
- package/dist/editor/components/StagedChangesDrawer.js +3 -3
- package/dist/editor/components/UndoToastMessage.d.ts +14 -0
- package/dist/editor/components/UndoToastMessage.js +9 -0
- package/dist/editor/components/UserBadge.js +9 -5
- package/dist/editor/copy.d.ts +14 -0
- package/dist/editor/copy.js +14 -0
- package/dist/editor/fields/BlockField.d.ts +5 -0
- package/dist/editor/fields/BlockField.js +38 -32
- package/dist/editor/fields/CodeField.d.ts +2 -0
- package/dist/editor/fields/CodeField.js +5 -2
- package/dist/editor/fields/DateTimeField.d.ts +2 -0
- package/dist/editor/fields/DateTimeField.js +5 -2
- package/dist/editor/fields/FieldCrashFallback.d.ts +3 -3
- package/dist/editor/fields/FieldCrashFallback.js +4 -4
- package/dist/editor/fields/FieldLabel.d.ts +24 -0
- package/dist/editor/fields/FieldLabel.js +9 -0
- package/dist/editor/fields/ImageField.d.ts +4 -0
- package/dist/editor/fields/ImageField.js +17 -8
- package/dist/editor/fields/InlineGroupField.js +4 -3
- package/dist/editor/fields/MarkdownField.d.ts +6 -0
- package/dist/editor/fields/MarkdownField.js +41 -11
- package/dist/editor/fields/MdxImageDialog.js +1 -1
- package/dist/editor/fields/NumberField.d.ts +2 -0
- package/dist/editor/fields/NumberField.js +4 -2
- package/dist/editor/fields/NumberListField.d.ts +2 -0
- package/dist/editor/fields/NumberListField.js +4 -2
- package/dist/editor/fields/ObjectField.d.ts +1 -0
- package/dist/editor/fields/ObjectField.js +5 -4
- package/dist/editor/fields/ReferenceField.d.ts +2 -0
- package/dist/editor/fields/ReferenceField.js +9 -3
- package/dist/editor/fields/SelectField.d.ts +2 -0
- package/dist/editor/fields/SelectField.js +8 -2
- package/dist/editor/fields/StringListField.d.ts +2 -0
- package/dist/editor/fields/StringListField.js +5 -2
- package/dist/editor/fields/TextField.d.ts +2 -0
- package/dist/editor/fields/TextField.js +5 -2
- package/dist/editor/fields/ToggleField.d.ts +2 -0
- package/dist/editor/fields/ToggleField.js +6 -3
- package/dist/editor/fields/entry-link/InsertEntryLink.js +1 -1
- package/dist/editor/fields/list-item-keys.d.ts +8 -0
- package/dist/editor/fields/list-item-keys.js +50 -0
- package/dist/editor/group-manager/GroupCard.js +1 -1
- package/dist/editor/group-manager/GroupForm.js +1 -1
- package/dist/editor/group-manager/InternalGroupsTab.js +1 -1
- package/dist/editor/group-manager/MemberList.js +1 -1
- package/dist/editor/group-manager/hooks/useGroupState.d.ts +1 -0
- package/dist/editor/group-manager/hooks/useGroupState.js +1 -1
- package/dist/editor/group-manager/index.js +26 -2
- package/dist/editor/hooks/useBranchActions.js +2 -2
- package/dist/editor/hooks/useBranchManager.js +36 -22
- package/dist/editor/hooks/useDraftManager.d.ts +8 -0
- package/dist/editor/hooks/useDraftManager.js +27 -5
- package/dist/editor/hooks/useEditorLayout.d.ts +45 -3
- package/dist/editor/hooks/useEditorLayout.js +97 -7
- package/dist/editor/hooks/useUserMetadata.js +12 -1
- package/dist/editor/media/AssetCard.js +1 -1
- package/dist/editor/media/CropStep.js +6 -1
- package/dist/editor/media/MediaLibraryBody.js +3 -3
- package/dist/editor/permission-manager/PermissionEditor.js +3 -3
- package/dist/editor/permission-manager/index.js +1 -1
- package/dist/editor/preview-bridge.js +2 -2
- package/dist/editor/schema-editor/CollectionEditor.js +1 -1
- package/dist/editor/schema-editor/EntryTypeEditor.js +1 -1
- package/dist/editor/theme.d.ts +1 -1
- package/dist/editor/theme.js +11 -11
- package/dist/editor/undo-removal.d.ts +44 -0
- package/dist/editor/undo-removal.js +129 -0
- package/dist/editor/user-display.d.ts +4 -0
- package/dist/editor/user-display.js +5 -0
- package/dist/editor/utils/confirm-modal.d.ts +8 -0
- package/dist/editor/utils/confirm-modal.js +12 -0
- package/dist/entry-link-resolver.d.ts +11 -1
- package/dist/entry-link-resolver.js +65 -5
- package/dist/git-manager.d.ts +6 -6
- package/dist/git-manager.js +16 -15
- package/dist/github-service.d.ts +25 -1
- package/dist/github-service.js +65 -6
- package/dist/http/handler.js +2 -1
- package/dist/static/seo.d.ts +5 -5
- package/dist/static/seo.js +5 -5
- package/dist/system-users.d.ts +12 -0
- package/dist/system-users.js +12 -0
- package/dist/types.d.ts +9 -1
- package/dist/utils/error.js +4 -3
- package/dist/utils/escape-text.d.ts +7 -0
- package/dist/utils/escape-text.js +27 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/branch-policy.d.ts +124 -0
- package/dist/worker/branch-policy.js +243 -0
- package/dist/worker/bundle-header.d.ts +117 -0
- package/dist/worker/bundle-header.js +253 -0
- package/dist/worker/cms-worker.d.ts +68 -17
- package/dist/worker/cms-worker.js +116 -33
- package/dist/worker/gateway-egress.d.ts +43 -0
- package/dist/worker/gateway-egress.js +209 -0
- package/dist/worker/gateway-instance.d.ts +42 -0
- package/dist/worker/gateway-instance.js +129 -0
- package/dist/worker/git-process.d.ts +81 -0
- package/dist/worker/git-process.js +234 -0
- package/dist/worker/git-sync.d.ts +8 -7
- package/dist/worker/git-sync.js +184 -74
- package/dist/worker/github-gateway-http.d.ts +62 -0
- package/dist/worker/github-gateway-http.js +977 -0
- package/dist/worker/github-gateway-wire.d.ts +589 -0
- package/dist/worker/github-gateway-wire.js +484 -0
- package/dist/worker/github-gateway.d.ts +152 -58
- package/dist/worker/github-gateway.js +485 -129
- package/dist/worker/github-mirror-upkeep.d.ts +75 -0
- package/dist/worker/github-mirror-upkeep.js +266 -0
- package/dist/worker/github-mirror.d.ts +271 -71
- package/dist/worker/github-mirror.js +755 -238
- package/dist/worker/github-transfer.d.ts +56 -0
- package/dist/worker/github-transfer.js +444 -0
- package/dist/worker/self-checks.d.ts +107 -0
- package/dist/worker/self-checks.js +358 -0
- package/dist/worker/shared-repo-git.d.ts +20 -7
- package/dist/worker/shared-repo-git.js +51 -22
- package/dist/worker/stale-mirror.d.ts +82 -0
- package/dist/worker/stale-mirror.js +130 -0
- package/dist/worker/task-runner.d.ts +2 -0
- package/dist/worker/task-runner.js +49 -20
- package/dist/worker/worker-context.d.ts +6 -0
- package/package.json +1 -1
package/dist/cli/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ function redactCredentials(message) {
|
|
|
23
23
|
let result = message;
|
|
24
24
|
result = result.replace(/(:\/\/)[^/\s@]+@/g, "$1***@");
|
|
25
25
|
result = result.replace(/(\bauthorization\s*:\s*(?:basic|bearer|token)\s+)[A-Za-z0-9+/=._~-]+/gi, "$1***");
|
|
26
|
-
result = result.replace(/eC1hY2Nlc3MtdG9rZW46[A-Za-z0-9+/]
|
|
26
|
+
result = result.replace(/eC1hY2Nlc3MtdG9rZW46(?:[A-Za-z0-9+/]|%2[BbFf])*(?:=|%3[Dd]){0,2}/g, "***");
|
|
27
27
|
result = result.replace(/\b(?:gh[pousr]|github_pat)_[A-Za-z0-9_]{8,}/g, "***");
|
|
28
28
|
result = result.replace(/\b(Bearer\s+)[A-Za-z0-9._~+/=-]{8,}/g, "$1***");
|
|
29
29
|
result = result.replace(/-----BEGIN [A-Z]{0,9} ?PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z]{0,9} ?PRIVATE KEY-----|$)/g, "<private-key>");
|
|
@@ -2523,8 +2523,8 @@ async function githubRequest(apiPath, init2 = {}) {
|
|
|
2523
2523
|
} catch {
|
|
2524
2524
|
body = null;
|
|
2525
2525
|
}
|
|
2526
|
-
const
|
|
2527
|
-
const message = response.ok ? "" : redactCredentials(typeof
|
|
2526
|
+
const asRecord3 = body;
|
|
2527
|
+
const message = response.ok ? "" : redactCredentials(typeof asRecord3?.message === "string" ? asRecord3.message : text3.slice(0, 200));
|
|
2528
2528
|
return { ok: response.ok, status: response.status, body, message };
|
|
2529
2529
|
}
|
|
2530
2530
|
function spawnKeyDestination(command, args) {
|
|
@@ -3236,7 +3236,7 @@ function redactCredentials2(message) {
|
|
|
3236
3236
|
let result = message;
|
|
3237
3237
|
result = result.replace(/(:\/\/)[^/\s@]+@/g, "$1***@");
|
|
3238
3238
|
result = result.replace(/(\bauthorization\s*:\s*(?:basic|bearer|token)\s+)[A-Za-z0-9+/=._~-]+/gi, "$1***");
|
|
3239
|
-
result = result.replace(/eC1hY2Nlc3MtdG9rZW46[A-Za-z0-9+/]
|
|
3239
|
+
result = result.replace(/eC1hY2Nlc3MtdG9rZW46(?:[A-Za-z0-9+/]|%2[BbFf])*(?:=|%3[Dd]){0,2}/g, "***");
|
|
3240
3240
|
result = result.replace(/\b(?:gh[pousr]|github_pat)_[A-Za-z0-9_]{8,}/g, "***");
|
|
3241
3241
|
result = result.replace(/\b(Bearer\s+)[A-Za-z0-9._~+/=-]{8,}/g, "$1***");
|
|
3242
3242
|
result = result.replace(/-----BEGIN [A-Z]{0,9} ?PRIVATE KEY-----[\s\S]*?(?:-----END [A-Z]{0,9} ?PRIVATE KEY-----|$)/g, "<private-key>");
|
|
@@ -4336,6 +4336,23 @@ function findBodyFieldName(fields) {
|
|
|
4336
4336
|
}
|
|
4337
4337
|
return "body";
|
|
4338
4338
|
}
|
|
4339
|
+
function extractSeoFields(entryData, opts = {}) {
|
|
4340
|
+
const names = { ...DEFAULT_SEO_FIELD_NAMES, ...opts.fields };
|
|
4341
|
+
const entry = asRecord(entryData);
|
|
4342
|
+
const source = opts.group ? asRecord(entry?.[opts.group]) : entry;
|
|
4343
|
+
return {
|
|
4344
|
+
title: asText(source?.[names.title]) ?? asText(opts.fallbackTitle),
|
|
4345
|
+
description: asText(source?.[names.description]) ?? asText(opts.fallbackDescription),
|
|
4346
|
+
ogImage: asImageUrl(source?.[names.ogImage]),
|
|
4347
|
+
ogType: asOgType(source?.[names.ogType]),
|
|
4348
|
+
canonical: asText(source?.[names.canonical]),
|
|
4349
|
+
noindex: asFlag(source?.[names.noindex]),
|
|
4350
|
+
twitterCard: asTwitterCard(source?.[names.twitterCard])
|
|
4351
|
+
};
|
|
4352
|
+
}
|
|
4353
|
+
function isNoindexEntry(entryData, opts = {}) {
|
|
4354
|
+
return extractSeoFields(entryData, opts).noindex === true;
|
|
4355
|
+
}
|
|
4339
4356
|
function buildResolvedReference(data, meta, body) {
|
|
4340
4357
|
const resolved = { ...data };
|
|
4341
4358
|
if (body && body.value)
|
|
@@ -5816,17 +5833,21 @@ function createReferenceRendering(idIndex, flatSchema, entryLinkUrl, markdownCop
|
|
|
5816
5833
|
function resolveEntryUrl(location, contentRoot) {
|
|
5817
5834
|
return computeEntryUrl(location.collection ?? "", location.slug ?? "", contentRoot);
|
|
5818
5835
|
}
|
|
5819
|
-
function resolveEntryLinksInText(text3, idIndex, contentRoot, customResolver) {
|
|
5836
|
+
function resolveEntryLinksInText(text3, idIndex, contentRoot, customResolver, options = {}) {
|
|
5837
|
+
const { isLinkable } = options;
|
|
5820
5838
|
const parts = splitByCodeRegions(text3);
|
|
5821
5839
|
return parts.map((part) => {
|
|
5822
5840
|
if (part.isCode)
|
|
5823
5841
|
return part.text;
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5842
|
+
const partText = isLinkable ? unwrapInlineLinks(part.text, (id) => !isLinkable(id) || !findEntry(idIndex, id)) : part.text;
|
|
5843
|
+
return partText.replace(ENTRY_LINK_PATTERN, (_match, id, anchor) => {
|
|
5844
|
+
const location = findEntry(idIndex, id);
|
|
5845
|
+
if (!location) {
|
|
5827
5846
|
log6.warn("resolve", `Entry link target not found: entry:${id}`);
|
|
5828
|
-
return anchor ?? "#";
|
|
5847
|
+
return isLinkable ? "#" : anchor ?? "#";
|
|
5829
5848
|
}
|
|
5849
|
+
if (isLinkable && !isLinkable(id))
|
|
5850
|
+
return "#";
|
|
5830
5851
|
let url;
|
|
5831
5852
|
if (customResolver) {
|
|
5832
5853
|
url = customResolver({
|
|
@@ -5841,6 +5862,45 @@ function resolveEntryLinksInText(text3, idIndex, contentRoot, customResolver) {
|
|
|
5841
5862
|
});
|
|
5842
5863
|
}).join("");
|
|
5843
5864
|
}
|
|
5865
|
+
function findEntry(idIndex, id) {
|
|
5866
|
+
const location = idIndex.findById(id);
|
|
5867
|
+
if (!location || location.type !== "entry" || !location.collection || !location.slug) {
|
|
5868
|
+
return void 0;
|
|
5869
|
+
}
|
|
5870
|
+
return location;
|
|
5871
|
+
}
|
|
5872
|
+
function unwrapInlineLinks(text3, shouldUnwrap) {
|
|
5873
|
+
let out = "";
|
|
5874
|
+
let cursor = 0;
|
|
5875
|
+
let scanFloor = 0;
|
|
5876
|
+
for (const match of text3.matchAll(INLINE_LINK_TARGET)) {
|
|
5877
|
+
const close = match.index;
|
|
5878
|
+
if (close < cursor || !shouldUnwrap(match[1]))
|
|
5879
|
+
continue;
|
|
5880
|
+
const open = findOpeningBracket(text3, close, Math.max(cursor, scanFloor));
|
|
5881
|
+
if (open === -1) {
|
|
5882
|
+
scanFloor = close;
|
|
5883
|
+
continue;
|
|
5884
|
+
}
|
|
5885
|
+
const isImage = open > cursor && text3[open - 1] === "!" && text3[open - 2] !== "\\";
|
|
5886
|
+
const start = isImage ? open - 1 : open;
|
|
5887
|
+
out += text3.slice(cursor, start) + text3.slice(open + 1, close);
|
|
5888
|
+
cursor = close + match[0].length;
|
|
5889
|
+
}
|
|
5890
|
+
return out + text3.slice(cursor);
|
|
5891
|
+
}
|
|
5892
|
+
function findOpeningBracket(text3, close, floor) {
|
|
5893
|
+
let depth = 1;
|
|
5894
|
+
for (let i = close - 1; i >= floor; i--) {
|
|
5895
|
+
if (i > floor && text3[i - 1] === "\\")
|
|
5896
|
+
continue;
|
|
5897
|
+
if (text3[i] === "]")
|
|
5898
|
+
depth++;
|
|
5899
|
+
else if (text3[i] === "[" && --depth === 0)
|
|
5900
|
+
return i;
|
|
5901
|
+
}
|
|
5902
|
+
return -1;
|
|
5903
|
+
}
|
|
5844
5904
|
function splitByCodeRegions(text3) {
|
|
5845
5905
|
const parts = [];
|
|
5846
5906
|
let current = "";
|
|
@@ -5913,6 +5973,7 @@ function splitByCodeRegions(text3) {
|
|
|
5913
5973
|
}
|
|
5914
5974
|
async function generateAIContent(options) {
|
|
5915
5975
|
const { store, flatSchema, contentRoot, config, entryLinkUrl, generatedAt, buildId } = options;
|
|
5976
|
+
assertValidNoindexConfig(config);
|
|
5916
5977
|
const files = /* @__PURE__ */ new Map();
|
|
5917
5978
|
const idIndex = await store.idIndex();
|
|
5918
5979
|
const read = {
|
|
@@ -5949,6 +6010,16 @@ async function generateAIContent(options) {
|
|
|
5949
6010
|
let round = allPending;
|
|
5950
6011
|
for (; ; ) {
|
|
5951
6012
|
for (const pending of round) {
|
|
6013
|
+
if (pending.body !== void 0) {
|
|
6014
|
+
const linked = /* @__PURE__ */ new Set();
|
|
6015
|
+
pending.entry.body = resolveEntryLinksInText(pending.body, idIndex, contentRoot, entryLinkUrl, {
|
|
6016
|
+
isLinkable: (id) => {
|
|
6017
|
+
linked.add(id);
|
|
6018
|
+
return exported.has(id);
|
|
6019
|
+
}
|
|
6020
|
+
});
|
|
6021
|
+
pending.linkedIds = [...linked];
|
|
6022
|
+
}
|
|
5952
6023
|
maskUnexportedTargets(pending.entry, exported);
|
|
5953
6024
|
pending.entry.appendedSections = void 0;
|
|
5954
6025
|
await runEntryTransform(pending.entry, pending.absolutePath, pending.contentId, config);
|
|
@@ -5956,11 +6027,19 @@ async function generateAIContent(options) {
|
|
|
5956
6027
|
const failed = renderAll(round, config, references);
|
|
5957
6028
|
if (failed.length === 0)
|
|
5958
6029
|
break;
|
|
6030
|
+
const failedIds = /* @__PURE__ */ new Set();
|
|
5959
6031
|
for (const pending of failed) {
|
|
5960
|
-
if (pending.contentId
|
|
5961
|
-
|
|
6032
|
+
if (pending.contentId === null)
|
|
6033
|
+
continue;
|
|
6034
|
+
exported.delete(pending.contentId);
|
|
6035
|
+
failedIds.add(pending.contentId);
|
|
5962
6036
|
}
|
|
5963
|
-
round = allPending.filter((pending) =>
|
|
6037
|
+
round = allPending.filter((pending) => {
|
|
6038
|
+
if (!isRendered(pending))
|
|
6039
|
+
return false;
|
|
6040
|
+
const masked = maskUnexportedTargets(pending.entry, exported);
|
|
6041
|
+
return masked || pending.linkedIds.some((id) => failedIds.has(id));
|
|
6042
|
+
});
|
|
5964
6043
|
}
|
|
5965
6044
|
const manifestCollections = collectionNodes.map((node) => emitCollection(node, files));
|
|
5966
6045
|
const manifestRootEntries = emitEntries(rootEntries, files);
|
|
@@ -6029,6 +6108,7 @@ async function collectCollection(read, collection, flatSchema) {
|
|
|
6029
6108
|
}
|
|
6030
6109
|
async function collectEntries(read, collection, cleanPath) {
|
|
6031
6110
|
const { store, contentRoot, config, idIndex, entryLinkUrl, resolveTarget: resolveTarget2 } = read;
|
|
6111
|
+
const skipNoindex = config?.exclude?.noindex !== false;
|
|
6032
6112
|
const pending = [];
|
|
6033
6113
|
const listed = await store.getCollectionEntryPaths(collection.logicalPath);
|
|
6034
6114
|
const directEntries = listed.filter((e) => e.collection === collection.logicalPath);
|
|
@@ -6045,15 +6125,19 @@ async function collectEntries(read, collection, cleanPath) {
|
|
|
6045
6125
|
const doc = await store.read(listEntry.collection, listEntry.slug, {
|
|
6046
6126
|
resolveReferences: false
|
|
6047
6127
|
});
|
|
6128
|
+
if (skipNoindex && isNoindexEntry(doc.data, config?.seo))
|
|
6129
|
+
continue;
|
|
6048
6130
|
doc.data = await resolveReferenceFields(doc.data, entryTypeConfig.schema, resolveTarget2);
|
|
6049
6131
|
const aiEntry = docToAIEntry(doc, listEntry.slug, entryTypeName, entryTypeConfig, cleanPath);
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6132
|
+
const body = aiEntry.body;
|
|
6133
|
+
if (body)
|
|
6134
|
+
aiEntry.body = resolveEntryLinksInText(body, idIndex, contentRoot, entryLinkUrl);
|
|
6053
6135
|
if (config?.exclude?.where?.(aiEntry))
|
|
6054
6136
|
continue;
|
|
6055
6137
|
pending.push({
|
|
6056
6138
|
entry: aiEntry,
|
|
6139
|
+
body,
|
|
6140
|
+
linkedIds: [],
|
|
6057
6141
|
contentId: extractIdFromFilename(path13.basename(listEntry.relativePath)),
|
|
6058
6142
|
absolutePath: doc.absolutePath,
|
|
6059
6143
|
collectionPath: collection.logicalPath,
|
|
@@ -6094,6 +6178,31 @@ function emitCollection(node, files) {
|
|
|
6094
6178
|
subcollections: manifestSubcollections.length > 0 ? manifestSubcollections : void 0
|
|
6095
6179
|
};
|
|
6096
6180
|
}
|
|
6181
|
+
function assertValidNoindexConfig(config) {
|
|
6182
|
+
const noindex = config?.exclude?.noindex;
|
|
6183
|
+
if (noindex !== void 0 && typeof noindex !== "boolean") {
|
|
6184
|
+
throw new Error(`AI content config: exclude.noindex must be a boolean, got ${typeof noindex}`);
|
|
6185
|
+
}
|
|
6186
|
+
const seo = config?.seo;
|
|
6187
|
+
if (seo === void 0)
|
|
6188
|
+
return;
|
|
6189
|
+
if (typeof seo !== "object" || seo === null || Array.isArray(seo)) {
|
|
6190
|
+
throw new Error("AI content config: seo must be an object of { group?, fields? }");
|
|
6191
|
+
}
|
|
6192
|
+
const { group, fields } = seo;
|
|
6193
|
+
if (group !== void 0 && typeof group !== "string") {
|
|
6194
|
+
throw new Error("AI content config: seo.group must be a string");
|
|
6195
|
+
}
|
|
6196
|
+
if (fields === void 0)
|
|
6197
|
+
return;
|
|
6198
|
+
if (typeof fields !== "object" || fields === null || Array.isArray(fields) || Object.values(fields).some((name) => typeof name !== "string")) {
|
|
6199
|
+
throw new Error("AI content config: seo.fields must map SEO fields to field-name strings");
|
|
6200
|
+
}
|
|
6201
|
+
const unknown = Object.keys(fields).filter((key) => !(key in DEFAULT_SEO_FIELD_NAMES));
|
|
6202
|
+
if (unknown.length > 0) {
|
|
6203
|
+
throw new Error(`AI content config: unknown seo.fields key(s): ${unknown.join(", ")}`);
|
|
6204
|
+
}
|
|
6205
|
+
}
|
|
6097
6206
|
function stripContentRoot(logicalPath, contentRoot) {
|
|
6098
6207
|
if (logicalPath.startsWith(contentRoot + "/")) {
|
|
6099
6208
|
return logicalPath.slice(contentRoot.length + 1);
|
|
@@ -6418,7 +6527,7 @@ async function ensureRemoteGitConfig(gitDir, git = simpleGit22().env(gitChildEnv
|
|
|
6418
6527
|
}
|
|
6419
6528
|
}
|
|
6420
6529
|
async function countObjects(git, gitDir) {
|
|
6421
|
-
const output = await git.raw(["--git-dir", gitDir, "count-objects", "-v"]);
|
|
6530
|
+
const output = await git.raw(["--git-dir", gitDir, "count-objects", "-v", "--end-of-options"]);
|
|
6422
6531
|
const fields = new Map(output.split("\n").map((line) => {
|
|
6423
6532
|
const [name, value = ""] = line.split(": ");
|
|
6424
6533
|
return [name, value.trim()];
|
|
@@ -6438,8 +6547,8 @@ async function repackBareRemoteIfNeeded(gitDir, git = simpleGit22().env(gitChild
|
|
|
6438
6547
|
return { repacked: false, before };
|
|
6439
6548
|
}
|
|
6440
6549
|
const startedAt = Date.now();
|
|
6441
|
-
await git.raw(["--git-dir", gitDir, "repack", "-a", "-d", "--cruft", "-q"]);
|
|
6442
|
-
await git.raw(["--git-dir", gitDir, "pack-refs", "--all"]);
|
|
6550
|
+
await git.raw(["--git-dir", gitDir, "repack", "-a", "-d", "--cruft", "-q", "--end-of-options"]);
|
|
6551
|
+
await git.raw(["--git-dir", gitDir, "pack-refs", "--all", "--end-of-options"]);
|
|
6443
6552
|
const after = await countObjects(git, gitDir);
|
|
6444
6553
|
return { repacked: true, before, after, ms: Date.now() - startedAt };
|
|
6445
6554
|
}
|
|
@@ -7358,7 +7467,7 @@ async function generateAIContentCLI(options) {
|
|
|
7358
7467
|
console.log(` Output: ${result.outputDir}
|
|
7359
7468
|
`);
|
|
7360
7469
|
}
|
|
7361
|
-
var __defProp3, __getOwnPropNames3, __esm3, __export3, init_error3, init_atomic_write2, active2, init_logger2, SENTINEL_BASE2, DOT_SEGMENT2, init_sanitize_href2, init_normalize, ROOT_COLLECTION_ID, init_types2, normalizePathValue, flattenSchema, init_flatten, scalarFieldTypes2, markdownFieldTypes2, primitiveFieldTypes2, fieldTypes2, init_types22, SAFE_HTML_TAGS2, COMPONENT_NAME2, MDX_BINDINGS2, FORBIDDEN_ATTRIBUTES2, init_mdx_allowlist2, fieldBaseSchema2, selectOptionSchema2, referenceOptionSchema2, primitiveFieldSchema2, mdxPropAllowSchema2, mdxAllowlistSchema2, markdownFieldSchema2, ASPECT_RATIO_RE2, imageFieldSchema2, selectFieldSchema2, referenceFieldSchema2, fieldHolder2, blockSchema2, blockFieldSchema2, objectFieldSchema2, inlineGroupFieldSchema2, customFieldSchema2, knownFieldSchema2, fieldSchema2, init_field2, relativePathSchema2, entryTypeSchema2, collectionSchema2, init_collection2, uploadTargetUrlSchema2, previewPrefixSchema2, init_url2, mediaSchema2, init_media2, defaultBranchAccessSchema2, defaultPathAccessLevelSchema2, defaultPathAccessLevelsSchema2, defaultPathAccessSchema2, defaultBaseBranchSchema2, defaultRemoteNameSchema2, defaultRemoteUrlSchema2, gitBotAuthorNameSchema2, gitBotAuthorEmailSchema2, githubTokenEnvVarSchema2, operatingModeSchema2, deployedAsSchema2, contentRootSchema2, sourceRootSchema2, basePathSchema2, deploymentNameSchema2, devContentSyncSchema2, devConfigSchema2, editorConfigSchema2, CanopyConfigSchema2, DEFAULT_PROD_WORKSPACE2, init_config3, SERVER_MODE_ENV_VAR, BROWSER_MODE_ENV_VAR, warned2, init_mode_env, forEachReferenceField, init_validation, ProdClientSafeStrategy2, DevClientSafeStrategy2, clientStrategyCache, init_client_safe_strategy, warned3, VALID_DEPLOYMENT_NAME2, isValidDeploymentName2, init_deployment_name, init_config22, ProdStrategy2, DevStrategy2, strategyCache2, init_client_unsafe_strategy, operating_mode_exports, init_operating_mode, task_queue_config_exports2, init_task_queue_config2, worker_status_exports, WORKER_STATUS_FILE, init_worker_status, BLOCK_DISCRIMINATOR_KEYS, BLOCK_STRUCTURAL_KEYS, LOG_LEVELS2, DebugLogger2, testLogger2, END, FRESH, LINE_WIDTH, MIN_LINE_WIDTH, SourceSplicer, log2, MAX_LCS_CELLS, Splicer, log22, EVIDENCE_MAX_DEPTH, log3, locks, PROVISIONING_LOCK_STALE_MS, sleep, META_DIR, CONTENT_WRITE_LOCK_NAME, DEFAULT_CONTENT_WRITE_LOCK_WAIT_MS, ContentWriteLockBusyError, sleep2, CONTENT_WRITE_LOCK_STALE_MS, DEFAULT_SEO_FIELD_NAMES, RESTRICTED_REFERENCE_MARKER, SEO_GROUP_FIELDS, MAX_WARNED, warned4, SchemaUnavailableError, BASE58_PATTERN, CONTENT_ID_PATTERN, PHYSICAL_SEGMENT_PATTERN, isValidId, EMPTY_LOGICAL_PATH, ContentIdIndex, parseTypedFilename, CONTENT_EXTENSIONS, registry, finalization, log4, META_DIR2, entryTypeMetaSchema, collectionMetaSchema, rootCollectionMetaSchema, fingerprints, editDistance, closestName, forEachEntryType, collectEntryTypeNames, validateReferenceEntryTypes, isDeployedStatic, isBuildMode, readsFromCheckout, STATIC_DEPLOY_USER, storage, log5, BaseBranchUnresolvedError, NETWORK_SCHEME_PATTERN, TRANSPORT_HELPER_PATTERN, LEADING_OPTION_PATTERN, WINDOWS_DRIVE_PATTERN, COLON_BEFORE_SLASH_PATTERN, MISSING_REMOTE_REF_REASONS, CANOPY_META_DIR, SCHEMA_CACHE_VERSION, MTIME_CHECK_DEBOUNCE_MS, SCHEMA_CACHE_FILE, SCHEMA_GENERATION_RESOURCE, reportedIssues, BranchSchemaCache, RESOURCE, getFormatExtension, isDataOnlyFormat,
|
|
7470
|
+
var __defProp3, __getOwnPropNames3, __esm3, __export3, init_error3, init_atomic_write2, active2, init_logger2, SENTINEL_BASE2, DOT_SEGMENT2, init_sanitize_href2, init_normalize, ROOT_COLLECTION_ID, init_types2, normalizePathValue, flattenSchema, init_flatten, scalarFieldTypes2, markdownFieldTypes2, primitiveFieldTypes2, fieldTypes2, init_types22, SAFE_HTML_TAGS2, COMPONENT_NAME2, MDX_BINDINGS2, FORBIDDEN_ATTRIBUTES2, init_mdx_allowlist2, fieldBaseSchema2, selectOptionSchema2, referenceOptionSchema2, primitiveFieldSchema2, mdxPropAllowSchema2, mdxAllowlistSchema2, markdownFieldSchema2, ASPECT_RATIO_RE2, imageFieldSchema2, selectFieldSchema2, referenceFieldSchema2, fieldHolder2, blockSchema2, blockFieldSchema2, objectFieldSchema2, inlineGroupFieldSchema2, customFieldSchema2, knownFieldSchema2, fieldSchema2, init_field2, relativePathSchema2, entryTypeSchema2, collectionSchema2, init_collection2, uploadTargetUrlSchema2, previewPrefixSchema2, init_url2, mediaSchema2, init_media2, defaultBranchAccessSchema2, defaultPathAccessLevelSchema2, defaultPathAccessLevelsSchema2, defaultPathAccessSchema2, defaultBaseBranchSchema2, defaultRemoteNameSchema2, defaultRemoteUrlSchema2, gitBotAuthorNameSchema2, gitBotAuthorEmailSchema2, githubTokenEnvVarSchema2, operatingModeSchema2, deployedAsSchema2, contentRootSchema2, sourceRootSchema2, basePathSchema2, deploymentNameSchema2, devContentSyncSchema2, devConfigSchema2, editorConfigSchema2, CanopyConfigSchema2, DEFAULT_PROD_WORKSPACE2, init_config3, SERVER_MODE_ENV_VAR, BROWSER_MODE_ENV_VAR, warned2, init_mode_env, forEachReferenceField, init_validation, ProdClientSafeStrategy2, DevClientSafeStrategy2, clientStrategyCache, init_client_safe_strategy, warned3, VALID_DEPLOYMENT_NAME2, isValidDeploymentName2, init_deployment_name, init_config22, ProdStrategy2, DevStrategy2, strategyCache2, init_client_unsafe_strategy, operating_mode_exports, init_operating_mode, task_queue_config_exports2, init_task_queue_config2, worker_status_exports, WORKER_STATUS_FILE, init_worker_status, BLOCK_DISCRIMINATOR_KEYS, BLOCK_STRUCTURAL_KEYS, LOG_LEVELS2, DebugLogger2, testLogger2, END, FRESH, LINE_WIDTH, MIN_LINE_WIDTH, SourceSplicer, log2, MAX_LCS_CELLS, Splicer, log22, EVIDENCE_MAX_DEPTH, log3, locks, PROVISIONING_LOCK_STALE_MS, sleep, META_DIR, CONTENT_WRITE_LOCK_NAME, DEFAULT_CONTENT_WRITE_LOCK_WAIT_MS, ContentWriteLockBusyError, sleep2, CONTENT_WRITE_LOCK_STALE_MS, DEFAULT_SEO_FIELD_NAMES, asRecord, asText, asFlag, asImageUrl, asOgType, asTwitterCard, RESTRICTED_REFERENCE_MARKER, SEO_GROUP_FIELDS, MAX_WARNED, warned4, SchemaUnavailableError, BASE58_PATTERN, CONTENT_ID_PATTERN, PHYSICAL_SEGMENT_PATTERN, isValidId, EMPTY_LOGICAL_PATH, ContentIdIndex, parseTypedFilename, CONTENT_EXTENSIONS, registry, finalization, log4, META_DIR2, entryTypeMetaSchema, collectionMetaSchema, rootCollectionMetaSchema, fingerprints, editDistance, closestName, forEachEntryType, collectEntryTypeNames, validateReferenceEntryTypes, isDeployedStatic, isBuildMode, readsFromCheckout, STATIC_DEPLOY_USER, storage, log5, BaseBranchUnresolvedError, NETWORK_SCHEME_PATTERN, TRANSPORT_HELPER_PATTERN, LEADING_OPTION_PATTERN, WINDOWS_DRIVE_PATTERN, COLON_BEFORE_SLASH_PATTERN, MISSING_REMOTE_REF_REASONS, CANOPY_META_DIR, SCHEMA_CACHE_VERSION, MTIME_CHECK_DEBOUNCE_MS, SCHEMA_CACHE_FILE, SCHEMA_GENERATION_RESOURCE, reportedIssues, BranchSchemaCache, RESOURCE, getFormatExtension, isDataOnlyFormat, asRecord2, RESERVED_SETTINGS_BRANCH_PREFIX, BranchPathError, resolveContentBranchesRoot, ContentStoreError, ContentConflictError, BranchSyncingError, DuplicateContentIdError, UrlPathConflictError, DEFAULT_INDEX_FRESHNESS_INTERVAL_MS, FORCED_REFRESH_MIN_INTERVAL_MS, STALE_LOOKUP, isMissingReference, createReferenceResolveCache, ContentStore, ATTR_CONTENT, BLOCK_PREFIX, BLOCK_SUFFIX, BLOCK_RESTORE_RE, INLINE_PREFIX, INLINE_SUFFIX, INLINE_RESTORE_RE, DEFAULT_REFERENCE_RENDERING, FLAT_CELL_TYPES, log6, BASE58_CHAR, ENTRY_LINK_PATTERN, INLINE_LINK_TARGET, BranchMetadataCorruptError, BRANCH_META_DIR, BRANCH_META_FILE, branchMetadataFilePath, UNKNOWN_TIME, enumOf, branchMetadataShape, branchMetadataSchema, branchMetadataFileSchema, log7, REGISTRY_FILE, REGISTRY_STALE_FILE, REGISTRY_TEMP_FILE, REGISTRY_VERSION, RESOURCE2, GET_MISS_REFRESH_MIN_INTERVAL_MS, snapshotSchema, reportedUnreadable, BranchRegistry, log8, OccWriteConflictError, CURRENT_SCHEMA_VERSION, BranchMetadataConflictError, BranchMetadataFileManager, loadBranchContext, log9, GIT_ENV_PASSTHROUGH, FORCE_C_LOCALE, GIT_NETWORK_ENV_PASSTHROUGH, NO_AUTO_GC_CONFIG, REMOTE_GIT_CONFIG, REMOTE_GIT_MAX_LOOSE_OBJECTS, REMOTE_GIT_MAX_PACKS, PARALLEL_CHECKOUT_ARGS, remoteInitLocks, GITHUB_TRACKING_REF_PREFIX, GitConflictError, GitRemoteRefMissingError, RemoteNotReadyError, SettingsRemoteUnreadableError, SettingsBranchDivergedError, SETTINGS_BRANCH_FILES, SettingsBranchHasContentHistoryError, GitManager, PUBLISH_LOCK_WAIT_MS, CREATE_RESIDUE_MIN_QUIET_MS, STAGING_MAX_AGE_MS, REPAIR_MAX_AGE_MS, DELETING_MAX_AGE_MS, SETTINGS_TRASH_MAX_AGE_MS, BranchProvisioningBusyError, BranchDirOccupiedError, STAGING_PREFIX, REPAIR_PREFIX, TRASH_PREFIX, stagingDirName, NO_GIT, RENAME_BLOCKED, SPARSE_CONE_RECORD, defaultSink, sink, ProvisionLog, testHooks, provisionsInFlight, BranchWorkspaceManager, log10, normalizePath, readEntryData, createReferenceResolver, withoutUnavailableEntries, resolveCollectionItemReferences, looksLikeMalformedEntry, listCollectionEntries, MAX_INPUT_PIXELS, CROP_PRECISION, KNOWN_FIELD_TYPES, STRING_FIELD_TYPES, selectOptionValues, GENERATED_RECORD_FILENAME, SAFE_BUILD_ID, BUILD_ID_RULE, jiti;
|
|
7362
7471
|
var init_generate_ai_content = __esm({
|
|
7363
7472
|
"dist/cli/generate-ai-content.js"() {
|
|
7364
7473
|
"use strict";
|
|
@@ -8797,6 +8906,28 @@ var init_generate_ai_content = __esm({
|
|
|
8797
8906
|
noindex: "noindex",
|
|
8798
8907
|
twitterCard: "twitterCard"
|
|
8799
8908
|
};
|
|
8909
|
+
asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
8910
|
+
asText = (value) => {
|
|
8911
|
+
if (typeof value !== "string")
|
|
8912
|
+
return void 0;
|
|
8913
|
+
const trimmed = value.trim();
|
|
8914
|
+
return trimmed === "" ? void 0 : trimmed;
|
|
8915
|
+
};
|
|
8916
|
+
asFlag = (value) => typeof value === "boolean" ? value : void 0;
|
|
8917
|
+
asImageUrl = (value) => {
|
|
8918
|
+
const text3 = asText(value);
|
|
8919
|
+
if (text3)
|
|
8920
|
+
return text3;
|
|
8921
|
+
return asText(asRecord(value)?.src);
|
|
8922
|
+
};
|
|
8923
|
+
asOgType = (value) => {
|
|
8924
|
+
const text3 = asText(value);
|
|
8925
|
+
return text3 === "website" || text3 === "article" || text3 === "profile" ? text3 : void 0;
|
|
8926
|
+
};
|
|
8927
|
+
asTwitterCard = (value) => {
|
|
8928
|
+
const text3 = asText(value);
|
|
8929
|
+
return text3 === "summary" || text3 === "summary_large_image" ? text3 : void 0;
|
|
8930
|
+
};
|
|
8800
8931
|
RESTRICTED_REFERENCE_MARKER = "unavailable";
|
|
8801
8932
|
SEO_GROUP_FIELDS = [
|
|
8802
8933
|
{
|
|
@@ -9497,7 +9628,7 @@ var init_generate_ai_content = __esm({
|
|
|
9497
9628
|
return ".json";
|
|
9498
9629
|
};
|
|
9499
9630
|
isDataOnlyFormat = (format) => format === "json" || format === "yaml";
|
|
9500
|
-
|
|
9631
|
+
asRecord2 = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
9501
9632
|
init_normalize();
|
|
9502
9633
|
init_operating_mode();
|
|
9503
9634
|
RESERVED_SETTINGS_BRANCH_PREFIX = "canopycms-settings-";
|
|
@@ -9989,7 +10120,7 @@ var init_generate_ai_content = __esm({
|
|
|
9989
10120
|
fields = entryTypeConfig?.schema || [];
|
|
9990
10121
|
}
|
|
9991
10122
|
if (format === "json") {
|
|
9992
|
-
const data =
|
|
10123
|
+
const data = asRecord2(JSON.parse(raw));
|
|
9993
10124
|
doc = {
|
|
9994
10125
|
collection: schemaItem.logicalPath,
|
|
9995
10126
|
collectionName: schemaItem.name,
|
|
@@ -9999,7 +10130,7 @@ var init_generate_ai_content = __esm({
|
|
|
9999
10130
|
absolutePath
|
|
10000
10131
|
};
|
|
10001
10132
|
} else if (format === "yaml") {
|
|
10002
|
-
const data =
|
|
10133
|
+
const data = asRecord2(yamlParse(raw));
|
|
10003
10134
|
doc = {
|
|
10004
10135
|
collection: schemaItem.logicalPath,
|
|
10005
10136
|
collectionName: schemaItem.name,
|
|
@@ -10712,6 +10843,7 @@ var init_generate_ai_content = __esm({
|
|
|
10712
10843
|
log6 = createDebugLogger2({ prefix: "EntryLinks" });
|
|
10713
10844
|
BASE58_CHAR = "[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]";
|
|
10714
10845
|
ENTRY_LINK_PATTERN = new RegExp(`entry:(${BASE58_CHAR}{12})(#[^\\s)>"']*)?`, "g");
|
|
10846
|
+
INLINE_LINK_TARGET = new RegExp(`\\]\\(entry:(${BASE58_CHAR}{12})(?:#[^\\s)>"'\\]]*)?(?:[ \\t]+"[^"\\n]*")?\\)`, "g");
|
|
10715
10847
|
init_error3();
|
|
10716
10848
|
BranchMetadataCorruptError = class extends Error {
|
|
10717
10849
|
constructor(branchRoot, cause) {
|
|
@@ -11476,10 +11608,10 @@ var init_generate_ai_content = __esm({
|
|
|
11476
11608
|
* Delete `refs/heads/<branch>` from a bare local mirror, if present. A
|
|
11477
11609
|
* no-op (not an error) when the ref doesn't exist.
|
|
11478
11610
|
*
|
|
11479
|
-
* The
|
|
11480
|
-
*
|
|
11481
|
-
*
|
|
11482
|
-
*
|
|
11611
|
+
* The path that removes a deleted branch's local head at once; the sync
|
|
11612
|
+
* loop's reconcileTrackedBranches removes one only after GitHub no longer
|
|
11613
|
+
* has the branch. Called by api/branch.ts's deleteBranchHandler: a head
|
|
11614
|
+
* left in `remote.git` makes the
|
|
11483
11615
|
* create -> publish -> squash-merge -> delete -> reuse-the-name cycle reject
|
|
11484
11616
|
* the reused branch's first publish non-fast-forward against the stale head
|
|
11485
11617
|
* (`GitManager.push()` pushes the branch to the same name, and a squash-merged old tip is
|
|
@@ -12664,10 +12796,10 @@ var init_generate_ai_content = __esm({
|
|
|
12664
12796
|
try {
|
|
12665
12797
|
const raw = await fs20.readFile(filePath, "utf8");
|
|
12666
12798
|
if (format === "json") {
|
|
12667
|
-
return
|
|
12799
|
+
return asRecord2(JSON.parse(raw));
|
|
12668
12800
|
}
|
|
12669
12801
|
if (format === "yaml") {
|
|
12670
|
-
return
|
|
12802
|
+
return asRecord2(yamlParse2(raw));
|
|
12671
12803
|
}
|
|
12672
12804
|
const parsed = matter3(raw);
|
|
12673
12805
|
const data = { ...parsed.data ?? {} };
|