@valkyrianlabs/payload-markdown-docs 0.1.0-canary.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/README.md +195 -0
- package/dist/admin/DocsSetManager.d.ts +2 -0
- package/dist/admin/DocsSetManager.js +298 -0
- package/dist/admin/DocsSetManager.js.map +1 -0
- package/dist/admin/docsSetManagerData.d.ts +25 -0
- package/dist/admin/docsSetManagerData.js +266 -0
- package/dist/admin/docsSetManagerData.js.map +1 -0
- package/dist/admin/docsSetManagerTypes.d.ts +103 -0
- package/dist/admin/docsSetManagerTypes.js +3 -0
- package/dist/admin/docsSetManagerTypes.js.map +1 -0
- package/dist/admin/index.d.ts +3 -0
- package/dist/admin/index.js +4 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/cli/commands/install.d.ts +2 -0
- package/dist/cli/commands/install.js +211 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/keygen.d.ts +2 -0
- package/dist/cli/commands/keygen.js +89 -0
- package/dist/cli/commands/keygen.js.map +1 -0
- package/dist/cli/commands/manifest.d.ts +2 -0
- package/dist/cli/commands/manifest.js +50 -0
- package/dist/cli/commands/manifest.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +2 -0
- package/dist/cli/commands/plan.js +110 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/push.d.ts +3 -0
- package/dist/cli/commands/push.js +308 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.js +109 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/filesystem.d.ts +20 -0
- package/dist/cli/filesystem.js +96 -0
- package/dist/cli/filesystem.js.map +1 -0
- package/dist/cli/format.d.ts +35 -0
- package/dist/cli/format.js +76 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/http.d.ts +19 -0
- package/dist/cli/http.js +39 -0
- package/dist/cli/http.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +214 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/parseArgs.d.ts +5 -0
- package/dist/cli/parseArgs.js +219 -0
- package/dist/cli/parseArgs.js.map +1 -0
- package/dist/cli/types.d.ts +51 -0
- package/dist/cli/types.js +3 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/collections/docs.d.ts +9 -0
- package/dist/collections/docs.js +168 -0
- package/dist/collections/docs.js.map +1 -0
- package/dist/collections/docsGroups.d.ts +5 -0
- package/dist/collections/docsGroups.js +57 -0
- package/dist/collections/docsGroups.js.map +1 -0
- package/dist/collections/docsSets.d.ts +8 -0
- package/dist/collections/docsSets.js +158 -0
- package/dist/collections/docsSets.js.map +1 -0
- package/dist/collections/index.d.ts +10 -0
- package/dist/collections/index.js +7 -0
- package/dist/collections/index.js.map +1 -0
- package/dist/collections/nonces.d.ts +6 -0
- package/dist/collections/nonces.js +57 -0
- package/dist/collections/nonces.js.map +1 -0
- package/dist/collections/syncRuns.d.ts +5 -0
- package/dist/collections/syncRuns.js +139 -0
- package/dist/collections/syncRuns.js.map +1 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.js +23 -0
- package/dist/constants.js.map +1 -0
- package/dist/endpoints/index.d.ts +2 -0
- package/dist/endpoints/index.js +3 -0
- package/dist/endpoints/index.js.map +1 -0
- package/dist/endpoints/sync.d.ts +47 -0
- package/dist/endpoints/sync.js +616 -0
- package/dist/endpoints/sync.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/next/PayloadMarkdownDocsPage.d.ts +7 -0
- package/dist/next/PayloadMarkdownDocsPage.js +142 -0
- package/dist/next/PayloadMarkdownDocsPage.js.map +1 -0
- package/dist/next/index.d.ts +9 -0
- package/dist/next/index.js +7 -0
- package/dist/next/index.js.map +1 -0
- package/dist/next/markdown.d.ts +14 -0
- package/dist/next/markdown.js +232 -0
- package/dist/next/markdown.js.map +1 -0
- package/dist/next/metadata.d.ts +3 -0
- package/dist/next/metadata.js +33 -0
- package/dist/next/metadata.js.map +1 -0
- package/dist/next/records.d.ts +14 -0
- package/dist/next/records.js +146 -0
- package/dist/next/records.js.map +1 -0
- package/dist/next/route.d.ts +6 -0
- package/dist/next/route.js +271 -0
- package/dist/next/route.js.map +1 -0
- package/dist/next/sidebar.d.ts +15 -0
- package/dist/next/sidebar.js +137 -0
- package/dist/next/sidebar.js.map +1 -0
- package/dist/next/types.d.ts +117 -0
- package/dist/next/types.js +3 -0
- package/dist/next/types.js.map +1 -0
- package/dist/payload/applyDocsSync.d.ts +54 -0
- package/dist/payload/applyDocsSync.js +176 -0
- package/dist/payload/applyDocsSync.js.map +1 -0
- package/dist/payload/docsConflicts.d.ts +12 -0
- package/dist/payload/docsConflicts.js +34 -0
- package/dist/payload/docsConflicts.js.map +1 -0
- package/dist/payload/docsData.d.ts +23 -0
- package/dist/payload/docsData.js +59 -0
- package/dist/payload/docsData.js.map +1 -0
- package/dist/payload/docsSets.d.ts +38 -0
- package/dist/payload/docsSets.js +57 -0
- package/dist/payload/docsSets.js.map +1 -0
- package/dist/payload/existingDocs.d.ts +43 -0
- package/dist/payload/existingDocs.js +97 -0
- package/dist/payload/existingDocs.js.map +1 -0
- package/dist/payload/index.d.ts +15 -0
- package/dist/payload/index.js +10 -0
- package/dist/payload/index.js.map +1 -0
- package/dist/payload/routeCollisions.d.ts +31 -0
- package/dist/payload/routeCollisions.js +104 -0
- package/dist/payload/routeCollisions.js.map +1 -0
- package/dist/payload/syncRuns.d.ts +60 -0
- package/dist/payload/syncRuns.js +53 -0
- package/dist/payload/syncRuns.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.js +165 -0
- package/dist/plugin.js.map +1 -0
- package/dist/routing/index.d.ts +3 -0
- package/dist/routing/index.js +4 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/paths.d.ts +7 -0
- package/dist/routing/paths.js +23 -0
- package/dist/routing/paths.js.map +1 -0
- package/dist/routing/reservations.d.ts +37 -0
- package/dist/routing/reservations.js +79 -0
- package/dist/routing/reservations.js.map +1 -0
- package/dist/security/canonical.d.ts +12 -0
- package/dist/security/canonical.js +24 -0
- package/dist/security/canonical.js.map +1 -0
- package/dist/security/githubOidc.d.ts +45 -0
- package/dist/security/githubOidc.js +177 -0
- package/dist/security/githubOidc.js.map +1 -0
- package/dist/security/headers.d.ts +22 -0
- package/dist/security/headers.js +44 -0
- package/dist/security/headers.js.map +1 -0
- package/dist/security/index.d.ts +15 -0
- package/dist/security/index.js +9 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/jwks.d.ts +20 -0
- package/dist/security/jwks.js +40 -0
- package/dist/security/jwks.js.map +1 -0
- package/dist/security/jwt.d.ts +10 -0
- package/dist/security/jwt.js +42 -0
- package/dist/security/jwt.js.map +1 -0
- package/dist/security/nonce.d.ts +34 -0
- package/dist/security/nonce.js +43 -0
- package/dist/security/nonce.js.map +1 -0
- package/dist/security/sign.d.ts +13 -0
- package/dist/security/sign.js +39 -0
- package/dist/security/sign.js.map +1 -0
- package/dist/security/verify.d.ts +28 -0
- package/dist/security/verify.js +54 -0
- package/dist/security/verify.js.map +1 -0
- package/dist/skills/codex/SKILL.md +173 -0
- package/dist/skills/codex/examples/docs-page.md +42 -0
- package/dist/skills/codex/examples/github-actions.md +64 -0
- package/dist/skills/codex/reference/admin.md +28 -0
- package/dist/skills/codex/reference/frontmatter.md +39 -0
- package/dist/skills/codex/reference/payload-markdown-directives.md +77 -0
- package/dist/skills/codex/reference/routing.md +35 -0
- package/dist/skills/codex/reference/sync.md +35 -0
- package/dist/skills/codex/reference/troubleshooting.md +53 -0
- package/dist/skills/codex/reference/workflow.md +39 -0
- package/dist/sync/aiExportManifest.d.ts +58 -0
- package/dist/sync/aiExportManifest.js +430 -0
- package/dist/sync/aiExportManifest.js.map +1 -0
- package/dist/sync/frontmatter.d.ts +28 -0
- package/dist/sync/frontmatter.js +210 -0
- package/dist/sync/frontmatter.js.map +1 -0
- package/dist/sync/hash.d.ts +1 -0
- package/dist/sync/hash.js +8 -0
- package/dist/sync/hash.js.map +1 -0
- package/dist/sync/index.d.ts +12 -0
- package/dist/sync/index.js +9 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/manifest.d.ts +58 -0
- package/dist/sync/manifest.js +21 -0
- package/dist/sync/manifest.js.map +1 -0
- package/dist/sync/paths.d.ts +16 -0
- package/dist/sync/paths.js +116 -0
- package/dist/sync/paths.js.map +1 -0
- package/dist/sync/plan.d.ts +29 -0
- package/dist/sync/plan.js +72 -0
- package/dist/sync/plan.js.map +1 -0
- package/dist/sync/validate.d.ts +26 -0
- package/dist/sync/validate.js +308 -0
- package/dist/sync/validate.js.map +1 -0
- package/dist/types.d.ts +84 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +143 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/push.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\n\nimport type { DocsDeleteBehavior } from '../../sync/index.js'\nimport type {\n HttpGetJson,\n HttpPostJson,\n} from '../http.js'\nimport type {\n CliResult,\n ParsedCliArgs,\n PushCommandOptions,\n} from '../types.js'\n\nimport { DEFAULT_GITHUB_OIDC_AUDIENCE } from '../../constants.js'\nimport { signDocsSyncRequest } from '../../security/index.js'\nimport {\n buildDocsManifest,\n sha256Hex,\n validateDocsManifest,\n} from '../../sync/index.js'\nimport {\n readDocsAiExportManifest,\n walkDocsFiles,\n} from '../filesystem.js'\nimport { formatIssues, formatPushSummary, printJson } from '../format.js'\nimport {\n getJson,\n postJson,\n} from '../http.js'\nimport { getFlagBoolean, getFlagString } from '../parseArgs.js'\nimport { getDocsCommandOptions } from './validate.js'\n\nconst supportedPushDeleteBehaviors = new Set<DocsDeleteBehavior>([\n 'archive',\n 'delete',\n 'draft',\n 'ignore',\n])\n\ntype ServerPushResponse = {\n deleteBehavior?: string\n effectivePublishMode?: string\n error?: {\n code?: string\n message?: string\n }\n ok?: boolean\n publishRequested?: boolean\n summary?: {\n archive?: number\n create?: number\n delete?: number\n draft?: number\n unchanged?: number\n update?: number\n warnings?: number\n }\n syncRunId?: string\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst isServerPushResponse = (value: unknown): value is ServerPushResponse =>\n isRecord(value)\n\nconst validateEndpointUrl = (endpoint: string): CliResult | string => {\n try {\n const parsed = new URL(endpoint)\n\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n return {\n exitCode: 1,\n stderr: '--endpoint must be a full http:// or https:// URL.\\n',\n }\n }\n\n return parsed.toString()\n } catch {\n return {\n exitCode: 1,\n stderr: '--endpoint must be a valid full http:// or https:// URL.\\n',\n }\n }\n}\n\nconst readPrivateKey = async (\n args: ParsedCliArgs,\n): Promise<CliResult | string> => {\n const privateKeyFile = getFlagString(args, 'private-key-file')\n const privateKeyEnv = getFlagString(args, 'private-key-env')\n\n if (privateKeyFile && privateKeyEnv) {\n return {\n exitCode: 1,\n stderr:\n 'Use either --private-key-file or --private-key-env, not both.\\n',\n }\n }\n\n if (!privateKeyFile && !privateKeyEnv) {\n return {\n exitCode: 1,\n stderr: 'Push requires --private-key-file or --private-key-env.\\n',\n }\n }\n\n if (privateKeyEnv) {\n const privateKey = process.env[privateKeyEnv]\n\n if (!privateKey) {\n return {\n exitCode: 1,\n stderr: `Environment variable \"${privateKeyEnv}\" is not set.\\n`,\n }\n }\n\n return privateKey\n }\n\n try {\n return await readFile(privateKeyFile ?? '', 'utf8')\n } catch (error) {\n return {\n exitCode: 1,\n stderr:\n error instanceof Error\n ? `Could not read private key file: ${error.message}\\n`\n : 'Could not read private key file.\\n',\n }\n }\n}\n\nconst getGithubOidcTokenRequestUrl = ({\n audience,\n requestUrl,\n}: {\n audience: string\n requestUrl: string\n}): CliResult | string => {\n try {\n const url = new URL(requestUrl)\n url.searchParams.set('audience', audience)\n\n return url.toString()\n } catch {\n return {\n exitCode: 1,\n stderr: 'ACTIONS_ID_TOKEN_REQUEST_URL is not a valid URL.\\n',\n }\n }\n}\n\nconst readGithubOidcToken = async ({\n args,\n audience,\n httpGet,\n}: {\n args: ParsedCliArgs\n audience: string\n httpGet: HttpGetJson\n}): Promise<CliResult | string> => {\n const tokenEnv = getFlagString(args, 'oidc-token-env')\n\n if (tokenEnv) {\n const token = process.env[tokenEnv]\n\n if (!token) {\n return {\n exitCode: 1,\n stderr: `Environment variable \"${tokenEnv}\" is not set.\\n`,\n }\n }\n\n return token\n }\n\n const requestUrl = process.env.ACTIONS_ID_TOKEN_REQUEST_URL\n const requestToken = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN\n\n if (!requestUrl || !requestToken) {\n return {\n exitCode: 1,\n stderr:\n 'GitHub OIDC push requires ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN, or --oidc-token-env.\\n',\n }\n }\n\n const url = getGithubOidcTokenRequestUrl({\n audience,\n requestUrl,\n })\n\n if (typeof url !== 'string') {\n return url\n }\n\n const response = await httpGet({\n headers: {\n Authorization: `bearer ${requestToken}`,\n },\n url,\n })\n\n if (!response.ok || !isRecord(response.body) || typeof response.body.value !== 'string') {\n return {\n exitCode: 1,\n stderr: `Could not retrieve GitHub OIDC token. HTTP status ${response.status}.\\n`,\n }\n }\n\n return response.body.value\n}\n\nconst getPushCommandOptions = async (\n args: ParsedCliArgs,\n): Promise<CliResult | PushCommandOptions> => {\n const docsOptions = getDocsCommandOptions(args)\n\n if ('exitCode' in docsOptions) {\n return docsOptions\n }\n\n const endpointFlag = getFlagString(args, 'endpoint')\n\n if (!endpointFlag) {\n return {\n exitCode: 1,\n stderr: 'Push requires --endpoint <url>.\\n',\n }\n }\n\n const endpoint = validateEndpointUrl(endpointFlag)\n\n if (typeof endpoint !== 'string') {\n return endpoint\n }\n\n if (getFlagBoolean(args, 'dry-run') && getFlagBoolean(args, 'sync')) {\n return {\n exitCode: 1,\n stderr: 'Use either --dry-run or --sync, not both.\\n',\n }\n }\n\n const deleteBehaviorFlag = getFlagString(args, 'delete-behavior')\n\n if (\n deleteBehaviorFlag !== undefined &&\n !supportedPushDeleteBehaviors.has(deleteBehaviorFlag as DocsDeleteBehavior)\n ) {\n return {\n exitCode: 1,\n stderr: '--delete-behavior for push must be archive, delete, draft, or ignore.\\n',\n }\n }\n\n const mode: PushCommandOptions['mode'] = getFlagBoolean(args, 'sync')\n ? 'sync'\n : 'dry-run'\n const baseOptions = {\n ...docsOptions,\n deleteBehavior: deleteBehaviorFlag as DocsDeleteBehavior | undefined,\n endpoint,\n mode,\n publish: getFlagBoolean(args, 'publish'),\n }\n\n if (getFlagBoolean(args, 'github-oidc')) {\n if (getFlagString(args, 'key-id')) {\n return {\n exitCode: 1,\n stderr: 'Do not use --key-id with --github-oidc.\\n',\n }\n }\n\n if (getFlagString(args, 'private-key-file') || getFlagString(args, 'private-key-env')) {\n return {\n exitCode: 1,\n stderr: 'Do not use Ed25519 private key flags with --github-oidc.\\n',\n }\n }\n\n return {\n ...baseOptions,\n authMode: 'github-oidc',\n oidcAudience:\n getFlagString(args, 'oidc-audience') ?? DEFAULT_GITHUB_OIDC_AUDIENCE,\n oidcTokenEnv: getFlagString(args, 'oidc-token-env'),\n }\n }\n\n const keyId = getFlagString(args, 'key-id')\n\n if (!keyId) {\n return {\n exitCode: 1,\n stderr: 'Push requires --key-id <id>.\\n',\n }\n }\n\n const privateKey = await readPrivateKey(args)\n\n if (typeof privateKey !== 'string') {\n return privateKey\n }\n\n return {\n ...baseOptions,\n authMode: 'ed25519',\n keyId,\n privateKey,\n }\n}\n\nconst formatServerFailure = ({\n body,\n status,\n}: {\n body: unknown\n status: number\n}): string => {\n if (isServerPushResponse(body) && body.error?.message) {\n return `${body.error.message}\\n`\n }\n\n return `Sync request failed with HTTP status ${status}.\\n`\n}\n\nexport const runPushCommand = async (\n args: ParsedCliArgs,\n httpPost: HttpPostJson = postJson,\n httpGet: HttpGetJson = getJson,\n): Promise<CliResult> => {\n const options = await getPushCommandOptions(args)\n\n if ('exitCode' in options) {\n return options\n }\n\n const files = await walkDocsFiles({\n root: options.docsRoot,\n })\n const aiExport = await readDocsAiExportManifest({\n root: options.docsRoot,\n })\n\n if (!aiExport.ok) {\n return {\n exitCode: 1,\n stderr: `AI export manifest is invalid.\\n\\nErrors:\\n${formatIssues(aiExport.issues)}\\n`,\n }\n }\n\n const manifest = buildDocsManifest({\n aiExport: aiExport.manifest,\n branch: options.branch,\n commit: options.commit,\n deleteBehavior: options.deleteBehavior ?? 'archive',\n files,\n mode: options.mode,\n publish: options.publish,\n repository: options.repository,\n root: options.sourceRoot,\n sourceId: options.sourceId,\n })\n const validation = validateDocsManifest(manifest, {\n maxFileBytes: options.maxFileBytes,\n maxFiles: options.maxFiles,\n maxTotalBytes: options.maxTotalBytes,\n routeBase: options.routeBase,\n })\n\n if (!validation.ok) {\n return {\n exitCode: 1,\n stderr: `Manifest is invalid.\\n\\nErrors:\\n${formatIssues(validation.issues)}\\n`,\n }\n }\n\n const body = JSON.stringify(manifest)\n let signedRequest:\n | {\n body: string\n headers: Record<string, string>\n }\n | ReturnType<typeof signDocsSyncRequest>\n\n if (options.authMode === 'github-oidc') {\n const oidcToken = await readGithubOidcToken({\n args,\n audience: options.oidcAudience,\n httpGet,\n })\n\n if (typeof oidcToken !== 'string') {\n return oidcToken\n }\n\n signedRequest = {\n body,\n headers: {\n Authorization: `Bearer ${oidcToken}`,\n 'Content-Type': 'application/json',\n 'X-VL-MD-DOCS-Body-SHA256': sha256Hex(body),\n },\n }\n } else {\n signedRequest = signDocsSyncRequest({\n body,\n endpoint: options.endpoint,\n keyId: options.keyId,\n privateKey: options.privateKey,\n })\n }\n\n const response = await httpPost({\n body: signedRequest.body,\n headers: signedRequest.headers,\n url: options.endpoint,\n })\n\n if (getFlagBoolean(args, 'json')) {\n return {\n exitCode:\n response.ok &&\n isServerPushResponse(response.body) &&\n response.body.ok === true\n ? 0\n : 1,\n stdout: printJson(\n {\n endpoint: options.endpoint,\n mode: options.mode,\n response: response.body,\n sourceId: options.sourceId,\n status: response.status,\n },\n getFlagBoolean(args, 'pretty'),\n ),\n }\n }\n\n if (\n !response.ok ||\n !isServerPushResponse(response.body) ||\n response.body.ok !== true\n ) {\n return {\n exitCode: 1,\n stderr: formatServerFailure({\n body: response.body,\n status: response.status,\n }),\n }\n }\n\n return {\n exitCode: 0,\n stdout: formatPushSummary({\n endpoint: options.endpoint,\n mode: options.mode,\n response: response.body,\n sourceId: options.sourceId,\n }),\n }\n}\n"],"names":["readFile","DEFAULT_GITHUB_OIDC_AUDIENCE","signDocsSyncRequest","buildDocsManifest","sha256Hex","validateDocsManifest","readDocsAiExportManifest","walkDocsFiles","formatIssues","formatPushSummary","printJson","getJson","postJson","getFlagBoolean","getFlagString","getDocsCommandOptions","supportedPushDeleteBehaviors","Set","isRecord","value","Array","isArray","isServerPushResponse","validateEndpointUrl","endpoint","parsed","URL","protocol","exitCode","stderr","toString","readPrivateKey","args","privateKeyFile","privateKeyEnv","privateKey","process","env","error","Error","message","getGithubOidcTokenRequestUrl","audience","requestUrl","url","searchParams","set","readGithubOidcToken","httpGet","tokenEnv","token","ACTIONS_ID_TOKEN_REQUEST_URL","requestToken","ACTIONS_ID_TOKEN_REQUEST_TOKEN","response","headers","Authorization","ok","body","status","getPushCommandOptions","docsOptions","endpointFlag","deleteBehaviorFlag","undefined","has","mode","baseOptions","deleteBehavior","publish","authMode","oidcAudience","oidcTokenEnv","keyId","formatServerFailure","runPushCommand","httpPost","options","files","root","docsRoot","aiExport","issues","manifest","branch","commit","repository","sourceRoot","sourceId","validation","maxFileBytes","maxFiles","maxTotalBytes","routeBase","JSON","stringify","signedRequest","oidcToken","stdout"],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { buildDocsManifest, validateDocsManifest } from '../../sync/index.js';
|
|
3
|
+
import { readDocsAiExportManifest, walkDocsFiles } from '../filesystem.js';
|
|
4
|
+
import { formatValidationSummary, printJson } from '../format.js';
|
|
5
|
+
import { getFlagBoolean, getFlagString, parseIntegerFlag } from '../parseArgs.js';
|
|
6
|
+
export const getDocsCommandOptions = (args)=>{
|
|
7
|
+
const docsRoot = args.positionals[0] ?? getFlagString(args, 'root');
|
|
8
|
+
if (!docsRoot) {
|
|
9
|
+
return {
|
|
10
|
+
exitCode: 1,
|
|
11
|
+
stderr: `Command "${args.command}" requires a docs root path.\n`
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const maxFiles = parseIntegerFlag(args, 'max-files');
|
|
15
|
+
const maxFileBytes = parseIntegerFlag(args, 'max-file-bytes');
|
|
16
|
+
const maxTotalBytes = parseIntegerFlag(args, 'max-total-bytes');
|
|
17
|
+
for (const parsed of [
|
|
18
|
+
maxFiles,
|
|
19
|
+
maxFileBytes,
|
|
20
|
+
maxTotalBytes
|
|
21
|
+
]){
|
|
22
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
23
|
+
return parsed;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
branch: getFlagString(args, 'branch'),
|
|
28
|
+
commit: getFlagString(args, 'commit'),
|
|
29
|
+
docsRoot,
|
|
30
|
+
maxFileBytes: typeof maxFileBytes === 'number' ? maxFileBytes : undefined,
|
|
31
|
+
maxFiles: typeof maxFiles === 'number' ? maxFiles : undefined,
|
|
32
|
+
maxTotalBytes: typeof maxTotalBytes === 'number' ? maxTotalBytes : undefined,
|
|
33
|
+
repository: getFlagString(args, 'repository'),
|
|
34
|
+
routeBase: getFlagString(args, 'route-base'),
|
|
35
|
+
sourceId: getFlagString(args, 'source') ?? 'local-docs',
|
|
36
|
+
sourceRoot: getFlagString(args, 'root') ?? path.basename(path.resolve(docsRoot))
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export const runValidateCommand = async (args)=>{
|
|
40
|
+
const options = getDocsCommandOptions(args);
|
|
41
|
+
if ('exitCode' in options) {
|
|
42
|
+
return options;
|
|
43
|
+
}
|
|
44
|
+
const files = await walkDocsFiles({
|
|
45
|
+
root: options.docsRoot
|
|
46
|
+
});
|
|
47
|
+
const aiExport = await readDocsAiExportManifest({
|
|
48
|
+
root: options.docsRoot
|
|
49
|
+
});
|
|
50
|
+
if (!aiExport.ok) {
|
|
51
|
+
return {
|
|
52
|
+
exitCode: 1,
|
|
53
|
+
stdout: formatValidationSummary({
|
|
54
|
+
fileCount: files.length,
|
|
55
|
+
root: options.docsRoot,
|
|
56
|
+
sourceId: options.sourceId,
|
|
57
|
+
validation: {
|
|
58
|
+
issues: aiExport.issues,
|
|
59
|
+
ok: false,
|
|
60
|
+
warnings: aiExport.warnings
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const manifest = buildDocsManifest({
|
|
66
|
+
aiExport: aiExport.manifest,
|
|
67
|
+
branch: options.branch,
|
|
68
|
+
commit: options.commit,
|
|
69
|
+
files,
|
|
70
|
+
repository: options.repository,
|
|
71
|
+
root: options.sourceRoot,
|
|
72
|
+
sourceId: options.sourceId
|
|
73
|
+
});
|
|
74
|
+
const validation = validateDocsManifest(manifest, {
|
|
75
|
+
maxFileBytes: options.maxFileBytes,
|
|
76
|
+
maxFiles: options.maxFiles,
|
|
77
|
+
maxTotalBytes: options.maxTotalBytes,
|
|
78
|
+
routeBase: options.routeBase
|
|
79
|
+
});
|
|
80
|
+
const validationWithReadWarnings = {
|
|
81
|
+
...validation,
|
|
82
|
+
warnings: [
|
|
83
|
+
...aiExport.warnings,
|
|
84
|
+
...validation.warnings
|
|
85
|
+
]
|
|
86
|
+
};
|
|
87
|
+
if (getFlagBoolean(args, 'json')) {
|
|
88
|
+
return {
|
|
89
|
+
exitCode: validation.ok ? 0 : 1,
|
|
90
|
+
stdout: printJson({
|
|
91
|
+
fileCount: files.length,
|
|
92
|
+
root: options.docsRoot,
|
|
93
|
+
sourceId: options.sourceId,
|
|
94
|
+
validation: validationWithReadWarnings
|
|
95
|
+
}, getFlagBoolean(args, 'pretty'))
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
exitCode: validation.ok ? 0 : 1,
|
|
100
|
+
stdout: formatValidationSummary({
|
|
101
|
+
fileCount: files.length,
|
|
102
|
+
root: options.docsRoot,
|
|
103
|
+
sourceId: options.sourceId,
|
|
104
|
+
validation: validationWithReadWarnings
|
|
105
|
+
})
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/validate.ts"],"sourcesContent":["import path from 'node:path'\n\nimport type {\n CliResult,\n DocsCommandOptions,\n ParsedCliArgs,\n} from '../types.js'\n\nimport {\n buildDocsManifest,\n validateDocsManifest,\n} from '../../sync/index.js'\nimport {\n readDocsAiExportManifest,\n walkDocsFiles,\n} from '../filesystem.js'\nimport { formatValidationSummary, printJson } from '../format.js'\nimport {\n getFlagBoolean,\n getFlagString,\n parseIntegerFlag,\n} from '../parseArgs.js'\n\nexport const getDocsCommandOptions = (\n args: ParsedCliArgs,\n): CliResult | DocsCommandOptions => {\n const docsRoot = args.positionals[0] ?? getFlagString(args, 'root')\n\n if (!docsRoot) {\n return {\n exitCode: 1,\n stderr: `Command \"${args.command}\" requires a docs root path.\\n`,\n }\n }\n\n const maxFiles = parseIntegerFlag(args, 'max-files')\n const maxFileBytes = parseIntegerFlag(args, 'max-file-bytes')\n const maxTotalBytes = parseIntegerFlag(args, 'max-total-bytes')\n\n for (const parsed of [maxFiles, maxFileBytes, maxTotalBytes]) {\n if (typeof parsed === 'object' && parsed !== null) {\n return parsed\n }\n }\n\n return {\n branch: getFlagString(args, 'branch'),\n commit: getFlagString(args, 'commit'),\n docsRoot,\n maxFileBytes: typeof maxFileBytes === 'number' ? maxFileBytes : undefined,\n maxFiles: typeof maxFiles === 'number' ? maxFiles : undefined,\n maxTotalBytes: typeof maxTotalBytes === 'number' ? maxTotalBytes : undefined,\n repository: getFlagString(args, 'repository'),\n routeBase: getFlagString(args, 'route-base'),\n sourceId: getFlagString(args, 'source') ?? 'local-docs',\n sourceRoot: getFlagString(args, 'root') ?? path.basename(path.resolve(docsRoot)),\n }\n}\n\nexport const runValidateCommand = async (\n args: ParsedCliArgs,\n): Promise<CliResult> => {\n const options = getDocsCommandOptions(args)\n\n if ('exitCode' in options) {\n return options\n }\n\n const files = await walkDocsFiles({\n root: options.docsRoot,\n })\n const aiExport = await readDocsAiExportManifest({\n root: options.docsRoot,\n })\n\n if (!aiExport.ok) {\n return {\n exitCode: 1,\n stdout: formatValidationSummary({\n fileCount: files.length,\n root: options.docsRoot,\n sourceId: options.sourceId,\n validation: {\n issues: aiExport.issues,\n ok: false,\n warnings: aiExport.warnings,\n },\n }),\n }\n }\n\n const manifest = buildDocsManifest({\n aiExport: aiExport.manifest,\n branch: options.branch,\n commit: options.commit,\n files,\n repository: options.repository,\n root: options.sourceRoot,\n sourceId: options.sourceId,\n })\n const validation = validateDocsManifest(manifest, {\n maxFileBytes: options.maxFileBytes,\n maxFiles: options.maxFiles,\n maxTotalBytes: options.maxTotalBytes,\n routeBase: options.routeBase,\n })\n const validationWithReadWarnings = {\n ...validation,\n warnings: [...aiExport.warnings, ...validation.warnings],\n } as typeof validation\n\n if (getFlagBoolean(args, 'json')) {\n return {\n exitCode: validation.ok ? 0 : 1,\n stdout: printJson({\n fileCount: files.length,\n root: options.docsRoot,\n sourceId: options.sourceId,\n validation: validationWithReadWarnings,\n }, getFlagBoolean(args, 'pretty')),\n }\n }\n\n return {\n exitCode: validation.ok ? 0 : 1,\n stdout: formatValidationSummary({\n fileCount: files.length,\n root: options.docsRoot,\n sourceId: options.sourceId,\n validation: validationWithReadWarnings,\n }),\n }\n}\n"],"names":["path","buildDocsManifest","validateDocsManifest","readDocsAiExportManifest","walkDocsFiles","formatValidationSummary","printJson","getFlagBoolean","getFlagString","parseIntegerFlag","getDocsCommandOptions","args","docsRoot","positionals","exitCode","stderr","command","maxFiles","maxFileBytes","maxTotalBytes","parsed","branch","commit","undefined","repository","routeBase","sourceId","sourceRoot","basename","resolve","runValidateCommand","options","files","root","aiExport","ok","stdout","fileCount","length","validation","issues","warnings","manifest","validationWithReadWarnings"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DocsAiExportManifest, DocsValidationIssue } from '../sync/index.js';
|
|
2
|
+
export type WalkDocsFilesOptions = {
|
|
3
|
+
root: string;
|
|
4
|
+
};
|
|
5
|
+
export type WalkedDocsFile = {
|
|
6
|
+
content: string;
|
|
7
|
+
path: string;
|
|
8
|
+
};
|
|
9
|
+
export type ReadDocsAiExportManifestResult = {
|
|
10
|
+
issues: DocsValidationIssue[];
|
|
11
|
+
manifest?: DocsAiExportManifest;
|
|
12
|
+
ok: true;
|
|
13
|
+
warnings: DocsValidationIssue[];
|
|
14
|
+
} | {
|
|
15
|
+
issues: DocsValidationIssue[];
|
|
16
|
+
ok: false;
|
|
17
|
+
warnings: DocsValidationIssue[];
|
|
18
|
+
};
|
|
19
|
+
export declare const walkDocsFiles: ({ root, }: WalkDocsFilesOptions) => Promise<WalkedDocsFile[]>;
|
|
20
|
+
export declare const readDocsAiExportManifest: ({ root, }: WalkDocsFilesOptions) => Promise<ReadDocsAiExportManifestResult>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { access, readdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES, normalizeDocsPath, parseDocsAiExportManifestYaml } from '../sync/index.js';
|
|
4
|
+
const ignoredDirectories = new Set([
|
|
5
|
+
'.git',
|
|
6
|
+
'.next',
|
|
7
|
+
'build',
|
|
8
|
+
'dist',
|
|
9
|
+
'node_modules'
|
|
10
|
+
]);
|
|
11
|
+
const fileExists = async (filePath)=>{
|
|
12
|
+
try {
|
|
13
|
+
await access(filePath);
|
|
14
|
+
return true;
|
|
15
|
+
} catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
export const walkDocsFiles = async ({ root })=>{
|
|
20
|
+
const absoluteRoot = path.resolve(root);
|
|
21
|
+
const files = [];
|
|
22
|
+
const walkDirectory = async (directory)=>{
|
|
23
|
+
const entries = await readdir(directory, {
|
|
24
|
+
withFileTypes: true
|
|
25
|
+
});
|
|
26
|
+
for (const entry of entries){
|
|
27
|
+
if (entry.isSymbolicLink()) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const absolutePath = path.join(directory, entry.name);
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
if (!ignoredDirectories.has(entry.name)) {
|
|
33
|
+
await walkDirectory(absolutePath);
|
|
34
|
+
}
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!entry.isFile() || !entry.name.endsWith('.md')) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const relativePath = path.relative(absoluteRoot, absolutePath).split(path.sep).join('/');
|
|
41
|
+
const normalizedPath = normalizeDocsPath(relativePath);
|
|
42
|
+
if (!normalizedPath.ok) {
|
|
43
|
+
throw new Error(normalizedPath.message);
|
|
44
|
+
}
|
|
45
|
+
files.push({
|
|
46
|
+
content: await readFile(absolutePath, 'utf8'),
|
|
47
|
+
path: normalizedPath.path
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
await walkDirectory(absoluteRoot);
|
|
52
|
+
return files.sort((left, right)=>left.path.localeCompare(right.path));
|
|
53
|
+
};
|
|
54
|
+
export const readDocsAiExportManifest = async ({ root })=>{
|
|
55
|
+
const absoluteRoot = path.resolve(root);
|
|
56
|
+
const manifestPaths = [];
|
|
57
|
+
for (const filename of AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES){
|
|
58
|
+
const manifestPath = path.join(absoluteRoot, filename);
|
|
59
|
+
if (await fileExists(manifestPath)) {
|
|
60
|
+
manifestPaths.push(filename);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (manifestPaths.length === 0) {
|
|
64
|
+
return {
|
|
65
|
+
issues: [],
|
|
66
|
+
ok: true,
|
|
67
|
+
warnings: []
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const selectedPath = manifestPaths[0] ?? AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES[0];
|
|
71
|
+
const warnings = manifestPaths.length > 1 ? [
|
|
72
|
+
{
|
|
73
|
+
code: 'invalid_ai_export_manifest',
|
|
74
|
+
message: 'Both index.ai.yml and index.ai.yaml exist. Using index.ai.yml.',
|
|
75
|
+
path: selectedPath
|
|
76
|
+
}
|
|
77
|
+
] : [];
|
|
78
|
+
const parsed = parseDocsAiExportManifestYaml({
|
|
79
|
+
content: await readFile(path.join(absoluteRoot, selectedPath), 'utf8'),
|
|
80
|
+
sourcePath: selectedPath
|
|
81
|
+
});
|
|
82
|
+
if (!parsed.ok) {
|
|
83
|
+
return parsed;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
issues: [],
|
|
87
|
+
manifest: parsed.manifest,
|
|
88
|
+
ok: true,
|
|
89
|
+
warnings: [
|
|
90
|
+
...warnings,
|
|
91
|
+
...parsed.warnings
|
|
92
|
+
]
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/filesystem.ts"],"sourcesContent":["import { access, readdir, readFile } from 'node:fs/promises'\nimport path from 'node:path'\n\nimport type {\n DocsAiExportManifest,\n DocsValidationIssue,\n} from '../sync/index.js'\n\nimport {\n AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES,\n normalizeDocsPath,\n parseDocsAiExportManifestYaml,\n} from '../sync/index.js'\n\nexport type WalkDocsFilesOptions = {\n root: string\n}\n\nexport type WalkedDocsFile = {\n content: string\n path: string\n}\n\nexport type ReadDocsAiExportManifestResult =\n | {\n issues: DocsValidationIssue[]\n manifest?: DocsAiExportManifest\n ok: true\n warnings: DocsValidationIssue[]\n }\n | {\n issues: DocsValidationIssue[]\n ok: false\n warnings: DocsValidationIssue[]\n }\n\nconst ignoredDirectories = new Set(['.git', '.next', 'build', 'dist', 'node_modules'])\n\nconst fileExists = async (filePath: string): Promise<boolean> => {\n try {\n await access(filePath)\n\n return true\n } catch {\n return false\n }\n}\n\nexport const walkDocsFiles = async ({\n root,\n}: WalkDocsFilesOptions): Promise<WalkedDocsFile[]> => {\n const absoluteRoot = path.resolve(root)\n const files: WalkedDocsFile[] = []\n\n const walkDirectory = async (directory: string): Promise<void> => {\n const entries = await readdir(directory, {\n withFileTypes: true,\n })\n\n for (const entry of entries) {\n if (entry.isSymbolicLink()) {\n continue\n }\n\n const absolutePath = path.join(directory, entry.name)\n\n if (entry.isDirectory()) {\n if (!ignoredDirectories.has(entry.name)) {\n await walkDirectory(absolutePath)\n }\n\n continue\n }\n\n if (!entry.isFile() || !entry.name.endsWith('.md')) {\n continue\n }\n\n const relativePath = path.relative(absoluteRoot, absolutePath).split(path.sep).join('/')\n const normalizedPath = normalizeDocsPath(relativePath)\n\n if (!normalizedPath.ok) {\n throw new Error(normalizedPath.message)\n }\n\n files.push({\n content: await readFile(absolutePath, 'utf8'),\n path: normalizedPath.path,\n })\n }\n }\n\n await walkDirectory(absoluteRoot)\n\n return files.sort((left, right) => left.path.localeCompare(right.path))\n}\n\nexport const readDocsAiExportManifest = async ({\n root,\n}: WalkDocsFilesOptions): Promise<ReadDocsAiExportManifestResult> => {\n const absoluteRoot = path.resolve(root)\n const manifestPaths: string[] = []\n\n for (const filename of AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES) {\n const manifestPath = path.join(absoluteRoot, filename)\n\n if (await fileExists(manifestPath)) {\n manifestPaths.push(filename)\n }\n }\n\n if (manifestPaths.length === 0) {\n return {\n issues: [],\n ok: true,\n warnings: [],\n }\n }\n\n const selectedPath = manifestPaths[0] ?? AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES[0]\n const warnings: DocsValidationIssue[] =\n manifestPaths.length > 1\n ? [\n {\n code: 'invalid_ai_export_manifest',\n message:\n 'Both index.ai.yml and index.ai.yaml exist. Using index.ai.yml.',\n path: selectedPath,\n },\n ]\n : []\n const parsed = parseDocsAiExportManifestYaml({\n content: await readFile(path.join(absoluteRoot, selectedPath), 'utf8'),\n sourcePath: selectedPath,\n })\n\n if (!parsed.ok) {\n return parsed\n }\n\n return {\n issues: [],\n manifest: parsed.manifest,\n ok: true,\n warnings: [...warnings, ...parsed.warnings],\n }\n}\n"],"names":["access","readdir","readFile","path","AI_MARKDOWN_EXPORT_MANIFEST_FILENAMES","normalizeDocsPath","parseDocsAiExportManifestYaml","ignoredDirectories","Set","fileExists","filePath","walkDocsFiles","root","absoluteRoot","resolve","files","walkDirectory","directory","entries","withFileTypes","entry","isSymbolicLink","absolutePath","join","name","isDirectory","has","isFile","endsWith","relativePath","relative","split","sep","normalizedPath","ok","Error","message","push","content","sort","left","right","localeCompare","readDocsAiExportManifest","manifestPaths","filename","manifestPath","length","issues","warnings","selectedPath","code","parsed","sourcePath","manifest"],"mappings":"AAAA,SAASA,MAAM,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,mBAAkB;AAC5D,OAAOC,UAAU,YAAW;AAO5B,SACEC,qCAAqC,EACrCC,iBAAiB,EACjBC,6BAA6B,QACxB,mBAAkB;AAwBzB,MAAMC,qBAAqB,IAAIC,IAAI;IAAC;IAAQ;IAAS;IAAS;IAAQ;CAAe;AAErF,MAAMC,aAAa,OAAOC;IACxB,IAAI;QACF,MAAMV,OAAOU;QAEb,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,OAAO,MAAMC,gBAAgB,OAAO,EAClCC,IAAI,EACiB;IACrB,MAAMC,eAAeV,KAAKW,OAAO,CAACF;IAClC,MAAMG,QAA0B,EAAE;IAElC,MAAMC,gBAAgB,OAAOC;QAC3B,MAAMC,UAAU,MAAMjB,QAAQgB,WAAW;YACvCE,eAAe;QACjB;QAEA,KAAK,MAAMC,SAASF,QAAS;YAC3B,IAAIE,MAAMC,cAAc,IAAI;gBAC1B;YACF;YAEA,MAAMC,eAAenB,KAAKoB,IAAI,CAACN,WAAWG,MAAMI,IAAI;YAEpD,IAAIJ,MAAMK,WAAW,IAAI;gBACvB,IAAI,CAAClB,mBAAmBmB,GAAG,CAACN,MAAMI,IAAI,GAAG;oBACvC,MAAMR,cAAcM;gBACtB;gBAEA;YACF;YAEA,IAAI,CAACF,MAAMO,MAAM,MAAM,CAACP,MAAMI,IAAI,CAACI,QAAQ,CAAC,QAAQ;gBAClD;YACF;YAEA,MAAMC,eAAe1B,KAAK2B,QAAQ,CAACjB,cAAcS,cAAcS,KAAK,CAAC5B,KAAK6B,GAAG,EAAET,IAAI,CAAC;YACpF,MAAMU,iBAAiB5B,kBAAkBwB;YAEzC,IAAI,CAACI,eAAeC,EAAE,EAAE;gBACtB,MAAM,IAAIC,MAAMF,eAAeG,OAAO;YACxC;YAEArB,MAAMsB,IAAI,CAAC;gBACTC,SAAS,MAAMpC,SAASoB,cAAc;gBACtCnB,MAAM8B,eAAe9B,IAAI;YAC3B;QACF;IACF;IAEA,MAAMa,cAAcH;IAEpB,OAAOE,MAAMwB,IAAI,CAAC,CAACC,MAAMC,QAAUD,KAAKrC,IAAI,CAACuC,aAAa,CAACD,MAAMtC,IAAI;AACvE,EAAC;AAED,OAAO,MAAMwC,2BAA2B,OAAO,EAC7C/B,IAAI,EACiB;IACrB,MAAMC,eAAeV,KAAKW,OAAO,CAACF;IAClC,MAAMgC,gBAA0B,EAAE;IAElC,KAAK,MAAMC,YAAYzC,sCAAuC;QAC5D,MAAM0C,eAAe3C,KAAKoB,IAAI,CAACV,cAAcgC;QAE7C,IAAI,MAAMpC,WAAWqC,eAAe;YAClCF,cAAcP,IAAI,CAACQ;QACrB;IACF;IAEA,IAAID,cAAcG,MAAM,KAAK,GAAG;QAC9B,OAAO;YACLC,QAAQ,EAAE;YACVd,IAAI;YACJe,UAAU,EAAE;QACd;IACF;IAEA,MAAMC,eAAeN,aAAa,CAAC,EAAE,IAAIxC,qCAAqC,CAAC,EAAE;IACjF,MAAM6C,WACJL,cAAcG,MAAM,GAAG,IACnB;QACE;YACEI,MAAM;YACNf,SACE;YACFjC,MAAM+C;QACR;KACD,GACD,EAAE;IACR,MAAME,SAAS9C,8BAA8B;QAC3CgC,SAAS,MAAMpC,SAASC,KAAKoB,IAAI,CAACV,cAAcqC,eAAe;QAC/DG,YAAYH;IACd;IAEA,IAAI,CAACE,OAAOlB,EAAE,EAAE;QACd,OAAOkB;IACT;IAEA,OAAO;QACLJ,QAAQ,EAAE;QACVM,UAAUF,OAAOE,QAAQ;QACzBpB,IAAI;QACJe,UAAU;eAAIA;eAAaG,OAAOH,QAAQ;SAAC;IAC7C;AACF,EAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DocsSyncPlan, DocsValidationIssue, DocsValidationResult } from '../sync/index.js';
|
|
2
|
+
export type PushSummaryInput = {
|
|
3
|
+
deleteBehavior?: string;
|
|
4
|
+
effectivePublishMode?: string;
|
|
5
|
+
endpoint: string;
|
|
6
|
+
mode: 'dry-run' | 'sync';
|
|
7
|
+
publishRequested?: boolean;
|
|
8
|
+
response: {
|
|
9
|
+
deleteBehavior?: string;
|
|
10
|
+
effectivePublishMode?: string;
|
|
11
|
+
ok?: boolean;
|
|
12
|
+
publishRequested?: boolean;
|
|
13
|
+
summary?: {
|
|
14
|
+
archive?: number;
|
|
15
|
+
create?: number;
|
|
16
|
+
delete?: number;
|
|
17
|
+
draft?: number;
|
|
18
|
+
unchanged?: number;
|
|
19
|
+
update?: number;
|
|
20
|
+
warnings?: number;
|
|
21
|
+
};
|
|
22
|
+
syncRunId?: string;
|
|
23
|
+
};
|
|
24
|
+
sourceId: string;
|
|
25
|
+
};
|
|
26
|
+
export declare const formatIssues: (issues: DocsValidationIssue[]) => string;
|
|
27
|
+
export declare const formatValidationSummary: ({ fileCount, root, sourceId, validation, }: {
|
|
28
|
+
fileCount: number;
|
|
29
|
+
root: string;
|
|
30
|
+
sourceId: string;
|
|
31
|
+
validation: DocsValidationResult;
|
|
32
|
+
}) => string;
|
|
33
|
+
export declare const formatPlanSummary: (plan: DocsSyncPlan) => string;
|
|
34
|
+
export declare const formatPushSummary: ({ deleteBehavior, effectivePublishMode, endpoint, mode, publishRequested, response, sourceId, }: PushSummaryInput) => string;
|
|
35
|
+
export declare const printJson: (value: unknown, pretty?: boolean) => string;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const formatIssue = (issue)=>{
|
|
2
|
+
if (issue.path) {
|
|
3
|
+
return `- ${issue.path}: ${issue.message}`;
|
|
4
|
+
}
|
|
5
|
+
return `- ${issue.message}`;
|
|
6
|
+
};
|
|
7
|
+
export const formatIssues = (issues)=>{
|
|
8
|
+
if (issues.length === 0) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
return issues.map(formatIssue).join('\n');
|
|
12
|
+
};
|
|
13
|
+
export const formatValidationSummary = ({ fileCount, root, sourceId, validation })=>{
|
|
14
|
+
const lines = [
|
|
15
|
+
'payload-markdown-docs validate',
|
|
16
|
+
'',
|
|
17
|
+
`Source: ${sourceId}`,
|
|
18
|
+
`Root: ${root}`,
|
|
19
|
+
`Files: ${fileCount}`,
|
|
20
|
+
`Status: ${validation.ok ? 'valid' : 'invalid'}`
|
|
21
|
+
];
|
|
22
|
+
if (validation.warnings.length > 0) {
|
|
23
|
+
lines.push('', 'Warnings:', formatIssues(validation.warnings));
|
|
24
|
+
}
|
|
25
|
+
if (!validation.ok && validation.issues.length > 0) {
|
|
26
|
+
lines.push('', 'Errors:', formatIssues(validation.issues));
|
|
27
|
+
}
|
|
28
|
+
return `${lines.join('\n')}\n`;
|
|
29
|
+
};
|
|
30
|
+
export const formatPlanSummary = (plan)=>{
|
|
31
|
+
const lines = [
|
|
32
|
+
'payload-markdown-docs plan',
|
|
33
|
+
'',
|
|
34
|
+
`Create: ${plan.create.length}`,
|
|
35
|
+
`Update: ${plan.update.length}`,
|
|
36
|
+
`Unchanged: ${plan.unchanged.length}`,
|
|
37
|
+
`Archive: ${plan.archive.length}`,
|
|
38
|
+
`Delete: ${plan.delete.length}`,
|
|
39
|
+
`Draft: ${plan.draft.length}`,
|
|
40
|
+
`Warnings: ${plan.warnings.length}`
|
|
41
|
+
];
|
|
42
|
+
if (plan.warnings.length > 0) {
|
|
43
|
+
lines.push('', 'Warnings:', formatIssues(plan.warnings));
|
|
44
|
+
}
|
|
45
|
+
return `${lines.join('\n')}\n`;
|
|
46
|
+
};
|
|
47
|
+
export const formatPushSummary = ({ deleteBehavior, effectivePublishMode, endpoint, mode, publishRequested, response, sourceId })=>{
|
|
48
|
+
const summary = response.summary ?? {};
|
|
49
|
+
const lines = [
|
|
50
|
+
'payload-markdown-docs push',
|
|
51
|
+
'',
|
|
52
|
+
`Endpoint: ${endpoint}`,
|
|
53
|
+
`Mode: ${mode}`,
|
|
54
|
+
`Source: ${sourceId}`,
|
|
55
|
+
`Publish requested: ${(publishRequested ?? response.publishRequested) === true ? 'yes' : 'no'}`,
|
|
56
|
+
`Publish mode: ${effectivePublishMode ?? response.effectivePublishMode ?? 'unknown'}`,
|
|
57
|
+
`Delete behavior: ${deleteBehavior ?? response.deleteBehavior ?? 'unknown'}`,
|
|
58
|
+
'',
|
|
59
|
+
`Create: ${summary.create ?? 0}`,
|
|
60
|
+
`Update: ${summary.update ?? 0}`,
|
|
61
|
+
`Unchanged: ${summary.unchanged ?? 0}`,
|
|
62
|
+
`Archive: ${summary.archive ?? 0}`,
|
|
63
|
+
`Delete: ${summary.delete ?? 0}`,
|
|
64
|
+
`Draft: ${summary.draft ?? 0}`,
|
|
65
|
+
`Warnings: ${summary.warnings ?? 0}`,
|
|
66
|
+
'',
|
|
67
|
+
`Status: ${mode === 'sync' ? 'applied' : 'accepted'}`
|
|
68
|
+
];
|
|
69
|
+
if (response.syncRunId) {
|
|
70
|
+
lines.push(`Sync run: ${response.syncRunId}`);
|
|
71
|
+
}
|
|
72
|
+
return `${lines.join('\n')}\n`;
|
|
73
|
+
};
|
|
74
|
+
export const printJson = (value, pretty = false)=>`${JSON.stringify(value, null, pretty ? 2 : 0)}\n`;
|
|
75
|
+
|
|
76
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/format.ts"],"sourcesContent":["import type {\n DocsSyncPlan,\n DocsValidationIssue,\n DocsValidationResult,\n} from '../sync/index.js'\n\nexport type PushSummaryInput = {\n deleteBehavior?: string\n effectivePublishMode?: string\n endpoint: string\n mode: 'dry-run' | 'sync'\n publishRequested?: boolean\n response: {\n deleteBehavior?: string\n effectivePublishMode?: string\n ok?: boolean\n publishRequested?: boolean\n summary?: {\n archive?: number\n create?: number\n delete?: number\n draft?: number\n unchanged?: number\n update?: number\n warnings?: number\n }\n syncRunId?: string\n }\n sourceId: string\n}\n\nconst formatIssue = (issue: DocsValidationIssue): string => {\n if (issue.path) {\n return `- ${issue.path}: ${issue.message}`\n }\n\n return `- ${issue.message}`\n}\n\nexport const formatIssues = (issues: DocsValidationIssue[]): string => {\n if (issues.length === 0) {\n return ''\n }\n\n return issues.map(formatIssue).join('\\n')\n}\n\nexport const formatValidationSummary = ({\n fileCount,\n root,\n sourceId,\n validation,\n}: {\n fileCount: number\n root: string\n sourceId: string\n validation: DocsValidationResult\n}): string => {\n const lines = [\n 'payload-markdown-docs validate',\n '',\n `Source: ${sourceId}`,\n `Root: ${root}`,\n `Files: ${fileCount}`,\n `Status: ${validation.ok ? 'valid' : 'invalid'}`,\n ]\n\n if (validation.warnings.length > 0) {\n lines.push('', 'Warnings:', formatIssues(validation.warnings))\n }\n\n if (!validation.ok && validation.issues.length > 0) {\n lines.push('', 'Errors:', formatIssues(validation.issues))\n }\n\n return `${lines.join('\\n')}\\n`\n}\n\nexport const formatPlanSummary = (plan: DocsSyncPlan): string => {\n const lines = [\n 'payload-markdown-docs plan',\n '',\n `Create: ${plan.create.length}`,\n `Update: ${plan.update.length}`,\n `Unchanged: ${plan.unchanged.length}`,\n `Archive: ${plan.archive.length}`,\n `Delete: ${plan.delete.length}`,\n `Draft: ${plan.draft.length}`,\n `Warnings: ${plan.warnings.length}`,\n ]\n\n if (plan.warnings.length > 0) {\n lines.push('', 'Warnings:', formatIssues(plan.warnings))\n }\n\n return `${lines.join('\\n')}\\n`\n}\n\nexport const formatPushSummary = ({\n deleteBehavior,\n effectivePublishMode,\n endpoint,\n mode,\n publishRequested,\n response,\n sourceId,\n}: PushSummaryInput): string => {\n const summary = response.summary ?? {}\n const lines = [\n 'payload-markdown-docs push',\n '',\n `Endpoint: ${endpoint}`,\n `Mode: ${mode}`,\n `Source: ${sourceId}`,\n `Publish requested: ${\n (publishRequested ?? response.publishRequested) === true ? 'yes' : 'no'\n }`,\n `Publish mode: ${\n effectivePublishMode ?? response.effectivePublishMode ?? 'unknown'\n }`,\n `Delete behavior: ${deleteBehavior ?? response.deleteBehavior ?? 'unknown'}`,\n '',\n `Create: ${summary.create ?? 0}`,\n `Update: ${summary.update ?? 0}`,\n `Unchanged: ${summary.unchanged ?? 0}`,\n `Archive: ${summary.archive ?? 0}`,\n `Delete: ${summary.delete ?? 0}`,\n `Draft: ${summary.draft ?? 0}`,\n `Warnings: ${summary.warnings ?? 0}`,\n '',\n `Status: ${mode === 'sync' ? 'applied' : 'accepted'}`,\n ]\n\n if (response.syncRunId) {\n lines.push(`Sync run: ${response.syncRunId}`)\n }\n\n return `${lines.join('\\n')}\\n`\n}\n\nexport const printJson = (value: unknown, pretty = false): string =>\n `${JSON.stringify(value, null, pretty ? 2 : 0)}\\n`\n"],"names":["formatIssue","issue","path","message","formatIssues","issues","length","map","join","formatValidationSummary","fileCount","root","sourceId","validation","lines","ok","warnings","push","formatPlanSummary","plan","create","update","unchanged","archive","delete","draft","formatPushSummary","deleteBehavior","effectivePublishMode","endpoint","mode","publishRequested","response","summary","syncRunId","printJson","value","pretty","JSON","stringify"],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type HttpPostJsonArgs = {
|
|
2
|
+
body: string;
|
|
3
|
+
headers: Record<string, string>;
|
|
4
|
+
url: string;
|
|
5
|
+
};
|
|
6
|
+
export type HttpPostJsonResponse = {
|
|
7
|
+
body: unknown;
|
|
8
|
+
ok: boolean;
|
|
9
|
+
status: number;
|
|
10
|
+
text: string;
|
|
11
|
+
};
|
|
12
|
+
export type HttpPostJson = (args: HttpPostJsonArgs) => Promise<HttpPostJsonResponse>;
|
|
13
|
+
export type HttpGetJsonArgs = {
|
|
14
|
+
headers?: Record<string, string>;
|
|
15
|
+
url: string;
|
|
16
|
+
};
|
|
17
|
+
export type HttpGetJson = (args: HttpGetJsonArgs) => Promise<HttpPostJsonResponse>;
|
|
18
|
+
export declare const postJson: HttpPostJson;
|
|
19
|
+
export declare const getJson: HttpGetJson;
|
package/dist/cli/http.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const parseResponseBody = (text)=>{
|
|
2
|
+
if (text.trim() === '') {
|
|
3
|
+
return undefined;
|
|
4
|
+
}
|
|
5
|
+
try {
|
|
6
|
+
return JSON.parse(text);
|
|
7
|
+
} catch {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
export const postJson = async ({ body, headers, url })=>{
|
|
12
|
+
const response = await fetch(url, {
|
|
13
|
+
body,
|
|
14
|
+
headers,
|
|
15
|
+
method: 'POST'
|
|
16
|
+
});
|
|
17
|
+
const text = await response.text();
|
|
18
|
+
return {
|
|
19
|
+
body: parseResponseBody(text),
|
|
20
|
+
ok: response.ok,
|
|
21
|
+
status: response.status,
|
|
22
|
+
text
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export const getJson = async ({ headers, url })=>{
|
|
26
|
+
const response = await fetch(url, {
|
|
27
|
+
headers,
|
|
28
|
+
method: 'GET'
|
|
29
|
+
});
|
|
30
|
+
const text = await response.text();
|
|
31
|
+
return {
|
|
32
|
+
body: parseResponseBody(text),
|
|
33
|
+
ok: response.ok,
|
|
34
|
+
status: response.status,
|
|
35
|
+
text
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/http.ts"],"sourcesContent":["export type HttpPostJsonArgs = {\n body: string\n headers: Record<string, string>\n url: string\n}\n\nexport type HttpPostJsonResponse = {\n body: unknown\n ok: boolean\n status: number\n text: string\n}\n\nexport type HttpPostJson = (\n args: HttpPostJsonArgs,\n) => Promise<HttpPostJsonResponse>\n\nexport type HttpGetJsonArgs = {\n headers?: Record<string, string>\n url: string\n}\n\nexport type HttpGetJson = (\n args: HttpGetJsonArgs,\n) => Promise<HttpPostJsonResponse>\n\nconst parseResponseBody = (text: string): unknown => {\n if (text.trim() === '') {\n return undefined\n }\n\n try {\n return JSON.parse(text) as unknown\n } catch {\n return undefined\n }\n}\n\nexport const postJson: HttpPostJson = async ({\n body,\n headers,\n url,\n}: HttpPostJsonArgs): Promise<HttpPostJsonResponse> => {\n const response = await fetch(url, {\n body,\n headers,\n method: 'POST',\n })\n const text = await response.text()\n\n return {\n body: parseResponseBody(text),\n ok: response.ok,\n status: response.status,\n text,\n }\n}\n\nexport const getJson: HttpGetJson = async ({\n headers,\n url,\n}: HttpGetJsonArgs): Promise<HttpPostJsonResponse> => {\n const response = await fetch(url, {\n headers,\n method: 'GET',\n })\n const text = await response.text()\n\n return {\n body: parseResponseBody(text),\n ok: response.ok,\n status: response.status,\n text,\n }\n}\n"],"names":["parseResponseBody","text","trim","undefined","JSON","parse","postJson","body","headers","url","response","fetch","method","ok","status","getJson"],"mappings":"AA0BA,MAAMA,oBAAoB,CAACC;IACzB,IAAIA,KAAKC,IAAI,OAAO,IAAI;QACtB,OAAOC;IACT;IAEA,IAAI;QACF,OAAOC,KAAKC,KAAK,CAACJ;IACpB,EAAE,OAAM;QACN,OAAOE;IACT;AACF;AAEA,OAAO,MAAMG,WAAyB,OAAO,EAC3CC,IAAI,EACJC,OAAO,EACPC,GAAG,EACc;IACjB,MAAMC,WAAW,MAAMC,MAAMF,KAAK;QAChCF;QACAC;QACAI,QAAQ;IACV;IACA,MAAMX,OAAO,MAAMS,SAAST,IAAI;IAEhC,OAAO;QACLM,MAAMP,kBAAkBC;QACxBY,IAAIH,SAASG,EAAE;QACfC,QAAQJ,SAASI,MAAM;QACvBb;IACF;AACF,EAAC;AAED,OAAO,MAAMc,UAAuB,OAAO,EACzCP,OAAO,EACPC,GAAG,EACa;IAChB,MAAMC,WAAW,MAAMC,MAAMF,KAAK;QAChCD;QACAI,QAAQ;IACV;IACA,MAAMX,OAAO,MAAMS,SAAST,IAAI;IAEhC,OAAO;QACLM,MAAMP,kBAAkBC;QACxBY,IAAIH,SAASG,EAAE;QACfC,QAAQJ,SAASI,MAAM;QACvBb;IACF;AACF,EAAC"}
|