@thallylabs/migrate 0.2.47 → 0.2.48

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 CHANGED
@@ -128,6 +128,9 @@ versions, languages, and reusable `$ref` navigation files; it also preserves
128
128
  dropdown presentation, collection descriptions and icons, explicit default
129
129
  versions, page route casing, redirects, local snippets, static assets,
130
130
  compatible page frontmatter, site identity, and OpenAPI configuration.
131
+ A page `icon` written as an object (`name`, `style`, `library`) maps to the page's
132
+ `icon` and `iconType`; Thally has one icon library per site, so a page `library`
133
+ other than the site's `icons.library` (Font Awesome when unset) is reported.
131
134
  A page with no `description`, other than one that names an API operation, gets
132
135
  one from its first paragraph, which keeps it for search and metadata but marks it
133
136
  `descriptionPlacement: body`, so the runtime does not print the same sentence under
@@ -236,10 +239,12 @@ is bound once per spec file in a hidden tab (`OpenAPI: <spec>`, the same as for
236
239
  spec only a page names), which is what the pages' `openapi:` frontmatter resolves
237
240
  against; the renderer serves no `/api/` page, sitemap entry or search record for it. A remote spec's pages
238
241
  and tab are made by `hydrateRemoteApiSpecs` once it is downloaded; a download
239
- that fails leaves no tab and no page, as before. An operation the spec withholds
240
- (`x-hidden`, `x-excluded`) gets no page, nor does one listed only under a
242
+ that fails leaves no tab and no page, as before. An operation the spec marks
243
+ `x-hidden` or `x-excluded` gets no generated page, nor does one listed only under a
241
244
  `hidden` group or an access-restricted container (such groups are left out of
242
- the tab, as above). Of two operations with the same tag and
245
+ the tab, as above). A page the source wrote that names an `x-hidden` operation
246
+ (`openapi: post /quote`) still renders it, without Try it, as on Mintlify; a page
247
+ that names an `x-excluded` operation is not served. Of two operations with the same tag and
243
248
  summary the first listed keeps the URL and one warning names the others; an
244
249
  authored page at that URL keeps it. Nothing is redirected from these URLs and a
245
250
  link to one stays as written; a link to a tag folder or to an address under the
@@ -273,7 +278,8 @@ Mintlify `styling.eyebrows: "breadcrumbs"` becomes `eyebrow: "path"` (the full
273
278
  group path above the page title); `"section"` or no setting writes nothing.
274
279
  Mintlify sources also get `smartQuotes: true`, because Mintlify renders straight
275
280
  quotes in prose as curly ones; the setting leaves code, heading ids, Markdown and
276
- `llms.txt` as written.
281
+ `llms.txt` as written, and so does the destination of a Markdown link with its
282
+ quoted title (a Docusaurus heading ends in `[](#id "Direct link to ...")`).
277
283
 
278
284
  Thally leaves out the sidebar heading of a group named after its tab or dropdown, because
279
285
  the collection already names it. Mintlify keeps that heading, so a source with such a group
@@ -335,6 +341,12 @@ without regard to a trailing slash, so a redirect whose source is a page of the
335
341
  migrated site would hide that page, and two redirects that send a visit back to
336
342
  each other never settle. Each such redirect is left out, and a warning
337
343
  lists the first ten of each kind; the earlier redirect of a loop is kept. A
