Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tasty-rockets-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'gtx-cli': patch
---

Wrapping text node URLs for Mintlify MDX to align with their parser
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ describe('aggregateFiles - Empty File Handling', () => {
placeholderPaths: {},
},
defaultLocale: 'en',
framework: 'mintlify',
options: {
mintlify: {
inferTitleFromFilename: true,
Expand All @@ -312,6 +313,7 @@ describe('aggregateFiles - Empty File Handling', () => {
placeholderPaths: {},
},
defaultLocale: 'en',
framework: 'mintlify',
options: {
mintlify: {
inferTitleFromFilename: true,
Expand Down Expand Up @@ -343,6 +345,7 @@ describe('aggregateFiles - Empty File Handling', () => {
placeholderPaths: {},
},
defaultLocale: 'en',
framework: 'mintlify',
options: {
mintlify: {
inferTitleFromFilename: true,
Expand All @@ -369,6 +372,7 @@ describe('aggregateFiles - Empty File Handling', () => {
placeholderPaths: {},
},
defaultLocale: 'es',
framework: 'mintlify',
options: {
mintlify: {
inferTitleFromFilename: true,
Expand Down
51 changes: 13 additions & 38 deletions packages/cli/src/formats/files/aggregateFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ import { getRelative, readFile } from '../../fs/findFilepath.js';
import { Settings } from '../../types/index.js';
import type { FileFormat, DataFormat, FileToUpload } from '../../types/data.js';
import { SUPPORTED_FILE_EXTENSIONS } from './supportedFiles.js';
import sanitizeFileContent from '../../utils/sanitizeFileContent.js';
import { parseJson } from '../json/parseJson.js';
import parseYaml from '../yaml/parseYaml.js';
import YAML from 'yaml';
import { determineLibrary } from '../../fs/determineFramework.js';
import { isValidMdx } from '../../utils/validateMdx.js';
import { hashStringSync } from '../../utils/hash.js';
import { applyMintlifyTitleFallback } from '../../utils/mintlifyTitleFallback.js';
import { preprocessContent } from './preprocessContent.js';
export const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];

export async function aggregateFiles(
Expand Down Expand Up @@ -159,48 +157,25 @@ export async function aggregateFiles(
const content = readFile(filePath);
const relativePath = getRelative(filePath);

if (fileType === 'mdx') {
if (!skipValidation?.mdx) {
const validation = isValidMdx(content, filePath);
if (!validation.isValid) {
logger.warn(
`Skipping ${relativePath}: MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`
);
recordWarning(
'skipped_file',
relativePath,
`MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`
);
return null;
}
}
}
const processed = preprocessContent(
content,
relativePath,
fileType,
settings
);

let processedContent = content;
let addedMintlifyTitle = false;
if (
fileType === 'mdx' &&
settings.options?.mintlify?.inferTitleFromFilename
) {
const result = applyMintlifyTitleFallback(
processedContent,
relativePath,
settings.defaultLocale
);
processedContent = result.content;
addedMintlifyTitle = result.addedTitle;
if (typeof processed !== 'string') {
logger.warn(`Skipping ${relativePath}: ${processed.skip}`);
recordWarning('skipped_file', relativePath, processed.skip);
return null;
}

const sanitizedContent = sanitizeFileContent(processedContent);
// Always hash original content for versionId
const computedVersionId = hashStringSync(content);

return {
content: sanitizedContent,
content: processed,
fileName: relativePath,
fileFormat: fileType.toUpperCase() as FileFormat,
fileId: hashStringSync(relativePath),
versionId: computedVersionId,
versionId: hashStringSync(content),
locale: settings.defaultLocale,
} satisfies FileToUpload;
})
Expand Down
20 changes: 20 additions & 0 deletions packages/cli/src/formats/files/preprocess/mdx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Settings } from '../../../types/index.js';
import { isValidMdx } from '../../../utils/validateMdx.js';

/**
* Runs MDX-specific preprocessing. Returns a skip reason if the file
* should be skipped, or null if validation passed.
*/
export function preprocessMdx(
content: string,
filePath: string,
settings: Settings
): string | null {
if (!settings.options?.skipFileValidation?.mdx) {
const validation = isValidMdx(content, filePath);
if (!validation.isValid) {
return `MDX file is not AST parsable${validation.error ? `: ${validation.error}` : ''}`;
}
}
return null;
}
29 changes: 29 additions & 0 deletions packages/cli/src/formats/files/preprocess/mintlify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Settings } from '../../../types/index.js';
import { applyMintlifyTitleFallback } from '../../../utils/mintlifyTitleFallback.js';
import wrapPlainUrls from '../../../utils/wrapPlainUrls.js';

/**
* Runs all Mintlify-specific preprocessing on file content.
*/
export function preprocessMintlify(
content: string,
filePath: string,
fileType: string,
settings: Settings
): string {
if (fileType !== 'mdx') return content;

let result = content;

if (settings.options?.mintlify?.inferTitleFromFilename) {
result = applyMintlifyTitleFallback(
result,
filePath,
settings.defaultLocale
).content;
}

result = wrapPlainUrls(result);

return result;
}
33 changes: 33 additions & 0 deletions packages/cli/src/formats/files/preprocessContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Settings } from '../../types/index.js';
import { preprocessMdx } from './preprocess/mdx.js';
import { preprocessMintlify } from './preprocess/mintlify.js';
import sanitizeFileContent from '../../utils/sanitizeFileContent.js';

/**
* Preprocesses file content before upload. Returns the processed content,
* or { skip: reason } if the file should be skipped.
*/
export function preprocessContent(
content: string,
filePath: string,
fileType: string,
settings: Settings
): string | { skip: string } {
let result = content;

// File-type-specific
if (fileType === 'mdx') {
const skipReason = preprocessMdx(result, filePath, settings);
if (skipReason) return { skip: skipReason };
}

// Framework-specific
if (settings.framework === 'mintlify') {
result = preprocessMintlify(result, filePath, fileType, settings);
}

// Universal
result = sanitizeFileContent(result);

return result;
}
2 changes: 1 addition & 1 deletion packages/cli/src/generated/version.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// This file is auto-generated. Do not edit manually.
export const PACKAGE_VERSION = '2.6.27';
export const PACKAGE_VERSION = '2.6.29';
Loading
Loading