@fern-api/fdr-sdk 1.2.165-800b1938f3 → 1.2.166-e8ae898b4d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/js/docs-ledger/index.js +20157 -0
- package/dist/js/docs-ledger/index.js.map +1 -0
- package/dist/js/docs-ledger/index.mjs +20113 -0
- package/dist/js/docs-ledger/index.mjs.map +1 -0
- package/dist/types/docs-ledger/buildLedgerManifest.d.ts +80 -0
- package/dist/types/docs-ledger/buildLedgerManifest.d.ts.map +1 -0
- package/dist/types/docs-ledger/docsLedgerHash.d.ts +80 -0
- package/dist/types/docs-ledger/docsLedgerHash.d.ts.map +1 -0
- package/dist/types/docs-ledger/docsPublishTransform.d.ts +178 -0
- package/dist/types/docs-ledger/docsPublishTransform.d.ts.map +1 -0
- package/dist/types/docs-ledger/index.d.ts +15 -0
- package/dist/types/docs-ledger/index.d.ts.map +1 -0
- package/dist/types/docs-ledger/inputTypes.d.ts +236 -0
- package/dist/types/docs-ledger/inputTypes.d.ts.map +1 -0
- package/dist/types/docs-ledger/stableHash.d.ts +7 -0
- package/dist/types/docs-ledger/stableHash.d.ts.map +1 -0
- package/dist/types/docs-ledger/toBasepathRelative.d.ts +25 -0
- package/dist/types/docs-ledger/toBasepathRelative.d.ts.map +1 -0
- package/package.json +8 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { LedgerManifest, LedgerSiblingSite } from "../orpc-client/index.js";
|
|
2
|
+
import type { TransformResult } from "./docsPublishTransform.js";
|
|
3
|
+
import type { ArtifactInput, InlineTranslationParams, PublishParams } from "./inputTypes.js";
|
|
4
|
+
export interface BuildLedgerManifestArgs {
|
|
5
|
+
/** Base-locale entities + deployment/site identity (canonical fern URL). */
|
|
6
|
+
params: PublishParams;
|
|
7
|
+
/** Base-locale transform result (carries config + file dimensions). */
|
|
8
|
+
baseResult: TransformResult;
|
|
9
|
+
/** Additional-locale entities, persisted in the same deployment. */
|
|
10
|
+
inlineTranslations: InlineTranslationParams[];
|
|
11
|
+
/**
|
|
12
|
+
* pageId → bare `fullPath`s of the files each page embeds, merged across all
|
|
13
|
+
* locales (ADR 0016, "File metadata on the render path"). Used to pack each
|
|
14
|
+
* route shard's `files` identity map and to prune the relocated files from
|
|
15
|
+
* the pointer's global `files` map. Empty ⇒ no shard-side files; the pointer
|
|
16
|
+
* keeps every file (graceful when the publishing CLI predates the field).
|
|
17
|
+
*/
|
|
18
|
+
referencedFilesByPageId: Record<string, string[]>;
|
|
19
|
+
deploymentId: string;
|
|
20
|
+
siteId: string;
|
|
21
|
+
deploymentHash: string;
|
|
22
|
+
orgId: string;
|
|
23
|
+
/** Canonical fern domain (the per-URL manifest is written once per URL by the caller). */
|
|
24
|
+
domain: string;
|
|
25
|
+
/**
|
|
26
|
+
* Domain used for file anchoring (S3 keys + manifest `files[].domain`).
|
|
27
|
+
* When set, overrides `params.site.domain` so preview publishes anchor
|
|
28
|
+
* files on the canonical production domain (ADR 0010).
|
|
29
|
+
*/
|
|
30
|
+
fileDomain?: string;
|
|
31
|
+
basepath: string;
|
|
32
|
+
isPreview: boolean;
|
|
33
|
+
isPrivate: boolean;
|
|
34
|
+
/** FAI Ask AI enablement for this URL; omitted when it could not be resolved. */
|
|
35
|
+
askAiEnabled?: boolean;
|
|
36
|
+
/** Live sites on this host; only for basepath-aware production publishes. */
|
|
37
|
+
siblingSites?: LedgerSiblingSite[];
|
|
38
|
+
/** ISO-8601 — request time the publish became live. */
|
|
39
|
+
assignedAt: string;
|
|
40
|
+
assignedBy: string | null;
|
|
41
|
+
/** artifact hash → ISO-8601 `created_at` from `docs_ledger_artifacts`. */
|
|
42
|
+
artifactHashToCreatedAt?: Map<string, string>;
|
|
43
|
+
}
|
|
44
|
+
export interface LedgerReadModelBlob {
|
|
45
|
+
hash: string;
|
|
46
|
+
bytes: Buffer;
|
|
47
|
+
contentType: string;
|
|
48
|
+
}
|
|
49
|
+
export interface BuildLedgerReadModelResult {
|
|
50
|
+
pointer: LedgerManifest;
|
|
51
|
+
blobs: LedgerReadModelBlob[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Overlay CAS content `created_at` onto the artifact-keyed `createdAt` map
|
|
55
|
+
* used for manifest route entries (sitemap `<lastmod>`). Artifact hashes are
|
|
56
|
+
* salted with `FDR_VERSION`, so their rows are re-minted on the first publish
|
|
57
|
+
* after every FDR deploy; the unsalted content row survives deploys and
|
|
58
|
+
* reflects when the page bytes first appeared. Content-less artifacts (links,
|
|
59
|
+
* files) keep the artifact row's timestamp.
|
|
60
|
+
*/
|
|
61
|
+
export declare function overlayContentCreatedAt({ artifacts, artifactHashToCreatedAt, contentHashToCreatedAt }: {
|
|
62
|
+
artifacts: ReadonlyArray<Pick<ArtifactInput, "hash" | "contentHash">>;
|
|
63
|
+
artifactHashToCreatedAt: ReadonlyMap<string, string>;
|
|
64
|
+
contentHashToCreatedAt: ReadonlyMap<string, string>;
|
|
65
|
+
}): Map<string, string>;
|
|
66
|
+
/**
|
|
67
|
+
* Assemble the pointer + immutable CAS read model (ADR 0016) from the
|
|
68
|
+
* in-memory transform result the DAO just persisted. No DB read-back: every
|
|
69
|
+
* field comes from `params` / `baseResult` / `inlineTranslations`, and segment /
|
|
70
|
+
* artifact ids are content hashes (the S3-only reader never correlates against
|
|
71
|
+
* postgres).
|
|
72
|
+
*
|
|
73
|
+
* Leaf content (page markdown, API definitions) is referenced by CAS hash only
|
|
74
|
+
* — the bundle fetches those blobs directly. Hot-path chrome text
|
|
75
|
+
* (header/footer/css.inline/js.inline) is re-inlined into the pointer so page
|
|
76
|
+
* renders do not pay extra CAS reads for site chrome.
|
|
77
|
+
*/
|
|
78
|
+
export declare function buildLedgerReadModel(args: BuildLedgerManifestArgs): BuildLedgerReadModelResult;
|
|
79
|
+
export declare function buildLedgerManifest(args: BuildLedgerManifestArgs): LedgerManifest;
|
|
80
|
+
//# sourceMappingURL=buildLedgerManifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildLedgerManifest.d.ts","sourceRoot":"","sources":["../../../src/docs-ledger/buildLedgerManifest.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAMR,cAAc,EAKd,iBAAiB,EAUpB,MAAM,yBAAyB,CAAC;AAWjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EACR,aAAa,EACb,uBAAuB,EACvB,aAAa,EAGhB,MAAM,iBAAiB,CAAC;AA8JzB,MAAM,WAAW,uBAAuB;IACpC,4EAA4E;IAC5E,MAAM,EAAE,aAAa,CAAC;IACtB,uEAAuE;IACvE,UAAU,EAAE,eAAe,CAAC;IAC5B,oEAAoE;IACpE,kBAAkB,EAAE,uBAAuB,EAAE,CAAC;IAC9C;;;;;;OAMG;IACH,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,iFAAiF;IACjF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACnC,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0EAA0E;IAC1E,uBAAuB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACvC,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,EACpC,SAAS,EACT,uBAAuB,EACvB,sBAAsB,EACzB,EAAE;IACC,SAAS,EAAE,aAAa,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC;IACtE,uBAAuB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvD,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,uBAAuB,GAAG,0BAA0B,CA2uB9F;AA0CD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,cAAc,CAEjF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic hash computation for docs-ledger entities.
|
|
3
|
+
*
|
|
4
|
+
* Server-internal — these functions are NOT shared with the client.
|
|
5
|
+
* The server is the sole authority for structural hash computation.
|
|
6
|
+
*
|
|
7
|
+
* All hashes use SHA-256 over {@link stableStringify}, which produces
|
|
8
|
+
* deterministic JSON by sorting object keys during serialization.
|
|
9
|
+
* `JSON.stringify`'s replacer runs after `toJSON()`, so Dates and custom
|
|
10
|
+
* serializers are handled by the engine — no special cases needed.
|
|
11
|
+
*/
|
|
12
|
+
import type { DocsPublishInput, LedgerSegmentDetailMetadata, LedgerSegmentMetadata } from "../orpc-client/index.js";
|
|
13
|
+
export { stableStringify } from "./stableHash.js";
|
|
14
|
+
/**
|
|
15
|
+
* The FDR release version, injected as an env var by the CDK deploy stack.
|
|
16
|
+
* Included in deployment, segment, and artifact hashes so that every FDR
|
|
17
|
+
* deploy invalidates cached structural rows — even when the publish input
|
|
18
|
+
* is byte-identical.
|
|
19
|
+
*
|
|
20
|
+
* Falls back to "local" for local development (where no env var is set),
|
|
21
|
+
* ensuring hashes are still deterministic within a single server instance.
|
|
22
|
+
*/
|
|
23
|
+
export declare const FDR_VERSION: string;
|
|
24
|
+
/**
|
|
25
|
+
* Compute the deployment hash directly from the publish input.
|
|
26
|
+
*
|
|
27
|
+
* Since the server-side transform is deterministic, identical inputs always
|
|
28
|
+
* produce identical deployments. This lets us:
|
|
29
|
+
* - Return a real deployment hash from register (before the transform runs)
|
|
30
|
+
* - Short-circuit finish when the deployment hash matches the current one
|
|
31
|
+
*
|
|
32
|
+
* The hash covers everything that affects the deployment's content:
|
|
33
|
+
* nav tree, page content hashes, API manifest hash, global blob hashes, locale,
|
|
34
|
+
* and the {@link FDR_VERSION} salt.
|
|
35
|
+
*/
|
|
36
|
+
export declare function hashDeploymentInput(input: DocsPublishInput): string;
|
|
37
|
+
export interface SegmentDetailHashInput {
|
|
38
|
+
type: string;
|
|
39
|
+
displayName: string;
|
|
40
|
+
icon?: string | null;
|
|
41
|
+
sortOrder: number;
|
|
42
|
+
metadata: LedgerSegmentDetailMetadata;
|
|
43
|
+
hidden: boolean;
|
|
44
|
+
viewers: string[];
|
|
45
|
+
orphaned: boolean;
|
|
46
|
+
featureFlags: string[];
|
|
47
|
+
}
|
|
48
|
+
export declare function hashSegmentDetail(input: SegmentDetailHashInput): string;
|
|
49
|
+
export interface ArtifactHashInput {
|
|
50
|
+
type: string;
|
|
51
|
+
hidden: boolean;
|
|
52
|
+
metadata: Record<string, unknown>;
|
|
53
|
+
/** CAS content hash. Null for content-less artifacts (links). */
|
|
54
|
+
contentHash: string | null;
|
|
55
|
+
}
|
|
56
|
+
export declare function hashArtifact(input: ArtifactHashInput): string;
|
|
57
|
+
export interface SegmentHashInput {
|
|
58
|
+
locale: string;
|
|
59
|
+
productHash?: string;
|
|
60
|
+
versionHash?: string;
|
|
61
|
+
variantHash?: string;
|
|
62
|
+
tabHash?: string;
|
|
63
|
+
section: string;
|
|
64
|
+
metadata: LedgerSegmentMetadata;
|
|
65
|
+
hidden: boolean;
|
|
66
|
+
/** Artifact hashes included in this segment — sorted internally for determinism. */
|
|
67
|
+
artifactHashes: string[];
|
|
68
|
+
/** Sidebar ordering: artifact hash + display position. Sorted by displaySortOrder for determinism. */
|
|
69
|
+
displaySortOrder: Array<{
|
|
70
|
+
artifactHash: string;
|
|
71
|
+
displaySortOrder: number;
|
|
72
|
+
}>;
|
|
73
|
+
/** Route entries — sorted by fullPath internally for determinism. */
|
|
74
|
+
routes: Array<{
|
|
75
|
+
fullPath: string;
|
|
76
|
+
artifactHash: string;
|
|
77
|
+
}>;
|
|
78
|
+
}
|
|
79
|
+
export declare function hashSegment(input: SegmentHashInput): string;
|
|
80
|
+
//# sourceMappingURL=docsLedgerHash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docsLedgerHash.d.ts","sourceRoot":"","sources":["../../../src/docs-ledger/docsLedgerHash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAIpH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAUlD;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,MAA2C,CAAC;AAEtE;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAOnE;AAuCD,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,2BAA2B,CAAC;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAavE;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,iEAAiE;IACjE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAE7D;AAED,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,oFAAoF;IACpF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,sGAAsG;IACtG,gBAAgB,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5E,qEAAqE;IACrE,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAyB3D"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type { ApiDefinition } from "../api-definition/index.js";
|
|
2
|
+
import type { BlobRef, LedgerConfig, LocaleEntry } from "../orpc-client/index.js";
|
|
3
|
+
import type { ArtifactInput, DeploymentApiDefinitionInput, DeploymentSegmentInput, DocsSiteProduct, NavInput, SegmentDetailInput, SegmentInput } from "./inputTypes.js";
|
|
4
|
+
/**
|
|
5
|
+
* Input type for `transformPublishInput`. A single locale's content fields
|
|
6
|
+
* plus the deployment-scoped `domain` (needed for file-artifact S3 key
|
|
7
|
+
* construction).
|
|
8
|
+
*/
|
|
9
|
+
export type TransformInput = LocaleEntry & {
|
|
10
|
+
domain: string;
|
|
11
|
+
/**
|
|
12
|
+
* Override for the file-anchoring domain (S3 keys). When set, files
|
|
13
|
+
* are keyed under this domain instead of `domain`, so preview
|
|
14
|
+
* publishes can anchor on the canonical fern domain (ADR 0010).
|
|
15
|
+
*/
|
|
16
|
+
fileDomain?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* A fileManifest entry collected during the transform. Carries everything
|
|
20
|
+
* the register/finish handlers need to route uploads to the correct S3
|
|
21
|
+
* bucket and upsert `docs_ledger_file` rows. The asset domain is the
|
|
22
|
+
* canonical `DocsPublishInput.domain`; custom domains share that namespace.
|
|
23
|
+
* The bucket is determined by the handler (not the transform) from the
|
|
24
|
+
* site's auth config.
|
|
25
|
+
*/
|
|
26
|
+
export interface TransformFileEntry {
|
|
27
|
+
fullPath: string;
|
|
28
|
+
hash: string;
|
|
29
|
+
contentType: string;
|
|
30
|
+
contentLength: number;
|
|
31
|
+
filename: string;
|
|
32
|
+
width?: number;
|
|
33
|
+
height?: number;
|
|
34
|
+
blurDataURL?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parsed API manifest: full API definitions keyed by apiDefinitionId.
|
|
38
|
+
* The finish handler fetches the manifest blob from S3 and parses it.
|
|
39
|
+
*/
|
|
40
|
+
export type ApiManifest = Record<string, ApiDefinition>;
|
|
41
|
+
/**
|
|
42
|
+
* A BlobRef whose bytes were generated server-side (pruned API content, link metadata).
|
|
43
|
+
* The router must upload these to CAS before persisting the deployment.
|
|
44
|
+
*/
|
|
45
|
+
export interface GeneratedBlob {
|
|
46
|
+
ref: BlobRef;
|
|
47
|
+
bytes: Buffer;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Transform result: hashed entities ready for the DAO, plus content
|
|
51
|
+
* references and server-generated blobs for CAS upload.
|
|
52
|
+
*/
|
|
53
|
+
export interface TransformResult {
|
|
54
|
+
segmentDetails: SegmentDetailInput[];
|
|
55
|
+
artifacts: ArtifactInput[];
|
|
56
|
+
segments: SegmentInput[];
|
|
57
|
+
nav: NavInput[];
|
|
58
|
+
deploymentSegments: DeploymentSegmentInput[];
|
|
59
|
+
apiDefinitions: DeploymentApiDefinitionInput[];
|
|
60
|
+
/** Visible top-level products in switcher order, snapshotted for sibling sites on the same host. */
|
|
61
|
+
siteProducts: DocsSiteProduct[];
|
|
62
|
+
jsFilesHash: string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* ADR 0009: structural config (everything except `header`, `footer`,
|
|
65
|
+
* `css.inline`, `js.inline`) ready to be written into
|
|
66
|
+
* `docs_ledger_deployments.config_json` as JSONB. The four extracted
|
|
67
|
+
* variable-length pieces are content-addressed via the `*Hash` fields
|
|
68
|
+
* below.
|
|
69
|
+
*/
|
|
70
|
+
configJson: unknown | undefined;
|
|
71
|
+
/** CAS hash for the extracted `config.header` blob, or undefined. */
|
|
72
|
+
headerHash: string | undefined;
|
|
73
|
+
/** CAS hash for the extracted `config.footer` blob, or undefined. */
|
|
74
|
+
footerHash: string | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* CAS hash for the extracted `config.css.inline` blob (joined with
|
|
77
|
+
* `\n`), or undefined.
|
|
78
|
+
*/
|
|
79
|
+
cssInlineHash: string | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* CAS hash for the extracted `config.js.inline` blob (joined with
|
|
82
|
+
* `\n`), or undefined.
|
|
83
|
+
*/
|
|
84
|
+
jsInlineHash: string | undefined;
|
|
85
|
+
domain: string;
|
|
86
|
+
/**
|
|
87
|
+
* The domain files are anchored on (defaults to `domain` when omitted
|
|
88
|
+
* in the input). Forwarded so callers can key S3 operations and
|
|
89
|
+
* manifest entries on the canonical domain for preview publishes.
|
|
90
|
+
*/
|
|
91
|
+
fileDomain: string;
|
|
92
|
+
version?: string | null;
|
|
93
|
+
repo?: string | null;
|
|
94
|
+
/**
|
|
95
|
+
* Git provenance pulled straight off the publish input (ADR 0012 /
|
|
96
|
+
* FER-10489). Forwarded to {@link DeploymentInput} so the deployment
|
|
97
|
+
* row captures the repo/branch/sha used by the read path to
|
|
98
|
+
* synthesise `editThisPageUrl`.
|
|
99
|
+
*/
|
|
100
|
+
git?: {
|
|
101
|
+
repoUrl: string;
|
|
102
|
+
branch: string;
|
|
103
|
+
commitSha?: string;
|
|
104
|
+
};
|
|
105
|
+
/** All content blobs referenced by this deployment (artifact content, globals, generated). */
|
|
106
|
+
contentRefs: Map<string, BlobRef>;
|
|
107
|
+
/** Blobs generated by the transform (pruned API defs). Must be uploaded to CAS. */
|
|
108
|
+
generatedBlobs: Map<string, GeneratedBlob>;
|
|
109
|
+
/**
|
|
110
|
+
* File manifest entries (images, fonts, pdfs). Tracked separately from
|
|
111
|
+
* `contentRefs` because file bytes land in the public/private docs bucket
|
|
112
|
+
* (key `{assetDomain}/{hash}/{fullPath}`), not in CAS. The register handler
|
|
113
|
+
* routes their uploads accordingly; the finish handler upserts a
|
|
114
|
+
* `docs_ledger_file` row per entry and resolves the resulting IDs onto
|
|
115
|
+
* file/image artifacts.
|
|
116
|
+
*/
|
|
117
|
+
fileEntries: TransformFileEntry[];
|
|
118
|
+
/**
|
|
119
|
+
* pageId → bare `fullPath`s of the files that page's markdown embeds (ADR
|
|
120
|
+
* 0014, "File metadata on the render path"). Copied straight off the publish
|
|
121
|
+
* input's `pages[pageId].referencedFiles` (captured CLI-side). Lets the read
|
|
122
|
+
* model materialise the page→file join into each route shard. Empty for
|
|
123
|
+
* pages with no embedded files or from CLIs that predate the field.
|
|
124
|
+
*/
|
|
125
|
+
referencedFilesByPageId: Record<string, string[]>;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Transform a single locale's content into hash-addressed entities ready for persistence.
|
|
129
|
+
*
|
|
130
|
+
* @param input - One locale entry (content fields) plus the deployment's `domain`.
|
|
131
|
+
* @param apiManifest - Parsed API definitions (fetched from CAS by the caller).
|
|
132
|
+
* Pass an empty object if there are no API references in the nav tree.
|
|
133
|
+
*/
|
|
134
|
+
export declare function transformPublishInput(input: TransformInput, apiManifest?: ApiManifest): TransformResult;
|
|
135
|
+
/**
|
|
136
|
+
* Result of {@link splitConfig}: the structural `stripped` config (written
|
|
137
|
+
* inline as JSONB on the deployment row) plus the four extracted CAS blobs.
|
|
138
|
+
*/
|
|
139
|
+
export interface SplitConfigResult {
|
|
140
|
+
/**
|
|
141
|
+
* `config` with `header`, `footer`, `css.inline`, `js.inline` removed.
|
|
142
|
+
* `css` / `js` are dropped entirely if `inline` was their only key.
|
|
143
|
+
*/
|
|
144
|
+
stripped: Omit<LedgerConfig, "header" | "footer" | "css" | "js"> & {
|
|
145
|
+
css?: Omit<NonNullable<LedgerConfig["css"]>, "inline">;
|
|
146
|
+
js?: Omit<NonNullable<LedgerConfig["js"]>, "inline">;
|
|
147
|
+
};
|
|
148
|
+
header: string | undefined;
|
|
149
|
+
footer: string | undefined;
|
|
150
|
+
cssInline: string | undefined;
|
|
151
|
+
jsInline: string | undefined;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Split a {@link LedgerConfig} into the structural portion (to be written
|
|
155
|
+
* inline as JSONB) and the four variable-length fields that are extracted
|
|
156
|
+
* to their own CAS blobs (ADR 0009).
|
|
157
|
+
*
|
|
158
|
+
* - `header`, `footer`: returned as the raw strings if non-empty.
|
|
159
|
+
* - `css.inline`, `js.inline`: arrays of strings, joined with `\n` into a
|
|
160
|
+
* single text blob if non-empty. The `inline` key is removed from `css`
|
|
161
|
+
* and `js` in the stripped config; any other sibling fields (`js.files`,
|
|
162
|
+
* `js.remote`) are preserved. `css.inline` is currently the only field
|
|
163
|
+
* on `css`, so `stripped.css` is dropped in practice — the empty-keys
|
|
164
|
+
* check is kept for symmetry with `js` and to stay correct if the
|
|
165
|
+
* schema grows new `css` siblings.
|
|
166
|
+
*
|
|
167
|
+
* The returned `stripped` object is a shallow-cloned subset of `config` so
|
|
168
|
+
* that callers can safely mutate it without affecting the original.
|
|
169
|
+
*
|
|
170
|
+
* The input has already been validated against `LedgerConfigSchema` by
|
|
171
|
+
* Zod upstream — no runtime shape checks are needed here.
|
|
172
|
+
*
|
|
173
|
+
* Exported for testing.
|
|
174
|
+
*
|
|
175
|
+
* @internal
|
|
176
|
+
*/
|
|
177
|
+
export declare function splitConfig(config: LedgerConfig): SplitConfigResult;
|
|
178
|
+
//# sourceMappingURL=docsPublishTransform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docsPublishTransform.d.ts","sourceRoot":"","sources":["../../../src/docs-ledger/docsPublishTransform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ledger publish transform — the pure (no DB, no S3) half of a docs publish.
|
|
3
|
+
*
|
|
4
|
+
* `transformPublishInput` turns a `DocsPublishInput` locale into hashed
|
|
5
|
+
* content-addressed entities, and `buildLedgerReadModel` assembles the pointer
|
|
6
|
+
* manifest + route shards the Astro renderer reads. FDR runs these on publish;
|
|
7
|
+
* the Fern CLI runs the same code to render a local project without a server.
|
|
8
|
+
*/
|
|
9
|
+
export * from "./buildLedgerManifest.js";
|
|
10
|
+
export * from "./docsLedgerHash.js";
|
|
11
|
+
export * from "./docsPublishTransform.js";
|
|
12
|
+
export * from "./inputTypes.js";
|
|
13
|
+
export { sha256Hex, stableHash } from "./stableHash.js";
|
|
14
|
+
export * from "./toBasepathRelative.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/docs-ledger/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-addressed input entities produced by the ledger publish transform
|
|
3
|
+
* (`transformPublishInput`) and consumed by both FDR's `DocsLedgerDao` and the
|
|
4
|
+
* read-model builder (`buildLedgerReadModel`). Pure data types — no DB or
|
|
5
|
+
* runtime coupling — so the CLI can run the same transform for local preview.
|
|
6
|
+
*/
|
|
7
|
+
import type { LedgerArtifactTypeMetadata, LedgerSegmentDetailMetadata, LedgerSegmentMetadata } from "../orpc-client/index.js";
|
|
8
|
+
/** Content-addressed segment detail (product/version/tab/variant metadata). */
|
|
9
|
+
export interface SegmentDetailInput {
|
|
10
|
+
hash: string;
|
|
11
|
+
type: string;
|
|
12
|
+
displayName: string;
|
|
13
|
+
icon?: string | null;
|
|
14
|
+
sortOrder: number;
|
|
15
|
+
metadata: LedgerSegmentDetailMetadata;
|
|
16
|
+
hidden: boolean;
|
|
17
|
+
viewers: string[];
|
|
18
|
+
orphaned: boolean;
|
|
19
|
+
featureFlags: string[];
|
|
20
|
+
}
|
|
21
|
+
/** Content-addressed artifact (page/endpoint/link/redirect/file/image). */
|
|
22
|
+
export type ArtifactInput = LedgerArtifactTypeMetadata & {
|
|
23
|
+
hash: string;
|
|
24
|
+
hidden: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* CAS content hash. Set for pages, API defs, redirects, jsFiles, etc.
|
|
27
|
+
* Null for link artifacts and for file/image artifacts (those resolve via
|
|
28
|
+
* `fileKey` instead — see {@link FileEntryInput} and the `docs_ledger_file`
|
|
29
|
+
* table). The DAO resolves this to `content_id`.
|
|
30
|
+
*/
|
|
31
|
+
contentHash: string | null;
|
|
32
|
+
/**
|
|
33
|
+
* File identity for file/image artifacts. Set on type=`file`/`image`,
|
|
34
|
+
* null otherwise. The DAO resolves this to `docs_ledger_file_id` via
|
|
35
|
+
* (assetDomain, hash, fullPath) — the asset domain is the canonical site
|
|
36
|
+
* domain passed to {@link DocsLedgerDao.persistDeployment}, while
|
|
37
|
+
* additional custom-domain site rows share the same uploaded file rows.
|
|
38
|
+
*
|
|
39
|
+
* Mutually exclusive with `contentHash` for content-bearing artifacts.
|
|
40
|
+
*/
|
|
41
|
+
fileKey: {
|
|
42
|
+
hash: string;
|
|
43
|
+
fullPath: string;
|
|
44
|
+
} | null;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A file (image/font/etc.) tracked in `docs_ledger_file`.
|
|
48
|
+
*
|
|
49
|
+
* The publish handler determines `bucket` from the site's auth model
|
|
50
|
+
* before calling {@link DocsLedgerDao.persistDeployment} — the DAO upserts
|
|
51
|
+
* one row per unique `(domain, hash, full_path)` and resolves the resulting
|
|
52
|
+
* IDs onto file/image artifacts. Custom domains do not get duplicate file
|
|
53
|
+
* rows; they resolve to the canonical site's uploaded asset namespace.
|
|
54
|
+
*/
|
|
55
|
+
export interface FileEntryInput {
|
|
56
|
+
fullPath: string;
|
|
57
|
+
hash: string;
|
|
58
|
+
contentType: string;
|
|
59
|
+
/** Which S3 bucket the bytes were uploaded to. */
|
|
60
|
+
bucket: "public_docs" | "private_docs";
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Content-addressed segment.
|
|
64
|
+
* References segment details by hash (resolved to database IDs during publish).
|
|
65
|
+
*/
|
|
66
|
+
export interface SegmentInput {
|
|
67
|
+
hash: string;
|
|
68
|
+
locale: string;
|
|
69
|
+
productHash?: string;
|
|
70
|
+
versionHash?: string;
|
|
71
|
+
variantHash?: string;
|
|
72
|
+
tabHash?: string;
|
|
73
|
+
section: string;
|
|
74
|
+
metadata: LedgerSegmentMetadata;
|
|
75
|
+
hidden: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Unified nav entry: routing + sidebar ordering in one row.
|
|
79
|
+
* - fullPath non-null = routable (path lookup)
|
|
80
|
+
* - displaySortOrder non-null = shows in sidebar
|
|
81
|
+
* - Both non-null = canonical route (routable + in sidebar)
|
|
82
|
+
* - fullPath null = sidebar-only (external links, folders)
|
|
83
|
+
* - displaySortOrder null = route-only (non-canonical aliases)
|
|
84
|
+
*/
|
|
85
|
+
export interface NavInput {
|
|
86
|
+
segmentHash: string;
|
|
87
|
+
artifactHash: string;
|
|
88
|
+
fullPath?: string;
|
|
89
|
+
displaySortOrder?: number;
|
|
90
|
+
}
|
|
91
|
+
/** Immutable deployment snapshot. */
|
|
92
|
+
export interface DeploymentInput {
|
|
93
|
+
id: string;
|
|
94
|
+
hash: string;
|
|
95
|
+
version?: string;
|
|
96
|
+
repo?: string;
|
|
97
|
+
jsFilesHash?: string;
|
|
98
|
+
/**
|
|
99
|
+
* Structural config (stripped of `header`, `footer`, `css.inline`,
|
|
100
|
+
* `js.inline`) to be written inline into `config_json`. The four
|
|
101
|
+
* extracted variable-length pieces are content-addressed below.
|
|
102
|
+
*/
|
|
103
|
+
configJson?: unknown;
|
|
104
|
+
/** CAS hash for the extracted `config.header` blob. */
|
|
105
|
+
headerHash?: string;
|
|
106
|
+
/** CAS hash for the extracted `config.footer` blob. */
|
|
107
|
+
footerHash?: string;
|
|
108
|
+
/** CAS hash for the extracted joined `config.css.inline` blob. */
|
|
109
|
+
cssInlineHash?: string;
|
|
110
|
+
/** CAS hash for the extracted joined `config.js.inline` blob. */
|
|
111
|
+
jsInlineHash?: string;
|
|
112
|
+
createdBy?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Git provenance (ADR 0012 / FER-10489). Captured from the CLI publish
|
|
115
|
+
* input so the read path can synthesise `editThisPageUrl`. All optional —
|
|
116
|
+
* CLIs that omit `git` map to NULL columns.
|
|
117
|
+
*/
|
|
118
|
+
gitRepoUrl?: string;
|
|
119
|
+
gitBranch?: string;
|
|
120
|
+
gitCommitSha?: string;
|
|
121
|
+
/** Default locale for this deployment (extracted from config_json.translations). */
|
|
122
|
+
defaultLocale?: string;
|
|
123
|
+
/** All locales supported by this deployment (including the default). */
|
|
124
|
+
translations?: string[];
|
|
125
|
+
/** FDR server version that produced this deployment (for cache-busting diagnostics). */
|
|
126
|
+
fdrVersion?: string;
|
|
127
|
+
/** Fern CLI version that produced this deployment (from X-CLI-Version header). */
|
|
128
|
+
cliVersion?: string;
|
|
129
|
+
}
|
|
130
|
+
/** Deployment → segment join entry (referenced by segment hash). */
|
|
131
|
+
export interface DeploymentSegmentInput {
|
|
132
|
+
segmentHash: string;
|
|
133
|
+
sortOrder: number;
|
|
134
|
+
}
|
|
135
|
+
/** Deployment → API definition join entry. */
|
|
136
|
+
export interface DeploymentApiDefinitionInput {
|
|
137
|
+
apiDefinitionId: string;
|
|
138
|
+
apiName: string | null;
|
|
139
|
+
contentHash: string;
|
|
140
|
+
}
|
|
141
|
+
/** New site row in the append-only site log. */
|
|
142
|
+
export interface SiteInput {
|
|
143
|
+
id: string;
|
|
144
|
+
orgId: string;
|
|
145
|
+
domain: string;
|
|
146
|
+
basepath: string;
|
|
147
|
+
previewId?: string;
|
|
148
|
+
assignedBy?: string;
|
|
149
|
+
}
|
|
150
|
+
/** Parameters for adding translation segments to an existing deployment. */
|
|
151
|
+
export interface TranslationSegmentParams {
|
|
152
|
+
deploymentId: string;
|
|
153
|
+
/** Owning org — CAS content/artifacts/segments are org-scoped (ADR 0008). */
|
|
154
|
+
orgId: string;
|
|
155
|
+
domain: string;
|
|
156
|
+
segmentDetails: SegmentDetailInput[];
|
|
157
|
+
artifacts: ArtifactInput[];
|
|
158
|
+
segments: SegmentInput[];
|
|
159
|
+
nav: NavInput[];
|
|
160
|
+
deploymentSegments: DeploymentSegmentInput[];
|
|
161
|
+
files: FileEntryInput[];
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Translation segment params without `deploymentId` — the ID is determined
|
|
165
|
+
* inside the `persistDeployment` transaction and injected automatically.
|
|
166
|
+
*/
|
|
167
|
+
export type InlineTranslationParams = Omit<TranslationSegmentParams, "deploymentId"> & {
|
|
168
|
+
locale: string;
|
|
169
|
+
/** Locale's structural config (translation overlay applied). Read-model only; not persisted to postgres. */
|
|
170
|
+
configJson?: unknown;
|
|
171
|
+
};
|
|
172
|
+
/** A product of a published site as stored in `docs_sites.products` (JSON). */
|
|
173
|
+
export type DocsSiteProduct = {
|
|
174
|
+
title: string;
|
|
175
|
+
/** Absolute href on the host (`/{basepath}/{slug}/`) or an external URL for product links. */
|
|
176
|
+
href: string;
|
|
177
|
+
subtitle?: string;
|
|
178
|
+
};
|
|
179
|
+
/** Everything needed to atomically publish a deployment. */
|
|
180
|
+
export interface PublishParams {
|
|
181
|
+
segmentDetails: SegmentDetailInput[];
|
|
182
|
+
artifacts: ArtifactInput[];
|
|
183
|
+
segments: SegmentInput[];
|
|
184
|
+
nav: NavInput[];
|
|
185
|
+
deployment: DeploymentInput;
|
|
186
|
+
deploymentSegments: DeploymentSegmentInput[];
|
|
187
|
+
apiDefinitions: DeploymentApiDefinitionInput[];
|
|
188
|
+
/**
|
|
189
|
+
* Canonical (fern URL) site row. Always inserted into `docs_ledger_site`,
|
|
190
|
+
* and serves as the anchor for `docs_ledger_file` rows (file bytes live
|
|
191
|
+
* at `{site.domain}/{hash}/{fullPath}` regardless of how many extra
|
|
192
|
+
* domains the deployment is served from — see ADR 0010).
|
|
193
|
+
*/
|
|
194
|
+
site: SiteInput;
|
|
195
|
+
/**
|
|
196
|
+
* Additional site rows for custom domains attached to the same
|
|
197
|
+
* deployment (ADR 0010). One row per (domain, basepath) pair, all
|
|
198
|
+
* pointing at the same `deployment_id`. No file rows fan out — the
|
|
199
|
+
* fern site (above) is the file-row anchor.
|
|
200
|
+
*/
|
|
201
|
+
additionalSites?: SiteInput[];
|
|
202
|
+
/**
|
|
203
|
+
* Files referenced by file/image artifacts. The DAO upserts one
|
|
204
|
+
* `docs_ledger_file` row per `(domain, hash, full_path)` inside the
|
|
205
|
+
* publish transaction, then resolves each file/image artifact's
|
|
206
|
+
* `docs_ledger_file_id` from its `fileKey`.
|
|
207
|
+
*
|
|
208
|
+
* The domain is taken from `site.domain` (the canonical fern URL) —
|
|
209
|
+
* file rows are anchored on the fern domain even for multi-domain
|
|
210
|
+
* publishes, per ADR 0010.
|
|
211
|
+
*/
|
|
212
|
+
files: FileEntryInput[];
|
|
213
|
+
/**
|
|
214
|
+
* Domain used for file anchoring (S3 keys + `docs_ledger_file` rows).
|
|
215
|
+
* When set, overrides `site.domain` for file operations so that
|
|
216
|
+
* preview publishes anchor files on the canonical fern domain
|
|
217
|
+
* (ADR 0010) instead of the ephemeral preview hostname.
|
|
218
|
+
*/
|
|
219
|
+
fileDomain?: string;
|
|
220
|
+
/**
|
|
221
|
+
* Optional inline translations to persist atomically with the base
|
|
222
|
+
* deployment. When provided, translation segments are inserted inside
|
|
223
|
+
* the same DB transaction as the base deployment — fully atomic.
|
|
224
|
+
*/
|
|
225
|
+
inlineTranslations?: InlineTranslationParams[];
|
|
226
|
+
}
|
|
227
|
+
/** Metadata stored on file/image artifacts. */
|
|
228
|
+
export type FileArtifactMetadata = {
|
|
229
|
+
contentType: string;
|
|
230
|
+
contentLength?: number;
|
|
231
|
+
filename: string;
|
|
232
|
+
width?: number;
|
|
233
|
+
height?: number;
|
|
234
|
+
blurDataURL?: string;
|
|
235
|
+
};
|
|
236
|
+
//# sourceMappingURL=inputTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputTypes.d.ts","sourceRoot":"","sources":["../../../src/docs-ledger/inputTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { stableStringify } from "../orpc-client/index.js";
|
|
2
|
+
export { stableStringify };
|
|
3
|
+
/** SHA-256 hex digest of the input string. */
|
|
4
|
+
export declare function sha256Hex(input: string): string;
|
|
5
|
+
/** Convenience: stable JSON + sha256 in one call. */
|
|
6
|
+
export declare function stableHash(value: unknown): string;
|
|
7
|
+
//# sourceMappingURL=stableHash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stableHash.d.ts","sourceRoot":"","sources":["../../../src/docs-ledger/stableHash.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAK1D,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strip exactly one leading `${basePrefix}/` (or a bare `basePrefix`) from
|
|
3
|
+
* `fullPath`, yielding the basepath-RELATIVE remainder.
|
|
4
|
+
*
|
|
5
|
+
* Lives in its own leaf module because both `docsPublishTransform` and
|
|
6
|
+
* `buildLedgerManifest` need it but cannot share a value import with each
|
|
7
|
+
* other (`buildLedgerManifest` already imports `docsPublishTransform`'s
|
|
8
|
+
* types).
|
|
9
|
+
*
|
|
10
|
+
* Write side (`buildLedgerManifest`): every fullPath the transform produces
|
|
11
|
+
* is basepath-rooted, so stripping the first segment is unambiguous — even
|
|
12
|
+
* for the pathological `docs/docs` page (the second segment is the page's
|
|
13
|
+
* own slug). Only `navBySegment` keys are made relative; `routes`, `routing`,
|
|
14
|
+
* `versionFirstRoute`, and `pages` keys stay ABSOLUTE.
|
|
15
|
+
*
|
|
16
|
+
* Transform side (`docsPublishTransform`): normalises a reconstructed
|
|
17
|
+
* link-redirect parent slug before it is re-prefixed with the basepath. Most
|
|
18
|
+
* products yield a basepath-relative parent slug (`astro`), but the root/home
|
|
19
|
+
* product (`slug: /`) has an accumulated V1 slug that already equals the
|
|
20
|
+
* basepath (`docs`) — `extractSlugSegment` cannot strip it, so the product
|
|
21
|
+
* slug leaks the basepath. Normalising here makes the subsequent single
|
|
22
|
+
* prefix idempotent and prevents a `docs/docs/...` key.
|
|
23
|
+
*/
|
|
24
|
+
export declare function toBasepathRelative(fullPath: string, basePrefix: string): string;
|
|
25
|
+
//# sourceMappingURL=toBasepathRelative.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toBasepathRelative.d.ts","sourceRoot":"","sources":["../../../src/docs-ledger/toBasepathRelative.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAS/E"}
|