@thallylabs/migrate 0.2.25 → 0.2.27
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 +83 -23
- package/dist/index.d.ts +59 -7
- package/dist/index.js +2488 -1596
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -115,6 +115,12 @@ Docusaurus `mdx-code-block` wrappers are opened as live MDX when the resulting
|
|
|
115
115
|
page compiles and its special fences contain no module declarations. Pages
|
|
116
116
|
whose fragments still need Docusaurus theme imports or remark plugins remain
|
|
117
117
|
fenced and are retained.
|
|
118
|
+
Directories and files whose names start with `_`, and `__tests__` directories,
|
|
119
|
+
are skipped, as Docusaurus does not treat them as documents. Pages with `unlisted`
|
|
120
|
+
set stay routable but are left out of navigation. Partial imports of `toc`,
|
|
121
|
+
`frontMatter`, `metadata` and `assets` are bound to values the page can use
|
|
122
|
+
instead of failing. `<Admonition>` becomes a callout like the colon fence, and
|
|
123
|
+
`<ThemedImage>` keeps its light image.
|
|
118
124
|
|
|
119
125
|
Fern repositories are located by their `fern/docs.yml` + `fern/fern.config.json`
|
|
120
126
|
pair. `docs.yml` is parsed as bounded YAML—never executed—and preserves tabs,
|
|
@@ -129,6 +135,8 @@ Internal links are adjusted for the site's domain path, selected version, and
|
|
|
129
135
|
source-file routes. Links to sections not imported into Thally stay on the
|
|
130
136
|
published Fern site and produce a migration warning, so the generated site can
|
|
131
137
|
build while the remaining content is moved separately.
|
|
138
|
+
`<Markdown src="...">` includes are inlined from the referenced file when it is
|
|
139
|
+
inside the repository.
|
|
132
140
|
Every `api:` section's OpenAPI document is resolved from its own
|
|
133
141
|
`generators.yml` (`api.specs[].openapi`, or the legacy `api:` string) and
|
|
134
142
|
imported into its own tab — a docs.yml with several API sections (e.g. a REST
|
|
@@ -332,30 +340,71 @@ generic unknown-component fallback.
|
|
|
332
340
|
|
|
333
341
|
### Access-restricted pages
|
|
334
342
|
|
|
335
|
-
|
|
336
|
-
frontmatter
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
`
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
`
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
343
|
+
Restricted Mintlify pages migrate as real pages with normalized access
|
|
344
|
+
frontmatter that the Thally runtime enforces (see `/guides/authenticated-docs`):
|
|
345
|
+
|
|
346
|
+
- Frontmatter `groups` becomes a list of trimmed group names (`groups: admin`
|
|
347
|
+
and `groups: "a, b"` become lists); `public` becomes a boolean (`"false"`,
|
|
348
|
+
`no`, `off`, `0` are `false`; `true`/`"true"` is `true`). Empty `groups`
|
|
349
|
+
restricts nothing.
|
|
350
|
+
- Rules on navigation containers (a group, tab, version, dropdown, anchor,
|
|
351
|
+
language, or `menu` item) are pushed down into the frontmatter of every page
|
|
352
|
+
below them, because the runtime reads access only from pages: container
|
|
353
|
+
`groups` (a list of strings) and `public: false` restrict, and Mintlify's
|
|
354
|
+
group-level `public: true` opens pages that name no groups of their own.
|
|
355
|
+
Pages stay in navigation where they were.
|
|
356
|
+
- Rules combine to the strictest: nested and page group lists intersect,
|
|
357
|
+
`public: false` anywhere wins, and a page listed under both an open and a
|
|
358
|
+
restricted container gets the restricted rule.
|
|
359
|
+
|
|
360
|
+
A page whose rules cannot be carried over safely fails closed instead: a
|
|
361
|
+
malformed value (`public: maybe`, `groups: [1]`), group lists that share no
|
|
362
|
+
group, or frontmatter that declares `groups`/`public` but cannot be parsed or
|
|
363
|
+
read. Such a page is not written to `src/content`, is removed from navigation,
|
|
364
|
+
and its original is written unchanged to `migration-quarantine/<original path>`
|
|
365
|
+
at the project root, which no runtime reader walks; `create-thally-docs` adds
|
|
366
|
+
that folder to `.gitignore`. Each quarantined page gets a `gated-page` warning.
|
|
367
|
+
|
|
368
|
+
Fern and Docusaurus have no runtime access mapping in Thally, so their restricted
|
|
369
|
+
pages fail closed in the same way: they are quarantined (not written to
|
|
370
|
+
`src/content`, removed from navigation, original saved under
|
|
371
|
+
`migration-quarantine/`) and never inlined into other pages. Fern signals:
|
|
372
|
+
frontmatter `viewers` (any non-empty value) or `authed`, `<If roles>` or
|
|
373
|
+
`<If viewers>` content in a page, and `viewers` in `docs.yml` on pages, sections,
|
|
374
|
+
tabs, products, versions and api nodes; the specs of a restricted api node are
|
|
375
|
+
withheld too. Docusaurus: a `draft` page, where any value other than unset,
|
|
376
|
+
`false` or `"false"` counts as a draft; the check is skipped for files under `_`
|
|
377
|
+
directories and `__tests__`, which Docusaurus does not publish as documents. Links
|
|
378
|
+
from other pages to a quarantined page are left as authored and will fail
|
|
379
|
+
`thally check`.
|
|
380
|
+
|
|
381
|
+
Fern migration stops with an explicit error if cyclic navigation, excessive
|
|
382
|
+
nesting, or the node budget prevents complete access classification. It emits
|
|
383
|
+
no pages, assets, or API specs, because an unvisited branch could restrict a
|
|
384
|
+
file also listed under a public node. Simplify the source navigation and retry.
|
|
385
|
+
|
|
386
|
+
Assets are copied to `public/` only when a published page, the site configuration,
|
|
387
|
+
copied styles or a migrated component names them by their exact normalized path;
|
|
388
|
+
a restricted page's text never makes an asset public. On a site that withholds
|
|
389
|
+
anything, an asset nothing published names that way, one named only by a bare file
|
|
390
|
+
name or in a different letter case, one built at runtime, and one that shares its
|
|
391
|
+
public path with another file are saved under `migration-quarantine/assets/`
|
|
392
|
+
instead, with a warning listing them so they can be copied back by hand. On every
|
|
393
|
+
platform a page over 2 MB is not inlined, OpenAPI spec reads are capped at 50 MB,
|
|
394
|
+
and a path that resolves outside the repository through a symlink is refused.
|
|
395
|
+
|
|
396
|
+
What a restricted page uses must not leak through surfaces that are not access
|
|
397
|
+
controlled: it is never inlined into another page (a `gated-page` warning names
|
|
398
|
+
the importer), images and other assets used only by restricted pages are not
|
|
399
|
+
copied to `public/` (they are saved under `migration-quarantine/assets/`), and
|
|
400
|
+
OpenAPI operations documented only on restricted pages are withheld from the
|
|
401
|
+
published spec. One `gated-page` summary counts the restricted pages and notes
|
|
402
|
+
that Thally hides them from everyone until reader authentication is configured
|
|
403
|
+
in `docs.json` `auth`; no `auth` block is generated, because Mintlify's
|
|
404
|
+
dashboard settings cannot be read from a repository. When any page sets
|
|
355
405
|
`public: true` (which implies the source site required sign-in for everything
|
|
356
|
-
else) one `gated-page` warning says
|
|
357
|
-
|
|
358
|
-
though Mintlify documents only `"public": true` on a group.
|
|
406
|
+
else), one more `gated-page` warning says every unrestricted page will be
|
|
407
|
+
public until `auth` is configured.
|
|
359
408
|
|
|
360
409
|
### Site-wide scripts, styles, fonts, and settings
|
|
361
410
|
|
|
@@ -382,6 +431,17 @@ Legacy `mint.json` `topbarLinks` and `topbarCtaButton` (including
|
|
|
382
431
|
|
|
383
432
|
## Branding
|
|
384
433
|
|
|
434
|
+
Docusaurus custom CSS projects Infima palette, typography, header spacing,
|
|
435
|
+
announcement styling, and local Prism colors into a portable stylesheet.
|
|
436
|
+
For Sass or Tailwind expressions, provide locally compiled
|
|
437
|
+
`build/assets/css/styles.*.css`; unresolved expressions produce a migration
|
|
438
|
+
warning. Configuration and theme modules are read as static data.
|
|
439
|
+
|
|
440
|
+
Remote Fern `global-theme` references fall back to local overrides and base
|
|
441
|
+
Thally tokens with a structured warning. The NVIDIA theme uses `#76B900`
|
|
442
|
+
when no local accent is configured. No remote theme assets are fetched.
|
|
443
|
+
Authored section expansion defaults are retained on desktop and mobile.
|
|
444
|
+
|
|
385
445
|
A source site's logo, favicon, and theme accent color(s) are extracted where
|
|
386
446
|
each platform's config exposes them (Mintlify's `colors`, Fern's
|
|
387
447
|
`colors.accent-primary`, Docusaurus's classic theme `customCss`). A valid
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
type MigrationPlatform = 'mintlify' | 'docusaurus' | 'fern' | 'gitbook' | 'nextra' | 'vitepress' | 'starlight' | 'thally' | 'generic' | 'unknown';
|
|
7
7
|
interface MigrationNavigationGroup {
|
|
8
|
+
defaultOpen?: boolean;
|
|
8
9
|
group: string;
|
|
9
10
|
icon?: string;
|
|
10
11
|
hidden?: boolean;
|
|
@@ -218,6 +219,8 @@ interface MigrationPage {
|
|
|
218
219
|
navigationId: string;
|
|
219
220
|
locale?: string;
|
|
220
221
|
title: string;
|
|
222
|
+
/** Authored display H1 when the source uses a different metadata title. */
|
|
223
|
+
headingTitle?: string;
|
|
221
224
|
navTitle?: string;
|
|
222
225
|
/** Sidebar icon name or image URL from page frontmatter, with its optional style. */
|
|
223
226
|
icon?: string;
|
|
@@ -230,6 +233,13 @@ interface MigrationPage {
|
|
|
230
233
|
mode?: 'default' | 'wide' | 'custom' | 'center' | 'home';
|
|
231
234
|
hidden?: boolean;
|
|
232
235
|
noindex?: boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Reader access groups (frontmatter `groups`): trimmed, non-empty names the
|
|
238
|
+
* runtime matches exactly. The page needs a signed-in reader in one of them.
|
|
239
|
+
*/
|
|
240
|
+
groups?: Array<string>;
|
|
241
|
+
/** Frontmatter `public`: `true` opens the page to anyone, `false` needs any signed-in reader. */
|
|
242
|
+
public?: boolean;
|
|
233
243
|
/** Social/SEO overrides from `og:*` and `twitter:*` frontmatter, keyed by the migrated frontmatter field. */
|
|
234
244
|
meta?: Partial<Record<'ogTitle' | 'ogDescription' | 'ogImage' | 'twitterTitle' | 'twitterDescription' | 'twitterImage', string>>;
|
|
235
245
|
/** OpenAPI operation key rendered by Thally instead of ordinary MDX. */
|
|
@@ -254,7 +264,7 @@ interface MigrationAsset {
|
|
|
254
264
|
}
|
|
255
265
|
interface MigrationWarning {
|
|
256
266
|
code: 'collision' | 'invalid-page' | 'missing-page' | 'unsupported-config' | 'limit-reached' | 'fetch-failed' | 'skipped-file'
|
|
257
|
-
/** Access-restricted source
|
|
267
|
+
/** Access-restricted source content: migrated with access rules, withheld (quarantined), or a site-wide auth risk. */
|
|
258
268
|
| 'gated-page';
|
|
259
269
|
message: string;
|
|
260
270
|
source?: string;
|
|
@@ -281,7 +291,11 @@ interface MigrationBundle {
|
|
|
281
291
|
remoteApiSpecs?: Array<RemoteApiSpec>;
|
|
282
292
|
/** Customer-owned component source and registry; paths are repository-relative. */
|
|
283
293
|
componentFiles?: Array<RenderedMigrationFile>;
|
|
284
|
-
/**
|
|
294
|
+
/**
|
|
295
|
+
* Restricted content that cannot be published safely (pages whose access
|
|
296
|
+
* rules are malformed or contradictory, and assets used only by restricted
|
|
297
|
+
* pages), written outside every published path.
|
|
298
|
+
*/
|
|
285
299
|
quarantinedFiles?: Array<RenderedMigrationFile>;
|
|
286
300
|
/** Access-restricted pages the file limit dropped: neither published nor saved in quarantinedFiles. */
|
|
287
301
|
droppedGatedPages?: number;
|
|
@@ -448,6 +462,30 @@ declare function detectRepositoryDocsDir(repositoryDir: string): string;
|
|
|
448
462
|
/** Import an already-available repository directory into a canonical bundle. */
|
|
449
463
|
declare function migrateRepository(options: RepositoryMigrationOptions): MigrationBundle;
|
|
450
464
|
|
|
465
|
+
/**
|
|
466
|
+
* Mintlify-only helpers: page access rules, site-wide CSS/JS/font assets,
|
|
467
|
+
* and appearance settings. Kept apart from the generic repository walk so the
|
|
468
|
+
* rules that decide how restricted pages migrate (and what is quarantined)
|
|
469
|
+
* are auditable in one place.
|
|
470
|
+
*
|
|
471
|
+
* Access invariant: a restricted page migrates with normalized `groups` /
|
|
472
|
+
* `public` frontmatter that the Thally runtime enforces; anything ambiguous
|
|
473
|
+
* (malformed values, group lists that share no group) fails closed and the
|
|
474
|
+
* page is quarantined instead.
|
|
475
|
+
*/
|
|
476
|
+
|
|
477
|
+
/** Access imposed by every navigation container above one appearance of a page. */
|
|
478
|
+
interface NavigationAccess {
|
|
479
|
+
/** Intersection of every container group list on the path. */
|
|
480
|
+
groups?: Array<string>;
|
|
481
|
+
/** Some container on the path sets `public: false`. */
|
|
482
|
+
hasPublicFalse: boolean;
|
|
483
|
+
/** Some container on the path sets `public: true` (Mintlify's documented group flag). */
|
|
484
|
+
hasPublicTrue: boolean;
|
|
485
|
+
/** Set when a container value is malformed or nested group lists share no group. */
|
|
486
|
+
problem?: string;
|
|
487
|
+
}
|
|
488
|
+
|
|
451
489
|
/**
|
|
452
490
|
* Navigation projection for imported sites. Mintlify's schema is intentionally
|
|
453
491
|
* more expressive than Thally's tab/group model, so complex containers are
|
|
@@ -459,16 +497,24 @@ interface MintlifyPageReference {
|
|
|
459
497
|
navigationId: string;
|
|
460
498
|
locale?: string;
|
|
461
499
|
}
|
|
462
|
-
/**
|
|
463
|
-
|
|
500
|
+
/**
|
|
501
|
+
* One appearance of a page reference in navigation, with the access rules of
|
|
502
|
+
* every container above it. Thally reads access only from page frontmatter,
|
|
503
|
+
* so these are pushed down into the frontmatter of the pages they cover.
|
|
504
|
+
*/
|
|
505
|
+
interface MintlifyReferenceAccess {
|
|
464
506
|
ref: string;
|
|
465
|
-
|
|
507
|
+
access: NavigationAccess;
|
|
466
508
|
}
|
|
467
509
|
interface MintlifyNavigationResult {
|
|
468
510
|
docsConfig: MigrationDocsConfig;
|
|
469
511
|
pageReferences: Array<MintlifyPageReference>;
|
|
470
|
-
/**
|
|
471
|
-
|
|
512
|
+
/**
|
|
513
|
+
* Access imposed by navigation containers, one entry per appearance of a
|
|
514
|
+
* page (open appearances included, so a page listed in several places can
|
|
515
|
+
* be given the strictest rule). Restricted pages stay in `docsConfig`.
|
|
516
|
+
*/
|
|
517
|
+
referenceAccess: Array<MintlifyReferenceAccess>;
|
|
472
518
|
/** `sourceRef` mounts under a restricted container; never resolved, so nothing of theirs is imported. */
|
|
473
519
|
gatedSourceRefs: Array<string>;
|
|
474
520
|
warnings: Array<MigrationWarning>;
|
|
@@ -527,6 +573,8 @@ interface FernPageDescriptor {
|
|
|
527
573
|
navTitle?: string;
|
|
528
574
|
/** Keep routable pages excluded by Fern's `hidden` navigation flag. */
|
|
529
575
|
hidden?: boolean;
|
|
576
|
+
/** Listed under a docs.yml node that sets `viewers` or `authed`: Fern shows it only to signed-in roles. */
|
|
577
|
+
restricted?: boolean;
|
|
530
578
|
}
|
|
531
579
|
/** One `api:` navigation node, resolved to the name/tab Thally needs to bind its spec. */
|
|
532
580
|
interface FernApiSection {
|
|
@@ -547,11 +595,15 @@ interface FernApiSection {
|
|
|
547
595
|
routeSegments: Array<string>;
|
|
548
596
|
}
|
|
549
597
|
interface FernNavigationResult {
|
|
598
|
+
/** A bounded walk skipped nodes whose access rules and API bindings are unknown. */
|
|
599
|
+
navigationIncomplete: boolean;
|
|
550
600
|
docsConfig: MigrationDocsConfig;
|
|
551
601
|
descriptors: Array<FernPageDescriptor>;
|
|
552
602
|
warnings: Array<MigrationWarning>;
|
|
553
603
|
/** 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). */
|
|
554
604
|
apiSections: Array<FernApiSection>;
|
|
605
|
+
/** `api:` nodes under a restricted node; their specs must not be published. */
|
|
606
|
+
restrictedApiSections: Array<FernApiSection>;
|
|
555
607
|
/** Fern changelog tabs render their entries as a feed at the bare route. */
|
|
556
608
|
changelogIndexes: Array<{
|
|
557
609
|
route: string;
|