@thallylabs/migrate 0.2.6 → 0.2.8
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 +188 -7
- package/dist/index.d.ts +102 -8
- package/dist/index.js +5034 -1622
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -15,10 +15,113 @@ compatible page frontmatter, site identity, and OpenAPI configuration. For publi
|
|
|
15
15
|
sites, the URL adapter reads the structured configuration embedded in the
|
|
16
16
|
rendered application before falling back to DOM link inference.
|
|
17
17
|
|
|
18
|
+
An `openapi` (or `asyncapi`) reference is resolved wherever Mintlify allows
|
|
19
|
+
it — the top-level `api.openapi`, or on any individual
|
|
20
|
+
tab/anchor/dropdown/product/version, e.g. `navigation.tabs[].openapi` — and
|
|
21
|
+
binds to that exact tab, not only the first one found. Remote `http://` and
|
|
22
|
+
`https://` specs are not downloaded during migration. The report names each
|
|
23
|
+
remote URL and tells you to add its spec to `public/`, then set the API source
|
|
24
|
+
in `docs.json` to that local path. Missing local specs also produce warnings
|
|
25
|
+
instead of silently dropping that API tab's reference. AsyncAPI has no Thally
|
|
26
|
+
renderer, so it always produces a clear warning naming the spec instead of
|
|
27
|
+
disappearing.
|
|
28
|
+
|
|
18
29
|
Docusaurus sidebars are parsed as bounded, data-only JSON5—never executed—and
|
|
19
30
|
preserve explicit categories, autogenerated slices, document IDs/slugs,
|
|
20
31
|
positions, generated indexes, admonitions, tabs, and `static/` assets where
|
|
21
|
-
supported.
|
|
32
|
+
supported. Every `@docusaurus/plugin-content-docs` instance declared in
|
|
33
|
+
`docusaurus.config` (not just the default one) is imported as its own tab,
|
|
34
|
+
routed under its `routeBasePath`; a `path` is resolved the way Docusaurus
|
|
35
|
+
itself resolves it (relative to the detected project root), with a fallback
|
|
36
|
+
to the repository root for monorepos that build by copying the project
|
|
37
|
+
root's contents up into the repository root before generating the site
|
|
38
|
+
(Playwright's own `nodejs/` is one real example) — a `path` still not found
|
|
39
|
+
under either root is reported with a warning naming the plugin instance
|
|
40
|
+
instead of being silently dropped. The same repository-root fallback applies
|
|
41
|
+
to `@site/...` aliases, relative component imports, and relative asset
|
|
42
|
+
`require()` calls in copied components; a `require()` that still can't be
|
|
43
|
+
resolved is replaced with an empty string (a broken image, not a build
|
|
44
|
+
failure) and warned about instead of left dangling. `@docusaurus/plugin-client-redirects`
|
|
45
|
+
rules are imported whether declared inline in `docusaurus.config` or in a
|
|
46
|
+
separate module it imports (a named export, e.g. `redirects.ts`); a `from`
|
|
47
|
+
may be a single path or an array of paths. Its `createRedirects` function
|
|
48
|
+
computes redirects dynamically and can't be evaluated statically, so its
|
|
49
|
+
presence is reported with a warning instead of being silently ignored. A
|
|
50
|
+
static `--ifm-color-primary` accent color in the classic theme's `customCss`
|
|
51
|
+
file is imported the same way Mintlify's and Fern's theme colors are.
|
|
52
|
+
Versioned docs under `versioned_docs/` and translated docs under
|
|
53
|
+
`i18n/<locale>/docusaurus-plugin-content-docs/` are imported with their
|
|
54
|
+
navigation, including locale-prefixed routes such as `/fr/...`. Each version
|
|
55
|
+
and locale keeps its own route tree; sidebar entries without source documents
|
|
56
|
+
are reported.
|
|
57
|
+
Docusaurus heading ID comments such as `{/* #custom-id */}` become explicit
|
|
58
|
+
HTML anchors so links to those headings keep working after migration. Links
|
|
59
|
+
using Docusaurus' implicit heading slugs also get explicit aliases when the
|
|
60
|
+
linked heading or option-table field can be matched uniquely. Repeated option
|
|
61
|
+
fields use the nearest preceding row when all local references agree;
|
|
62
|
+
otherwise ambiguous anchors remain warnings.
|
|
63
|
+
Longer fenced code examples keep nested shorter fences inert. An archived
|
|
64
|
+
admonition missing its closing delimiter is closed before the next top-level
|
|
65
|
+
heading (or at the end of the page) so its remaining content stays importable.
|
|
66
|
+
Docusaurus `mdx-code-block` wrappers are opened as live MDX when the resulting
|
|
67
|
+
page compiles and its special fences contain no module declarations. Pages
|
|
68
|
+
whose fragments still need Docusaurus theme imports or remark plugins remain
|
|
69
|
+
fenced and are retained.
|
|
70
|
+
|
|
71
|
+
Fern repositories are located by their `fern/docs.yml` + `fern/fern.config.json`
|
|
72
|
+
pair. `docs.yml` is parsed as bounded YAML—never executed—and preserves tabs,
|
|
73
|
+
nested sections (including `slug`/`skip-slug`), navbar links, redirects, the
|
|
74
|
+
default Fern version's navigation, and theme accent colors. Only pages
|
|
75
|
+
referenced from `docs.yml` are imported, matching Fern's own publishing model.
|
|
76
|
+
Versioned `folder:` entries expand the Markdown files they contain, even when
|
|
77
|
+
the folder or an individual page is outside `fern/` but still inside the
|
|
78
|
+
checkout. An explicit empty tab `slug` keeps pages at the site root; a folder
|
|
79
|
+
title changes its navigation label without changing its directory-based URL.
|
|
80
|
+
Internal links are adjusted for the site's domain path, selected version, and
|
|
81
|
+
source-file routes. Links to sections not imported into Thally stay on the
|
|
82
|
+
published Fern site and produce a migration warning, so the generated site can
|
|
83
|
+
build while the remaining content is moved separately.
|
|
84
|
+
Every `api:` section's OpenAPI document is resolved from its own
|
|
85
|
+
`generators.yml` (`api.specs[].openapi`, or the legacy `api:` string) and
|
|
86
|
+
imported into its own tab — a docs.yml with several API sections (e.g. a REST
|
|
87
|
+
API and a WebSocket API in separate tabs) gets a spec per tab, not just the
|
|
88
|
+
first. The per-API `fern/apis/<name>/` layout is checked first, keyed by the
|
|
89
|
+
node's `api-name` (the folder name) rather than `api` (its display title in
|
|
90
|
+
the nav) — the two are commonly different. The project-root `generators.yml`
|
|
91
|
+
is used only when the node has no `api-name` or the repo has no `fern/apis/`
|
|
92
|
+
folder. `openapi:` is conventionally relative to `generators.yml`'s own
|
|
93
|
+
directory rather than the Fern root, so it commonly resolves outside the API
|
|
94
|
+
folder (or outside `fern/` entirely, e.g. `../../../openapi.yaml`); the spec
|
|
95
|
+
is still found as long as it stays inside the repository checkout, and a path
|
|
96
|
+
that escapes the checkout is reported with a warning naming it, instead of
|
|
97
|
+
the API being silently dropped. A Fern Definition (a non-OpenAPI API with no
|
|
98
|
+
document to attach), an AsyncAPI/OpenRPC-only `api:` section (Thally has no
|
|
99
|
+
renderer for either), and an `api:` section for which no spec could be
|
|
100
|
+
resolved at all, are each reported as a warning naming the API instead of the
|
|
101
|
+
tab being silently dropped, as is `changelog`, which has no equivalent Thally
|
|
102
|
+
field yet.
|
|
103
|
+
|
|
104
|
+
A section/page/tab's explicit `slug` is used as literal Fern routing text
|
|
105
|
+
(e.g. `slug: baml_client`, matching a `baml_client/` folder) even when
|
|
106
|
+
Thally's own route still hyphenates it for consistency (`baml-client`); an
|
|
107
|
+
in-body link written against that literal, unslugified form — which Fern's
|
|
108
|
+
own file-path-based routing tolerates — gets a redirect to the route Thally
|
|
109
|
+
actually serves, instead of 404ing after migration.
|
|
110
|
+
|
|
111
|
+
KaTeX-style `$$...$$` math (block or inline) has no Thally renderer yet.
|
|
112
|
+
Rather than crashing the MDX compiler and silently excluding the whole page,
|
|
113
|
+
a block becomes a fenced ```` ```math ```` code block and an inline span
|
|
114
|
+
becomes an inline code span — both preserve the original math text — with a
|
|
115
|
+
warning.
|
|
116
|
+
|
|
117
|
+
A `products:` docs.yml (Fern's multi-product/product-switcher layout, as on
|
|
118
|
+
buildwithfern.com/learn) imports every product: each product's own
|
|
119
|
+
`navigation:`/`tabs:` becomes a top-level Thally tab named by its
|
|
120
|
+
`display-name`, routed under its `slug` (or a slugified display-name), with
|
|
121
|
+
its pages read from that product's own directory. Local component imports
|
|
122
|
+
from Fern MDX pages (`../../components/...`, resolved against the Fern
|
|
123
|
+
project root) are migrated the same way Mintlify and Docusaurus components
|
|
124
|
+
are — see "Mintlify compatibility" below.
|
|
22
125
|
|
|
23
126
|
## Mintlify compatibility
|
|
24
127
|
|
|
@@ -35,12 +138,90 @@ The importer creates a root redirect to the first available page in source
|
|
|
35
138
|
navigation when no root introduction exists, while retaining a separate custom
|
|
36
139
|
homepage and explicit redirects. Locale tags and recognized locale-prefixed
|
|
37
140
|
sections are normalized without discarding original URL redirects.
|
|
141
|
+
Mintlify's generated `param-*` links for settings headings and named fields
|
|
142
|
+
become explicit anchors in migrated MDX.
|
|
38
143
|
|
|
39
144
|
Simple interactive HTML blocks in MDX are extracted into client components.
|
|
145
|
+
For a copied client component that receives a simple page-authored JSX callback,
|
|
146
|
+
the importer moves the callback into a client wrapper and keeps the page. If
|
|
147
|
+
the callback cannot be moved safely, it keeps the page and the control's child
|
|
148
|
+
content as a passive fallback, with a warning identifying the control. A
|
|
149
|
+
stateful local snippet component is kept as a client component instead of
|
|
150
|
+
flattening away its hooks and state.
|
|
40
151
|
The Mintlify `search-bar-entry` click trigger is mapped to Thally's search
|
|
41
|
-
shortcut. Markdown mixed inside interactive JSX, computed imports,
|
|
42
|
-
imports
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
152
|
+
shortcut. Markdown mixed inside interactive JSX, computed imports, and
|
|
153
|
+
namespace imports are reported for manual review; unsupported source is
|
|
154
|
+
preserved, not replaced with empty stubs. An external package's JSX usage is
|
|
155
|
+
dropped and replaced with a safe fallback (with a warning); if that package's
|
|
156
|
+
binding is instead referenced outside JSX (an expression, a prop, or an
|
|
157
|
+
inline declaration) the import can't be rewritten the same way, so the whole
|
|
158
|
+
page is excluded — instead of shipping with an import `next build` can't
|
|
159
|
+
resolve — and pruned from navigation, with a warning naming the page, the
|
|
160
|
+
package, and the binding. A local/relative component import is fully owned by
|
|
161
|
+
the migration instead: the whole file (and its own local dependency graph) is
|
|
162
|
+
copied, keeping every binding's original name, so it makes no difference
|
|
163
|
+
whether a binding is used as a bare JSX tag or only referenced elsewhere (an
|
|
164
|
+
enum passed into a sibling component's prop, a member tag, a wrapping
|
|
165
|
+
declaration, ...) — the page is excluded only when the copy itself genuinely
|
|
166
|
+
fails (a missing file, a computed/dynamic dependency, a cycle, or a budget
|
|
167
|
+
overrun), with a warning naming the page and the component. Packages the starter already installs (`next`,
|
|
168
|
+
`react-dom`, `clsx`, `lucide-react`, `tailwind-merge`, and their subpaths) are
|
|
169
|
+
kept as-is (except `react-dom/server`, whose string renderers throw under
|
|
170
|
+
Next) and copied into any extracted client module. A source site's own
|
|
171
|
+
`@/…` path aliases are treated like an unavailable package. A page that
|
|
172
|
+
passes a page-authored function into a client component needs the client
|
|
173
|
+
wrapper described above; unsupported callback shapes retain their content
|
|
174
|
+
with a warning. An unconfirmed target is warned for review.
|
|
175
|
+
File paths cannot escape the repository checkout; symlinks and oversized
|
|
176
|
+
graphs are rejected. This is compatibility analysis, **not a code sandbox**:
|
|
177
|
+
imported JavaScript executes when the developer builds or runs the resulting
|
|
178
|
+
site.
|
|
179
|
+
|
|
180
|
+
A copied Mintlify `.jsx` snippet that uses the implicit `MintlifyComponents`
|
|
181
|
+
global (`const { Card } = MintlifyComponents`, Mintlify's own no-import
|
|
182
|
+
convention for its built-ins) gets that binding provided automatically,
|
|
183
|
+
reusing Thally's own built-in MDX component registry — the same way an
|
|
184
|
+
implicit `React`/hook global is already provided.
|
|
185
|
+
|
|
186
|
+
A copied component is prepended with `// @ts-nocheck`: the source
|
|
187
|
+
platform's own build never ran `next build`'s full `tsc --noEmit` type
|
|
188
|
+
check, so loose types, ambient globals (`window.ethereum`), and implicit
|
|
189
|
+
`any` parameters that were fine there would otherwise fail the migrated
|
|
190
|
+
build. A locally-owned wrapper component whose own body imports a known
|
|
191
|
+
YouTube-embed package (e.g. a custom `LiteYouTube` wrapping
|
|
192
|
+
`react-lite-youtube-embed`) gets the same working `<iframe>` fallback as a
|
|
193
|
+
page that imports that package directly, instead of losing the embed to the
|
|
194
|
+
generic unknown-component fallback.
|
|
195
|
+
|
|
196
|
+
## Branding
|
|
197
|
+
|
|
198
|
+
A source site's logo, favicon, and theme accent color(s) are extracted where
|
|
199
|
+
each platform's config exposes them (Mintlify's `colors`, Fern's
|
|
200
|
+
`colors.accent-primary`, Docusaurus's classic theme `customCss`). A valid
|
|
201
|
+
accent color is wired into the scaffolded project's `brandPreset` the same
|
|
202
|
+
way `create-thally-docs`'s own `--colors` flag does. Logo and favicon files
|
|
203
|
+
are copied into `public/`, but Thally's site configuration has no static
|
|
204
|
+
field for them — branding is managed from the admin dashboard at runtime —
|
|
205
|
+
so each site gets one warning naming the copied files and pointing at the
|
|
206
|
+
dashboard's branding settings instead of leaving the loss silent.
|
|
207
|
+
|
|
208
|
+
## Cloning a GitHub repository
|
|
209
|
+
|
|
210
|
+
`cloneGitHubRepository` retries a transient network-class failure with
|
|
211
|
+
backoff, and each underlying git process (the clone, and any submodule
|
|
212
|
+
fetch) is killed and treated as a retryable failure if it stalls — a
|
|
213
|
+
generous 10-minute default, configurable via
|
|
214
|
+
`THALLY_MIGRATE_CLONE_TIMEOUT_MS` (milliseconds) for an unusually large
|
|
215
|
+
repository on a slow link. The clone neutralizes the `filter.lfs.*`
|
|
216
|
+
smudge/clean/process filter driver for that one process only (via
|
|
217
|
+
`GIT_CONFIG_COUNT`/`GIT_CONFIG_KEY_n`/`GIT_CONFIG_VALUE_n`, never the user's
|
|
218
|
+
global git config), so a repository that uses Git LFS still clones even when
|
|
219
|
+
the host has no `git-lfs` binary installed — including a host where
|
|
220
|
+
`filter.lfs.*` is still registered globally from a previous install,
|
|
221
|
+
pointing at a command that no longer exists; an asset that's still a Git
|
|
222
|
+
LFS pointer file afterward (not its real content) is skipped with a warning
|
|
223
|
+
instead of being copied as if it were the real file. Submodules are
|
|
224
|
+
initialized one at a time, best-effort,
|
|
225
|
+
after a successful clone — a submodule that can't be fetched (private,
|
|
226
|
+
deleted, network trouble) is named in a warning instead of failing the
|
|
227
|
+
whole migration.
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* import paths. Callers materialize this bundle only after discovery and
|
|
4
4
|
* normalization finish, so a partial crawl can never leave a half-written site.
|
|
5
5
|
*/
|
|
6
|
-
type MigrationPlatform = 'mintlify' | 'docusaurus' | 'gitbook' | 'nextra' | 'vitepress' | 'starlight' | 'thally' | 'generic' | 'unknown';
|
|
6
|
+
type MigrationPlatform = 'mintlify' | 'docusaurus' | 'fern' | 'gitbook' | 'nextra' | 'vitepress' | 'starlight' | 'thally' | 'generic' | 'unknown';
|
|
7
7
|
interface MigrationNavigationGroup {
|
|
8
8
|
group: string;
|
|
9
9
|
icon?: string;
|
|
@@ -154,6 +154,18 @@ interface MigrationBundle {
|
|
|
154
154
|
site?: {
|
|
155
155
|
name?: string;
|
|
156
156
|
description?: string;
|
|
157
|
+
/**
|
|
158
|
+
* Source theme accent color(s), each a `#rrggbb`/`#rgb` hex string.
|
|
159
|
+
* Follows Mintlify's own `colors` schema: `light` is the color used in
|
|
160
|
+
* dark mode and `dark` is the color used in light mode. Fern's colors
|
|
161
|
+
* are normal (its `light`/`dark` match the mode they paint), so
|
|
162
|
+
* extraction swaps them onto this shape for a single downstream contract.
|
|
163
|
+
*/
|
|
164
|
+
colors?: {
|
|
165
|
+
primary?: string;
|
|
166
|
+
light?: string;
|
|
167
|
+
dark?: string;
|
|
168
|
+
};
|
|
157
169
|
};
|
|
158
170
|
warnings: Array<MigrationWarning>;
|
|
159
171
|
stats: {
|
|
@@ -182,9 +194,13 @@ interface RenderedMigrationFile {
|
|
|
182
194
|
}
|
|
183
195
|
|
|
184
196
|
/**
|
|
185
|
-
* Repository adapter for the shared migration engine. Traversal is bounded
|
|
186
|
-
*
|
|
187
|
-
*
|
|
197
|
+
* Repository adapter for the shared migration engine. Traversal is bounded;
|
|
198
|
+
* `scanFiles` follows a symbolic link only when its resolved real path stays
|
|
199
|
+
* inside the repository checkout (this covers a submodule mounted as a
|
|
200
|
+
* symlink, e.g. Oasis's `docs/core -> ../external/oasis-core/docs`) and
|
|
201
|
+
* guards against a cycle, but every other directory walk in this file still
|
|
202
|
+
* skips symlinks outright. Git is always invoked with an argument array so
|
|
203
|
+
* source-controlled branch names can never become shell commands.
|
|
188
204
|
*/
|
|
189
205
|
|
|
190
206
|
interface GitHubRepositorySource {
|
|
@@ -205,13 +221,30 @@ interface RepositoryMigrationOptions {
|
|
|
205
221
|
docusaurusSkipPlugins?: boolean;
|
|
206
222
|
/** @internal Additional docs plugins default to autogenerated navigation. */
|
|
207
223
|
docusaurusSkipSidebar?: boolean;
|
|
224
|
+
/** @internal A version's sidebar is parsed as static data. */
|
|
225
|
+
docusaurusSidebarPath?: string;
|
|
208
226
|
/** @internal Static assets are shared across docs-plugin instances. */
|
|
209
227
|
docusaurusSkipAssets?: boolean;
|
|
228
|
+
/** @internal Redirects are global config, read once, not per plugin instance. */
|
|
229
|
+
docusaurusSkipRedirects?: boolean;
|
|
210
230
|
}
|
|
211
231
|
/** Parse and validate a public GitHub repository URL. */
|
|
212
232
|
declare function parseGitHubRepositoryUrl(rawUrl: string): GitHubRepositorySource;
|
|
213
|
-
/**
|
|
214
|
-
declare function
|
|
233
|
+
/** Every submodule path declared in a cloned repository's `.gitmodules`, in file order. */
|
|
234
|
+
declare function gitmodulePaths(targetDir: string): Array<string>;
|
|
235
|
+
/**
|
|
236
|
+
* Clone a repository without a shell; callers own and remove `targetDir`. A
|
|
237
|
+
* large repository on a flaky connection can drop mid-clone (`RPC failed`,
|
|
238
|
+
* `Recv failure`, a `curl 56`, …) — retry a network-class failure a couple
|
|
239
|
+
* of times with backoff instead of surfacing a hard failure on the first
|
|
240
|
+
* blip. A partial checkout from the failed attempt is removed first, or
|
|
241
|
+
* `git clone` refuses to reuse the (now non-empty) target directory. A
|
|
242
|
+
* stalled clone/submodule-init is killed by `runGit`'s own timeout, which
|
|
243
|
+
* surfaces as a retryable error. `warnings`, if given, collects a
|
|
244
|
+
* submodule-fetch-failure warning (this function otherwise returns exactly
|
|
245
|
+
* as before, so existing callers are unaffected).
|
|
246
|
+
*/
|
|
247
|
+
declare function cloneGitHubRepository(source: GitHubRepositorySource, targetDir: string, warnings?: Array<MigrationWarning>): Promise<void>;
|
|
215
248
|
/** Detect a supported repository docs platform from unambiguous config files. */
|
|
216
249
|
declare function detectRepositoryPlatform(repositoryDir: string, docsDir?: string): MigrationPlatform;
|
|
217
250
|
/** Pick the first conventional content root containing Markdown. */
|
|
@@ -257,6 +290,65 @@ interface GeneratedNavigationOptions {
|
|
|
257
290
|
}
|
|
258
291
|
/** Build deterministic fallback navigation from imported default-locale pages. */
|
|
259
292
|
declare function buildNavigationFromPages(pages: Array<MigrationPage>, options?: GeneratedNavigationOptions): MigrationDocsConfig;
|
|
293
|
+
/**
|
|
294
|
+
* A source page can be excluded after navigation is projected (invalid MDX,
|
|
295
|
+
* a client-boundary function prop, a duplicate id). Its reference still sits
|
|
296
|
+
* in the projected tabs/groups at that point, across every tab, group, and
|
|
297
|
+
* locale, since the nav tree and the page list are built from the same
|
|
298
|
+
* source config independently. Drop those dangling references here so
|
|
299
|
+
* `thally check` never reports a nav entry with no backing MDX file, and
|
|
300
|
+
* drop any group left with no pages as a result. Shared by every platform's
|
|
301
|
+
* navigation projection (Mintlify, Fern, Docusaurus).
|
|
302
|
+
*/
|
|
303
|
+
declare function pruneMissingNavigationPages(config: MigrationDocsConfig, availableIds: ReadonlySet<string>): MigrationDocsConfig;
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Static Fern (`fern/docs.yml`) repository projection. Fern navigation and
|
|
307
|
+
* generator config are plain YAML data files, so this adapter only ever
|
|
308
|
+
* parses them with `yaml` and never imports or executes JavaScript.
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
interface FernPageDescriptor {
|
|
312
|
+
/** Path to the referenced page file, relative to the Fern root. */
|
|
313
|
+
sourcePath: string;
|
|
314
|
+
navigationId: string;
|
|
315
|
+
}
|
|
316
|
+
/** One `api:` navigation node, resolved to the name/tab Thally needs to bind its spec. */
|
|
317
|
+
interface FernApiSection {
|
|
318
|
+
/** The node's own value (a display name or, in multi-API repos, a `fern/apis/<name>` identifier). */
|
|
319
|
+
name: string;
|
|
320
|
+
/** True when `name` came from an explicit `api-name` field rather than falling back to the `api:` display title. */
|
|
321
|
+
nameExplicit: boolean;
|
|
322
|
+
/** Label of the tab that owns this node, if that tab also has other content and survived projection. */
|
|
323
|
+
tabLabel?: string;
|
|
324
|
+
/**
|
|
325
|
+
* Route segments (section slugs) leading to this node, used only to
|
|
326
|
+
* disambiguate two `api:` nodes that land on the same `tabLabel` — a
|
|
327
|
+
* "Production API Reference" and "Testnet API Reference" section both
|
|
328
|
+
* nested under one tab both want that tab's label; without this, the
|
|
329
|
+
* second one silently overwrites the first tab's binding instead of
|
|
330
|
+
* getting its own tab.
|
|
331
|
+
*/
|
|
332
|
+
routeSegments: Array<string>;
|
|
333
|
+
}
|
|
334
|
+
interface FernNavigationResult {
|
|
335
|
+
docsConfig: MigrationDocsConfig;
|
|
336
|
+
descriptors: Array<FernPageDescriptor>;
|
|
337
|
+
warnings: Array<MigrationWarning>;
|
|
338
|
+
/** Every `api:` node found in navigation, in document order. A repo can declare several (e.g. a REST and a WebSocket API in separate tabs). */
|
|
339
|
+
apiSections: Array<FernApiSection>;
|
|
340
|
+
}
|
|
341
|
+
/** Read `fern/docs.yml` without executing anything. */
|
|
342
|
+
declare function readFernConfig(fernRoot: string): {
|
|
343
|
+
config: Record<string, unknown>;
|
|
344
|
+
sourcePath: string;
|
|
345
|
+
} | null;
|
|
346
|
+
/** Project a Fern `docs.yml` navigation tree into Thally tabs/groups. */
|
|
347
|
+
declare function projectFernNavigation(input: {
|
|
348
|
+
config: Record<string, unknown>;
|
|
349
|
+
fernRoot: string;
|
|
350
|
+
repositoryRoot?: string;
|
|
351
|
+
}): FernNavigationResult;
|
|
260
352
|
|
|
261
353
|
/** Markdown/MDX normalization that preserves every component Thally supports. */
|
|
262
354
|
|
|
@@ -266,7 +358,7 @@ interface MarkdownPageIdentity {
|
|
|
266
358
|
locale?: string;
|
|
267
359
|
}
|
|
268
360
|
/** Normalize only syntax Thally cannot render; supported source JSX stays intact. */
|
|
269
|
-
declare function normalizeMdx(body: string): string;
|
|
361
|
+
declare function normalizeMdx(body: string, platform?: MigrationPlatform, unwrapMdxCodeBlocks?: boolean): string;
|
|
270
362
|
/** Parse source Markdown or MDX into the canonical page representation. */
|
|
271
363
|
declare function parseMarkdownPage(input: {
|
|
272
364
|
id: string;
|
|
@@ -274,6 +366,8 @@ declare function parseMarkdownPage(input: {
|
|
|
274
366
|
locale?: string;
|
|
275
367
|
raw: string;
|
|
276
368
|
source: string;
|
|
369
|
+
/** Gates platform-specific textual renames in `normalizeMdx`; omitted runs them all. */
|
|
370
|
+
platform?: MigrationPlatform;
|
|
277
371
|
/** Resolve platform-specific routes from the already-parsed frontmatter. */
|
|
278
372
|
resolveIdentity?: (frontmatter: Record<string, unknown>, fallback: MarkdownPageIdentity) => MarkdownPageIdentity;
|
|
279
373
|
}): MigrationPage | null;
|
|
@@ -310,4 +404,4 @@ declare const defaultMigrationFetcher: MigrationFetcher;
|
|
|
310
404
|
/** Crawl one public docs origin into a canonical, caller-independent bundle. */
|
|
311
405
|
declare function migrateUrl(options: UrlMigrationOptions): Promise<MigrationBundle>;
|
|
312
406
|
|
|
313
|
-
export { type GitHubRepositorySource, type MigrationAsset, type MigrationBundle, type MigrationDocsConfig, type MigrationFetchRequest, type MigrationFetchResponse, type MigrationFetcher, type MigrationNavigationGroup, type MigrationNavigationTab, type MigrationPage, type MigrationPlatform, type MigrationWarning, type RenderedMigrationFile, type RepositoryMigrationOptions, type UrlMigrationOptions, addMintlifyDirectoryRedirects, buildNavigationFromPages, cloneGitHubRepository, defaultMigrationFetcher, detectRepositoryDocsDir, detectRepositoryPlatform, mergeMigrationConfig, migrateRepository, migrateUrl, normalizeMdx, parseGitHubRepositoryUrl, parseMarkdownPage, projectMintlifyNavigation, readMintlifyConfig, renderMigrationFiles, validateMigrationUrl };
|
|
407
|
+
export { type GitHubRepositorySource, type MigrationAsset, type MigrationBundle, type MigrationDocsConfig, type MigrationFetchRequest, type MigrationFetchResponse, type MigrationFetcher, type MigrationNavigationGroup, type MigrationNavigationTab, type MigrationPage, type MigrationPlatform, type MigrationWarning, type RenderedMigrationFile, type RepositoryMigrationOptions, type UrlMigrationOptions, addMintlifyDirectoryRedirects, buildNavigationFromPages, cloneGitHubRepository, defaultMigrationFetcher, detectRepositoryDocsDir, detectRepositoryPlatform, gitmodulePaths, mergeMigrationConfig, migrateRepository, migrateUrl, normalizeMdx, parseGitHubRepositoryUrl, parseMarkdownPage, projectFernNavigation, projectMintlifyNavigation, pruneMissingNavigationPages, readFernConfig, readMintlifyConfig, renderMigrationFiles, validateMigrationUrl };
|