@thallylabs/migrate 0.2.11 → 0.2.14

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
@@ -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. Remote `http://` and
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 `public/`, then set the API source
24
- in `docs.json` to that local path. Missing local specs also produce warnings
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 and are warned about one by one.
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
@@ -167,6 +183,23 @@ the callback cannot be moved safely, it keeps the page and the control's child
167
183
  content as a passive fallback, with a warning identifying the control. A
168
184
  stateful local snippet component is kept as a client component instead of
169
185
  flattening away its hooks and state.
186
+ A component a page declares itself (`export const Counter = () => ...`) that
187
+ calls a React hook is moved into its own `'use client'` module, together with
188
+ every page-local component, helper and constant it uses (a sibling it renders,
189
+ a dependency that is itself stateful, a value only reached through a prop),
190
+ in source order and under their original names. The imports that moved code
191
+ needs move with it. What the page still renders stays reachable: a server-safe
192
+ dependency the page also uses is kept in the page and copied, while a
193
+ client-only one is imported from the module. A page-local name always wins
194
+ over a same-named built-in. If any dependency cannot run in a client module
195
+ (server-only APIs such as `process` or `await`, an undeclared name, a package
196
+ the migration removed, a dynamic `import()`), the component is left where it
197
+ is and a warning names it and the blocker.
198
+ `<Snippet file="...">` accepts the documented `snippets/`-relative path as well
199
+ as a `/snippets/...` or page-relative one. An outer code fence that contains a
200
+ same-length nested fence is widened so the inner fence no longer closes it, and
201
+ a bare placeholder tag in prose (`<Feature> requires a plan`) that would stop
202
+ the page compiling is escaped as text rather than losing the page.
170
203
  The Mintlify `search-bar-entry` click trigger is mapped to Thally's search
171
204
  shortcut. Markdown mixed inside interactive JSX, computed imports, and
172
205
  namespace imports are reported for manual review; unsupported source is
@@ -228,18 +261,21 @@ dashboard's branding settings instead of leaving the loss silent.
228
261
 
229
262
  `cloneGitHubRepository` retries a transient network-class failure with
230
263
  backoff, and each underlying git process (the clone, and any submodule
231
- fetch) is killed and treated as a retryable failure if it stalls — a
232
- generous 10-minute default, configurable via
233
- `THALLY_MIGRATE_CLONE_TIMEOUT_MS` (milliseconds) for an unusually large
234
- repository on a slow link. The clone neutralizes the `filter.lfs.*`
264
+ fetch) is killed and treated as a retryable failure if it stalls, meaning
265
+ git prints no progress for 2 minutes (a large repository that is still
266
+ downloading is never cut off; an hour is the absolute ceiling for one git
267
+ process). The allowed silence is configurable via
268
+ `THALLY_MIGRATE_CLONE_TIMEOUT_MS` (milliseconds) for an unusually slow link.
269
+ The clone neutralizes the `filter.lfs.*`
235
270
  smudge/clean/process filter driver for that one process only (via
236
271
  `GIT_CONFIG_COUNT`/`GIT_CONFIG_KEY_n`/`GIT_CONFIG_VALUE_n`, never the user's
237
272
  global git config), so a repository that uses Git LFS still clones even when
238
273
  the host has no `git-lfs` binary installed — including a host where
239
274
  `filter.lfs.*` is still registered globally from a previous install,
240
275
  pointing at a command that no longer exists; an asset that's still a Git
241
- LFS pointer file afterward (not its real content) is skipped with a warning
242
- instead of being copied as if it were the real file. Submodules are
276
+ LFS pointer file afterward (not its real content) is skipped, and one
277
+ warning lists those files, instead of copying them as if they were the real
278
+ files. Submodules are
243
279
  initialized one at a time, best-effort,
244
280
  after a successful clone — a submodule that can't be fetched (private,
245
281
  deleted, network trouble) is named in a warning instead of failing the
package/dist/index.d.ts CHANGED
@@ -163,9 +163,11 @@ interface MigrationPage {
163
163
  frontmatterError?: string;
164
164
  }
165
165
  interface MigrationAsset {
166
- /** Path below `public`, always normalized and traversal-free. */
166
+ /** Path below `public` (or below the project root when `projectRelative`), always normalized and traversal-free. */
167
167
  path: string;
168
168
  content: Uint8Array;
169
+ /** Write at the project root instead of `public/`, so the host never serves it statically. */
170
+ projectRelative?: boolean;
169
171
  }
170
172
  interface MigrationWarning {
171
173
  code: 'collision' | 'invalid-page' | 'missing-page' | 'unsupported-config' | 'limit-reached' | 'fetch-failed' | 'skipped-file';
@@ -182,6 +184,9 @@ interface MigrationBundle {
182
184
  remoteApiSpecs?: Array<{
183
185
  url: string;
184
186
  tabLabel?: string;
187
+ parentTab?: string;
188
+ icon?: string;
189
+ hidden?: boolean;
185
190
  }>;
186
191
  /** Customer-owned component source and registry; paths are repository-relative. */
187
192
  componentFiles?: Array<RenderedMigrationFile>;