@thallylabs/migrate 0.2.44 → 0.2.45
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/dist/index.d.ts +0 -1
- package/dist/index.js +192 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -118,7 +118,6 @@ declare function detectRepositoryPlatform(repositoryDir: string, docsDir?: strin
|
|
|
118
118
|
declare function detectRepositoryDocsDir(repositoryDir: string): string;
|
|
119
119
|
/** Enumerate generated endpoint routes using the same spec visibility, tab ids and slugs as migration linking. */
|
|
120
120
|
declare function migrationApiRoutes(bundle: Pick<MigrationBundle, 'docsConfig' | 'assets'>): Array<string>;
|
|
121
|
-
/** Import an already-available repository directory into a canonical bundle. */
|
|
122
121
|
declare function migrateRepository(options: RepositoryMigrationOptions): MigrationBundle;
|
|
123
122
|
|
|
124
123
|
/**
|
package/dist/index.js
CHANGED
|
@@ -8217,7 +8217,122 @@ function propertyStart(source, name) {
|
|
|
8217
8217
|
}
|
|
8218
8218
|
return -1;
|
|
8219
8219
|
}
|
|
8220
|
-
function
|
|
8220
|
+
function staticModulePath(repositoryRoot, specifier) {
|
|
8221
|
+
if (!specifier.startsWith(".")) return null;
|
|
8222
|
+
try {
|
|
8223
|
+
const relativePath = specifier.replace(/^\.\/+/, "");
|
|
8224
|
+
return ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".json"].map((extension) => withinRealRoot(resolveWithin(repositoryRoot, `${relativePath}${extension}`), repositoryRoot)).find((candidate) => existsSync4(candidate) && lstatSync4(candidate).isFile()) ?? null;
|
|
8225
|
+
} catch {
|
|
8226
|
+
return null;
|
|
8227
|
+
}
|
|
8228
|
+
}
|
|
8229
|
+
function staticObjectStrings(objectText) {
|
|
8230
|
+
const fields = /* @__PURE__ */ new Map();
|
|
8231
|
+
try {
|
|
8232
|
+
const parsed = JSON5.parse(objectText);
|
|
8233
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fields;
|
|
8234
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
8235
|
+
if (typeof value === "string") fields.set(key, value);
|
|
8236
|
+
}
|
|
8237
|
+
} catch {
|
|
8238
|
+
return fields;
|
|
8239
|
+
}
|
|
8240
|
+
return fields;
|
|
8241
|
+
}
|
|
8242
|
+
function defaultExportObjectLiteralText(source) {
|
|
8243
|
+
const exported = /\bexport\s+default\s+/.exec(source);
|
|
8244
|
+
if (!exported) return null;
|
|
8245
|
+
const start = exported.index + exported[0].length;
|
|
8246
|
+
const literal = matchingObjectLiteral(source, start);
|
|
8247
|
+
if (literal) return literal;
|
|
8248
|
+
const identifier = source.slice(start).match(/^([A-Za-z_$][\w$]*)/)?.[1];
|
|
8249
|
+
if (!identifier) return null;
|
|
8250
|
+
const declaration = new RegExp(
|
|
8251
|
+
`\\b(?:const|let|var)\\s+${identifier}\\b(?:\\s*:\\s*[^=;]+)?\\s*=\\s*`
|
|
8252
|
+
).exec(source);
|
|
8253
|
+
return declaration ? matchingObjectLiteral(source, declaration.index + declaration[0].length) : null;
|
|
8254
|
+
}
|
|
8255
|
+
function namedExportStringText(source, name) {
|
|
8256
|
+
const match = new RegExp(
|
|
8257
|
+
`\\bexport\\s+(?:const|let|var)\\s+${name}\\b(?:\\s*:\\s*[^=;]+)?\\s*=\\s*`
|
|
8258
|
+
).exec(source);
|
|
8259
|
+
if (!match) return void 0;
|
|
8260
|
+
const quoted = source.slice(match.index + match[0].length).match(/^("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/);
|
|
8261
|
+
if (!quoted) return void 0;
|
|
8262
|
+
try {
|
|
8263
|
+
const parsed = JSON5.parse(quoted[1]);
|
|
8264
|
+
return typeof parsed === "string" ? parsed : void 0;
|
|
8265
|
+
} catch {
|
|
8266
|
+
return void 0;
|
|
8267
|
+
}
|
|
8268
|
+
}
|
|
8269
|
+
function staticImportBindings(source, repositoryRoot) {
|
|
8270
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
8271
|
+
const addObject = (local, specifier, exported) => {
|
|
8272
|
+
const modulePath = staticModulePath(repositoryRoot, specifier);
|
|
8273
|
+
if (!modulePath) return;
|
|
8274
|
+
const moduleSource = readBoundedText(modulePath);
|
|
8275
|
+
const objectText = extname5(modulePath).toLowerCase() === ".json" ? moduleSource : exported === "default" ? defaultExportObjectLiteralText(moduleSource) : namedExportObjectLiteralText(moduleSource, exported);
|
|
8276
|
+
if (!objectText) return;
|
|
8277
|
+
for (const [key, value] of staticObjectStrings(objectText)) {
|
|
8278
|
+
bindings.set(`${local}.${key}`, value);
|
|
8279
|
+
}
|
|
8280
|
+
};
|
|
8281
|
+
const addString = (local, specifier, exported) => {
|
|
8282
|
+
const modulePath = staticModulePath(repositoryRoot, specifier);
|
|
8283
|
+
if (!modulePath || extname5(modulePath).toLowerCase() === ".json") return;
|
|
8284
|
+
const value = namedExportStringText(readBoundedText(modulePath), exported);
|
|
8285
|
+
if (value !== void 0) bindings.set(local, value);
|
|
8286
|
+
};
|
|
8287
|
+
const addNamespace = (local, specifier) => {
|
|
8288
|
+
const modulePath = staticModulePath(repositoryRoot, specifier);
|
|
8289
|
+
if (!modulePath) return;
|
|
8290
|
+
const moduleSource = readBoundedText(modulePath);
|
|
8291
|
+
if (extname5(modulePath).toLowerCase() === ".json") {
|
|
8292
|
+
for (const [key, value] of staticObjectStrings(moduleSource)) {
|
|
8293
|
+
bindings.set(`${local}.${key}`, value);
|
|
8294
|
+
}
|
|
8295
|
+
return;
|
|
8296
|
+
}
|
|
8297
|
+
const defaultText = defaultExportObjectLiteralText(moduleSource);
|
|
8298
|
+
if (defaultText) {
|
|
8299
|
+
for (const [key, value] of staticObjectStrings(defaultText)) {
|
|
8300
|
+
bindings.set(`${local}.default.${key}`, value);
|
|
8301
|
+
}
|
|
8302
|
+
}
|
|
8303
|
+
for (const match of moduleSource.matchAll(/\bexport\s+(?:const|let|var)\s+([A-Za-z_$][\w$]*)\b/g)) {
|
|
8304
|
+
const name = match[1];
|
|
8305
|
+
const value = namedExportStringText(moduleSource, name);
|
|
8306
|
+
if (value !== void 0) bindings.set(`${local}.${name}`, value);
|
|
8307
|
+
const objectText = namedExportObjectLiteralText(moduleSource, name);
|
|
8308
|
+
if (!objectText) continue;
|
|
8309
|
+
for (const [key, objectValue5] of staticObjectStrings(objectText)) {
|
|
8310
|
+
bindings.set(`${local}.${name}.${key}`, objectValue5);
|
|
8311
|
+
}
|
|
8312
|
+
}
|
|
8313
|
+
};
|
|
8314
|
+
for (const match of source.matchAll(
|
|
8315
|
+
/\bimport\s+([A-Za-z_$][\w$]*)\s*(?:,\s*\{[^}]*\})?\s+from\s*(['"])([^'"]+)\2/g
|
|
8316
|
+
)) {
|
|
8317
|
+
addObject(match[1], match[3], "default");
|
|
8318
|
+
}
|
|
8319
|
+
for (const match of source.matchAll(
|
|
8320
|
+
/\bimport\s+\*\s+as\s+([A-Za-z_$][\w$]*)\s+from\s*(['"])([^'"]+)\2/g
|
|
8321
|
+
)) {
|
|
8322
|
+
addNamespace(match[1], match[3]);
|
|
8323
|
+
}
|
|
8324
|
+
for (const match of source.matchAll(/\bimport\s*\{([^}]*)\}\s*from\s*(['"])([^'"]+)\2/g)) {
|
|
8325
|
+
for (const entry of match[1].split(",")) {
|
|
8326
|
+
const [imported, alias] = entry.split(/\s+as\s+/).map((part) => part.trim());
|
|
8327
|
+
if (!imported || !/^[A-Za-z_$][\w$]*$/.test(imported)) continue;
|
|
8328
|
+
const local = alias && /^[A-Za-z_$][\w$]*$/.test(alias) ? alias : imported;
|
|
8329
|
+
addObject(local, match[3], imported);
|
|
8330
|
+
addString(local, match[3], imported);
|
|
8331
|
+
}
|
|
8332
|
+
}
|
|
8333
|
+
return bindings;
|
|
8334
|
+
}
|
|
8335
|
+
function staticStringBindings(source, repositoryRoot) {
|
|
8221
8336
|
const bindings = /* @__PURE__ */ new Map();
|
|
8222
8337
|
for (const match of source.matchAll(/\bconst\s+([A-Z][A-Z0-9_]*)\s*=\s*((?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'))/g)) {
|
|
8223
8338
|
try {
|
|
@@ -8226,6 +8341,11 @@ function staticStringBindings(source) {
|
|
|
8226
8341
|
} catch {
|
|
8227
8342
|
}
|
|
8228
8343
|
}
|
|
8344
|
+
if (repositoryRoot) {
|
|
8345
|
+
for (const [reference, value] of staticImportBindings(source, repositoryRoot)) {
|
|
8346
|
+
bindings.set(reference, value);
|
|
8347
|
+
}
|
|
8348
|
+
}
|
|
8229
8349
|
return bindings;
|
|
8230
8350
|
}
|
|
8231
8351
|
function staticArrayField(source, name) {
|
|
@@ -8293,8 +8413,8 @@ function staticStringField(source, name, bindings) {
|
|
|
8293
8413
|
if (start < 0) return void 0;
|
|
8294
8414
|
const quoted = source.slice(start).match(/^("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')/);
|
|
8295
8415
|
if (!quoted) {
|
|
8296
|
-
const
|
|
8297
|
-
return
|
|
8416
|
+
const reference = source.slice(start).match(/^([A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*)/)?.[1];
|
|
8417
|
+
return reference ? bindings?.get(reference) : void 0;
|
|
8298
8418
|
}
|
|
8299
8419
|
try {
|
|
8300
8420
|
const parsed = JSON5.parse(quoted[1]);
|
|
@@ -8308,10 +8428,10 @@ function readDocusaurusSiteSettings(repositoryRoot) {
|
|
|
8308
8428
|
const configPath = findDocusaurusConfigPath(repositoryRoot);
|
|
8309
8429
|
if (!configPath) return empty2;
|
|
8310
8430
|
const source = readBoundedText(configPath);
|
|
8311
|
-
const bindings = staticStringBindings(source);
|
|
8431
|
+
const bindings = staticStringBindings(source, repositoryRoot);
|
|
8312
8432
|
const presets = staticArrayField(source, "presets");
|
|
8313
8433
|
const classicDocs = presets && [...presets.matchAll(/["']?docs["']?\s*:\s*/g)].map((match) => matchingObjectLiteral(presets, (match.index ?? 0) + match[0].length)).find((object3) => Boolean(object3));
|
|
8314
|
-
const docsRouteBasePath = classicDocs && staticStringField(classicDocs, "routeBasePath") || "docs";
|
|
8434
|
+
const docsRouteBasePath = classicDocs && staticStringField(classicDocs, "routeBasePath", bindings) || "docs";
|
|
8315
8435
|
const themeStart = propertyStart(source, "themeConfig");
|
|
8316
8436
|
const theme = themeStart < 0 ? null : matchingObjectLiteral(source, themeStart);
|
|
8317
8437
|
const colorModeStart = theme ? propertyStart(theme, "colorMode") : -1;
|
|
@@ -8354,21 +8474,29 @@ function readDocusaurusSiteSettings(repositoryRoot) {
|
|
|
8354
8474
|
const announcement = announcementStart < 0 ? null : matchingObjectLiteral(theme, announcementStart);
|
|
8355
8475
|
const announcementContent = announcement && staticStringField(announcement, "content") || announcement?.slice(propertyStart(announcement, "content")).match(/^`([^`]+)`/)?.[1];
|
|
8356
8476
|
const bannerContent = announcementContent ? announcementMarkdown(announcementContent) : "";
|
|
8477
|
+
const name = staticStringField(source, "title", bindings);
|
|
8478
|
+
const description = staticStringField(source, "tagline", bindings);
|
|
8479
|
+
const navbarTitle = navbar ? staticStringField(navbar, "title", bindings) : void 0;
|
|
8480
|
+
const unresolvedIdentity = [];
|
|
8481
|
+
if (!name && propertyStart(source, "title") >= 0) unresolvedIdentity.push("title");
|
|
8482
|
+
if (!description && propertyStart(source, "tagline") >= 0) unresolvedIdentity.push("tagline");
|
|
8483
|
+
if (!navbarTitle && navbar && propertyStart(navbar, "title") >= 0) unresolvedIdentity.push("navbarTitle");
|
|
8357
8484
|
return {
|
|
8358
8485
|
...bannerContent ? { banner: { content: bannerContent, dismissible: !/isCloseable\s*:\s*false/.test(announcement), ...staticStringField(announcement, "id") ? { id: staticStringField(announcement, "id") } : {} } } : {},
|
|
8359
|
-
name:
|
|
8360
|
-
description:
|
|
8361
|
-
...
|
|
8486
|
+
...name ? { name } : {},
|
|
8487
|
+
...description ? { description } : {},
|
|
8488
|
+
...navbarTitle ? { navbarTitle } : {},
|
|
8489
|
+
...unresolvedIdentity.length > 0 ? { unresolvedIdentity } : {},
|
|
8362
8490
|
defaultColorMode,
|
|
8363
8491
|
docsRouteBasePath,
|
|
8364
|
-
...logo && staticStringField(logo, "src") ? {
|
|
8492
|
+
...logo && staticStringField(logo, "src", bindings) ? {
|
|
8365
8493
|
logo: {
|
|
8366
|
-
light: staticStringField(logo, "src"),
|
|
8367
|
-
...staticStringField(logo, "srcDark") ? { dark: staticStringField(logo, "srcDark") } : {},
|
|
8368
|
-
showTitle: Boolean(
|
|
8494
|
+
light: staticStringField(logo, "src", bindings),
|
|
8495
|
+
...staticStringField(logo, "srcDark", bindings) ? { dark: staticStringField(logo, "srcDark", bindings) } : {},
|
|
8496
|
+
showTitle: Boolean(navbarTitle)
|
|
8369
8497
|
}
|
|
8370
8498
|
} : {},
|
|
8371
|
-
...staticStringField(source, "favicon") ? { favicon: staticStringField(source, "favicon") } : {},
|
|
8499
|
+
...staticStringField(source, "favicon", bindings) ? { favicon: staticStringField(source, "favicon", bindings) } : {},
|
|
8372
8500
|
navbarLinks,
|
|
8373
8501
|
footerLinks,
|
|
8374
8502
|
...copyright ? { copyright } : {}
|
|
@@ -15838,6 +15966,46 @@ function componentSourceIdentity(sourceUrl, repositoryDir, siteRoot, namespace)
|
|
|
15838
15966
|
const docsRoot = relative6(repositoryDir, siteRoot).replace(/\\/g, "/");
|
|
15839
15967
|
return JSON.stringify(namespace ? [repository, docsRoot, namespace] : [repository, docsRoot]);
|
|
15840
15968
|
}
|
|
15969
|
+
function sourcePackageName(repositoryDir) {
|
|
15970
|
+
try {
|
|
15971
|
+
const path = withinRealRoot(resolveWithin(repositoryDir, "package.json"), repositoryDir);
|
|
15972
|
+
const metadata = lstatSync6(path);
|
|
15973
|
+
if (!metadata.isFile() || metadata.size > MAX_PAGE_BYTES) return void 0;
|
|
15974
|
+
const parsed = JSON.parse(readFileSync6(path, "utf8"));
|
|
15975
|
+
if (typeof parsed.name !== "string") return void 0;
|
|
15976
|
+
return parsed.name.split("/").pop()?.trim() || void 0;
|
|
15977
|
+
} catch {
|
|
15978
|
+
return void 0;
|
|
15979
|
+
}
|
|
15980
|
+
}
|
|
15981
|
+
function docusaurusProjectName(settings, repositoryDir, sourceUrl) {
|
|
15982
|
+
const configured = settings.navbarTitle ?? settings.name;
|
|
15983
|
+
if (configured) return { name: configured };
|
|
15984
|
+
const packageName = sourcePackageName(repositoryDir);
|
|
15985
|
+
if (packageName) return { name: packageName, origin: "the source package.json name" };
|
|
15986
|
+
const sourceName = (() => {
|
|
15987
|
+
try {
|
|
15988
|
+
const segment = new URL(sourceUrl).pathname.split("/").filter(Boolean).pop();
|
|
15989
|
+
return segment ? decodeURIComponent(segment).replace(/\.git$/i, "") : void 0;
|
|
15990
|
+
} catch {
|
|
15991
|
+
return void 0;
|
|
15992
|
+
}
|
|
15993
|
+
})();
|
|
15994
|
+
if (sourceName) return { name: sourceName, origin: "the source repository name" };
|
|
15995
|
+
const sourceHost = (() => {
|
|
15996
|
+
try {
|
|
15997
|
+
return new URL(sourceUrl).hostname || void 0;
|
|
15998
|
+
} catch {
|
|
15999
|
+
return void 0;
|
|
16000
|
+
}
|
|
16001
|
+
})();
|
|
16002
|
+
return sourceHost ? { name: sourceHost, origin: "the source host" } : void 0;
|
|
16003
|
+
}
|
|
16004
|
+
var DOCUSAURUS_IDENTITY_LABELS = {
|
|
16005
|
+
title: "site title",
|
|
16006
|
+
tagline: "site tagline",
|
|
16007
|
+
navbarTitle: "navbar title"
|
|
16008
|
+
};
|
|
15841
16009
|
function migrateRepository(options) {
|
|
15842
16010
|
const repositoryDir = options.repositoryDir;
|
|
15843
16011
|
const platform = options.platform ?? detectRepositoryPlatform(repositoryDir, options.docsDir);
|
|
@@ -17506,7 +17674,16 @@ ${reasons.map((reason) => `- ${reason}`).join("\n")}` : "No importable Markdown
|
|
|
17506
17674
|
const isTopLevelDocusaurus = platform === "docusaurus" && docusaurusProjectRoot && !options.docusaurusSkipRedirects;
|
|
17507
17675
|
const docusaurusSettings = isTopLevelDocusaurus ? readDocusaurusSiteSettings(docusaurusProjectRoot) : void 0;
|
|
17508
17676
|
const presentation = docusaurusSettings ? readDocusaurusPresentation(docusaurusProjectRoot) : void 0;
|
|
17677
|
+
const docusaurusIdentity = docusaurusSettings ? docusaurusProjectName(docusaurusSettings, repositoryDir, options.sourceUrl) : void 0;
|
|
17509
17678
|
if (docusaurusSettings) {
|
|
17679
|
+
for (const field of docusaurusSettings.unresolvedIdentity ?? []) {
|
|
17680
|
+
const namesTheProject = field === "title" || field === "navbarTitle";
|
|
17681
|
+
const fallback = namesTheProject && docusaurusIdentity?.origin ? ` The project name was taken from ${docusaurusIdentity.origin}.` : "";
|
|
17682
|
+
warnings.push({
|
|
17683
|
+
code: "unsupported-config",
|
|
17684
|
+
message: `The Docusaurus ${DOCUSAURUS_IDENTITY_LABELS[field]} could not be read without running the config and was left out of the migration.${fallback} Use a string literal, or plain data in an imported module, to import it.`
|
|
17685
|
+
});
|
|
17686
|
+
}
|
|
17510
17687
|
if (presentation) {
|
|
17511
17688
|
assets.push({ path: "_thally/source-theme.css", content: Buffer.from(presentation.css) });
|
|
17512
17689
|
docsConfig = { ...docsConfig, stylesheets: [...docsConfig.stylesheets ?? [], "/_thally/source-theme.css"], ...presentation.headingFont ? { fonts: { ...docsConfig.fonts, heading: { family: presentation.headingFont, weight: ["400", "500", "600", "700"] } } } : {} };
|
|
@@ -17753,9 +17930,9 @@ ${reasons.map((reason) => `- ${reason}`).join("\n")}` : "No importable Markdown
|
|
|
17753
17930
|
...typeof fernRawConfig.title === "string" ? { name: fernRawConfig.title } : {},
|
|
17754
17931
|
...themeColors ? { colors: themeColors } : {}
|
|
17755
17932
|
}
|
|
17756
|
-
} : docusaurusSettings && (
|
|
17933
|
+
} : docusaurusSettings && (docusaurusIdentity?.name || docusaurusSettings.description || themeColors) ? {
|
|
17757
17934
|
site: {
|
|
17758
|
-
...
|
|
17935
|
+
...docusaurusIdentity?.name ? { name: docusaurusIdentity.name } : {},
|
|
17759
17936
|
...docusaurusSettings.description ? { description: docusaurusSettings.description } : {},
|
|
17760
17937
|
...themeColors ? { colors: themeColors } : {}
|
|
17761
17938
|
}
|