gtx-cli 2.6.3 → 2.6.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # gtx-cli
2
2
 
3
+ ## 2.6.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#969](https://github.com/generaltranslation/gt/pull/969) [`0fef5cb`](https://github.com/generaltranslation/gt/commit/0fef5cb5266a0aa6ccdf2dc8778ee913eb145b5d) Thanks [@fernando-aviles](https://github.com/fernando-aviles)! - Add flag for Mintlify docs to infer title from source file name when missing title in YAML frontmatter
8
+
3
9
  ## 2.6.3
4
10
 
5
11
  ### Patch Changes
@@ -118,6 +118,11 @@ export async function generateSettings(flags, cwd = process.cwd()) {
118
118
  : { resolvedPaths: {}, placeholderPaths: {}, transformPaths: {} };
119
119
  mergedOptions.options = {
120
120
  ...(mergedOptions.options || {}),
121
+ mintlify: {
122
+ ...(mergedOptions.options?.mintlify || {}),
123
+ inferTitleFromFilename: gtConfig.options?.mintlify?.inferTitleFromFilename ||
124
+ mergedOptions.options?.mintlify?.inferTitleFromFilename,
125
+ },
121
126
  experimentalLocalizeStaticImports: gtConfig.options?.experimentalLocalizeStaticImports ||
122
127
  flags.experimentalLocalizeStaticImports,
123
128
  experimentalLocalizeStaticUrls: gtConfig.options?.experimentalLocalizeStaticUrls ||
@@ -8,6 +8,7 @@ import YAML from 'yaml';
8
8
  import { determineLibrary } from '../../fs/determineFramework.js';
9
9
  import { isValidMdx } from '../../utils/validateMdx.js';
10
10
  import { hashStringSync } from '../../utils/hash.js';
11
+ import { applyMintlifyTitleFallback } from '../../utils/mintlifyTitleFallback.js';
11
12
  export const SUPPORTED_DATA_FORMATS = ['JSX', 'ICU', 'I18NEXT'];
12
13
  export async function aggregateFiles(settings) {
13
14
  // Aggregate all files to translate
@@ -126,13 +127,21 @@ export async function aggregateFiles(settings) {
126
127
  }
127
128
  }
128
129
  }
129
- const sanitizedContent = sanitizeFileContent(content);
130
+ let processedContent = content;
131
+ let addedMintlifyTitle = false;
132
+ if (fileType === 'mdx' &&
133
+ settings.options?.mintlify?.inferTitleFromFilename) {
134
+ const result = applyMintlifyTitleFallback(processedContent, relativePath, settings.defaultLocale);
135
+ processedContent = result.content;
136
+ addedMintlifyTitle = result.addedTitle;
137
+ }
138
+ const sanitizedContent = sanitizeFileContent(processedContent);
130
139
  return {
131
140
  content: sanitizedContent,
132
141
  fileName: relativePath,
133
142
  fileFormat: fileType.toUpperCase(),
134
143
  fileId: hashStringSync(relativePath),
135
- versionId: hashStringSync(content),
144
+ versionId: hashStringSync(addedMintlifyTitle ? processedContent : content),
136
145
  locale: settings.defaultLocale,
137
146
  };
138
147
  })
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "2.6.3";
1
+ export declare const PACKAGE_VERSION = "2.6.4";
@@ -1,2 +1,2 @@
1
1
  // This file is auto-generated. Do not edit manually.
2
- export const PACKAGE_VERSION = '2.6.3';
2
+ export const PACKAGE_VERSION = '2.6.4';
@@ -36,6 +36,7 @@ export type OpenApiConfig = {
36
36
  };
37
37
  export type MintlifyOptions = {
38
38
  openapi?: OpenApiConfig;
39
+ inferTitleFromFilename?: boolean;
39
40
  };
