@thallylabs/migrate 0.2.12 → 0.2.17
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 +79 -10
- package/dist/index.d.ts +26 -2
- package/dist/index.js +998 -178
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,10 +18,18 @@ rendered application before falling back to DOM link inference.
|
|
|
18
18
|
An `openapi` (or `asyncapi`) reference is resolved wherever Mintlify allows
|
|
19
19
|
it — the top-level `api.openapi`, or on any individual
|
|
20
20
|
tab/anchor/dropdown/product/version, e.g. `navigation.tabs[].openapi` — and
|
|
21
|
-
binds to that exact tab, not only the first one found.
|
|
21
|
+
binds to that exact tab, not only the first one found. An `openapi` item inside
|
|
22
|
+
a tab `menu` (string or `{ source, directory }`) becomes its own API tab named
|
|
23
|
+
`<Tab>: <Item>`, so its endpoints appear in the sidebar; when it is the tab's
|
|
24
|
+
only content it binds to the tab itself. The item's `icon` and `hidden` carry
|
|
25
|
+
onto that tab, and a `directory` output folder is not used (a warning says so:
|
|
26
|
+
endpoint pages are generated under `/api/`). An item Thally cannot represent
|
|
27
|
+
produces a warning naming it. Specs that share a file name across folders are
|
|
28
|
+
kept as separate files in `openapi/`. Remote `http://` and
|
|
22
29
|
`https://` specs are not downloaded during migration. The report names each
|
|
23
|
-
remote URL and tells you to add its spec to
|
|
24
|
-
in `docs.json` to that
|
|
30
|
+
remote URL and tells you to add its spec to a project-root folder such as
|
|
31
|
+
`openapi/`, then set the API source in `docs.json` to that path. Missing local
|
|
32
|
+
specs also produce warnings
|
|
25
33
|
instead of silently dropping that API tab's reference. AsyncAPI has no Thally
|
|
26
34
|
renderer, so it always produces a clear warning naming the spec instead of
|
|
27
35
|
disappearing.
|
|
@@ -39,12 +47,20 @@ version first, then pages not listed in navigation, and one warning counts and
|
|
|
39
47
|
names (the first three of) the pages left out and suggests `--docs-dir` to
|
|
40
48
|
migrate a smaller part of the repository. Scanning itself stops after 100,000
|
|
41
49
|
files with its own warning. Individual assets over 25 MB, or beyond 500 MB in
|
|
42
|
-
total, are not copied
|
|
50
|
+
total, are not copied; one warning per reason gives the count, the first five
|
|
51
|
+
paths, and the next step (copy them into `public/` manually).
|
|
43
52
|
|
|
44
53
|
Headings written with an explicit `{#custom-id}` become a preceding
|
|
45
54
|
`<a id="custom-id"></a>` anchor and keep their text, so links to that id still
|
|
46
55
|
work and the page still compiles as MDX.
|
|
47
56
|
|
|
57
|
+
Migrated specs are written to `openapi/`, never `public/`, because the host
|
|
58
|
+
serves `public/` as-is and would publish operations marked `x-excluded` or
|
|
59
|
+
`x-hidden`. Migrating into an existing site does not delete anything: an
|
|
60
|
+
older copy of a spec already in `public/` stays publicly downloadable. The
|
|
61
|
+
migration warns and lists such files, and `thally check` keeps flagging them;
|
|
62
|
+
delete them manually.
|
|
63
|
+
|
|
48
64
|
Docusaurus sidebars are parsed as bounded, data-only JSON5—never executed—and
|
|
49
65
|
preserve explicit categories, autogenerated slices, document IDs/slugs,
|
|
50
66
|
positions, generated indexes, admonitions, tabs, and `static/` assets where
|
|
@@ -229,6 +245,56 @@ YouTube-embed package (e.g. a custom `LiteYouTube` wrapping
|
|
|
229
245
|
page that imports that package directly, instead of losing the embed to the
|
|
230
246
|
generic unknown-component fallback.
|
|
231
247
|
|
|
248
|
+
### Access-restricted pages
|
|
249
|
+
|
|
250
|
+
A gated Mintlify page must never migrate as public. A page is withheld when its
|
|
251
|
+
frontmatter sets a non-empty `groups` (list or string) or `public: false`
|
|
252
|
+
(also `"false"`, `no`, `off`, `0`; empty `groups` restricts nothing), or when it sits
|
|
253
|
+
under a navigation group or tab that sets `groups` (a list of strings) or
|
|
254
|
+
`public: false`. `public: true` alone is not gating. Withheld pages are not
|
|
255
|
+
written to `src/content` and are removed from navigation (emptied groups and
|
|
256
|
+
tabs included), whether or not navigation lists them. The original file is
|
|
257
|
+
written unchanged to `migration-quarantine/<original path>` at the project
|
|
258
|
+
root, which no runtime content reader, search index, or `llms` output walks;
|
|
259
|
+
`create-thally-docs` also adds it to the project's `.gitignore` (appended once,
|
|
260
|
+
existing entries kept) so it is never committed or pushed. A public page that
|
|
261
|
+
imports a withheld page as a component does not inline it (a `gated-page`
|
|
262
|
+
warning names the importer). Invalid frontmatter fails the run rather than
|
|
263
|
+
importing the page. Each page gets a
|
|
264
|
+
`gated-page` warning, plus a summary; `create-thally-docs` prints these last
|
|
265
|
+
under an "ACCESS-RESTRICTED CONTENT" heading and the report records them and a
|
|
266
|
+
`quarantined` count. Links from other pages to a withheld page are left as
|
|
267
|
+
authored and will fail `thally check`; images and other assets used only by
|
|
268
|
+
gated pages are still copied to `public/`. Mintlify's site-wide authentication mode lives in its
|
|
269
|
+
dashboard and cannot be read from a repository, so when any page sets
|
|
270
|
+
`public: true` (which implies the source site required sign-in for everything
|
|
271
|
+
else) one `gated-page` warning says Thally will publish every imported page.
|
|
272
|
+
Restricted-container `groups` and `public: false` are honored fail-closed even
|
|
273
|
+
though Mintlify documents only `"public": true` on a group.
|
|
274
|
+
|
|
275
|
+
### Site-wide scripts, styles, fonts, and settings
|
|
276
|
+
|
|
277
|
+
Mintlify serves every `.css` and `.js` file in the content directory on every
|
|
278
|
+
page. Those files are copied to `public/` (tooling config such as
|
|
279
|
+
`*.config.js`, `tailwind.*`, `postcss.*`, plus `dist`/`build`/`coverage`
|
|
280
|
+
output, dot-directories, and `node_modules` are not) under the normal asset
|
|
281
|
+
size limits. Scripts are added to `docs.json` `customScripts` (URL-encoded),
|
|
282
|
+
except modules that pages import as components, which are copied as components
|
|
283
|
+
instead. Thally cannot
|
|
284
|
+
load a stylesheet from `docs.json`, so each `.css` is preserved with a warning
|
|
285
|
+
that it is not applied and likely targets Mintlify's DOM. Fonts named by
|
|
286
|
+
`fonts.source` (top level, `heading`, `body`) that are local `.woff`, `.woff2`,
|
|
287
|
+
`.ttf`, or `.otf` files are copied; Thally's `fonts` setting loads Google Fonts
|
|
288
|
+
by family only, so a warning says the file is not applied. Remote font URLs
|
|
289
|
+
are not downloaded, and unsafe or missing paths are warned about.
|
|
290
|
+
|
|
291
|
+
Legacy `mint.json` `topbarLinks` and `topbarCtaButton` (including
|
|
292
|
+
`type: github`) map to `navbar.links` and `navbar.primary`; `docs.json`
|
|
293
|
+
`navbar` fields win, with a warning. `appearance.default`, `appearance.strict`
|
|
294
|
+
(`showToggle: false`), and legacy `modeToggle.default` / `isHidden` map to
|
|
295
|
+
`appearance`; invalid values are skipped with a warning. Mintlify sources set
|
|
296
|
+
`markdown.enabled: true`, matching Mintlify's default Markdown mirrors.
|
|
297
|
+
|
|
232
298
|
## Branding
|
|
233
299
|
|
|
234
300
|
A source site's logo, favicon, and theme accent color(s) are extracted where
|
|
@@ -245,18 +311,21 @@ dashboard's branding settings instead of leaving the loss silent.
|
|
|
245
311
|
|
|
246
312
|
`cloneGitHubRepository` retries a transient network-class failure with
|
|
247
313
|
backoff, and each underlying git process (the clone, and any submodule
|
|
248
|
-
fetch) is killed and treated as a retryable failure if it stalls
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
314
|
+
fetch) is killed and treated as a retryable failure if it stalls, meaning
|
|
315
|
+
git prints no progress for 2 minutes (a large repository that is still
|
|
316
|
+
downloading is never cut off; an hour is the absolute ceiling for one git
|
|
317
|
+
process). The allowed silence is configurable via
|
|
318
|
+
`THALLY_MIGRATE_CLONE_TIMEOUT_MS` (milliseconds) for an unusually slow link.
|
|
319
|
+
The clone neutralizes the `filter.lfs.*`
|
|
252
320
|
smudge/clean/process filter driver for that one process only (via
|
|
253
321
|
`GIT_CONFIG_COUNT`/`GIT_CONFIG_KEY_n`/`GIT_CONFIG_VALUE_n`, never the user's
|
|
254
322
|
global git config), so a repository that uses Git LFS still clones even when
|
|
255
323
|
the host has no `git-lfs` binary installed — including a host where
|
|
256
324
|
`filter.lfs.*` is still registered globally from a previous install,
|
|
257
325
|
pointing at a command that no longer exists; an asset that's still a Git
|
|
258
|
-
LFS pointer file afterward (not its real content) is skipped
|
|
259
|
-
instead of
|
|
326
|
+
LFS pointer file afterward (not its real content) is skipped, and one
|
|
327
|
+
warning lists those files, instead of copying them as if they were the real
|
|
328
|
+
files. Submodules are
|
|
260
329
|
initialized one at a time, best-effort,
|
|
261
330
|
after a successful clone — a submodule that can't be fetched (private,
|
|
262
331
|
deleted, network trouble) is named in a warning instead of failing the
|
package/dist/index.d.ts
CHANGED
|
@@ -113,6 +113,10 @@ interface MigrationDocsConfig {
|
|
|
113
113
|
feedback?: {
|
|
114
114
|
thumbsRating?: boolean;
|
|
115
115
|
};
|
|
116
|
+
customScripts?: Array<{
|
|
117
|
+
src: string;
|
|
118
|
+
strategy?: 'beforeInteractive' | 'afterInteractive' | 'lazyOnload';
|
|
119
|
+
}>;
|
|
116
120
|
ai?: {
|
|
117
121
|
chat?: boolean;
|
|
118
122
|
label?: string;
|
|
@@ -163,12 +167,16 @@ interface MigrationPage {
|
|
|
163
167
|
frontmatterError?: string;
|
|
164
168
|
}
|
|
165
169
|
interface MigrationAsset {
|
|
166
|
-
/** Path below `public
|
|
170
|
+
/** Path below `public` (or below the project root when `projectRelative`), always normalized and traversal-free. */
|
|
167
171
|
path: string;
|
|
168
172
|
content: Uint8Array;
|
|
173
|
+
/** Write at the project root instead of `public/`, so the host never serves it statically. */
|
|
174
|
+
projectRelative?: boolean;
|
|
169
175
|
}
|
|
170
176
|
interface MigrationWarning {
|
|
171
|
-
code: 'collision' | 'invalid-page' | 'missing-page' | 'unsupported-config' | 'limit-reached' | 'fetch-failed' | 'skipped-file'
|
|
177
|
+
code: 'collision' | 'invalid-page' | 'missing-page' | 'unsupported-config' | 'limit-reached' | 'fetch-failed' | 'skipped-file'
|
|
178
|
+
/** Access-restricted source page withheld from the published site (or a site-wide auth risk). */
|
|
179
|
+
| 'gated-page';
|
|
172
180
|
message: string;
|
|
173
181
|
source?: string;
|
|
174
182
|
}
|
|
@@ -182,9 +190,16 @@ interface MigrationBundle {
|
|
|
182
190
|
remoteApiSpecs?: Array<{
|
|
183
191
|
url: string;
|
|
184
192
|
tabLabel?: string;
|
|
193
|
+
parentTab?: string;
|
|
194
|
+
icon?: string;
|
|
195
|
+
hidden?: boolean;
|
|
185
196
|
}>;
|
|
186
197
|
/** Customer-owned component source and registry; paths are repository-relative. */
|
|
187
198
|
componentFiles?: Array<RenderedMigrationFile>;
|
|
199
|
+
/** Access-restricted source pages, written outside every published path. */
|
|
200
|
+
quarantinedFiles?: Array<RenderedMigrationFile>;
|
|
201
|
+
/** Access-restricted pages the file limit dropped: neither published nor saved in quarantinedFiles. */
|
|
202
|
+
droppedGatedPages?: number;
|
|
188
203
|
docsConfig: MigrationDocsConfig;
|
|
189
204
|
site?: {
|
|
190
205
|
name?: string;
|
|
@@ -260,6 +275,8 @@ interface RepositoryMigrationOptions {
|
|
|
260
275
|
docusaurusSidebarPath?: string;
|
|
261
276
|
/** @internal Static assets are shared across docs-plugin instances. */
|
|
262
277
|
docusaurusSkipAssets?: boolean;
|
|
278
|
+
/** @internal Test seam: lowers the 5,000-file budget so budget behaviour can be exercised with small fixtures. */
|
|
279
|
+
maxSourceFiles?: number;
|
|
263
280
|
/** @internal Redirects are global config, read once, not per plugin instance. */
|
|
264
281
|
docusaurusSkipRedirects?: boolean;
|
|
265
282
|
}
|
|
@@ -298,9 +315,16 @@ interface MintlifyPageReference {
|
|
|
298
315
|
navigationId: string;
|
|
299
316
|
locale?: string;
|
|
300
317
|
}
|
|
318
|
+
/** A page listed under an access-restricted navigation container. */
|
|
319
|
+
interface MintlifyGatedReference {
|
|
320
|
+
ref: string;
|
|
321
|
+
reason: string;
|
|
322
|
+
}
|
|
301
323
|
interface MintlifyNavigationResult {
|
|
302
324
|
docsConfig: MigrationDocsConfig;
|
|
303
325
|
pageReferences: Array<MintlifyPageReference>;
|
|
326
|
+
/** Pages under a restricted container; withheld from `docsConfig` and `pageReferences`. */
|
|
327
|
+
gatedReferences: Array<MintlifyGatedReference>;
|
|
304
328
|
warnings: Array<MigrationWarning>;
|
|
305
329
|
}
|
|
306
330
|
interface MintlifyProjectionOptions {
|