344
+ Mintlify redirect from the source's own config is the exception: Mintlify
345
+ follows it even when a page has that address, so the redirect is kept, the page
346
+ is marked `noindex` and stays as a stub (its navigation entry follows the
347
+ redirect), and a warning lists the first ten and says to delete the page and its
348
+ navigation entry if it is not needed. The home page (each language's too), and an
349
+ address that differs from a page only in letter case, are still left out. A
338
350
  generated redirect (a version alias, an endpoint URL) for an address that
339
351
  already serves a page is left out without a warning, since the page is still
340
352
  reachable there. These checks ignore letter case, because a site can run on
@@ -369,6 +381,14 @@ purpose; a `url` that is not an `http(s)` address is ignored. The home page
369
381
  both redirect, and the redirect from `/` replaces the generated one to the first
370
382
  page. A redirect for `/` that the source site wrote stays, and a warning says so.
371
383
 
384
+ A Mintlify root `index.mdx` is the page Mintlify serves at `/`, listed in
385
+ docs.json or not, so the root is not redirected to the first navigation page
386
+ for it (an `introduction.mdx` gets that redirect). An `index.mdx` that docs.json
387
+ does not list stays out of the navigation, as it is on Mintlify. A section path (`/guides`) is redirected to its `overview` or `introduction` page
388
+ only when the navigation lists pages under that directory, which is when
389
+ Mintlify redirects it too; with only unlisted pages under it Mintlify answers
390
+ 404, and so does the migrated site.
391
+
372
392
  An authored redirect (Mintlify and Fern `redirects`, Docusaurus
373
393
  `plugin-client-redirects`) starts at a path on the site and ends at another
374
394
  path on it or at an absolute `http(s)` address, which is kept exactly as written
@@ -598,6 +618,29 @@ homepage and explicit redirects. Locale tags and recognized locale-prefixed
598
618
  sections are normalized without discarding original URL redirects.
599
619
  Mintlify's generated `param-*` links for settings headings and named fields
600
620
  become explicit anchors in migrated MDX.
621
+ A `<video autoPlay>` gets the `muted`, `loop` and `playsInline` it lacks, as
622
+ Mintlify renders it, so browsers let it start; a video without `autoPlay` is
623
+ left as written.
624
+ A component `href` that starts with `./` or `../` (`<Card href="./lesson-1">`) is
625
+ rewritten to the root-absolute path the browser reaches from the page's own route
626
+ (`/ua-course/lesson-1` on `ua-course/intro`; a directory index is served at its
627
+ parent route), keeping any query and fragment, so Thally's cards render it and
628
+ `thally check` validates it. A `href` that climbs above the site root stops at the
629
+ root, as the browser does. Markdown links and code are left alone.
630
+ A link to the source site's own host becomes root-relative when it reaches an
631
+ imported page. The host is `seo.metatags.canonical` when set (a link outside the path
632
+ that address names, such as `/docs`, is left alone), else the
633
+ `integrations.plausible.domain` when its first label is `docs`, `developer` or
634
+ `developers`, because Plausible is often set up for the marketing apex, whose pages
635
+ are not docs pages. Separately, a leading mount path such as `/docs/` is dropped from
636
+ a link, whatever its host, when what remains is an imported page. Another host, port
637
+ or login, a path that is no imported page, and a target longer than 2048 characters
638
+ keep the URL as written.
639
+ Mintlify pages converted from Docusaurus keep `<Tabs values>` and `<TabItem>`: they
640
+ become `<Tabs>` and `<Tab title>`, titled by the item's `label`, else the `values`
641
+ label for its `value`, else the `value`. A
642
+ `<TabItem>` outside any `<Tabs>` is mapped only when it has its own `</TabItem>`, so
643
+ one named in prose is escaped as text and the page is kept.
601
644
 
602
645
  Simple interactive HTML blocks in MDX are extracted into client components.
603
646
  For a copied client component that receives a simple page-authored JSX callback,
@@ -638,6 +681,12 @@ over a same-named built-in. If any dependency cannot run in a client module
638
681
  (server-only APIs such as `process` or `await`, an undeclared name, a package
639
682
  the migration removed, a dynamic `import()`), the component is left where it
640
683
  is and a warning names it and the blocker.
684
+ A component that reads `window`, `document` or another browser global while it
685
+ renders (`if (typeof window === "undefined") return null`, a `fetch` that fills
686
+ the DOM by hand) is moved the same way, and its module renders it only after the
687
+ client has mounted, so the server HTML and the first client render agree; the
688
+ list or table it builds appears once the page has loaded. A component with JSX event
689
+ handlers is left to the interactive-block extraction above.
641
690
  `<Snippet file="...">` accepts the documented `snippets/`-relative path as well
642
691
  as a `/snippets/...` or page-relative one. A multi-line snippet keeps the
643
692
  indentation of the tag it replaces on every line (aligned with the item text
@@ -664,7 +713,11 @@ written in text and as the child of an element inside an expression
664
713
  (`{mode === "x" && <Note>{children}</Note>}`) alike. A `{name}` inside a fenced code
665
714
  block is never replaced, and a fence closes only as CommonMark closes it (the same
666
715
  character, at least as long, nothing after it), so a three-backtick block inside a
667
- four-backtick one stays code. An outer code fence that contains a
716
+ four-backtick one stays code. A prop that a component snippet destructures
717
+ (`({ img, imgDark, size = "md" }) => ...`) and the call leaves out is its string
718
+ default, or `undefined` without one, as in the component: `{imgDark || img}` keeps
719
+ `img` and `{model && ...}` leaves nothing. A call that spreads props, or passes the
720
+ prop as an expression, leaves it as it was. An outer code fence that contains a
668
721
  same-length nested fence is widened so the inner fence no longer closes it, and
669
722
  a bare placeholder tag in prose (`<Feature> requires a plan`) that would stop
670
723
  the page compiling is escaped as text rather than losing the page.
@@ -696,11 +749,30 @@ Other relative imports of a copied file are handled the same way: a namespace
696
749
  import (`import * as X from './comp.jsx'`) and a dynamic `import('./comp.jsx')`
697
750
  point at the copied module, and a relative side-effect import
698
751
  (`import './styles.css'`) is removed with a warning, like one from an npm
699
- package. A page is excluded only when the relative target is not copied (for
752
+ package. An `import` line inside a template literal of the page's JavaScript (an
753
+ `export`, an expression or a JSX attribute value: a code sample held in a string) is
754
+ text, so it stays in the string and is not hoisted. That needs the page to parse as
755
+ MDX at that point, with the frontmatter set aside, HTML comments blanked, and unmatched
756
+ closing tags and prose braces acorn rejects escaped for the read; a page that still
757
+ does not parse (an HTML tag that is never closed, say) is hoisted as before. A page is excluded only when the relative target is not copied (for
700
758
  example a Next.js `./metadata` module, or an `export ... from` re-export), with
701
759
  a single warning naming it. An MDX expression that names an identifier the page
702
760
  never defines (`{missing}`) is removed with a warning, since it would throw at
703
761
  render; define the name or escape the braces as `\{ \}` to keep the text.
762
+ Prose braces that are not a valid expression at all (a path placeholder such as
763
+ `/{chainId?}`) are escaped as literal text, which is how Mintlify shows them, and
764
+ one warning per page quotes up to three of the escaped spans (the same goes for
765
+ unmatched closing tags). A bare URL needs no escape: the runtime compiles with
766
+ remark-gfm, which autolinks it, braces included, and every check of whether a page
767
+ compiles reads it that way. The page is kept only if it then compiles, and a page
768
+ that needs more than 50 repairs is not repaired: a broken expression in a JSX
769
+ attribute, a broken `export`, or a brace that never closes still excludes the page.
770
+ A page the component analysis could not parse is repaired first (its HTML comments
771
+ converted for the read) and analysed again, so its inline components are still
772
+ extracted. If the analysis still fails on a page that needed a brace repair, the page
773
+ is excluded as before when it has an `import` or `export` line, an event handler or
774
+ an asset `require(` outside code for the analysis to act on, and kept when it has
775
+ none (a licence text with `<COPYRIGHT HOLDER>`, say).
704
776
  A value import from a local snippet (`import { FEE, fee } from
705
777
  '/snippets/c.mdx'`) is inlined when each name is a static value (string,
706
778
  number, boolean, `null`, or an object/array of those) or a self-contained
@@ -737,6 +809,17 @@ YouTube-embed package (e.g. a custom `LiteYouTube` wrapping
737
809
  page that imports that package directly, instead of losing the embed to the
738
810
  generic unknown-component fallback.
739
811
 
812
+ A quoted frontmatter value that goes on over unindented lines (the closing quote
813
+ alone on the next line, say) is read as Mintlify reads it, with each line break
814
+ folded into a space, though strict YAML rejects it. A quote that is never
815
+ closed, or text after the closing quote, is still reported as invalid YAML.
816
+
817
+ A Mintlify page without a frontmatter `title` is titled from its file name
818
+ (`RelayBridge.mdx` is "RelayBridge") and keeps a leading `# Heading` in its body
819
+ as an ordinary heading, as Mintlify shows it; a page that names an OpenAPI
820
+ operation still takes that heading as its title. Docusaurus and Fern pages take
821
+ the leading heading as the title and drop it from the body.
822
+
740
823
  ### Access-restricted pages
741
824
 
742
825
  Restricted Mintlify pages migrate as real pages with normalized access
@@ -813,7 +896,9 @@ page. Those files are copied to `public/` (tooling config such as
813
896
  output, dot-directories, and `node_modules` are not) under the normal asset
814
897
  size limits. Scripts are added to `docs.json` `customScripts` (URL-encoded),
815
898
  except modules that pages import as components, which are copied as components
816
- instead. Thally loads a local stylesheet that `docs.json` lists under
899
+ instead. A script that loads or names a known tracker (PostHog, Intercom,
900
+ Segment, Hotjar, Google Tag Manager or Analytics, Mixpanel, Amplitude) is still
901
+ carried, with one warning for that file naming the trackers. Thally loads a local stylesheet that `docs.json` lists under
817
902
  `stylesheets`, but the migrator does not list the `.css` files it copies, since
818
903
  their rules likely target Mintlify's DOM: each is preserved with a warning that it
819
904
  is not applied. Fonts named by
@@ -876,6 +961,11 @@ Legacy `mint.json` `topbarLinks` and `topbarCtaButton` (including
876
961
  (`showToggle: false`), and legacy `modeToggle.default` / `isHidden` map to
877
962
  `appearance`; invalid values are skipped with a warning. Mintlify sources set
878
963
  `markdown.enabled: true`, matching Mintlify's default Markdown mirrors.
964
+ `errors.404.redirect` (a boolean) is written to `docs.json` as
965
+ `"errors": { "404": { "redirect": true } }`; one warning names every other
966
+ setting under `errors`, which is not carried. `theme: "maple"` keeps its name and
967
+ `"mint"` becomes Thally's `default` theme; any other `theme` is mapped to the
968
+ closest Thally theme, and a warning says so.
879
969
 
880
970
  ## Branding
881
971
 
@@ -899,6 +989,8 @@ are copied into `public/`, but Thally's site configuration has no static
899
989
  field for them — branding is managed from the admin dashboard at runtime —
900
990
  so each site gets one warning naming the copied files and pointing at the
901
991
  dashboard's branding settings instead of leaving the loss silent.
992
+ A `docs.json` logo or favicon path written with a leading `./` (`./logo/icon.svg`)
993
+ counts like `logo/icon.svg`; one that climbs out with `../` is not imported.
902
994
 
903
995
  ## Cloning a GitHub repository
904
996
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MigrationPage, a as MigrationAsset, b as MigrationNavigationGroup, R as RenderedMigrationFile, c as MigrationWarning, d as MigrationFetcher, e as MigrationPlatform, f as MigrationBundle, g as MigrationDocsConfig, E as EndpointTabSlot } from './url-run-D-E4dr2h.js';
2
- export { h as MigrationCapture, i as MigrationCaptureProvider, j as MigrationCaptureState, k as MigrationCapturedAsset, l as MigrationEvidence, m as MigrationFetchRequest, n as MigrationFetchResponse, o as MigrationJournalAsset, p as MigrationNavigationOccurrence, q as MigrationNavigationTab, U as UrlMigrationCheckpoint, r as UrlMigrationCheckpointDelta, s as UrlMigrationIssue, t as UrlMigrationRecord, u as UrlMigrationRun, v as UrlMigrationRunOptions, w as UrlMigrationValidation, x as classifyMigrationResponse, y as mergeMigrationConfig, z as renderMigrationFiles, A as runUrlMigration, B as validateUrlMigration } from './url-run-D-E4dr2h.js';
1
+ import { M as MigrationPage, a as MigrationAsset, b as MigrationNavigationGroup, R as RenderedMigrationFile, c as MigrationWarning, d as MigrationFetcher, e as MigrationPlatform, f as MigrationBundle, g as MigrationDocsConfig, E as EndpointTabSlot } from './url-run-0BYlnvvB.js';
2
+ export { h as MigrationCapture, i as MigrationCaptureProvider, j as MigrationCaptureState, k as MigrationCapturedAsset, l as MigrationEvidence, m as MigrationFetchRequest, n as MigrationFetchResponse, o as MigrationJournalAsset, p as MigrationNavigationOccurrence, q as MigrationNavigationTab, U as UrlMigrationCheckpoint, r as UrlMigrationCheckpointDelta, s as UrlMigrationIssue, t as UrlMigrationRecord, u as UrlMigrationRun, v as UrlMigrationRunOptions, w as UrlMigrationValidation, x as classifyMigrationResponse, y as mergeMigrationConfig, z as renderMigrationFiles, A as runUrlMigration, B as validateUrlMigration } from './url-run-0BYlnvvB.js';
3
3
  export { isPassiveSvg } from './svg-policy.js';
4
4
 
5
5
  /**
@@ -371,6 +371,8 @@ declare function parseMarkdownPage(input: {
371
371
  resolveIdentity?: (frontmatter: Record<string, unknown>, fallback: MarkdownPageIdentity) => MarkdownPageIdentity;
372
372
  /** Receives a message when frontmatter is dropped or altered. */
373
373
  warn?: (message: string) => void;
374
+ /** The icon library the migrated site uses; a page icon naming another one is reported, and none is when omitted. */
375
+ siteIconLibrary?: string;
374
376
  }): MigrationPage | null;
375
377
 
376
378
  /**