40
41
  export type SharedFlags = {
41
42
  config?: string;
@@ -0,0 +1,6 @@
1
+ type TitleFallbackResult = {
2
+ content: string;
3
+ addedTitle: boolean;
4
+ };
5
+ export declare function applyMintlifyTitleFallback(content: string, fileName: string, defaultLocale?: string): TitleFallbackResult;
6
+ export {};
@@ -0,0 +1,80 @@
1
+ import path from 'path';
2
+ import YAML from 'yaml';
3
+ const FRONTMATTER_REGEX = /^---\s*\r?\n([\s\S]*?)\r?\n(---|\.\.\.)\s*(?:\r?\n|$)/;
4
+ function toTitleCase(value) {
5
+ return value
6
+ .split(' ')
7
+ .map((word) => {
8
+ if (!word)
9
+ return '';
10
+ return word[0].toUpperCase() + word.slice(1);
11
+ })
12
+ .join(' ');
13
+ }
14
+ function deriveTitleFromFilename(fileName, defaultLocale) {
15
+ const base = path.basename(fileName, path.extname(fileName));
16
+ if (base.toLowerCase() === 'index') {
17
+ const parentDir = path.dirname(fileName);
18
+ if (parentDir === '.' || parentDir === path.sep) {
19
+ return 'Index';
20
+ }
21
+ const parent = path.basename(parentDir);
22
+ if (parent && defaultLocale && parent === defaultLocale) {
23
+ return 'Index';
24
+ }
25
+ if (parent) {
26
+ return toTitleCase(parent.replace(/[-_]+/g, ' ').trim());
27
+ }
28
+ return 'Index';
29
+ }
30
+ const normalized = base.replace(/[-_]+/g, ' ').replace(/\s+/g, ' ').trim();
31
+ if (!normalized) {
32
+ return base;
33
+ }
34
+ return toTitleCase(normalized);
35
+ }
36
+ function hasMeaningfulTitle(value) {
37
+ if (value === null || value === undefined) {
38
+ return false;
39
+ }
40
+ if (typeof value === 'string') {
41
+ return value.trim().length > 0;
42
+ }
43
+ return true;
44
+ }
45
+ export function applyMintlifyTitleFallback(content, fileName, defaultLocale) {
46
+ const inferredTitle = deriveTitleFromFilename(fileName, defaultLocale);
47
+ if (!inferredTitle) {
48
+ return { content, addedTitle: false };
49
+ }
50
+ const hasBom = content.startsWith('\uFEFF');
51
+ const contentBody = hasBom ? content.slice(1) : content;
52
+ const newline = contentBody.includes('\r\n') ? '\r\n' : '\n';
53
+ const frontmatterMatch = contentBody.match(FRONTMATTER_REGEX);
54
+ if (frontmatterMatch) {
55
+ const frontmatterContent = frontmatterMatch[1];
56
+ let parsed;
57
+ try {
58
+ parsed = YAML.parse(frontmatterContent);
59
+ }
60
+ catch {
61
+ return { content, addedTitle: false };
62
+ }
63
+ if (parsed && hasMeaningfulTitle(parsed.title)) {
64
+ return { content, addedTitle: false };
65
+ }
66
+ const titleLine = YAML.stringify({ title: inferredTitle }).trimEnd();
67
+ const headerEndIndex = contentBody.indexOf(newline) + newline.length;
68
+ const updated = contentBody.slice(0, headerEndIndex) +
69
+ titleLine +
70
+ newline +
71
+ contentBody.slice(headerEndIndex);
72
+ return { content: (hasBom ? '\uFEFF' : '') + updated, addedTitle: true };
73
+ }
74
+ const titleLine = YAML.stringify({ title: inferredTitle }).trimEnd();
75
+ const frontmatterBlock = `---${newline}${titleLine}${newline}---${newline}${newline}`;
76
+ return {
77
+ content: (hasBom ? '\uFEFF' : '') + frontmatterBlock + contentBody,
78
+ addedTitle: true,
79
+ };
80
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gtx-cli",
3
- "version": "2.6.3",
3
+ "version": "2.6.4",
4
4
  "main": "dist/index.js",
5
5
  "bin": "dist/main.js",
6
6
  "files": [