canopycms 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +188 -47
- package/dist/api/branch-review.d.ts +11 -1
- package/dist/api/branch-review.js +96 -18
- package/dist/api/branch-status.d.ts +26 -2
- package/dist/api/branch-status.js +38 -2
- package/dist/api/branch-withdraw.js +4 -7
- package/dist/api/branch.d.ts +2 -0
- package/dist/api/client.d.ts +3 -3
- package/dist/api/client.js +4 -4
- package/dist/api/comments.d.ts +2 -2
- package/dist/api/comments.js +4 -0
- package/dist/api/content.d.ts +2 -2
- package/dist/api/github-sync.d.ts +4 -0
- package/dist/api/github-sync.js +38 -6
- package/dist/api/pr-comment-sync.d.ts +18 -0
- package/dist/api/pr-comment-sync.js +77 -0
- package/dist/api/request-deadline.d.ts +15 -7
- package/dist/api/request-deadline.js +15 -7
- package/dist/api/schema.d.ts +16 -16
- package/dist/authorization/review-role.d.ts +33 -0
- package/dist/authorization/review-role.js +17 -0
- package/dist/branch-metadata-file.d.ts +3 -0
- package/dist/branch-metadata-file.js +1 -0
- package/dist/cli/cli.js +699 -130
- package/dist/cli/generate-ai-content.js +524 -59
- package/dist/cli/github-app-output.d.ts +34 -0
- package/dist/cli/github-app-output.js +85 -0
- package/dist/cli/init-github-app.d.ts +18 -0
- package/dist/cli/init-github-app.js +66 -58
- package/dist/cli/init.js +10 -1
- package/dist/comment-store.d.ts +5 -0
- package/dist/comment-store.js +24 -0
- package/dist/config/helpers.js +1 -3
- package/dist/config/schemas/collection.d.ts +2 -2
- package/dist/config/schemas/config.d.ts +3 -0
- package/dist/config/schemas/config.js +2 -1
- package/dist/config/schemas/url.d.ts +6 -0
- package/dist/config/schemas/url.js +16 -0
- package/dist/config/types.d.ts +12 -1
- package/dist/content-id-index.d.ts +9 -0
- package/dist/content-id-index.js +31 -0
- package/dist/editor/BranchManager.d.ts +3 -0
- package/dist/editor/BranchManager.js +75 -44
- package/dist/editor/CanopyEditor.js +2 -2
- package/dist/editor/CanopyEditorPage.js +3 -4
- package/dist/editor/Editor.js +47 -8
- package/dist/editor/branch-lock.d.ts +7 -0
- package/dist/editor/branch-lock.js +9 -2
- package/dist/editor/client-reference-resolver.d.ts +5 -3
- package/dist/editor/client-reference-resolver.js +10 -5
- package/dist/editor/components/BranchesLoadFailedNotice.d.ts +13 -0
- package/dist/editor/components/BranchesLoadFailedNotice.js +12 -0
- package/dist/editor/components/EditorHeader.d.ts +10 -4
- package/dist/editor/components/EditorHeader.js +108 -28
- package/dist/editor/components/EntryHeader.d.ts +5 -1
- package/dist/editor/components/EntryHeader.js +3 -1
- package/dist/editor/components/ReasonedMenuItem.d.ts +8 -0
- package/dist/editor/components/ReasonedMenuItem.js +2 -2
- package/dist/editor/components/ReviewDialogs.d.ts +19 -0
- package/dist/editor/components/ReviewDialogs.js +41 -0
- package/dist/editor/copy.d.ts +4 -0
- package/dist/editor/copy.js +4 -0
- package/dist/editor/fields/MarkdownField.js +1 -1
- package/dist/editor/hooks/create-branch-request.d.ts +6 -2
- package/dist/editor/hooks/create-branch-request.js +7 -2
- package/dist/editor/hooks/useBranchManager.d.ts +7 -2
- package/dist/editor/hooks/useBranchManager.js +252 -37
- package/dist/editor-url.d.ts +20 -0
- package/dist/editor-url.js +71 -0
- package/dist/git-manager.js +10 -6
- package/dist/github-service.d.ts +2 -2
- package/dist/github-service.js +4 -2
- package/dist/pr-comments.d.ts +33 -0
- package/dist/pr-comments.js +41 -0
- package/dist/schema/schema-store.d.ts +8 -8
- package/dist/services.d.ts +2 -17
- package/dist/services.js +38 -1
- package/dist/settings-workspace.d.ts +21 -7
- package/dist/settings-workspace.js +91 -16
- package/dist/submission-attribution.d.ts +38 -1
- package/dist/submission-attribution.js +197 -18
- package/dist/task-queue/cms-task-queue.d.ts +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/utils/content-serialize.js +7 -6
- package/dist/utils/markdown-body-splice.d.ts +15 -10
- package/dist/utils/markdown-body-splice.js +71 -28
- package/dist/utils/markdown-export-options.d.ts +13 -0
- package/dist/utils/markdown-export-options.js +13 -0
- package/dist/utils/markdown-restyle.d.ts +58 -0
- package/dist/utils/markdown-restyle.js +482 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/bundle-header.d.ts +13 -9
- package/dist/worker/bundle-header.js +17 -11
- package/dist/worker/git-process.d.ts +2 -2
- package/dist/worker/git-sync.js +5 -0
- package/dist/worker/github-gateway-http.js +3 -2
- package/dist/worker/github-gateway-wire.d.ts +3 -0
- package/dist/worker/github-gateway-wire.js +1 -0
- package/dist/worker/github-gateway.d.ts +1 -1
- package/dist/worker/github-transfer.js +72 -2
- package/dist/worker/task-runner.js +53 -3
- package/package.json +2 -2
- package/dist/editor/fields/markdown-export-options.d.ts +0 -2
- package/dist/editor/fields/markdown-export-options.js +0 -8
package/dist/cli/cli.js
CHANGED
|
@@ -1227,7 +1227,7 @@ CanopyCMS worker run-once (mode: ${mode}, auth: ${authMode})
|
|
|
1227
1227
|
}
|
|
1228
1228
|
console.log("\nDone");
|
|
1229
1229
|
}
|
|
1230
|
-
var __defProp2, __getOwnPropNames2, __esm2, __export2, active, init_logger, scalarFieldTypes, markdownFieldTypes, primitiveFieldTypes, fieldTypes, init_types, SAFE_HTML_TAGS, COMPONENT_NAME, MDX_BINDINGS, FORBIDDEN_ATTRIBUTES, init_mdx_allowlist, fieldBaseSchema, selectOptionSchema, referenceOptionSchema, primitiveFieldSchema, mdxPropAllowSchema, mdxAllowlistSchema, markdownFieldSchema, ASPECT_RATIO_RE, imageFieldSchema, selectFieldSchema, referenceSortFieldSchema, referenceFieldSchema, fieldHolder, blockSchema, blockFieldSchema, objectFieldSchema, inlineGroupFieldSchema, customFieldSchema, knownFieldSchema, fieldSchema, init_field, relativePathSchema, entryTypeSchema, collectionSchema, init_collection, SENTINEL_BASE, DOT_SEGMENT, init_sanitize_href, uploadTargetUrlSchema, previewPrefixSchema, init_url, mediaSchema, init_media, defaultBranchAccessSchema, defaultPathAccessLevelSchema, defaultPathAccessLevelsSchema, defaultPathAccessSchema, defaultBaseBranchSchema, defaultRemoteNameSchema, defaultRemoteUrlSchema, gitBotAuthorNameSchema, gitBotAuthorEmailSchema, githubTokenEnvVarSchema, operatingModeSchema, deployedAsSchema, contentRootSchema, sourceRootSchema, basePathSchema, deploymentNameSchema, devContentSyncSchema, devConfigSchema, editorConfigSchema, seoFieldNameSchema, seoSchema, CanopyConfigSchema, DEFAULT_PROD_WORKSPACE, init_config, init_config2, init_error2, init_fs2, templates_exports, __dirname, TEMPLATES_DIR, SCAFFOLD_STACK_NAME, init_templates, project_detect_exports, COMMANDS, MAX_WORKSPACE_DEPTH, PLACEHOLDER_GITHUB_REPO, CDK_DEPENDENCIES, init_project_detect, task_queue_config_exports, init_task_queue_config, envFlag, LOG_LEVELS, DebugLogger, testLogger, init_debug, init_atomic_write, DEFAULT_MAX_RETRIES, nullLogger, init_task_queue, cms_task_queue_exports, debugLogger, cmsTaskQueueLogger, init_cms_task_queue, ProdClientSafeStrategy, DevClientSafeStrategy, warned, VALID_DEPLOYMENT_NAME, isValidDeploymentName, ProdStrategy, DevStrategy, strategyCache;
|
|
1230
|
+
var __defProp2, __getOwnPropNames2, __esm2, __export2, active, init_logger, scalarFieldTypes, markdownFieldTypes, primitiveFieldTypes, fieldTypes, init_types, SAFE_HTML_TAGS, COMPONENT_NAME, MDX_BINDINGS, FORBIDDEN_ATTRIBUTES, init_mdx_allowlist, fieldBaseSchema, selectOptionSchema, referenceOptionSchema, primitiveFieldSchema, mdxPropAllowSchema, mdxAllowlistSchema, markdownFieldSchema, ASPECT_RATIO_RE, imageFieldSchema, selectFieldSchema, referenceSortFieldSchema, referenceFieldSchema, fieldHolder, blockSchema, blockFieldSchema, objectFieldSchema, inlineGroupFieldSchema, customFieldSchema, knownFieldSchema, fieldSchema, init_field, relativePathSchema, entryTypeSchema, collectionSchema, init_collection, SENTINEL_BASE, DOT_SEGMENT, init_sanitize_href, uploadTargetUrlSchema, previewPrefixSchema, editorUrlSchema, init_url, mediaSchema, init_media, defaultBranchAccessSchema, defaultPathAccessLevelSchema, defaultPathAccessLevelsSchema, defaultPathAccessSchema, defaultBaseBranchSchema, defaultRemoteNameSchema, defaultRemoteUrlSchema, gitBotAuthorNameSchema, gitBotAuthorEmailSchema, githubTokenEnvVarSchema, operatingModeSchema, deployedAsSchema, contentRootSchema, sourceRootSchema, basePathSchema, deploymentNameSchema, devContentSyncSchema, devConfigSchema, editorConfigSchema, seoFieldNameSchema, seoSchema, CanopyConfigSchema, DEFAULT_PROD_WORKSPACE, init_config, init_config2, init_error2, init_fs2, templates_exports, __dirname, TEMPLATES_DIR, SCAFFOLD_STACK_NAME, init_templates, project_detect_exports, COMMANDS, MAX_WORKSPACE_DEPTH, PLACEHOLDER_GITHUB_REPO, CDK_DEPENDENCIES, init_project_detect, task_queue_config_exports, init_task_queue_config, envFlag, LOG_LEVELS, DebugLogger, testLogger, init_debug, init_atomic_write, DEFAULT_MAX_RETRIES, nullLogger, init_task_queue, cms_task_queue_exports, debugLogger, cmsTaskQueueLogger, init_cms_task_queue, ProdClientSafeStrategy, DevClientSafeStrategy, warned, VALID_DEPLOYMENT_NAME, isValidDeploymentName, ProdStrategy, DevStrategy, strategyCache;
|
|
1231
1231
|
var init_init = __esm({
|
|
1232
1232
|
"dist/cli/init.js"() {
|
|
1233
1233
|
"use strict";
|
|
@@ -1542,6 +1542,14 @@ var init_init = __esm({
|
|
|
1542
1542
|
previewPrefixSchema = z3.string().trim().refine((value) => isHttpUrlOrSameOriginPath(value), {
|
|
1543
1543
|
message: 'editor.previewPrefix must be an absolute http(s) URL or a site-relative path beginning with a single "/", with no query or fragment'
|
|
1544
1544
|
});
|
|
1545
|
+
editorUrlSchema = z3.string().trim().refine((value) => {
|
|
1546
|
+
if (!isHttpUrlOrSameOriginPath(value) || !/^https?:\/\//i.test(value))
|
|
1547
|
+
return false;
|
|
1548
|
+
const url = new URL(value);
|
|
1549
|
+
return !url.username && !url.password;
|
|
1550
|
+
}, {
|
|
1551
|
+
message: "editorUrl must be an absolute http(s) URL with no credentials, query or fragment"
|
|
1552
|
+
});
|
|
1545
1553
|
}
|
|
1546
1554
|
});
|
|
1547
1555
|
init_media = __esm2({
|
|
@@ -1684,6 +1692,7 @@ var init_init = __esm({
|
|
|
1684
1692
|
contentRoot: contentRootSchema.default("content"),
|
|
1685
1693
|
sourceRoot: sourceRootSchema.optional(),
|
|
1686
1694
|
basePath: basePathSchema,
|
|
1695
|
+
editorUrl: editorUrlSchema.optional(),
|
|
1687
1696
|
unauthenticatedStatus: z5.union([z5.literal(401), z5.literal(419)]).optional(),
|
|
1688
1697
|
danglingReferences: z5.enum(["error", "warn"]).optional(),
|
|
1689
1698
|
editor: editorConfigSchema.optional(),
|
|
@@ -2237,6 +2246,84 @@ var init_github_app_manifest = __esm({
|
|
|
2237
2246
|
}
|
|
2238
2247
|
});
|
|
2239
2248
|
|
|
2249
|
+
// dist/cli/github-app-output.js
|
|
2250
|
+
import pc from "picocolors";
|
|
2251
|
+
function colorsFor(stream) {
|
|
2252
|
+
const { NO_COLOR, FORCE_COLOR, TERM } = process.env;
|
|
2253
|
+
if (NO_COLOR)
|
|
2254
|
+
return pc.createColors(false);
|
|
2255
|
+
if (FORCE_COLOR)
|
|
2256
|
+
return pc.createColors(FORCE_COLOR !== "0" && FORCE_COLOR !== "false");
|
|
2257
|
+
return pc.createColors(Boolean(stream.isTTY) && TERM !== "dumb");
|
|
2258
|
+
}
|
|
2259
|
+
function recoveryPreamble() {
|
|
2260
|
+
return [
|
|
2261
|
+
outColors.bold(outColors.yellow("If this goes wrong after you click Create")),
|
|
2262
|
+
" The App will exist, but this command will not have its private key. To recover, either:",
|
|
2263
|
+
" \u2022 delete the App in its settings and re-run this command, or",
|
|
2264
|
+
' \u2022 open the App, scroll to "Private keys" and click "Generate a private key". The',
|
|
2265
|
+
" .pem it downloads is your only chance to save it.",
|
|
2266
|
+
outColors.dim(' (Not the "client secret" a few sections above: that is for OAuth user flows, is unused\n by this App, and fails confusingly when used to sign.)'),
|
|
2267
|
+
""
|
|
2268
|
+
].join("\n");
|
|
2269
|
+
}
|
|
2270
|
+
function registrationMessage(input) {
|
|
2271
|
+
const width = Math.max(...Object.keys(CANOPY_APP_PERMISSIONS).map((name) => name.length));
|
|
2272
|
+
const permissions = Object.entries(CANOPY_APP_PERMISSIONS).map(([name, level]) => ` ${name.padEnd(width)} ${outColors.bold(level)}`);
|
|
2273
|
+
return [
|
|
2274
|
+
outColors.bold(`Registering "${input.name}" for ${input.owner}/${input.repo}`),
|
|
2275
|
+
"",
|
|
2276
|
+
`${outColors.bold("Permissions")} ${outColors.dim("(the part that matters)")}`,
|
|
2277
|
+
...permissions,
|
|
2278
|
+
"",
|
|
2279
|
+
`${outColors.bold("Private key")} goes to ${input.destination}`,
|
|
2280
|
+
outColors.dim(" If that fails you are asked for somewhere else before the key is discarded."),
|
|
2281
|
+
"",
|
|
2282
|
+
step(1, "Open this file in a browser:"),
|
|
2283
|
+
"",
|
|
2284
|
+
` ${link(input.formFile)}`,
|
|
2285
|
+
"",
|
|
2286
|
+
" The browser matters, twice over. It must be:",
|
|
2287
|
+
` \u2022 ${outColors.bold("logged in to GitHub")} as an owner of ${input.owner}`,
|
|
2288
|
+
` \u2022 running ${outColors.bold("on this machine")}: the redirect returns to 127.0.0.1:${input.callbackPort}, which only a local browser can reach`,
|
|
2289
|
+
outColors.dim(" An embedded or app-internal browser bounces off the GitHub login wall and appears\n to do nothing when you click Create."),
|
|
2290
|
+
"",
|
|
2291
|
+
" The page posts the manifest to GitHub, which shows the App pre-filled with exactly",
|
|
2292
|
+
" those permissions. Review them and click Create.",
|
|
2293
|
+
"",
|
|
2294
|
+
outColors.dim(`Waiting for GitHub to redirect back (up to ${input.timeoutMinutes} minutes)...`)
|
|
2295
|
+
].join("\n");
|
|
2296
|
+
}
|
|
2297
|
+
function deploymentSettingsMessage(appId, installationId) {
|
|
2298
|
+
return [
|
|
2299
|
+
"",
|
|
2300
|
+
outColors.bold("Set these on your deployment"),
|
|
2301
|
+
"",
|
|
2302
|
+
` GITHUB_APP_ID=${appId}`,
|
|
2303
|
+
` GITHUB_APP_INSTALLATION_ID=${installationId ?? "<run `verify` to read it>"}`,
|
|
2304
|
+
` GITHUB_APP_PRIVATE_KEY_SECRET_ARN=<wherever you just put the key>`,
|
|
2305
|
+
"",
|
|
2306
|
+
outColors.dim(' Both ids are numeric. The App ID is NOT the "Client ID" (`Iv1.\u2026`) shown beside it,\n and the installation id is NOT the App ID: an App installed twice has one App ID\n and two installation ids.'),
|
|
2307
|
+
"",
|
|
2308
|
+
outColors.bold("Re-check this any time, without creating anything"),
|
|
2309
|
+
` canopycms init-github-app verify --app-id ${appId} --key-file <path>`
|
|
2310
|
+
].join("\n");
|
|
2311
|
+
}
|
|
2312
|
+
var outColors, errColors, tick, failMark, cross, link, step;
|
|
2313
|
+
var init_github_app_output = __esm({
|
|
2314
|
+
"dist/cli/github-app-output.js"() {
|
|
2315
|
+
"use strict";
|
|
2316
|
+
init_github_app_manifest();
|
|
2317
|
+
outColors = colorsFor(process.stdout);
|
|
2318
|
+
errColors = colorsFor(process.stderr);
|
|
2319
|
+
tick = (text3) => `${outColors.green("\u2713")} ${text3}`;
|
|
2320
|
+
failMark = errColors.red("\u2717");
|
|
2321
|
+
cross = (text3) => `${failMark} ${text3}`;
|
|
2322
|
+
link = (url, palette = outColors) => palette.cyan(palette.underline(url));
|
|
2323
|
+
step = (n, text3) => outColors.bold(outColors.cyan(`${n}.`) + ` ${text3}`);
|
|
2324
|
+
}
|
|
2325
|
+
});
|
|
2326
|
+
|
|
2240
2327
|
// dist/cli/prompt.js
|
|
2241
2328
|
import { createInterface } from "node:readline";
|
|
2242
2329
|
function readLineOnce(prompt) {
|
|
@@ -2464,10 +2551,13 @@ var init_github_app_exports = {};
|
|
|
2464
2551
|
__export(init_github_app_exports, {
|
|
2465
2552
|
appJwt: () => appJwt,
|
|
2466
2553
|
appManifest: () => appManifest,
|
|
2554
|
+
appSettingsUrl: () => appSettingsUrl,
|
|
2467
2555
|
creationForm: () => creationForm,
|
|
2468
2556
|
handOffKey: () => handOffKey,
|
|
2469
2557
|
handOffWithRetry: () => handOffWithRetry,
|
|
2470
2558
|
initGitHubApp: () => initGitHubApp,
|
|
2559
|
+
installStepMessage: () => installStepMessage,
|
|
2560
|
+
keyNotStoredMessage: () => keyNotStoredMessage,
|
|
2471
2561
|
manifestPostUrl: () => manifestPostUrl,
|
|
2472
2562
|
parseKeyRetryAnswer: () => parseKeyRetryAnswer,
|
|
2473
2563
|
startCallbackServer: () => startCallbackServer
|
|
@@ -2479,8 +2569,33 @@ import { mkdtemp, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
|
2479
2569
|
import { tmpdir } from "node:os";
|
|
2480
2570
|
import path10 from "node:path";
|
|
2481
2571
|
import { Readable } from "node:stream";
|
|
2572
|
+
function appsBaseUrl(target) {
|
|
2573
|
+
return target.isOrganization ? `https://github.com/organizations/${encodeURIComponent(target.owner)}/settings/apps` : "https://github.com/settings/apps";
|
|
2574
|
+
}
|
|
2575
|
+
function appSettingsUrl(target, slug) {
|
|
2576
|
+
return `${appsBaseUrl(target)}/${encodeURIComponent(slug)}`;
|
|
2577
|
+
}
|
|
2578
|
+
function keyNotStoredMessage(target, created) {
|
|
2579
|
+
return `
|
|
2580
|
+
${errColors.bold(errColors.red("Stopping here:"))} the App exists but its key was not stored, so installing it now
|
|
2581
|
+
would achieve nothing. To recover, open the App and generate a private key from
|
|
2582
|
+
its "Private keys" section, then run \`verify\`; or delete the App and start again.
|
|
2583
|
+
|
|
2584
|
+
GITHUB_APP_ID=${created.id}
|
|
2585
|
+
App settings: ${link(appSettingsUrl(target, created.slug), errColors)}`;
|
|
2586
|
+
}
|
|
2587
|
+
function installStepMessage(target, slug) {
|
|
2588
|
+
return `
|
|
2589
|
+
${step(2, `Install it on ${target.owner}/${target.repo}:`)}
|
|
2590
|
+
|
|
2591
|
+
${link(`${appSettingsUrl(target, slug)}/installations`)}
|
|
2592
|
+
|
|
2593
|
+
That page shows an Install button first \u2014 the repository picker only appears after
|
|
2594
|
+
you click it. Choose "Only select repositories" and pick that one repository.
|
|
2595
|
+
`;
|
|
2596
|
+
}
|
|
2482
2597
|
function manifestPostUrl(target, state) {
|
|
2483
|
-
const base =
|
|
2598
|
+
const base = `${appsBaseUrl(target)}/new`;
|
|
2484
2599
|
return `${base}?state=${encodeURIComponent(state)}`;
|
|
2485
2600
|
}
|
|
2486
2601
|
function appManifest(target, redirectUrl, name = appName(target.repo)) {
|
|
@@ -2784,7 +2899,7 @@ async function handOffWithRetry(pem, destination) {
|
|
|
2784
2899
|
const result = await handOffKey(pem, attempt);
|
|
2785
2900
|
if (result.stored) {
|
|
2786
2901
|
console.log(`
|
|
2787
|
-
|
|
2902
|
+
${tick(`Private key: ${result.detail}`)}`);
|
|
2788
2903
|
return true;
|
|
2789
2904
|
}
|
|
2790
2905
|
console.error(`
|
|
@@ -2884,41 +2999,41 @@ No installation of this App found on ${target.owner}/${target.repo} (HTTP ${foun
|
|
|
2884
2999
|
}
|
|
2885
3000
|
const installation = found.body;
|
|
2886
3001
|
console.log(`
|
|
2887
|
-
|
|
3002
|
+
${outColors.bold(`Installation ${installation.id}`)} on ${target.owner}/${target.repo}`);
|
|
2888
3003
|
const findings = readbackVerdict(installation);
|
|
2889
3004
|
if (findings.length === 0) {
|
|
2890
|
-
console.log(" grant matches exactly what this package needs:");
|
|
3005
|
+
console.log(" The grant matches exactly what this package needs:");
|
|
2891
3006
|
for (const [name, level] of Object.entries(CANOPY_APP_PERMISSIONS)) {
|
|
2892
|
-
console.log(`
|
|
3007
|
+
console.log(` ${tick(`${name}: ${level}`)}`);
|
|
2893
3008
|
}
|
|
2894
3009
|
} else {
|
|
2895
3010
|
for (const finding of findings) {
|
|
2896
|
-
console.error(`
|
|
3011
|
+
console.error(` ${cross(finding.message)}`);
|
|
2897
3012
|
}
|
|
2898
3013
|
}
|
|
2899
3014
|
let installationsOk = false;
|
|
2900
3015
|
const installations = await installationCount(jwt);
|
|
2901
3016
|
if (installations === null) {
|
|
2902
|
-
console.error(`
|
|
3017
|
+
console.error(` ${failMark} could not list this App's installations, so "installed once" is UNCHECKED.
|
|
2903
3018
|
Reported as a failure rather than passed over: this is the check that observes
|
|
2904
3019
|
the one-App-per-site rule, and an unread check is not a satisfied one.`);
|
|
2905
3020
|
} else if (installations === 1) {
|
|
2906
3021
|
installationsOk = true;
|
|
2907
|
-
console.log("
|
|
3022
|
+
console.log(` ${tick("installed once, so this key reaches no other account")}`);
|
|
2908
3023
|
} else if (installations > 1) {
|
|
2909
|
-
console.error(`
|
|
3024
|
+
console.error(` ${failMark} this App is installed ${installations} times, and should be installed ONCE.
|
|
2910
3025
|
Its private key is App-level: whoever holds it can mint a token for any of
|
|
2911
3026
|
those installations. Register a separate App per site instead, and remove
|
|
2912
3027
|
the installations that do not belong to this one.`);
|
|
2913
3028
|
} else {
|
|
2914
|
-
console.error(`
|
|
3029
|
+
console.error(` ${failMark} GitHub reports ${installations} installations of this App, yet one was just read
|
|
2915
3030
|
back for this repository. Something is inconsistent; re-run before trusting it.`);
|
|
2916
3031
|
}
|
|
2917
3032
|
const mint = await proveTokenMint(jwt, installation.id, target.repo);
|
|
2918
3033
|
if (mint.ok) {
|
|
2919
|
-
console.log(`
|
|
3034
|
+
console.log(` ${tick(`installation token ${mint.detail}`)}`);
|
|
2920
3035
|
} else {
|
|
2921
|
-
console.error(`
|
|
3036
|
+
console.error(` ${failMark} could not mint an installation token \u2014 ${mint.detail}
|
|
2922
3037
|
If that message says the requested permissions are not granted to this
|
|
2923
3038
|
installation, that is a GitHub behaviour rather than a bug here: adding a
|
|
2924
3039
|
permission to an App does NOT apply to existing installations until an account
|
|
@@ -2994,7 +3109,7 @@ async function createCommand(options) {
|
|
|
2994
3109
|
console.log(`! Could not check whether the name "${name}" is already taken, so this is unverified.
|
|
2995
3110
|
`);
|
|
2996
3111
|
}
|
|
2997
|
-
console.log(
|
|
3112
|
+
console.log(recoveryPreamble());
|
|
2998
3113
|
const state = randomUUID();
|
|
2999
3114
|
let formDir;
|
|
3000
3115
|
let callback;
|
|
@@ -3017,29 +3132,15 @@ async function createCommand(options) {
|
|
|
3017
3132
|
formDir = await mkdtemp(path10.join(tmpdir(), "canopycms-app-"));
|
|
3018
3133
|
const formFile = path10.join(formDir, `create-${slug}.html`);
|
|
3019
3134
|
await writeFile2(formFile, creationForm(postUrl, manifest), { mode: 384, flag: "wx" });
|
|
3020
|
-
console.log(
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
1. Open this file in a browser:
|
|
3030
|
-
|
|
3031
|
-
${formFile}
|
|
3032
|
-
|
|
3033
|
-
The browser matters, twice over. It must be LOGGED IN TO GITHUB as an owner of
|
|
3034
|
-
${target.owner}, and it must be running on THIS machine \u2014 the redirect comes back to
|
|
3035
|
-
127.0.0.1:${callback.port}, which only a local browser can reach. An embedded or
|
|
3036
|
-
app-internal browser bounces off the GitHub login wall and simply appears to do
|
|
3037
|
-
nothing when you click Create.
|
|
3038
|
-
|
|
3039
|
-
The page posts the manifest to GitHub, which shows you the App pre-filled with
|
|
3040
|
-
exactly those permissions. Review them and click Create.
|
|
3041
|
-
|
|
3042
|
-
Waiting for GitHub to redirect back (up to ${CALLBACK_TIMEOUT_MS / 6e4} minutes)...`);
|
|
3135
|
+
console.log(registrationMessage({
|
|
3136
|
+
name,
|
|
3137
|
+
owner: target.owner,
|
|
3138
|
+
repo: target.repo,
|
|
3139
|
+
destination: describeDestination(destination),
|
|
3140
|
+
formFile,
|
|
3141
|
+
callbackPort: callback.port,
|
|
3142
|
+
timeoutMinutes: CALLBACK_TIMEOUT_MS / 6e4
|
|
3143
|
+
}));
|
|
3043
3144
|
let code;
|
|
3044
3145
|
try {
|
|
3045
3146
|
code = await callback.code;
|
|
@@ -3054,32 +3155,20 @@ ${getErrorMessage(err2)}.
|
|
|
3054
3155
|
See the recovery note printed above if the App was in fact created.`);
|
|
3055
3156
|
return 1;
|
|
3056
3157
|
}
|
|
3057
|
-
console.log(
|
|
3158
|
+
console.log(`
|
|
3159
|
+
${tick("Got the manifest code; exchanging it for the App credentials")}`);
|
|
3058
3160
|
const created = await convertManifest(code);
|
|
3059
3161
|
if (!created) {
|
|
3060
3162
|
console.error(' the exchange failed, so this command never received the private key.\n\n Do NOT simply re-run `create`: it submits a fresh manifest and would register a\n SECOND App. The App you just created almost certainly exists \u2014 open it, generate\n a key from its "Private keys" section (see the recovery note above), and then run\n `canopycms init-github-app verify`. Delete the App instead if you would rather\n start over.');
|
|
3061
3163
|
return 1;
|
|
3062
3164
|
}
|
|
3063
|
-
console.log(`
|
|
3165
|
+
console.log(tick(`Created App ${outColors.bold(created.slug)} (id ${created.id}); private key captured, sending it to ${describeDestination(destination)}`));
|
|
3064
3166
|
const stored = await handOffWithRetry(created.pem, destination);
|
|
3065
3167
|
if (!stored) {
|
|
3066
|
-
console.error(
|
|
3067
|
-
Stopping here: the App exists but its key was not stored, so installing it now
|
|
3068
|
-
would achieve nothing. To recover, open the App and generate a private key from
|
|
3069
|
-
its "Private keys" section, then run \`verify\`; or delete the App and start again.
|
|
3070
|
-
|
|
3071
|
-
GITHUB_APP_ID=${created.id}
|
|
3072
|
-
App settings: https://github.com/settings/apps/${created.slug}`);
|
|
3168
|
+
console.error(keyNotStoredMessage(target, created));
|
|
3073
3169
|
return 1;
|
|
3074
3170
|
}
|
|
3075
|
-
console.log(
|
|
3076
|
-
2. Install it on ${target.owner}/${target.repo}:
|
|
3077
|
-
|
|
3078
|
-
https://github.com/settings/apps/${created.slug}/installations
|
|
3079
|
-
|
|
3080
|
-
That page shows an Install button first \u2014 the repository picker only appears after
|
|
3081
|
-
you click it. Choose "Only select repositories" and pick that one repository.
|
|
3082
|
-
`);
|
|
3171
|
+
console.log(installStepMessage(target, created.slug));
|
|
3083
3172
|
await pressEnter(" Press Enter once it is installed.");
|
|
3084
3173
|
let readback;
|
|
3085
3174
|
try {
|
|
@@ -3090,19 +3179,7 @@ Stopping here: the App exists but its key was not stored, so installing it now
|
|
|
3090
3179
|
This says nothing about the App or the key \u2014 re-run \`canopycms init-github-app verify\`.`);
|
|
3091
3180
|
readback = { ok: false, installationId: null };
|
|
3092
3181
|
}
|
|
3093
|
-
console.log(
|
|
3094
|
-
Set these on your deployment:
|
|
3095
|
-
|
|
3096
|
-
GITHUB_APP_ID=${created.id}
|
|
3097
|
-
GITHUB_APP_INSTALLATION_ID=${readback.installationId ?? "<run `verify` to read it>"}
|
|
3098
|
-
GITHUB_APP_PRIVATE_KEY_SECRET_ARN=<wherever you just put the key>
|
|
3099
|
-
|
|
3100
|
-
Both ids are numeric. The App ID is NOT the "Client ID" (\`Iv1.\u2026\`) shown beside it,
|
|
3101
|
-
and the installation id is NOT the App ID \u2014 an App installed twice has one App ID
|
|
3102
|
-
and two installation ids.
|
|
3103
|
-
|
|
3104
|
-
Re-check this any time, without creating anything:
|
|
3105
|
-
canopycms init-github-app verify --app-id ${created.id} --key-file <path>`);
|
|
3182
|
+
console.log(deploymentSettingsMessage(created.id, readback.installationId));
|
|
3106
3183
|
return stored && readback.ok ? 0 : 1;
|
|
3107
3184
|
} finally {
|
|
3108
3185
|
callback.close();
|
|
@@ -3147,6 +3224,7 @@ var init_init_github_app = __esm({
|
|
|
3147
3224
|
init_error();
|
|
3148
3225
|
init_github_auth();
|
|
3149
3226
|
init_github_app_manifest();
|
|
3227
|
+
init_github_app_output();
|
|
3150
3228
|
init_prompt();
|
|
3151
3229
|
CALLBACK_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
3152
3230
|
REQUEST_TIMEOUT_MS = 3e4;
|
|
@@ -3710,6 +3788,70 @@ function isBlockStructuralKey(key) {
|
|
|
3710
3788
|
function createDebugLogger2(options) {
|
|
3711
3789
|
return new DebugLogger2(options);
|
|
3712
3790
|
}
|
|
3791
|
+
function startOf(node) {
|
|
3792
|
+
return node?.position?.start.offset;
|
|
3793
|
+
}
|
|
3794
|
+
function endOf(node) {
|
|
3795
|
+
return node?.position?.end.offset;
|
|
3796
|
+
}
|
|
3797
|
+
function apply(source, edits, from = 0, to = source.length) {
|
|
3798
|
+
let out = "";
|
|
3799
|
+
let at = from;
|
|
3800
|
+
for (const edit of [...edits].sort((a, b) => a.start - b.start)) {
|
|
3801
|
+
if (edit.start < at || edit.end > to)
|
|
3802
|
+
continue;
|
|
3803
|
+
out += source.slice(at, edit.start) + edit.text;
|
|
3804
|
+
at = edit.end;
|
|
3805
|
+
}
|
|
3806
|
+
return out + source.slice(at, to);
|
|
3807
|
+
}
|
|
3808
|
+
function underscoreStarts(node) {
|
|
3809
|
+
const bare = startOf(node) === startOf(node.children?.[0]);
|
|
3810
|
+
if (node.type === "link" && !bare || node.type === "linkReference")
|
|
3811
|
+
return [];
|
|
3812
|
+
if (node.type === "text" || node.type === "mdxTextExpression") {
|
|
3813
|
+
const start = startOf(node);
|
|
3814
|
+
return start !== void 0 && (node.value ?? "").includes("_") ? [start] : [];
|
|
3815
|
+
}
|
|
3816
|
+
return (node.children ?? []).flatMap(underscoreStarts);
|
|
3817
|
+
}
|
|
3818
|
+
function orderedNumber(numbers, index) {
|
|
3819
|
+
const [first = 1, second, third] = numbers;
|
|
3820
|
+
if (index === 0)
|
|
3821
|
+
return first;
|
|
3822
|
+
const ones = numbers.length > 1 && second === 1 && (first !== 0 || numbers.length < 3 || third === 1);
|
|
3823
|
+
return ones ? 1 : first + index;
|
|
3824
|
+
}
|
|
3825
|
+
function restyleMarkdown(source, tree, fixed, readsBack) {
|
|
3826
|
+
if (source.startsWith("\uFEFF"))
|
|
3827
|
+
return void 0;
|
|
3828
|
+
const blocks = tree.children ?? [];
|
|
3829
|
+
const groups = blocks.map(() => []);
|
|
3830
|
+
new Restyler(source).children(tree, [], [], fixed, (index) => groups[index] ?? []);
|
|
3831
|
+
const changed = groups.filter((group) => group.length > 0);
|
|
3832
|
+
if (changed.length === 0)
|
|
3833
|
+
return void 0;
|
|
3834
|
+
let kept = [];
|
|
3835
|
+
let best;
|
|
3836
|
+
let budget = 8 * Math.ceil(Math.log2(changed.length + 1)) + 8;
|
|
3837
|
+
const attempt = (tried) => {
|
|
3838
|
+
if (budget-- <= 0)
|
|
3839
|
+
return;
|
|
3840
|
+
const trial = [...kept, ...tried.flat()];
|
|
3841
|
+
const text3 = apply(source, trial);
|
|
3842
|
+
const parsed = readsBack(text3);
|
|
3843
|
+
if (parsed !== void 0) {
|
|
3844
|
+
kept = trial;
|
|
3845
|
+
best = { text: text3, tree: parsed };
|
|
3846
|
+
} else if (tried.length > 1) {
|
|
3847
|
+
const half = Math.ceil(tried.length / 2);
|
|
3848
|
+
attempt(tried.slice(0, half));
|
|
3849
|
+
attempt(tried.slice(half));
|
|
3850
|
+
}
|
|
3851
|
+
};
|
|
3852
|
+
attempt(changed);
|
|
3853
|
+
return best;
|
|
3854
|
+
}
|
|
3713
3855
|
function snapshotDocument(doc) {
|
|
3714
3856
|
const items = /* @__PURE__ */ new Map();
|
|
3715
3857
|
const visitNode = (node) => {
|
|
@@ -3823,15 +3965,15 @@ function canonical(node) {
|
|
|
3823
3965
|
function kindOf(node) {
|
|
3824
3966
|
return `${node.type}:${String(node.ordered ?? "")}:${String(node.checked ?? "")}`;
|
|
3825
3967
|
}
|
|
3826
|
-
function
|
|
3968
|
+
function startOf2(node) {
|
|
3827
3969
|
return node?.position?.start.offset;
|
|
3828
3970
|
}
|
|
3829
|
-
function
|
|
3971
|
+
function endOf2(node) {
|
|
3830
3972
|
return node?.position?.end.offset;
|
|
3831
3973
|
}
|
|
3832
3974
|
function sliceOf(text3, node) {
|
|
3833
|
-
const start =
|
|
3834
|
-
const end =
|
|
3975
|
+
const start = startOf2(node);
|
|
3976
|
+
const end = endOf2(node);
|
|
3835
3977
|
return start === void 0 || end === void 0 ? void 0 : text3.slice(start, end);
|
|
3836
3978
|
}
|
|
3837
3979
|
function reindent(text3, from, to) {
|
|
@@ -3895,12 +4037,12 @@ function leadWidth(text3, offset) {
|
|
|
3895
4037
|
return /^(?: |[-*+](?= )|\d{1,9}[.)](?= )|\[[ xX]\](?= ))*$/.test(lead) ? lead.length : void 0;
|
|
3896
4038
|
}
|
|
3897
4039
|
function gapBetween(text3, a, b) {
|
|
3898
|
-
const end =
|
|
3899
|
-
const start =
|
|
4040
|
+
const end = endOf2(a);
|
|
4041
|
+
const start = startOf2(b);
|
|
3900
4042
|
return end === void 0 || start === void 0 ? void 0 : text3.slice(end, start);
|
|
3901
4043
|
}
|
|
3902
4044
|
function listMarkers(text3, items, ordered) {
|
|
3903
|
-
const firstStart =
|
|
4045
|
+
const firstStart = startOf2(items[0]);
|
|
3904
4046
|
if (firstStart === void 0)
|
|
3905
4047
|
return void 0;
|
|
3906
4048
|
if (!ordered) {
|
|
@@ -3913,16 +4055,14 @@ function listMarkers(text3, items, ordered) {
|
|
|
3913
4055
|
const first = numberAt(firstStart);
|
|
3914
4056
|
if (first === null)
|
|
3915
4057
|
return void 0;
|
|
3916
|
-
const start = Number(first[1]);
|
|
3917
4058
|
const delimiter = first[2] ?? ".";
|
|
3918
4059
|
const padTo = first[1]?.startsWith("0") ? first[1].length : 0;
|
|
3919
|
-
const
|
|
3920
|
-
const step = second !== null && Number(second[1]) === start ? 0 : 1;
|
|
4060
|
+
const typed = items.map((item) => Number(numberAt(startOf2(item))?.[1]));
|
|
3921
4061
|
return (itemText, index) => {
|
|
3922
4062
|
const current = /^\d{1,9}[.)]/.exec(itemText);
|
|
3923
4063
|
if (current === null)
|
|
3924
4064
|
return void 0;
|
|
3925
|
-
const marker = `${String(
|
|
4065
|
+
const marker = `${String(orderedNumber(typed, index)).padStart(padTo, "0")}${delimiter}`;
|
|
3926
4066
|
if (marker.length !== current[0].length && itemText.includes("\n"))
|
|
3927
4067
|
return void 0;
|
|
3928
4068
|
return marker + itemText.slice(current[0].length);
|
|
@@ -3938,22 +4078,56 @@ function preserveMarkdownSource(original, updated, format) {
|
|
|
3938
4078
|
return updated;
|
|
3939
4079
|
}
|
|
3940
4080
|
}
|
|
4081
|
+
function diskBlocks(oNodes, nNodes) {
|
|
4082
|
+
const oKeys = oNodes.map(canonical);
|
|
4083
|
+
const nKeys = nNodes.map(canonical);
|
|
4084
|
+
const pairs = matchSequences(oKeys, nKeys);
|
|
4085
|
+
const fromDisk = new Set(pairs.map(([, ni]) => ni));
|
|
4086
|
+
const matched = new Set(pairs.map(([oi]) => oi));
|
|
4087
|
+
const unmatched = /* @__PURE__ */ new Map();
|
|
4088
|
+
oKeys.forEach((key, index) => {
|
|
4089
|
+
if (!matched.has(index))
|
|
4090
|
+
unmatched.set(key, (unmatched.get(key) ?? 0) + 1);
|
|
4091
|
+
});
|
|
4092
|
+
nKeys.forEach((key, index) => {
|
|
4093
|
+
const left = unmatched.get(key) ?? 0;
|
|
4094
|
+
if (fromDisk.has(index) || left === 0)
|
|
4095
|
+
return;
|
|
4096
|
+
unmatched.set(key, left - 1);
|
|
4097
|
+
fromDisk.add(index);
|
|
4098
|
+
});
|
|
4099
|
+
return fromDisk;
|
|
4100
|
+
}
|
|
3941
4101
|
function splice(original, updated, format) {
|
|
3942
|
-
const before = parse(original, format);
|
|
4102
|
+
const before = original === void 0 ? void 0 : parse(original, format);
|
|
3943
4103
|
const after = parse(updated, format);
|
|
3944
|
-
if (
|
|
4104
|
+
if (after === void 0)
|
|
3945
4105
|
return void 0;
|
|
3946
4106
|
const target = canonical(after);
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
4107
|
+
const fromDisk = diskBlocks(before?.children ?? [], after.children);
|
|
4108
|
+
const restyled = restyleMarkdown(updated, after, (index) => fromDisk.has(index), (text3) => {
|
|
4109
|
+
const tree = parse(text3, format);
|
|
4110
|
+
return tree !== void 0 && canonical(tree) === target ? tree : void 0;
|
|
4111
|
+
});
|
|
4112
|
+
if (original === void 0 || before === void 0)
|
|
4113
|
+
return restyled?.text;
|
|
4114
|
+
const asSent = { text: updated, tree: after };
|
|
4115
|
+
const edits = restyled === void 0 || restyled.text === updated ? [asSent] : [restyled, asSent];
|
|
4116
|
+
for (const edit of edits) {
|
|
4117
|
+
for (const deep of [true, false]) {
|
|
4118
|
+
const candidate = new Splicer(original, edit.text, deep).body(before, edit.tree);
|
|
4119
|
+
if (candidate === void 0)
|
|
4120
|
+
continue;
|
|
4121
|
+
const reparsed = parse(candidate, format);
|
|
4122
|
+
if (reparsed !== void 0 && canonical(reparsed) === target)
|
|
4123
|
+
return candidate;
|
|
4124
|
+
log2.debug("markdown-body-splice", "splice does not read back as the edit", {
|
|
4125
|
+
deep,
|
|
4126
|
+
restyled: edit !== asSent
|
|
4127
|
+
});
|
|
4128
|
+
}
|
|
3955
4129
|
}
|
|
3956
|
-
return
|
|
4130
|
+
return restyled?.text;
|
|
3957
4131
|
}
|
|
3958
4132
|
function createNode(ctx, value, asKey = false) {
|
|
3959
4133
|
const node = ctx.doc.createNode(value);
|
|
@@ -4238,7 +4412,7 @@ function writesFrontmatter(data) {
|
|
|
4238
4412
|
}
|
|
4239
4413
|
function bodyToWrite(body, data, format, existingRaw) {
|
|
4240
4414
|
const priorBody = existingRaw === void 0 ? void 0 : extractBody(existingRaw);
|
|
4241
|
-
const spliced =
|
|
4415
|
+
const spliced = preserveMarkdownSource(priorBody, body, format);
|
|
4242
4416
|
if (!writesFrontmatter(data)) {
|
|
4243
4417
|
const flush = spliced.replace(/^(?:\r?\n)+/, "");
|
|
4244
4418
|
return /^\uFEFF?---/.test(flush) ? `
|
|
@@ -7832,7 +8006,7 @@ async function generateAIContentCLI(options) {
|
|
|
7832
8006
|
console.log(` Output: ${result.outputDir}
|
|
7833
8007
|
`);
|
|
7834
8008
|
}
|
|
7835
|
-
var __defProp3, __getOwnPropNames3, __esm3, __export3, init_error3, init_atomic_write2, init_field_traversal, ITEM_KEY, ITEM_KEY_PATTERN, isItemKey, BASE58, isListField, init_item_keys, 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, referenceSortFieldSchema2, 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, seoFieldNameSchema2, seoSchema2, 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, envFlag2, 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, heldRoots, getFormatExtension, isDataOnlyFormat, asRecord, DEFAULT_SEO_FIELD_NAMES, asRecord2, 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,
|
|
8009
|
+
var __defProp3, __getOwnPropNames3, __esm3, __export3, init_error3, init_atomic_write2, init_field_traversal, ITEM_KEY, ITEM_KEY_PATTERN, isItemKey, BASE58, isListField, init_item_keys, 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, referenceSortFieldSchema2, referenceFieldSchema2, fieldHolder2, blockSchema2, blockFieldSchema2, objectFieldSchema2, inlineGroupFieldSchema2, customFieldSchema2, knownFieldSchema2, fieldSchema2, init_field2, relativePathSchema2, entryTypeSchema2, collectionSchema2, init_collection2, uploadTargetUrlSchema2, previewPrefixSchema2, editorUrlSchema2, init_url2, mediaSchema2, init_media2, defaultBranchAccessSchema2, defaultPathAccessLevelSchema2, defaultPathAccessLevelsSchema2, defaultPathAccessSchema2, defaultBaseBranchSchema2, defaultRemoteNameSchema2, defaultRemoteUrlSchema2, gitBotAuthorNameSchema2, gitBotAuthorEmailSchema2, githubTokenEnvVarSchema2, operatingModeSchema2, deployedAsSchema2, contentRootSchema2, sourceRootSchema2, basePathSchema2, deploymentNameSchema2, devContentSyncSchema2, devConfigSchema2, editorConfigSchema2, seoFieldNameSchema2, seoSchema2, 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, envFlag2, LOG_LEVELS2, DebugLogger2, testLogger2, MARKDOWN_EXPORT_OPTIONS, BULLETS, DELIMITERS, EMPHASIS, STRONG, RULE, WORD_CHAR, GAP, Restyler, 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, heldRoots, getFormatExtension, isDataOnlyFormat, asRecord, DEFAULT_SEO_FIELD_NAMES, asRecord2, asText, asFlag, asImageUrl, asOgType, asTwitterCard, RESTRICTED_REFERENCE_MARKER, SEO_GROUP_FIELDS, MAX_WARNED, warned4, SchemaUnavailableError, BASE58_PATTERN, CONTENT_ID_PATTERN, PHYSICAL_SEGMENT_PATTERN, isValidId, parseTypedFilename, EMPTY_LOGICAL_PATH, ENTRY_EXTENSIONS, ContentIdIndex, 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, RESERVED_SETTINGS_BRANCH_PREFIX, BranchPathError, resolveContentBranchesRoot, ContentStoreError, ContentConflictError, EntryGoneError, BranchSyncingError, DuplicateContentIdError, UrlPathConflictError, isEmptyFieldValue, 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;
|
|
7836
8010
|
var init_generate_ai_content = __esm({
|
|
7837
8011
|
"dist/cli/generate-ai-content.js"() {
|
|
7838
8012
|
"use strict";
|
|
@@ -8285,6 +8459,14 @@ var init_generate_ai_content = __esm({
|
|
|
8285
8459
|
previewPrefixSchema2 = z42.string().trim().refine((value) => isHttpUrlOrSameOriginPath2(value), {
|
|
8286
8460
|
message: 'editor.previewPrefix must be an absolute http(s) URL or a site-relative path beginning with a single "/", with no query or fragment'
|
|
8287
8461
|
});
|
|
8462
|
+
editorUrlSchema2 = z42.string().trim().refine((value) => {
|
|
8463
|
+
if (!isHttpUrlOrSameOriginPath2(value) || !/^https?:\/\//i.test(value))
|
|
8464
|
+
return false;
|
|
8465
|
+
const url = new URL(value);
|
|
8466
|
+
return !url.username && !url.password;
|
|
8467
|
+
}, {
|
|
8468
|
+
message: "editorUrl must be an absolute http(s) URL with no credentials, query or fragment"
|
|
8469
|
+
});
|
|
8288
8470
|
}
|
|
8289
8471
|
});
|
|
8290
8472
|
init_media2 = __esm3({
|
|
@@ -8427,6 +8609,7 @@ var init_generate_ai_content = __esm({
|
|
|
8427
8609
|
contentRoot: contentRootSchema2.default("content"),
|
|
8428
8610
|
sourceRoot: sourceRootSchema2.optional(),
|
|
8429
8611
|
basePath: basePathSchema2,
|
|
8612
|
+
editorUrl: editorUrlSchema2.optional(),
|
|
8430
8613
|
unauthenticatedStatus: z6.union([z6.literal(401), z6.literal(419)]).optional(),
|
|
8431
8614
|
danglingReferences: z6.enum(["error", "warn"]).optional(),
|
|
8432
8615
|
editor: editorConfigSchema2.optional(),
|
|
@@ -8796,6 +8979,360 @@ var init_generate_ai_content = __esm({
|
|
|
8796
8979
|
});
|
|
8797
8980
|
init_error3();
|
|
8798
8981
|
init_error3();
|
|
8982
|
+
MARKDOWN_EXPORT_OPTIONS = {
|
|
8983
|
+
listItemIndent: "one",
|
|
8984
|
+
bullet: "-",
|
|
8985
|
+
emphasis: "_",
|
|
8986
|
+
strong: "*",
|
|
8987
|
+
rule: "-"
|
|
8988
|
+
};
|
|
8989
|
+
BULLETS = [MARKDOWN_EXPORT_OPTIONS.bullet, "*"];
|
|
8990
|
+
DELIMITERS = [".", ")"];
|
|
8991
|
+
EMPHASIS = MARKDOWN_EXPORT_OPTIONS.emphasis;
|
|
8992
|
+
STRONG = MARKDOWN_EXPORT_OPTIONS.strong.repeat(2);
|
|
8993
|
+
RULE = MARKDOWN_EXPORT_OPTIONS.rule.repeat(3);
|
|
8994
|
+
WORD_CHAR = /[^\s\p{P}\p{S}]/u;
|
|
8995
|
+
GAP = /^[ \t>]*(?:\r?\n[ \t>]*)+$/;
|
|
8996
|
+
Restyler = class {
|
|
8997
|
+
constructor(source) {
|
|
8998
|
+
this.source = source;
|
|
8999
|
+
this.listMarker = /* @__PURE__ */ new Map();
|
|
9000
|
+
this.underscores = /* @__PURE__ */ new Map();
|
|
9001
|
+
}
|
|
9002
|
+
/** Edits for `node` and everything under it, given its ancestors (nearest last). */
|
|
9003
|
+
collect(node, ancestors, out) {
|
|
9004
|
+
const inside = [...ancestors, node];
|
|
9005
|
+
switch (node.type) {
|
|
9006
|
+
case "emphasis":
|
|
9007
|
+
this.emphasis(node, ancestors, out);
|
|
9008
|
+
break;
|
|
9009
|
+
case "strong":
|
|
9010
|
+
this.strong(node, out);
|
|
9011
|
+
break;
|
|
9012
|
+
case "text":
|
|
9013
|
+
this.text(node, ancestors, out);
|
|
9014
|
+
return;
|
|
9015
|
+
case "thematicBreak":
|
|
9016
|
+
this.replaceWhole(node, this.ruleIn(ancestors), out);
|
|
9017
|
+
return;
|
|
9018
|
+
case "code":
|
|
9019
|
+
this.fence(node, out);
|
|
9020
|
+
return;
|
|
9021
|
+
case "heading":
|
|
9022
|
+
this.heading(node, inside, out);
|
|
9023
|
+
return;
|
|
9024
|
+
case "table":
|
|
9025
|
+
this.table(node, inside, out);
|
|
9026
|
+
return;
|
|
9027
|
+
default:
|
|
9028
|
+
break;
|
|
9029
|
+
}
|
|
9030
|
+
this.children(node, inside, out);
|
|
9031
|
+
}
|
|
9032
|
+
/**
|
|
9033
|
+
* Edits for `parent`'s children and the gaps between them. `fixed` names children whose text
|
|
9034
|
+
* must stay as it is (untouched top-level blocks); their lists still count for alternation.
|
|
9035
|
+
*/
|
|
9036
|
+
children(parent, inside, out, fixed = () => false, outFor = () => out) {
|
|
9037
|
+
const children = parent.children ?? [];
|
|
9038
|
+
const markers = this.listMarkers(children, fixed);
|
|
9039
|
+
children.forEach((child, index) => {
|
|
9040
|
+
if (fixed(index))
|
|
9041
|
+
return;
|
|
9042
|
+
const edits = outFor(index);
|
|
9043
|
+
const marker = markers.get(child);
|
|
9044
|
+
if (marker !== void 0)
|
|
9045
|
+
this.list(child, marker, edits);
|
|
9046
|
+
this.collect(child, inside, edits);
|
|
9047
|
+
});
|
|
9048
|
+
const always = parent.type === "root" || parent.type === "blockquote";
|
|
9049
|
+
const spaced = always || parent.type === "list" || parent.type === "listItem";
|
|
9050
|
+
if (!spaced)
|
|
9051
|
+
return;
|
|
9052
|
+
for (let index = 1; index < children.length; index++) {
|
|
9053
|
+
if (fixed(index) && fixed(index - 1))
|
|
9054
|
+
continue;
|
|
9055
|
+
this.gap(children[index - 1], children[index], always, outFor(fixed(index) ? index - 1 : index));
|
|
9056
|
+
}
|
|
9057
|
+
}
|
|
9058
|
+
/** The marker each list among `children` takes: its own, then alternating with the one before. */
|
|
9059
|
+
listMarkers(children, fixed) {
|
|
9060
|
+
const markers = /* @__PURE__ */ new Map();
|
|
9061
|
+
let previous;
|
|
9062
|
+
children.forEach((child, index) => {
|
|
9063
|
+
if (child.type !== "list") {
|
|
9064
|
+
previous = void 0;
|
|
9065
|
+
return;
|
|
9066
|
+
}
|
|
9067
|
+
const ordered = Boolean(child.ordered);
|
|
9068
|
+
const current = this.markerOf(child);
|
|
9069
|
+
if (current === void 0) {
|
|
9070
|
+
previous = void 0;
|
|
9071
|
+
return;
|
|
9072
|
+
}
|
|
9073
|
+
let marker = current;
|
|
9074
|
+
if (!fixed(index)) {
|
|
9075
|
+
const choices = ordered ? DELIMITERS : BULLETS;
|
|
9076
|
+
const next = children[index + 1];
|
|
9077
|
+
const nextFixed = next?.type === "list" && Boolean(next.ordered) === ordered && fixed(index + 1) ? this.markerOf(next) : void 0;
|
|
9078
|
+
const before = previous?.ordered === ordered ? previous.marker : void 0;
|
|
9079
|
+
marker = choices.find((choice) => choice !== before && choice !== nextFixed) ?? current;
|
|
9080
|
+
markers.set(child, marker);
|
|
9081
|
+
}
|
|
9082
|
+
this.listMarker.set(child, marker);
|
|
9083
|
+
previous = { ordered, marker };
|
|
9084
|
+
});
|
|
9085
|
+
return markers;
|
|
9086
|
+
}
|
|
9087
|
+
/**
|
|
9088
|
+
* A rule's text: `---`, but inside a list Prettier writes `***`, or `---` when the list takes
|
|
9089
|
+
* the alternate marker.
|
|
9090
|
+
*/
|
|
9091
|
+
ruleIn(ancestors) {
|
|
9092
|
+
const list = [...ancestors].reverse().find((a) => a.type === "list");
|
|
9093
|
+
if (list === void 0)
|
|
9094
|
+
return RULE;
|
|
9095
|
+
const marker = this.listMarker.get(list);
|
|
9096
|
+
return marker === BULLETS[0] || marker === DELIMITERS[0] ? "***" : RULE;
|
|
9097
|
+
}
|
|
9098
|
+
/** A list's bullet, or its ordered delimiter, read from its first item. */
|
|
9099
|
+
markerOf(list) {
|
|
9100
|
+
const at = startOf(list.children?.[0]);
|
|
9101
|
+
if (at === void 0)
|
|
9102
|
+
return void 0;
|
|
9103
|
+
if (!list.ordered)
|
|
9104
|
+
return this.source[at];
|
|
9105
|
+
return /^\d{1,9}([.)])/.exec(this.source.slice(at, at + 10))?.[1];
|
|
9106
|
+
}
|
|
9107
|
+
/** Item markers: the list's bullet or delimiter, and Prettier's numbering where widths allow. */
|
|
9108
|
+
list(list, marker, out) {
|
|
9109
|
+
const items = list.children ?? [];
|
|
9110
|
+
const starts = items.map(startOf);
|
|
9111
|
+
if (!list.ordered) {
|
|
9112
|
+
for (const at of starts) {
|
|
9113
|
+
if (at !== void 0 && this.source[at] !== marker) {
|
|
9114
|
+
out.push({ start: at, end: at + 1, text: marker });
|
|
9115
|
+
}
|
|
9116
|
+
}
|
|
9117
|
+
return;
|
|
9118
|
+
}
|
|
9119
|
+
const numbers = starts.map((at) => at === void 0 ? null : /^(\d{1,9})[.)]/.exec(this.source.slice(at, at + 11)));
|
|
9120
|
+
const typed = numbers.map((match) => Number(match?.[1]));
|
|
9121
|
+
const renumber = numbers.every((match, i) => match !== null && String(orderedNumber(typed, i)).length === match[1]?.length);
|
|
9122
|
+
numbers.forEach((match, i) => {
|
|
9123
|
+
const at = starts[i];
|
|
9124
|
+
if (match === null || at === void 0)
|
|
9125
|
+
return;
|
|
9126
|
+
const digits = match[1] ?? "";
|
|
9127
|
+
const wanted = renumber ? String(orderedNumber(typed, i)) : digits;
|
|
9128
|
+
if (wanted !== digits || match[0].slice(-1) !== marker) {
|
|
9129
|
+
out.push({ start: at, end: at + match[0].length, text: wanted + marker });
|
|
9130
|
+
}
|
|
9131
|
+
});
|
|
9132
|
+
}
|
|
9133
|
+
/**
|
|
9134
|
+
* The gap between two siblings with exactly one blank line, kept in the container's own
|
|
9135
|
+
* prefix and line ending; where `always` is false, only a gap that had a blank line.
|
|
9136
|
+
*/
|
|
9137
|
+
gap(a, b, always, out) {
|
|
9138
|
+
const end = this.contentEnd(a);
|
|
9139
|
+
const start = startOf(b);
|
|
9140
|
+
if (end === void 0 || start === void 0)
|
|
9141
|
+
return;
|
|
9142
|
+
const gap = this.source.slice(end, start);
|
|
9143
|
+
if (!GAP.test(gap))
|
|
9144
|
+
return;
|
|
9145
|
+
const lines = gap.split(/\r?\n/);
|
|
9146
|
+
if (!always && lines.length < 3)
|
|
9147
|
+
return;
|
|
9148
|
+
const eol = gap.includes("\r\n") ? "\r\n" : "\n";
|
|
9149
|
+
const prefix = lines[lines.length - 1] ?? "";
|
|
9150
|
+
const together = a?.type === "definition" && b?.type === "definition";
|
|
9151
|
+
const text3 = together ? eol + prefix : eol + prefix.trimEnd() + eol + prefix;
|
|
9152
|
+
if (text3 !== gap)
|
|
9153
|
+
out.push({ start: end, end: start, text: text3 });
|
|
9154
|
+
}
|
|
9155
|
+
/**
|
|
9156
|
+
* Where `node`'s last line of content ends: a list's position runs on over the blank lines
|
|
9157
|
+
* after it, which in a block quote are lines of `>`.
|
|
9158
|
+
*/
|
|
9159
|
+
contentEnd(node) {
|
|
9160
|
+
const start = startOf(node);
|
|
9161
|
+
let end = endOf(node);
|
|
9162
|
+
if (start === void 0 || end === void 0)
|
|
9163
|
+
return end;
|
|
9164
|
+
for (; ; ) {
|
|
9165
|
+
const lineStart = this.source.lastIndexOf("\n", end - 1);
|
|
9166
|
+
if (lineStart <= start || !/^[ \t>]*$/.test(this.source.slice(lineStart + 1, end)))
|
|
9167
|
+
break;
|
|
9168
|
+
end = this.source[lineStart - 1] === "\r" ? lineStart - 1 : lineStart;
|
|
9169
|
+
}
|
|
9170
|
+
return end;
|
|
9171
|
+
}
|
|
9172
|
+
emphasis(node, ancestors, out) {
|
|
9173
|
+
const start = startOf(node);
|
|
9174
|
+
const end = endOf(node);
|
|
9175
|
+
if (start === void 0 || end === void 0)
|
|
9176
|
+
return;
|
|
9177
|
+
const open = this.source[start];
|
|
9178
|
+
if (open !== this.source[end - 1] || open !== "*" && open !== "_")
|
|
9179
|
+
return;
|
|
9180
|
+
const marker = ancestors.some((a) => a.type === "emphasis") || this.besideWord(start, end) || this.afterUnderscore(start, ancestors) ? "*" : EMPHASIS;
|
|
9181
|
+
if (open === marker)
|
|
9182
|
+
return;
|
|
9183
|
+
out.push({ start, end: start + 1, text: marker }, { start: end - 1, end, text: marker });
|
|
9184
|
+
}
|
|
9185
|
+
strong(node, out) {
|
|
9186
|
+
const start = startOf(node);
|
|
9187
|
+
const end = endOf(node);
|
|
9188
|
+
if (start === void 0 || end === void 0)
|
|
9189
|
+
return;
|
|
9190
|
+
if (this.source.slice(start, start + 2) !== "__" || this.source.slice(end - 2, end) !== "__") {
|
|
9191
|
+
return;
|
|
9192
|
+
}
|
|
9193
|
+
out.push({ start, end: start + 2, text: STRONG }, { start: end - 2, end, text: STRONG });
|
|
9194
|
+
}
|
|
9195
|
+
/** Whether the characters past the markers around `[start, end)` include a word character. */
|
|
9196
|
+
besideWord(start, end) {
|
|
9197
|
+
const markers = "*_";
|
|
9198
|
+
let before = start - 1;
|
|
9199
|
+
while (before >= 0 && markers.includes(this.source[before] ?? ""))
|
|
9200
|
+
before--;
|
|
9201
|
+
let after = end;
|
|
9202
|
+
while (after < this.source.length && markers.includes(this.source[after] ?? ""))
|
|
9203
|
+
after++;
|
|
9204
|
+
return WORD_CHAR.test(this.source[before] ?? " ") || WORD_CHAR.test(this.source[after] ?? " ");
|
|
9205
|
+
}
|
|
9206
|
+
afterUnderscore(start, ancestors) {
|
|
9207
|
+
const block = [...ancestors].reverse().find((a) => a.type === "paragraph" || a.type === "heading" || a.type === "tableCell");
|
|
9208
|
+
if (block === void 0)
|
|
9209
|
+
return false;
|
|
9210
|
+
let starts = this.underscores.get(block);
|
|
9211
|
+
if (starts === void 0) {
|
|
9212
|
+
starts = underscoreStarts(block);
|
|
9213
|
+
this.underscores.set(block, starts);
|
|
9214
|
+
}
|
|
9215
|
+
const link2 = [...ancestors].reverse().find((a) => a.type === "link" || a.type === "linkReference");
|
|
9216
|
+
const inLink = (link2?.children ?? []).flatMap(underscoreStarts);
|
|
9217
|
+
return [...starts, ...inLink].some((at) => at < start);
|
|
9218
|
+
}
|
|
9219
|
+
text(node, ancestors, out) {
|
|
9220
|
+
const start = startOf(node);
|
|
9221
|
+
const end = endOf(node);
|
|
9222
|
+
if (start === void 0 || end === void 0)
|
|
9223
|
+
return;
|
|
9224
|
+
const raw = this.source.slice(start, end);
|
|
9225
|
+
for (const match of raw.matchAll(/[ \t]+(?=\r?\n)/g)) {
|
|
9226
|
+
out.push({ start: start + match.index, end: start + match.index + match[0].length, text: "" });
|
|
9227
|
+
}
|
|
9228
|
+
if (ancestors.some((a) => a.type === "link" || a.type === "linkReference"))
|
|
9229
|
+
return;
|
|
9230
|
+
const block = [...ancestors].reverse().find((a) => a.type === "paragraph" || a.type === "heading" || a.type === "tableCell");
|
|
9231
|
+
const blockStart = startOf(block);
|
|
9232
|
+
const blockEnd = endOf(block);
|
|
9233
|
+
if (blockStart === void 0 || blockEnd === void 0)
|
|
9234
|
+
return;
|
|
9235
|
+
if (/\$|\[\[/.test(this.source.slice(blockStart, blockEnd)))
|
|
9236
|
+
return;
|
|
9237
|
+
for (const match of raw.matchAll(/(?<=[\p{L}\p{N}])\\_(?=[\p{L}\p{N}])/gu)) {
|
|
9238
|
+
out.push({ start: start + match.index, end: start + match.index + 1, text: "" });
|
|
9239
|
+
}
|
|
9240
|
+
}
|
|
9241
|
+
replaceWhole(node, text3, out) {
|
|
9242
|
+
const start = startOf(node);
|
|
9243
|
+
const end = endOf(node);
|
|
9244
|
+
if (start === void 0 || end === void 0)
|
|
9245
|
+
return;
|
|
9246
|
+
if (this.source.slice(start, end) !== text3)
|
|
9247
|
+
out.push({ start, end, text: text3 });
|
|
9248
|
+
}
|
|
9249
|
+
/** A `~~~` fence as backticks, when nothing inside it would end a backtick fence. */
|
|
9250
|
+
fence(node, out) {
|
|
9251
|
+
const start = startOf(node);
|
|
9252
|
+
const end = endOf(node);
|
|
9253
|
+
if (start === void 0 || end === void 0)
|
|
9254
|
+
return;
|
|
9255
|
+
const raw = this.source.slice(start, end);
|
|
9256
|
+
const close = /(?:\r?\n)[ \t>]*(~{3,})[ \t]*$/.exec(raw);
|
|
9257
|
+
if (!/^~~~(?!~)[^`\n]*\n/.test(raw) || close?.[1] === void 0 || raw.includes("`"))
|
|
9258
|
+
return;
|
|
9259
|
+
const closeAt = start + close.index + close[0].indexOf("~");
|
|
9260
|
+
out.push({ start, end: start + 3, text: "```" }, { start: closeAt, end: closeAt + close[1].length, text: "```" });
|
|
9261
|
+
}
|
|
9262
|
+
/** A one-line heading as `# x`, its content with its own edits. */
|
|
9263
|
+
heading(node, inside, out) {
|
|
9264
|
+
const inner = [];
|
|
9265
|
+
this.children(node, inside, inner);
|
|
9266
|
+
const children = node.children ?? [];
|
|
9267
|
+
const start = startOf(node);
|
|
9268
|
+
const end = endOf(node);
|
|
9269
|
+
const contentStart = startOf(children[0]);
|
|
9270
|
+
const contentEnd = endOf(children[children.length - 1]);
|
|
9271
|
+
if (start === void 0 || end === void 0 || contentStart === void 0 || contentEnd === void 0 || /[\r\n]/.test(this.source.slice(contentStart, contentEnd))) {
|
|
9272
|
+
out.push(...inner);
|
|
9273
|
+
return;
|
|
9274
|
+
}
|
|
9275
|
+
const content = apply(this.source, inner, contentStart, contentEnd);
|
|
9276
|
+
const text3 = `${"#".repeat(node.depth ?? 1)} ${content}`;
|
|
9277
|
+
if (text3 !== this.source.slice(start, end))
|
|
9278
|
+
out.push({ start, end, text: text3 });
|
|
9279
|
+
else
|
|
9280
|
+
out.push(...inner);
|
|
9281
|
+
}
|
|
9282
|
+
/** A table padded to its columns, as Prettier pads it; its cells keep their own text. */
|
|
9283
|
+
table(node, inside, out) {
|
|
9284
|
+
const start = startOf(node);
|
|
9285
|
+
const end = endOf(node);
|
|
9286
|
+
if (start === void 0 || end === void 0)
|
|
9287
|
+
return;
|
|
9288
|
+
const prefix = this.source.slice(this.source.lastIndexOf("\n", start - 1) + 1, start);
|
|
9289
|
+
const inner = [];
|
|
9290
|
+
const rows = (node.children ?? []).map((row) => (row.children ?? []).map((cell) => {
|
|
9291
|
+
const edits = [];
|
|
9292
|
+
this.children(cell, [...inside, row, cell], edits);
|
|
9293
|
+
inner.push(...edits);
|
|
9294
|
+
const content = cell.children ?? [];
|
|
9295
|
+
const from = startOf(content[0]);
|
|
9296
|
+
const to = endOf(content[content.length - 1]);
|
|
9297
|
+
return from === void 0 || to === void 0 ? "" : apply(this.source, edits, from, to);
|
|
9298
|
+
}));
|
|
9299
|
+
const plain = rows.every((row) => row.every((cell) => /^[\x20-\x7e]*$/.test(cell)));
|
|
9300
|
+
if (!plain || !/^[ \t>]*$/.test(prefix)) {
|
|
9301
|
+
out.push(...inner);
|
|
9302
|
+
return;
|
|
9303
|
+
}
|
|
9304
|
+
const align = node.align ?? [];
|
|
9305
|
+
const columns = Math.max(...rows.map((row) => row.length), align.length);
|
|
9306
|
+
const widths = Array.from({ length: columns }, (_, c) => Math.max(3, ...rows.map((row) => row[c]?.length ?? 0)));
|
|
9307
|
+
const pad = (text22, c) => {
|
|
9308
|
+
const room = (widths[c] ?? 3) - text22.length;
|
|
9309
|
+
if (align[c] === "right")
|
|
9310
|
+
return " ".repeat(room) + text22;
|
|
9311
|
+
if (align[c] === "center") {
|
|
9312
|
+
const left = Math.floor(room / 2);
|
|
9313
|
+
return " ".repeat(left) + text22 + " ".repeat(room - left);
|
|
9314
|
+
}
|
|
9315
|
+
return text22 + " ".repeat(room);
|
|
9316
|
+
};
|
|
9317
|
+
const delimiter = widths.map((width, c) => {
|
|
9318
|
+
const a = align[c];
|
|
9319
|
+
if (a === "left")
|
|
9320
|
+
return `:${"-".repeat(width - 1)}`;
|
|
9321
|
+
if (a === "right")
|
|
9322
|
+
return `${"-".repeat(width - 1)}:`;
|
|
9323
|
+
if (a === "center")
|
|
9324
|
+
return `:${"-".repeat(width - 2)}:`;
|
|
9325
|
+
return "-".repeat(width);
|
|
9326
|
+
});
|
|
9327
|
+
const line = (cells) => `| ${cells.join(" | ")} |`;
|
|
9328
|
+
const lines = rows.map((row) => line(row.map(pad)));
|
|
9329
|
+
lines.splice(1, 0, line(delimiter));
|
|
9330
|
+
const eol = this.source.slice(start, end).includes("\r\n") ? "\r\n" : "\n";
|
|
9331
|
+
const text3 = lines.join(eol + prefix);
|
|
9332
|
+
if (text3 !== this.source.slice(start, end))
|
|
9333
|
+
out.push({ start, end, text: text3 });
|
|
9334
|
+
}
|
|
9335
|
+
};
|
|
8799
9336
|
END = Symbol("end");
|
|
8800
9337
|
FRESH = Symbol("fresh");
|
|
8801
9338
|
LINE_WIDTH = 80;
|
|
@@ -9127,8 +9664,8 @@ var init_generate_ai_content = __esm({
|
|
|
9127
9664
|
body(before, after) {
|
|
9128
9665
|
const oNodes = before.children ?? [];
|
|
9129
9666
|
const nNodes = after.children ?? [];
|
|
9130
|
-
const first =
|
|
9131
|
-
const last =
|
|
9667
|
+
const first = startOf2(oNodes[0]);
|
|
9668
|
+
const last = endOf2(oNodes[oNodes.length - 1]);
|
|
9132
9669
|
if (first === void 0 || last === void 0 || nNodes.length === 0)
|
|
9133
9670
|
return void 0;
|
|
9134
9671
|
const o = { text: this.original, indent: "" };
|
|
@@ -9236,9 +9773,9 @@ var init_generate_ai_content = __esm({
|
|
|
9236
9773
|
item(o, oItem, n, nItem) {
|
|
9237
9774
|
const oChildren = oItem.children ?? [];
|
|
9238
9775
|
const nChildren = nItem.children ?? [];
|
|
9239
|
-
const oStart =
|
|
9240
|
-
const oContent =
|
|
9241
|
-
const nContent =
|
|
9776
|
+
const oStart = startOf2(oItem);
|
|
9777
|
+
const oContent = startOf2(oChildren[0]);
|
|
9778
|
+
const nContent = startOf2(nChildren[0]);
|
|
9242
9779
|
if (oStart === void 0 || oContent === void 0 || nContent === void 0)
|
|
9243
9780
|
return void 0;
|
|
9244
9781
|
const prefix = o.text.slice(oStart, oContent);
|
|
@@ -9417,7 +9954,32 @@ var init_generate_ai_content = __esm({
|
|
|
9417
9954
|
isValidId = isValidContentId;
|
|
9418
9955
|
init_error3();
|
|
9419
9956
|
init_logger2();
|
|
9957
|
+
parseTypedFilename = (filename, entryTypes) => {
|
|
9958
|
+
if (filename.startsWith("."))
|
|
9959
|
+
return null;
|
|
9960
|
+
const lastDot = filename.lastIndexOf(".");
|
|
9961
|
+
if (lastDot === -1)
|
|
9962
|
+
return null;
|
|
9963
|
+
const nameWithoutExt = filename.slice(0, lastDot);
|
|
9964
|
+
const parts = nameWithoutExt.split(".");
|
|
9965
|
+
if (parts.length < 3)
|
|
9966
|
+
return null;
|
|
9967
|
+
const potentialType = parts[0];
|
|
9968
|
+
if (entryTypes && !entryTypes.some((e) => e.name === potentialType)) {
|
|
9969
|
+
return null;
|
|
9970
|
+
}
|
|
9971
|
+
const id = parts[parts.length - 1];
|
|
9972
|
+
if (!isValidId(id))
|
|
9973
|
+
return null;
|
|
9974
|
+
const slug = parts.slice(1, -1).join(".").toLowerCase();
|
|
9975
|
+
return {
|
|
9976
|
+
type: potentialType,
|
|
9977
|
+
slug,
|
|
9978
|
+
id
|
|
9979
|
+
};
|
|
9980
|
+
};
|
|
9420
9981
|
EMPTY_LOGICAL_PATH = "";
|
|
9982
|
+
ENTRY_EXTENSIONS = new Set(Object.keys({ md: true, mdx: true, json: true, yaml: true }).map((format) => getFormatExtension(format)));
|
|
9421
9983
|
ContentIdIndex = class {
|
|
9422
9984
|
constructor(root) {
|
|
9423
9985
|
this.idToLocation = /* @__PURE__ */ new Map();
|
|
@@ -9705,30 +10267,6 @@ var init_generate_ai_content = __esm({
|
|
|
9705
10267
|
}
|
|
9706
10268
|
};
|
|
9707
10269
|
init_error3();
|
|
9708
|
-
parseTypedFilename = (filename, entryTypes) => {
|
|
9709
|
-
if (filename.startsWith("."))
|
|
9710
|
-
return null;
|
|
9711
|
-
const lastDot = filename.lastIndexOf(".");
|
|
9712
|
-
if (lastDot === -1)
|
|
9713
|
-
return null;
|
|
9714
|
-
const nameWithoutExt = filename.slice(0, lastDot);
|
|
9715
|
-
const parts = nameWithoutExt.split(".");
|
|
9716
|
-
if (parts.length < 3)
|
|
9717
|
-
return null;
|
|
9718
|
-
const potentialType = parts[0];
|
|
9719
|
-
if (entryTypes && !entryTypes.some((e) => e.name === potentialType)) {
|
|
9720
|
-
return null;
|
|
9721
|
-
}
|
|
9722
|
-
const id = parts[parts.length - 1];
|
|
9723
|
-
if (!isValidId(id))
|
|
9724
|
-
return null;
|
|
9725
|
-
const slug = parts.slice(1, -1).join(".").toLowerCase();
|
|
9726
|
-
return {
|
|
9727
|
-
type: potentialType,
|
|
9728
|
-
slug,
|
|
9729
|
-
id
|
|
9730
|
-
};
|
|
9731
|
-
};
|
|
9732
10270
|
CONTENT_EXTENSIONS = [".md", ".mdx", ".json", ".yaml"];
|
|
9733
10271
|
registry = /* @__PURE__ */ new Map();
|
|
9734
10272
|
finalization = new FinalizationRegistry(({ rootKey, ref }) => {
|
|
@@ -11322,6 +11860,7 @@ var init_generate_ai_content = __esm({
|
|
|
11322
11860
|
pullRequestNumber: z72.number().int().optional(),
|
|
11323
11861
|
submittedAt: z72.string().optional(),
|
|
11324
11862
|
pushedToGitHubAt: z72.string().optional(),
|
|
11863
|
+
editorUrl: z72.string().optional(),
|
|
11325
11864
|
syncStatus: enumOf({
|
|
11326
11865
|
synced: "synced",
|
|
11327
11866
|
"pending-sync": "pending-sync",
|
|
@@ -12375,7 +12914,7 @@ var init_generate_ai_content = __esm({
|
|
|
12375
12914
|
throw cleanupErr;
|
|
12376
12915
|
}
|
|
12377
12916
|
}
|
|
12378
|
-
const
|
|
12917
|
+
const step2 = (name, run) => options.provisionLog ? options.provisionLog.step(name, run) : run();
|
|
12379
12918
|
const identity = managedWorkspaceConfig(options.gitBotAuthorName, options.gitBotAuthorEmail);
|
|
12380
12919
|
let justCloned = false;
|
|
12381
12920
|
let resolvedRemoteUrl;
|
|
@@ -12388,9 +12927,9 @@ var init_generate_ai_content = __esm({
|
|
|
12388
12927
|
sourceRoot: options.sourceRoot,
|
|
12389
12928
|
allowNetworkRemoteInProd: options.allowNetworkRemoteInProd
|
|
12390
12929
|
});
|
|
12391
|
-
await
|
|
12930
|
+
await step2("clone", () => _GitManager.cloneWorkspace(remoteUrl, options.workspacePath, baseBranch, {
|
|
12392
12931
|
remoteName,
|
|
12393
|
-
noCheckout:
|
|
12932
|
+
noCheckout: true,
|
|
12394
12933
|
config: identity
|
|
12395
12934
|
}));
|
|
12396
12935
|
justCloned = true;
|
|
@@ -12403,7 +12942,7 @@ var init_generate_ai_content = __esm({
|
|
|
12403
12942
|
skipIndexMarker: options.branchType === "orphan"
|
|
12404
12943
|
});
|
|
12405
12944
|
if (!justCloned) {
|
|
12406
|
-
await
|
|
12945
|
+
await step2("config", async () => {
|
|
12407
12946
|
await git.ensureLocalConfig(identity);
|
|
12408
12947
|
const remoteUrl = await _GitManager.resolveRemoteUrl({
|
|
12409
12948
|
mode: options.mode,
|
|
@@ -12421,19 +12960,19 @@ var init_generate_ai_content = __esm({
|
|
|
12421
12960
|
}
|
|
12422
12961
|
if (options.branchType === "orphan") {
|
|
12423
12962
|
try {
|
|
12424
|
-
await
|
|
12963
|
+
await step2("checkout", () => git.createOrphanSettingsBranch(options.branchName, {}));
|
|
12425
12964
|
} catch (err2) {
|
|
12426
12965
|
if (err2 instanceof SettingsRemoteUnreadableError && !resolvedRemoteUrl) {
|
|
12427
12966
|
throw await _GitManager.remoteNotReadyError(options.mode) ?? err2;
|
|
12428
12967
|
}
|
|
12429
12968
|
throw err2;
|
|
12430
12969
|
}
|
|
12431
|
-
await
|
|
12970
|
+
await step2("exclude", () => git.ensureGitExclude("*.lock"));
|
|
12432
12971
|
} else {
|
|
12433
|
-
await
|
|
12972
|
+
await step2("checkout", () => justCloned ? git.checkoutFreshClone(options.branchName) : git.checkoutBranch(options.branchName));
|
|
12434
12973
|
const pattern = options.gitExcludePattern;
|
|
12435
12974
|
if (pattern) {
|
|
12436
|
-
await
|
|
12975
|
+
await step2("exclude", () => git.ensureGitExclude(pattern));
|
|
12437
12976
|
}
|
|
12438
12977
|
}
|
|
12439
12978
|
return git;
|
|
@@ -12858,7 +13397,7 @@ var init_generate_ai_content = __esm({
|
|
|
12858
13397
|
log9.debug("git", "Checked out the remote settings branch", { branchName });
|
|
12859
13398
|
return;
|
|
12860
13399
|
}
|
|
12861
|
-
await this.git.raw(["
|
|
13400
|
+
await this.git.raw(["switch", "--orphan", branchName]);
|
|
12862
13401
|
await this.git.raw(["rm", "-r", "-f", "-q", "--sparse", "--ignore-unmatch", "--", "."]);
|
|
12863
13402
|
const leftover = (await this.git.raw(["ls-files"])).trim();
|
|
12864
13403
|
if (leftover) {
|
|
@@ -15575,7 +16114,7 @@ var init_collection3 = __esm({
|
|
|
15575
16114
|
|
|
15576
16115
|
// dist/config/schemas/url.js
|
|
15577
16116
|
import { z as z12 } from "zod";
|
|
15578
|
-
var uploadTargetUrlSchema3, previewPrefixSchema3;
|
|
16117
|
+
var uploadTargetUrlSchema3, previewPrefixSchema3, editorUrlSchema3;
|
|
15579
16118
|
var init_url3 = __esm({
|
|
15580
16119
|
"dist/config/schemas/url.js"() {
|
|
15581
16120
|
"use strict";
|
|
@@ -15586,6 +16125,14 @@ var init_url3 = __esm({
|
|
|
15586
16125
|
previewPrefixSchema3 = z12.string().trim().refine((value) => isHttpUrlOrSameOriginPath3(value), {
|
|
15587
16126
|
message: 'editor.previewPrefix must be an absolute http(s) URL or a site-relative path beginning with a single "/", with no query or fragment'
|
|
15588
16127
|
});
|
|
16128
|
+
editorUrlSchema3 = z12.string().trim().refine((value) => {
|
|
16129
|
+
if (!isHttpUrlOrSameOriginPath3(value) || !/^https?:\/\//i.test(value))
|
|
16130
|
+
return false;
|
|
16131
|
+
const url = new URL(value);
|
|
16132
|
+
return !url.username && !url.password;
|
|
16133
|
+
}, {
|
|
16134
|
+
message: "editorUrl must be an absolute http(s) URL with no credentials, query or fragment"
|
|
16135
|
+
});
|
|
15589
16136
|
}
|
|
15590
16137
|
});
|
|
15591
16138
|
|
|
@@ -15822,6 +16369,7 @@ var init_config4 = __esm({
|
|
|
15822
16369
|
contentRoot: contentRootSchema3.default("content"),
|
|
15823
16370
|
sourceRoot: sourceRootSchema3.optional(),
|
|
15824
16371
|
basePath: basePathSchema3,
|
|
16372
|
+
editorUrl: editorUrlSchema3.optional(),
|
|
15825
16373
|
unauthenticatedStatus: z14.union([z14.literal(401), z14.literal(419)]).optional(),
|
|
15826
16374
|
danglingReferences: z14.enum(["error", "warn"]).optional(),
|
|
15827
16375
|
editor: editorConfigSchema3.optional(),
|
|
@@ -16463,6 +17011,23 @@ var init_id = __esm({
|
|
|
16463
17011
|
}
|
|
16464
17012
|
});
|
|
16465
17013
|
|
|
17014
|
+
// dist/utils/format.js
|
|
17015
|
+
var getFormatExtension2;
|
|
17016
|
+
var init_format = __esm({
|
|
17017
|
+
"dist/utils/format.js"() {
|
|
17018
|
+
"use strict";
|
|
17019
|
+
getFormatExtension2 = (format) => {
|
|
17020
|
+
if (format === "md")
|
|
17021
|
+
return ".md";
|
|
17022
|
+
if (format === "mdx")
|
|
17023
|
+
return ".mdx";
|
|
17024
|
+
if (format === "yaml")
|
|
17025
|
+
return ".yaml";
|
|
17026
|
+
return ".json";
|
|
17027
|
+
};
|
|
17028
|
+
}
|
|
17029
|
+
});
|
|
17030
|
+
|
|
16466
17031
|
// dist/content-id-index.js
|
|
16467
17032
|
function extractIdFromFilename2(filename) {
|
|
16468
17033
|
if (filename.startsWith(".")) {
|
|
@@ -16506,10 +17071,13 @@ function extractSlugFromFilename2(filename, entryTypeName) {
|
|
|
16506
17071
|
}
|
|
16507
17072
|
return filename.toLowerCase();
|
|
16508
17073
|
}
|
|
17074
|
+
var ENTRY_EXTENSIONS2;
|
|
16509
17075
|
var init_content_id_index = __esm({
|
|
16510
17076
|
"dist/content-id-index.js"() {
|
|
16511
17077
|
"use strict";
|
|
16512
17078
|
init_id();
|
|
17079
|
+
init_format();
|
|
17080
|
+
ENTRY_EXTENSIONS2 = new Set(Object.keys({ md: true, mdx: true, json: true, yaml: true }).map((format) => getFormatExtension2(format)));
|
|
16513
17081
|
}
|
|
16514
17082
|
});
|
|
16515
17083
|
|
|
@@ -17693,6 +18261,7 @@ var init_branch_metadata_file = __esm({
|
|
|
17693
18261
|
pullRequestNumber: z18.number().int().optional(),
|
|
17694
18262
|
submittedAt: z18.string().optional(),
|
|
17695
18263
|
pushedToGitHubAt: z18.string().optional(),
|
|
18264
|
+
editorUrl: z18.string().optional(),
|
|
17696
18265
|
syncStatus: enumOf2({
|
|
17697
18266
|
synced: "synced",
|
|
17698
18267
|
"pending-sync": "pending-sync",
|