canopycms 0.5.0 → 0.7.0
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 +185 -46
- 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 +704 -131
- 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 +15 -2
- package/dist/cli/template-files/cms-stack.ts.template +3 -0
- package/dist/cli/templates.js +5 -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/github-gateway-http.js +5 -4
- 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-gateway.js +2 -2
- 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
|
@@ -233,9 +233,13 @@ async function canopyContext(options) {
|
|
|
233
233
|
"// authenticated request instead of silently falling back to unauthenticated dev auth.",
|
|
234
234
|
"// CLERK_SECRET_KEY is read only where Clerk's backend API is called: the auth-cache",
|
|
235
235
|
"// refresh (the worker in prod, lazily on the dev server in dev).",
|
|
236
|
+
"// useOrganizationsAsGroups needs Organizations enabled on the Clerk instance and offers",
|
|
237
|
+
"// every organization in the instance as a group. In an AWS deployment the worker reads",
|
|
238
|
+
"// the setting from `clerkOrganizationsAsGroups` in the CDK stack, which governs there;",
|
|
239
|
+
"// keep the two equal.",
|
|
236
240
|
"const authPlugin =",
|
|
237
241
|
" config.server.mode === 'prod' || process.env.CANOPY_AUTH_MODE === 'clerk'",
|
|
238
|
-
" ? createClerkAuthPlugin({ useOrganizationsAsGroups:
|
|
242
|
+
" ? createClerkAuthPlugin({ useOrganizationsAsGroups: false })",
|
|
239
243
|
" : createDevAuthPlugin()"
|
|
240
244
|
].join("\n") : "const authPlugin = createDevAuthPlugin()";
|
|
241
245
|
return template.replace("{{AUTH_IMPORTS}}", authImports).replace("{{AUTH_PLUGIN_SETUP}}", authPluginSetup).replace("{{CONFIG_IMPORT}}", options.configImport);
|
|
@@ -1223,7 +1227,7 @@ CanopyCMS worker run-once (mode: ${mode}, auth: ${authMode})
|
|
|
1223
1227
|
}
|
|
1224
1228
|
console.log("\nDone");
|
|
1225
1229
|
}
|
|
1226
|
-
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;
|
|
1227
1231
|
var init_init = __esm({
|
|
1228
1232
|
"dist/cli/init.js"() {
|
|
1229
1233
|
"use strict";
|
|
@@ -1538,6 +1542,14 @@ var init_init = __esm({
|
|
|
1538
1542
|
previewPrefixSchema = z3.string().trim().refine((value) => isHttpUrlOrSameOriginPath(value), {
|
|
1539
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'
|
|
1540
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
|
+
});
|
|
1541
1553
|
}
|
|
1542
1554
|
});
|
|
1543
1555
|
init_media = __esm2({
|
|
@@ -1680,6 +1692,7 @@ var init_init = __esm({
|
|
|
1680
1692
|
contentRoot: contentRootSchema.default("content"),
|
|
1681
1693
|
sourceRoot: sourceRootSchema.optional(),
|
|
1682
1694
|
basePath: basePathSchema,
|
|
1695
|
+
editorUrl: editorUrlSchema.optional(),
|
|
1683
1696
|
unauthenticatedStatus: z5.union([z5.literal(401), z5.literal(419)]).optional(),
|
|
1684
1697
|
danglingReferences: z5.enum(["error", "warn"]).optional(),
|
|
1685
1698
|
editor: editorConfigSchema.optional(),
|
|
@@ -2233,6 +2246,84 @@ var init_github_app_manifest = __esm({
|
|
|
2233
2246
|
}
|
|
2234
2247
|
});
|
|
2235
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
|
+
|
|
2236
2327
|
// dist/cli/prompt.js
|
|
2237
2328
|
import { createInterface } from "node:readline";
|
|
2238
2329
|
function readLineOnce(prompt) {
|
|
@@ -2460,10 +2551,13 @@ var init_github_app_exports = {};
|
|
|
2460
2551
|
__export(init_github_app_exports, {
|
|
2461
2552
|
appJwt: () => appJwt,
|
|
2462
2553
|
appManifest: () => appManifest,
|
|
2554
|
+
appSettingsUrl: () => appSettingsUrl,
|
|
2463
2555
|
creationForm: () => creationForm,
|
|
2464
2556
|
handOffKey: () => handOffKey,
|
|
2465
2557
|
handOffWithRetry: () => handOffWithRetry,
|
|
2466
2558
|
initGitHubApp: () => initGitHubApp,
|
|
2559
|
+
installStepMessage: () => installStepMessage,
|
|
2560
|
+
keyNotStoredMessage: () => keyNotStoredMessage,
|
|
2467
2561
|
manifestPostUrl: () => manifestPostUrl,
|
|
2468
2562
|
parseKeyRetryAnswer: () => parseKeyRetryAnswer,
|
|
2469
2563
|
startCallbackServer: () => startCallbackServer
|
|
@@ -2475,8 +2569,33 @@ import { mkdtemp, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
|
2475
2569
|
import { tmpdir } from "node:os";
|
|
2476
2570
|
import path10 from "node:path";
|
|
2477
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
|
+
}
|
|
2478
2597
|
function manifestPostUrl(target, state) {
|
|
2479
|
-
const base =
|
|
2598
|
+
const base = `${appsBaseUrl(target)}/new`;
|
|
2480
2599
|
return `${base}?state=${encodeURIComponent(state)}`;
|
|
2481
2600
|
}
|
|
2482
2601
|
function appManifest(target, redirectUrl, name = appName(target.repo)) {
|
|
@@ -2780,7 +2899,7 @@ async function handOffWithRetry(pem, destination) {
|
|
|
2780
2899
|
const result = await handOffKey(pem, attempt);
|
|
2781
2900
|
if (result.stored) {
|
|
2782
2901
|
console.log(`
|
|
2783
|
-
|
|
2902
|
+
${tick(`Private key: ${result.detail}`)}`);
|
|
2784
2903
|
return true;
|
|
2785
2904
|
}
|
|
2786
2905
|
console.error(`
|
|
@@ -2880,41 +2999,41 @@ No installation of this App found on ${target.owner}/${target.repo} (HTTP ${foun
|
|
|
2880
2999
|
}
|
|
2881
3000
|
const installation = found.body;
|
|
2882
3001
|
console.log(`
|
|
2883
|
-
|
|
3002
|
+
${outColors.bold(`Installation ${installation.id}`)} on ${target.owner}/${target.repo}`);
|
|
2884
3003
|
const findings = readbackVerdict(installation);
|
|
2885
3004
|
if (findings.length === 0) {
|
|
2886
|
-
console.log(" grant matches exactly what this package needs:");
|
|
3005
|
+
console.log(" The grant matches exactly what this package needs:");
|
|
2887
3006
|
for (const [name, level] of Object.entries(CANOPY_APP_PERMISSIONS)) {
|
|
2888
|
-
console.log(`
|
|
3007
|
+
console.log(` ${tick(`${name}: ${level}`)}`);
|
|
2889
3008
|
}
|
|
2890
3009
|
} else {
|
|
2891
3010
|
for (const finding of findings) {
|
|
2892
|
-
console.error(`
|
|
3011
|
+
console.error(` ${cross(finding.message)}`);
|
|
2893
3012
|
}
|
|
2894
3013
|
}
|
|
2895
3014
|
let installationsOk = false;
|
|
2896
3015
|
const installations = await installationCount(jwt);
|
|
2897
3016
|
if (installations === null) {
|
|
2898
|
-
console.error(`
|
|
3017
|
+
console.error(` ${failMark} could not list this App's installations, so "installed once" is UNCHECKED.
|
|
2899
3018
|
Reported as a failure rather than passed over: this is the check that observes
|
|
2900
3019
|
the one-App-per-site rule, and an unread check is not a satisfied one.`);
|
|
2901
3020
|
} else if (installations === 1) {
|
|
2902
3021
|
installationsOk = true;
|
|
2903
|
-
console.log("
|
|
3022
|
+
console.log(` ${tick("installed once, so this key reaches no other account")}`);
|
|
2904
3023
|
} else if (installations > 1) {
|
|
2905
|
-
console.error(`
|
|
3024
|
+
console.error(` ${failMark} this App is installed ${installations} times, and should be installed ONCE.
|
|
2906
3025
|
Its private key is App-level: whoever holds it can mint a token for any of
|
|
2907
3026
|
those installations. Register a separate App per site instead, and remove
|
|
2908
3027
|
the installations that do not belong to this one.`);
|
|
2909
3028
|
} else {
|
|
2910
|
-
console.error(`
|
|
3029
|
+
console.error(` ${failMark} GitHub reports ${installations} installations of this App, yet one was just read
|
|
2911
3030
|
back for this repository. Something is inconsistent; re-run before trusting it.`);
|
|
2912
3031
|
}
|
|
2913
3032
|
const mint = await proveTokenMint(jwt, installation.id, target.repo);
|
|
2914
3033
|
if (mint.ok) {
|
|
2915
|
-
console.log(`
|
|
3034
|
+
console.log(` ${tick(`installation token ${mint.detail}`)}`);
|
|
2916
3035
|
} else {
|
|
2917
|
-
console.error(`
|
|
3036
|
+
console.error(` ${failMark} could not mint an installation token \u2014 ${mint.detail}
|
|
2918
3037
|
If that message says the requested permissions are not granted to this
|
|
2919
3038
|
installation, that is a GitHub behaviour rather than a bug here: adding a
|
|
2920
3039
|
permission to an App does NOT apply to existing installations until an account
|
|
@@ -2990,7 +3109,7 @@ async function createCommand(options) {
|
|
|
2990
3109
|
console.log(`! Could not check whether the name "${name}" is already taken, so this is unverified.
|
|
2991
3110
|
`);
|
|
2992
3111
|
}
|
|
2993
|
-
console.log(
|
|
3112
|
+
console.log(recoveryPreamble());
|
|
2994
3113
|
const state = randomUUID();
|
|
2995
3114
|
let formDir;
|
|
2996
3115
|
let callback;
|
|
@@ -3013,29 +3132,15 @@ async function createCommand(options) {
|
|
|
3013
3132
|
formDir = await mkdtemp(path10.join(tmpdir(), "canopycms-app-"));
|
|
3014
3133
|
const formFile = path10.join(formDir, `create-${slug}.html`);
|
|
3015
3134
|
await writeFile2(formFile, creationForm(postUrl, manifest), { mode: 384, flag: "wx" });
|
|
3016
|
-
console.log(
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
1. Open this file in a browser:
|
|
3026
|
-
|
|
3027
|
-
${formFile}
|
|
3028
|
-
|
|
3029
|
-
The browser matters, twice over. It must be LOGGED IN TO GITHUB as an owner of
|
|
3030
|
-
${target.owner}, and it must be running on THIS machine \u2014 the redirect comes back to
|
|
3031
|
-
127.0.0.1:${callback.port}, which only a local browser can reach. An embedded or
|
|
3032
|
-
app-internal browser bounces off the GitHub login wall and simply appears to do
|
|
3033
|
-
nothing when you click Create.
|
|
3034
|
-
|
|
3035
|
-
The page posts the manifest to GitHub, which shows you the App pre-filled with
|
|
3036
|
-
exactly those permissions. Review them and click Create.
|
|
3037
|
-
|
|
3038
|
-
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
|
+
}));
|
|
3039
3144
|
let code;
|
|
3040
3145
|
try {
|
|
3041
3146
|
code = await callback.code;
|
|
@@ -3050,32 +3155,20 @@ ${getErrorMessage(err2)}.
|
|
|
3050
3155
|
See the recovery note printed above if the App was in fact created.`);
|
|
3051
3156
|
return 1;
|
|
3052
3157
|
}
|
|
3053
|
-
console.log(
|
|
3158
|
+
console.log(`
|
|
3159
|
+
${tick("Got the manifest code; exchanging it for the App credentials")}`);
|
|
3054
3160
|
const created = await convertManifest(code);
|
|
3055
3161
|
if (!created) {
|
|
3056
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.');
|
|
3057
3163
|
return 1;
|
|
3058
3164
|
}
|
|
3059
|
-
console.log(`
|
|
3165
|
+
console.log(tick(`Created App ${outColors.bold(created.slug)} (id ${created.id}); private key captured, sending it to ${describeDestination(destination)}`));
|
|
3060
3166
|
const stored = await handOffWithRetry(created.pem, destination);
|
|
3061
3167
|
if (!stored) {
|
|
3062
|
-
console.error(
|
|
3063
|
-
Stopping here: the App exists but its key was not stored, so installing it now
|
|
3064
|
-
would achieve nothing. To recover, open the App and generate a private key from
|
|
3065
|
-
its "Private keys" section, then run \`verify\`; or delete the App and start again.
|
|
3066
|
-
|
|
3067
|
-
GITHUB_APP_ID=${created.id}
|
|
3068
|
-
App settings: https://github.com/settings/apps/${created.slug}`);
|
|
3168
|
+
console.error(keyNotStoredMessage(target, created));
|
|
3069
3169
|
return 1;
|
|
3070
3170
|
}
|
|
3071
|
-
console.log(
|
|
3072
|
-
2. Install it on ${target.owner}/${target.repo}:
|
|
3073
|
-
|
|
3074
|
-
https://github.com/settings/apps/${created.slug}/installations
|
|
3075
|
-
|
|
3076
|
-
That page shows an Install button first \u2014 the repository picker only appears after
|
|
3077
|
-
you click it. Choose "Only select repositories" and pick that one repository.
|
|
3078
|
-
`);
|
|
3171
|
+
console.log(installStepMessage(target, created.slug));
|
|
3079
3172
|
await pressEnter(" Press Enter once it is installed.");
|
|
3080
3173
|
let readback;
|
|
3081
3174
|
try {
|
|
@@ -3086,19 +3179,7 @@ Stopping here: the App exists but its key was not stored, so installing it now
|
|
|
3086
3179
|
This says nothing about the App or the key \u2014 re-run \`canopycms init-github-app verify\`.`);
|
|
3087
3180
|
readback = { ok: false, installationId: null };
|
|
3088
3181
|
}
|
|
3089
|
-
console.log(
|
|
3090
|
-
Set these on your deployment:
|
|
3091
|
-
|
|
3092
|
-
GITHUB_APP_ID=${created.id}
|
|
3093
|
-
GITHUB_APP_INSTALLATION_ID=${readback.installationId ?? "<run `verify` to read it>"}
|
|
3094
|
-
GITHUB_APP_PRIVATE_KEY_SECRET_ARN=<wherever you just put the key>
|
|
3095
|
-
|
|
3096
|
-
Both ids are numeric. The App ID is NOT the "Client ID" (\`Iv1.\u2026\`) shown beside it,
|
|
3097
|
-
and the installation id is NOT the App ID \u2014 an App installed twice has one App ID
|
|
3098
|
-
and two installation ids.
|
|
3099
|
-
|
|
3100
|
-
Re-check this any time, without creating anything:
|
|
3101
|
-
canopycms init-github-app verify --app-id ${created.id} --key-file <path>`);
|
|
3182
|
+
console.log(deploymentSettingsMessage(created.id, readback.installationId));
|
|
3102
3183
|
return stored && readback.ok ? 0 : 1;
|
|
3103
3184
|
} finally {
|
|
3104
3185
|
callback.close();
|
|
@@ -3143,6 +3224,7 @@ var init_init_github_app = __esm({
|
|
|
3143
3224
|
init_error();
|
|
3144
3225
|
init_github_auth();
|
|
3145
3226
|
init_github_app_manifest();
|
|
3227
|
+
init_github_app_output();
|
|
3146
3228
|
init_prompt();
|
|
3147
3229
|
CALLBACK_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
3148
3230
|
REQUEST_TIMEOUT_MS = 3e4;
|
|
@@ -3706,6 +3788,70 @@ function isBlockStructuralKey(key) {
|
|
|
3706
3788
|
function createDebugLogger2(options) {
|
|
3707
3789
|
return new DebugLogger2(options);
|
|
3708
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
|
+
}
|
|
3709
3855
|
function snapshotDocument(doc) {
|
|
3710
3856
|
const items = /* @__PURE__ */ new Map();
|
|
3711
3857
|
const visitNode = (node) => {
|
|
@@ -3819,15 +3965,15 @@ function canonical(node) {
|
|
|
3819
3965
|
function kindOf(node) {
|
|
3820
3966
|
return `${node.type}:${String(node.ordered ?? "")}:${String(node.checked ?? "")}`;
|
|
3821
3967
|
}
|
|
3822
|
-
function
|
|
3968
|
+
function startOf2(node) {
|
|
3823
3969
|
return node?.position?.start.offset;
|
|
3824
3970
|
}
|
|
3825
|
-
function
|
|
3971
|
+
function endOf2(node) {
|
|
3826
3972
|
return node?.position?.end.offset;
|
|
3827
3973
|
}
|
|
3828
3974
|
function sliceOf(text3, node) {
|
|
3829
|
-
const start =
|
|
3830
|
-
const end =
|
|
3975
|
+
const start = startOf2(node);
|
|
3976
|
+
const end = endOf2(node);
|
|
3831
3977
|
return start === void 0 || end === void 0 ? void 0 : text3.slice(start, end);
|
|
3832
3978
|
}
|
|
3833
3979
|
function reindent(text3, from, to) {
|
|
@@ -3891,12 +4037,12 @@ function leadWidth(text3, offset) {
|
|
|
3891
4037
|
return /^(?: |[-*+](?= )|\d{1,9}[.)](?= )|\[[ xX]\](?= ))*$/.test(lead) ? lead.length : void 0;
|
|
3892
4038
|
}
|
|
3893
4039
|
function gapBetween(text3, a, b) {
|
|
3894
|
-
const end =
|
|
3895
|
-
const start =
|
|
4040
|
+
const end = endOf2(a);
|
|
4041
|
+
const start = startOf2(b);
|
|
3896
4042
|
return end === void 0 || start === void 0 ? void 0 : text3.slice(end, start);
|
|
3897
4043
|
}
|
|
3898
4044
|
function listMarkers(text3, items, ordered) {
|
|
3899
|
-
const firstStart =
|
|
4045
|
+
const firstStart = startOf2(items[0]);
|
|
3900
4046
|
if (firstStart === void 0)
|
|
3901
4047
|
return void 0;
|
|
3902
4048
|
if (!ordered) {
|
|
@@ -3909,16 +4055,14 @@ function listMarkers(text3, items, ordered) {
|
|
|
3909
4055
|
const first = numberAt(firstStart);
|
|
3910
4056
|
if (first === null)
|
|
3911
4057
|
return void 0;
|
|
3912
|
-
const start = Number(first[1]);
|
|
3913
4058
|
const delimiter = first[2] ?? ".";
|
|
3914
4059
|
const padTo = first[1]?.startsWith("0") ? first[1].length : 0;
|
|
3915
|
-
const
|
|
3916
|
-
const step = second !== null && Number(second[1]) === start ? 0 : 1;
|
|
4060
|
+
const typed = items.map((item) => Number(numberAt(startOf2(item))?.[1]));
|
|
3917
4061
|
return (itemText, index) => {
|
|
3918
4062
|
const current = /^\d{1,9}[.)]/.exec(itemText);
|
|
3919
4063
|
if (current === null)
|
|
3920
4064
|
return void 0;
|
|
3921
|
-
const marker = `${String(
|
|
4065
|
+
const marker = `${String(orderedNumber(typed, index)).padStart(padTo, "0")}${delimiter}`;
|
|
3922
4066
|
if (marker.length !== current[0].length && itemText.includes("\n"))
|
|
3923
4067
|
return void 0;
|
|
3924
4068
|
return marker + itemText.slice(current[0].length);
|
|
@@ -3934,22 +4078,56 @@ function preserveMarkdownSource(original, updated, format) {
|
|
|
3934
4078
|
return updated;
|
|
3935
4079
|
}
|
|
3936
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
|
+
}
|
|
3937
4101
|
function splice(original, updated, format) {
|
|
3938
|
-
const before = parse(original, format);
|
|
4102
|
+
const before = original === void 0 ? void 0 : parse(original, format);
|
|
3939
4103
|
const after = parse(updated, format);
|
|
3940
|
-
if (
|
|
4104
|
+
if (after === void 0)
|
|
3941
4105
|
return void 0;
|
|
3942
4106
|
const target = canonical(after);
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
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
|
+
}
|
|
3951
4129
|
}
|
|
3952
|
-
return
|
|
4130
|
+
return restyled?.text;
|
|
3953
4131
|
}
|
|
3954
4132
|
function createNode(ctx, value, asKey = false) {
|
|
3955
4133
|
const node = ctx.doc.createNode(value);
|
|
@@ -4234,7 +4412,7 @@ function writesFrontmatter(data) {
|
|
|
4234
4412
|
}
|
|
4235
4413
|
function bodyToWrite(body, data, format, existingRaw) {
|
|
4236
4414
|
const priorBody = existingRaw === void 0 ? void 0 : extractBody(existingRaw);
|
|
4237
|
-
const spliced =
|
|
4415
|
+
const spliced = preserveMarkdownSource(priorBody, body, format);
|
|
4238
4416
|
if (!writesFrontmatter(data)) {
|
|
4239
4417
|
const flush = spliced.replace(/^(?:\r?\n)+/, "");
|
|
4240
4418
|
return /^\uFEFF?---/.test(flush) ? `
|
|
@@ -7828,7 +8006,7 @@ async function generateAIContentCLI(options) {
|
|
|
7828
8006
|
console.log(` Output: ${result.outputDir}
|
|
7829
8007
|
`);
|
|
7830
8008
|
}
|
|
7831
|
-
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;
|
|
7832
8010
|
var init_generate_ai_content = __esm({
|
|
7833
8011
|
"dist/cli/generate-ai-content.js"() {
|
|
7834
8012
|
"use strict";
|
|
@@ -8281,6 +8459,14 @@ var init_generate_ai_content = __esm({
|
|
|
8281
8459
|
previewPrefixSchema2 = z42.string().trim().refine((value) => isHttpUrlOrSameOriginPath2(value), {
|
|
8282
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'
|
|
8283
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
|
+
});
|
|
8284
8470
|
}
|
|
8285
8471
|
});
|
|
8286
8472
|
init_media2 = __esm3({
|
|
@@ -8423,6 +8609,7 @@ var init_generate_ai_content = __esm({
|
|
|
8423
8609
|
contentRoot: contentRootSchema2.default("content"),
|
|
8424
8610
|
sourceRoot: sourceRootSchema2.optional(),
|
|
8425
8611
|
basePath: basePathSchema2,
|
|
8612
|
+
editorUrl: editorUrlSchema2.optional(),
|
|
8426
8613
|
unauthenticatedStatus: z6.union([z6.literal(401), z6.literal(419)]).optional(),
|
|
8427
8614
|
danglingReferences: z6.enum(["error", "warn"]).optional(),
|
|
8428
8615
|
editor: editorConfigSchema2.optional(),
|
|
@@ -8792,6 +8979,360 @@ var init_generate_ai_content = __esm({
|
|
|
8792
8979
|
});
|
|
8793
8980
|
init_error3();
|
|
8794
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
|
+
};
|
|
8795
9336
|
END = Symbol("end");
|
|
8796
9337
|
FRESH = Symbol("fresh");
|
|
8797
9338
|
LINE_WIDTH = 80;
|
|
@@ -9123,8 +9664,8 @@ var init_generate_ai_content = __esm({
|
|
|
9123
9664
|
body(before, after) {
|
|
9124
9665
|
const oNodes = before.children ?? [];
|
|
9125
9666
|
const nNodes = after.children ?? [];
|
|
9126
|
-
const first =
|
|
9127
|
-
const last =
|
|
9667
|
+
const first = startOf2(oNodes[0]);
|
|
9668
|
+
const last = endOf2(oNodes[oNodes.length - 1]);
|
|
9128
9669
|
if (first === void 0 || last === void 0 || nNodes.length === 0)
|
|
9129
9670
|
return void 0;
|
|
9130
9671
|
const o = { text: this.original, indent: "" };
|
|
@@ -9232,9 +9773,9 @@ var init_generate_ai_content = __esm({
|
|
|
9232
9773
|
item(o, oItem, n, nItem) {
|
|
9233
9774
|
const oChildren = oItem.children ?? [];
|
|
9234
9775
|
const nChildren = nItem.children ?? [];
|
|
9235
|
-
const oStart =
|
|
9236
|
-
const oContent =
|
|
9237
|
-
const nContent =
|
|
9776
|
+
const oStart = startOf2(oItem);
|
|
9777
|
+
const oContent = startOf2(oChildren[0]);
|
|
9778
|
+
const nContent = startOf2(nChildren[0]);
|
|
9238
9779
|
if (oStart === void 0 || oContent === void 0 || nContent === void 0)
|
|
9239
9780
|
return void 0;
|
|
9240
9781
|
const prefix = o.text.slice(oStart, oContent);
|
|
@@ -9413,7 +9954,32 @@ var init_generate_ai_content = __esm({
|
|
|
9413
9954
|
isValidId = isValidContentId;
|
|
9414
9955
|
init_error3();
|
|
9415
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
|
+
};
|
|
9416
9981
|
EMPTY_LOGICAL_PATH = "";
|
|
9982
|
+
ENTRY_EXTENSIONS = new Set(Object.keys({ md: true, mdx: true, json: true, yaml: true }).map((format) => getFormatExtension(format)));
|
|
9417
9983
|
ContentIdIndex = class {
|
|
9418
9984
|
constructor(root) {
|
|
9419
9985
|
this.idToLocation = /* @__PURE__ */ new Map();
|
|
@@ -9701,30 +10267,6 @@ var init_generate_ai_content = __esm({
|
|
|
9701
10267
|
}
|
|
9702
10268
|
};
|
|
9703
10269
|
init_error3();
|
|
9704
|
-
parseTypedFilename = (filename, entryTypes) => {
|
|
9705
|
-
if (filename.startsWith("."))
|
|
9706
|
-
return null;
|
|
9707
|
-
const lastDot = filename.lastIndexOf(".");
|
|
9708
|
-
if (lastDot === -1)
|
|
9709
|
-
return null;
|
|
9710
|
-
const nameWithoutExt = filename.slice(0, lastDot);
|
|
9711
|
-
const parts = nameWithoutExt.split(".");
|
|
9712
|
-
if (parts.length < 3)
|
|
9713
|
-
return null;
|
|
9714
|
-
const potentialType = parts[0];
|
|
9715
|
-
if (entryTypes && !entryTypes.some((e) => e.name === potentialType)) {
|
|
9716
|
-
return null;
|
|
9717
|
-
}
|
|
9718
|
-
const id = parts[parts.length - 1];
|
|
9719
|
-
if (!isValidId(id))
|
|
9720
|
-
return null;
|
|
9721
|
-
const slug = parts.slice(1, -1).join(".").toLowerCase();
|
|
9722
|
-
return {
|
|
9723
|
-
type: potentialType,
|
|
9724
|
-
slug,
|
|
9725
|
-
id
|
|
9726
|
-
};
|
|
9727
|
-
};
|
|
9728
10270
|
CONTENT_EXTENSIONS = [".md", ".mdx", ".json", ".yaml"];
|
|
9729
10271
|
registry = /* @__PURE__ */ new Map();
|
|
9730
10272
|
finalization = new FinalizationRegistry(({ rootKey, ref }) => {
|
|
@@ -11318,6 +11860,7 @@ var init_generate_ai_content = __esm({
|
|
|
11318
11860
|
pullRequestNumber: z72.number().int().optional(),
|
|
11319
11861
|
submittedAt: z72.string().optional(),
|
|
11320
11862
|
pushedToGitHubAt: z72.string().optional(),
|
|
11863
|
+
editorUrl: z72.string().optional(),
|
|
11321
11864
|
syncStatus: enumOf({
|
|
11322
11865
|
synced: "synced",
|
|
11323
11866
|
"pending-sync": "pending-sync",
|
|
@@ -12371,7 +12914,7 @@ var init_generate_ai_content = __esm({
|
|
|
12371
12914
|
throw cleanupErr;
|
|
12372
12915
|
}
|
|
12373
12916
|
}
|
|
12374
|
-
const
|
|
12917
|
+
const step2 = (name, run) => options.provisionLog ? options.provisionLog.step(name, run) : run();
|
|
12375
12918
|
const identity = managedWorkspaceConfig(options.gitBotAuthorName, options.gitBotAuthorEmail);
|
|
12376
12919
|
let justCloned = false;
|
|
12377
12920
|
let resolvedRemoteUrl;
|
|
@@ -12384,9 +12927,9 @@ var init_generate_ai_content = __esm({
|
|
|
12384
12927
|
sourceRoot: options.sourceRoot,
|
|
12385
12928
|
allowNetworkRemoteInProd: options.allowNetworkRemoteInProd
|
|
12386
12929
|
});
|
|
12387
|
-
await
|
|
12930
|
+
await step2("clone", () => _GitManager.cloneWorkspace(remoteUrl, options.workspacePath, baseBranch, {
|
|
12388
12931
|
remoteName,
|
|
12389
|
-
noCheckout:
|
|
12932
|
+
noCheckout: true,
|
|
12390
12933
|
config: identity
|
|
12391
12934
|
}));
|
|
12392
12935
|
justCloned = true;
|
|
@@ -12399,7 +12942,7 @@ var init_generate_ai_content = __esm({
|
|
|
12399
12942
|
skipIndexMarker: options.branchType === "orphan"
|
|
12400
12943
|
});
|
|
12401
12944
|
if (!justCloned) {
|
|
12402
|
-
await
|
|
12945
|
+
await step2("config", async () => {
|
|
12403
12946
|
await git.ensureLocalConfig(identity);
|
|
12404
12947
|
const remoteUrl = await _GitManager.resolveRemoteUrl({
|
|
12405
12948
|
mode: options.mode,
|
|
@@ -12417,19 +12960,19 @@ var init_generate_ai_content = __esm({
|
|
|
12417
12960
|
}
|
|
12418
12961
|
if (options.branchType === "orphan") {
|
|
12419
12962
|
try {
|
|
12420
|
-
await
|
|
12963
|
+
await step2("checkout", () => git.createOrphanSettingsBranch(options.branchName, {}));
|
|
12421
12964
|
} catch (err2) {
|
|
12422
12965
|
if (err2 instanceof SettingsRemoteUnreadableError && !resolvedRemoteUrl) {
|
|
12423
12966
|
throw await _GitManager.remoteNotReadyError(options.mode) ?? err2;
|
|
12424
12967
|
}
|
|
12425
12968
|
throw err2;
|
|
12426
12969
|
}
|
|
12427
|
-
await
|
|
12970
|
+
await step2("exclude", () => git.ensureGitExclude("*.lock"));
|
|
12428
12971
|
} else {
|
|
12429
|
-
await
|
|
12972
|
+
await step2("checkout", () => justCloned ? git.checkoutFreshClone(options.branchName) : git.checkoutBranch(options.branchName));
|
|
12430
12973
|
const pattern = options.gitExcludePattern;
|
|
12431
12974
|
if (pattern) {
|
|
12432
|
-
await
|
|
12975
|
+
await step2("exclude", () => git.ensureGitExclude(pattern));
|
|
12433
12976
|
}
|
|
12434
12977
|
}
|
|
12435
12978
|
return git;
|
|
@@ -12854,7 +13397,7 @@ var init_generate_ai_content = __esm({
|
|
|
12854
13397
|
log9.debug("git", "Checked out the remote settings branch", { branchName });
|
|
12855
13398
|
return;
|
|
12856
13399
|
}
|
|
12857
|
-
await this.git.raw(["
|
|
13400
|
+
await this.git.raw(["switch", "--orphan", branchName]);
|
|
12858
13401
|
await this.git.raw(["rm", "-r", "-f", "-q", "--sparse", "--ignore-unmatch", "--", "."]);
|
|
12859
13402
|
const leftover = (await this.git.raw(["ls-files"])).trim();
|
|
12860
13403
|
if (leftover) {
|
|
@@ -15571,7 +16114,7 @@ var init_collection3 = __esm({
|
|
|
15571
16114
|
|
|
15572
16115
|
// dist/config/schemas/url.js
|
|
15573
16116
|
import { z as z12 } from "zod";
|
|
15574
|
-
var uploadTargetUrlSchema3, previewPrefixSchema3;
|
|
16117
|
+
var uploadTargetUrlSchema3, previewPrefixSchema3, editorUrlSchema3;
|
|
15575
16118
|
var init_url3 = __esm({
|
|
15576
16119
|
"dist/config/schemas/url.js"() {
|
|
15577
16120
|
"use strict";
|
|
@@ -15582,6 +16125,14 @@ var init_url3 = __esm({
|
|
|
15582
16125
|
previewPrefixSchema3 = z12.string().trim().refine((value) => isHttpUrlOrSameOriginPath3(value), {
|
|
15583
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'
|
|
15584
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
|
+
});
|
|
15585
16136
|
}
|
|
15586
16137
|
});
|
|
15587
16138
|
|
|
@@ -15818,6 +16369,7 @@ var init_config4 = __esm({
|
|
|
15818
16369
|
contentRoot: contentRootSchema3.default("content"),
|
|
15819
16370
|
sourceRoot: sourceRootSchema3.optional(),
|
|
15820
16371
|
basePath: basePathSchema3,
|
|
16372
|
+
editorUrl: editorUrlSchema3.optional(),
|
|
15821
16373
|
unauthenticatedStatus: z14.union([z14.literal(401), z14.literal(419)]).optional(),
|
|
15822
16374
|
danglingReferences: z14.enum(["error", "warn"]).optional(),
|
|
15823
16375
|
editor: editorConfigSchema3.optional(),
|
|
@@ -16459,6 +17011,23 @@ var init_id = __esm({
|
|
|
16459
17011
|
}
|
|
16460
17012
|
});
|
|
16461
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
|
+
|
|
16462
17031
|
// dist/content-id-index.js
|
|
16463
17032
|
function extractIdFromFilename2(filename) {
|
|
16464
17033
|
if (filename.startsWith(".")) {
|
|
@@ -16502,10 +17071,13 @@ function extractSlugFromFilename2(filename, entryTypeName) {
|
|
|
16502
17071
|
}
|
|
16503
17072
|
return filename.toLowerCase();
|
|
16504
17073
|
}
|
|
17074
|
+
var ENTRY_EXTENSIONS2;
|
|
16505
17075
|
var init_content_id_index = __esm({
|
|
16506
17076
|
"dist/content-id-index.js"() {
|
|
16507
17077
|
"use strict";
|
|
16508
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)));
|
|
16509
17081
|
}
|
|
16510
17082
|
});
|
|
16511
17083
|
|
|
@@ -17689,6 +18261,7 @@ var init_branch_metadata_file = __esm({
|
|
|
17689
18261
|
pullRequestNumber: z18.number().int().optional(),
|
|
17690
18262
|
submittedAt: z18.string().optional(),
|
|
17691
18263
|
pushedToGitHubAt: z18.string().optional(),
|
|
18264
|
+
editorUrl: z18.string().optional(),
|
|
17692
18265
|
syncStatus: enumOf2({
|
|
17693
18266
|
synced: "synced",
|
|
17694
18267
|
"pending-sync": "pending-sync",
|