Skip to content

Commit b003b78

Browse files
committed
feat: migrate plugins to TypeScript and update package configurations
1 parent 9d5e577 commit b003b78

13 files changed

Lines changed: 2016 additions & 1898 deletions

File tree

plugins/remark-codeblock-language-as-title/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "0.0.1",
44
"private": true,
55
"description": "Remark plugin for using codeblock language as title",
6-
"main": "src/index.js",
6+
"main": "src/index.ts",
77
"type": "module",
88
"keywords": [
99
"remark",
@@ -20,6 +20,7 @@
2020
"unist-util-visit": "^5.0.0"
2121
},
2222
"devDependencies": {
23+
"@types/mdast": "^4.0.4",
2324
"remark": "^15.0.1"
2425
}
2526
}

plugins/remark-codeblock-language-as-title/src/index.js renamed to plugins/remark-codeblock-language-as-title/src/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8+
import { Root } from 'mdast';
9+
810
export default function codeblockLanguageAsTitleRemarkPlugin() {
9-
/**
10-
* @param {import('mdast').Root} root - The root node of the Markdown AST
11-
* @returns {Promise<void>}
12-
*/
13-
return async root => {
11+
return async (root: Root) => {
1412
const {visit} = await import('unist-util-visit');
1513
visit(root, 'code', node => {
1614
if (node.lang) {

plugins/remark-lint-no-dead-urls/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "0.0.1",
44
"private": true,
55
"description": "Remark linter rule to check for dead urls",
6-
"main": "src/index.js",
6+
"main": "src/index.ts",
77
"type": "module",
88
"keywords": [
99
"remark",

plugins/remark-lint-no-dead-urls/src/index.js renamed to plugins/remark-lint-no-dead-urls/src/index.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import {lintRule} from 'unified-lint-rule';
1212
import {visit} from 'unist-util-visit';
1313

1414
import {fetch} from './lib.js';
15+
import { Node, Data } from 'unist';
16+
import { Root } from 'mdast';
17+
18+
import { Method } from 'got';
1519

1620
const linkCache = new Map();
1721

@@ -23,12 +27,12 @@ const HTTP = {
2327
};
2428

2529
const uri = {
26-
isLocalhost: url => /^(https?:\/\/)(localhost|127\.0\.0\.1)(:\d+)?/.test(url),
27-
isExternal: url => /(https?:\/\/)/.test(url),
28-
isPath: url => /^\/.*/.test(url),
30+
isLocalhost: (url: string) => /^(https?:\/\/)(localhost|127\.0\.0\.1)(:\d+)?/.test(url),
31+
isExternal: (url: string) => /(https?:\/\/)/.test(url),
32+
isPath: (url: string) => /^\/.*/.test(url),
2933
};
3034

31-
async function cacheFetch(urlOrPath, method, options) {
35+
async function cacheFetch(urlOrPath: string, method: Method, options: { [x: string]: any; baseUrl: any; }) {
3236
if (linkCache.has(urlOrPath)) {
3337
return [urlOrPath, linkCache.get(urlOrPath)];
3438
}
@@ -42,9 +46,9 @@ async function cacheFetch(urlOrPath, method, options) {
4246
return [urlOrPath, code];
4347
}
4448

45-
async function naiveLinkCheck(urls, options) {
49+
async function naiveLinkCheck(urls: string[] , options : { [x: string]: any; baseUrl: any; }) {
4650
return Promise.allSettled(
47-
urls.map(async url => {
51+
urls.map(async (url) => {
4852
try {
4953
return await cacheFetch(url, 'HEAD', options);
5054
} catch {
@@ -64,7 +68,15 @@ async function naiveLinkCheck(urls, options) {
6468
);
6569
}
6670

67-
async function noDeadUrls(ast, file, options = {}) {
71+
async function noDeadUrls(
72+
ast: Root,
73+
file: any,
74+
options: {
75+
skipUrlPatterns?: string[];
76+
baseUrl?: string;
77+
[key: string]: any;
78+
} = {}
79+
) {
6880
const urlToNodes = new Map();
6981

7082
const {skipUrlPatterns, ...clientOptions} = options;

plugins/remark-lint-no-dead-urls/src/lib.js renamed to plugins/remark-lint-no-dead-urls/src/lib.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
import got from 'got';
8+
import got, { Method } from 'got';
99

10-
export async function fetch(url, method, options = {}) {
10+
export async function fetch(url: string, method: Method, options = {}) {
1111
const {statusCode} = await got(url, {
1212
...options,
1313
method,

plugins/remark-snackplayer/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "0.1.0",
44
"private": true,
55
"description": "Remark Expo Snack Plugin",
6-
"main": "src/index.js",
6+
"main": "src/index.ts",
77
"type": "module",
88
"keywords": [
99
"remark",
@@ -17,14 +17,16 @@
1717
],
1818
"scripts": {
1919
"lint": "eslint .",
20-
"test": "yarn tape tests/index.js"
20+
"test": "yarn tape tests/index.ts"
2121
},
2222
"dependencies": {
2323
"dedent": "^1.5.3",
2424
"object.fromentries": "^2.0.3",
2525
"unist-util-visit-parents": "^3.1.1"
2626
},
2727
"devDependencies": {
28+
"@types/object.fromentries": "^2.0.4",
29+
"@types/tape": "^5.8.1",
2830
"remark": "^15.0.1",
2931
"remark-mdx": "^3.1.0",
3032
"tape": "^5.7.0"
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import visit from 'unist-util-visit-parents';
1111
import fromEntries from 'object.fromentries';
12+
import { Node, Data } from 'unist';
13+
import { Root } from 'mdast';
1214

1315
const parseParams = (paramString = '') => {
1416
const params = fromEntries(new URLSearchParams(paramString));
@@ -20,15 +22,15 @@ const parseParams = (paramString = '') => {
2022
return params;
2123
};
2224

23-
function attr(name, value) {
25+
function attr(name: string, value: string) {
2426
return {
2527
type: 'mdxJsxAttribute',
2628
name,
2729
value,
2830
};
2931
}
3032

31-
async function toJsxNode(node) {
33+
async function toJsxNode(node: Node<Data>) {
3234
const params = parseParams(node.meta);
3335

3436
// Gather necessary Params
@@ -85,7 +87,7 @@ async function toJsxNode(node) {
8587
}
8688

8789
export default function SnackPlayer() {
88-
return async tree => {
90+
return async (tree: Node<Data>) => {
8991
const nodesToProcess = [];
9092
visit(tree, 'code', (node, parent) => {
9193
if (node.lang === 'SnackPlayer') {
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import {remark} from 'remark';
1111
import remarkMdx from 'remark-mdx';
1212
import test from 'tape';
1313

14-
import SnackPlayer from '../src/index.js';
14+
import SnackPlayer from '../src/index';
1515

16-
function read(name) {
16+
function read(name: string) {
1717
return fs.readFileSync(path.join(import.meta.dirname, name), 'utf8');
1818
}
1919

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const SLUG_TO_URL = {
3939
};
4040

4141
// Function to convert the TypeScript sidebar config to JSON
42-
async function convertSidebarConfigToJson(fileName) {
42+
async function convertSidebarConfigToJson(fileName: string) {
4343
const inputFileContent = fs.readFileSync(
4444
path.join(import.meta.dirname, '../website', fileName),
4545
'utf8'
@@ -70,8 +70,8 @@ async function convertSidebarConfigToJson(fileName) {
7070
}
7171

7272
// Function to extract URLs from sidebar config
73-
function extractUrlsFromSidebar(sidebarConfig, prefix) {
74-
const urls = [];
73+
function extractUrlsFromSidebar(sidebarConfig: SidebarConfig, prefix: string) {
74+
const urls: string[] = [];
7575

7676
// Process each section (docs, api, components)
7777
Object.entries(sidebarConfig).forEach(([, categories]) => {
@@ -93,15 +93,19 @@ function extractUrlsFromSidebar(sidebarConfig, prefix) {
9393
return urls;
9494
}
9595

96+
type SidebarItem = string | {type: string; id?: string; items?: SidebarItem[]; label?: string};
97+
type Items = SidebarItem[] | {items: SidebarItem[]};
98+
99+
interface SidebarConfig {
100+
[section: string]: {
101+
[category: string]: Items;
102+
};
103+
}
96104
// Recursive function to process items and extract URLs
97-
function processItemsForUrls(items, urls, prefix) {
98-
if (typeof items === 'object' && Array.isArray(items.items)) {
99-
processItemsForUrls(items.items, urls, prefix);
100-
return;
101-
}
105+
function processItemsForUrls(items: Items, urls: string[], prefix: string) {
106+
const itemsArray = getItemsArray(items);
102107

103-
if (Array.isArray(items)) {
104-
items.forEach(item => {
108+
itemsArray.forEach(item => {
105109
if (typeof item === 'string') {
106110
urls.push(`${URL_PREFIX}${prefix}/${item}`);
107111
} else if (typeof item === 'object') {
@@ -112,11 +116,16 @@ function processItemsForUrls(items, urls, prefix) {
112116
}
113117
}
114118
});
115-
}
119+
}
120+
121+
interface UrlCheckResult {
122+
url: string;
123+
status: number | string;
124+
error?: string;
116125
}
117126

118127
// Function to check URL status
119-
function checkUrl(urlString) {
128+
function checkUrl(urlString: string): Promise<UrlCheckResult> {
120129
return new Promise(resolve => {
121130
const parsedUrl = url.parse(urlString);
122131

@@ -130,7 +139,7 @@ function checkUrl(urlString) {
130139
const req = https.request(options, res => {
131140
resolve({
132141
url: urlString,
133-
status: res.statusCode,
142+
status: res.statusCode || 0,
134143
});
135144
});
136145

@@ -155,8 +164,8 @@ function checkUrl(urlString) {
155164
}
156165

157166
// Process each URL
158-
async function processUrls(urls) {
159-
const unavailableUrls = [];
167+
async function processUrls(urls: string[]) {
168+
const unavailableUrls: UnavailableUrl[] = [];
160169

161170
for (const urlToCheck of urls) {
162171
const result = await checkUrl(urlToCheck);
@@ -176,7 +185,7 @@ async function processUrls(urls) {
176185
}
177186

178187
// Function to extract title from markdown frontmatter
179-
function extractMetadataFromMarkdown(filePath) {
188+
function extractMetadataFromMarkdown(filePath: string) {
180189
try {
181190
const content = fs.readFileSync(filePath, 'utf8');
182191
const frontmatterMatch = content.match(/---\n([\s\S]*?)\n---/);
@@ -188,7 +197,7 @@ function extractMetadataFromMarkdown(filePath) {
188197
return {
189198
title: titleMatch
190199
? titleMatch[1].trim()
191-
: filePath.split('/').pop().replace('.md', ''),
200+
: filePath.split('/').pop()?.replace('.md', ''),
192201
slug: slugMatch ? slugMatch[1].trim().replace(/^\//, '') : null,
193202
};
194203
}
@@ -197,14 +206,18 @@ function extractMetadataFromMarkdown(filePath) {
197206
}
198207
// If no frontmatter found, on an error occurred use the filename
199208
return {
200-
title: filePath.split('/').pop().replace('.md', ''),
209+
title: filePath.split('/').pop()?.replace('.md', ''),
201210
slug: null,
202211
};
203212
}
204213

205214
// Function to map special cases for file names that don't match the sidebar
206-
function mapDocPath(item, prefix) {
207-
const specialCases = {
215+
interface SpecialCases {
216+
[key: string]: string;
217+
}
218+
219+
function mapDocPath(item: string | SidebarItem, prefix: string): string {
220+
const specialCases: SpecialCases = {
208221
'environment-setup': 'getting-started.md',
209222
'native-platform': 'native-platforms.md',
210223
'turbo-native-modules-introduction': 'turbo-native-modules.md',
@@ -223,8 +236,19 @@ function mapDocPath(item, prefix) {
223236
return `${item}.md`;
224237
}
225238

239+
type UnavailableUrl = {url: string; status: number | string; error: string | null;};
240+
241+
// Helper function to extract items array from Items type
242+
function getItemsArray(items: Items): SidebarItem[] {
243+
if (Array.isArray(items)) {
244+
return items;
245+
} else {
246+
return items.items;
247+
}
248+
}
249+
226250
// Function to generate output for each sidebar
227-
function generateMarkdown(sidebarConfig, docPath, prefix, unavailableUrls) {
251+
function generateMarkdown(sidebarConfig: SidebarConfig, docPath: string, prefix: string, unavailableUrls: UnavailableUrl[]) {
228252
let markdown = '';
229253

230254
// Process each section (docs, api, components)
@@ -235,12 +259,10 @@ function generateMarkdown(sidebarConfig, docPath, prefix, unavailableUrls) {
235259
Object.entries(categories).forEach(([categoryName, items]) => {
236260
markdown += `### ${categoryName === '0' ? 'General' : categoryName}\n\n`;
237261

238-
if (typeof items === 'object' && Array.isArray(items.items)) {
239-
items = items.items;
240-
}
241-
const reorderedArray = items.every(item => typeof item === 'string')
242-
? items
243-
: [...items].sort((a, b) =>
262+
const itemsArray = getItemsArray(items);
263+
const reorderedArray = itemsArray.every(item => typeof item === 'string')
264+
? itemsArray
265+
: [...itemsArray].sort((a, b) =>
244266
typeof a === 'string' && typeof b !== 'string'
245267
? -1
246268
: typeof a !== 'string' && typeof b === 'string'
@@ -268,7 +290,7 @@ function generateMarkdown(sidebarConfig, docPath, prefix, unavailableUrls) {
268290
} else if (item.type === 'category' && Array.isArray(item.items)) {
269291
// This is a category with nested items
270292
markdown += `#### ${item.label}\n\n`;
271-
item.items.forEach(nestedItem => {
293+
item.items.forEach((nestedItem: SidebarItem) => {
272294
if (typeof nestedItem === 'string') {
273295
const fullDocPath = `${docPath}${mapDocPath(nestedItem, prefix)}`;
274296
if (!isEntryUnavailable(unavailableUrls, fullDocPath)) {
@@ -296,7 +318,7 @@ function generateMarkdown(sidebarConfig, docPath, prefix, unavailableUrls) {
296318
}
297319

298320
async function generateOutput() {
299-
const results = [];
321+
const results: { markdown: string; prefix: string; }[] = [];
300322
const promises = [];
301323

302324
let output = `# ${TITLE}\n\n`;
@@ -365,7 +387,7 @@ async function generateOutput() {
365387
});
366388
}
367389

368-
function isEntryUnavailable(unavailableUrls, docPath) {
390+
function isEntryUnavailable(unavailableUrls: UnavailableUrl[], docPath: string) {
369391
return !!unavailableUrls.find(entry =>
370392
entry.url.endsWith(docPath.substring(1))
371393
);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import path from 'node:path';
1212
const imageReferenceRegExp = new RegExp(/!\[.*?\]\((.*)\)/g);
1313

1414
async function main() {
15-
const assets = [];
15+
const assets: { imagePath: string; markdownPath: string; }[] = [];
1616
const missingAssets = [];
1717
const queue = [];
1818

0 commit comments

Comments
 (0)