Skip to content

Commit 78864c8

Browse files
committed
feat: add backplane url to template
* refactor index.ts CU-86c31cygc
1 parent 3820716 commit 78864c8

File tree

13 files changed

+174
-171
lines changed

13 files changed

+174
-171
lines changed

index.ts

Lines changed: 131 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -3,184 +3,185 @@ const path = require("path");
33
const matter = require("gray-matter");
44
const { execSync } = require("child_process");
55

6-
/**
7-
* Convert git remote URL to HTTP URL
8-
*/
9-
function convertGitToHttpUrl(gitUrl) {
10-
if (gitUrl.startsWith("git@github.com:")) {
11-
return gitUrl.replace("git@github.com:", "https://github.com/");
12-
}
13-
return gitUrl;
14-
}
15-
16-
/**
17-
* Get GitHub remote URLs in HTTP and SSH format
18-
*/
19-
function getGithubRemoteUrls(filePath) {
6+
function getGitHubRemoteUrl() {
207
try {
21-
const remoteUrl = execSync("git config --get remote.origin.url").toString().trim().replace(/https?:\/\/.*?@github\.com\//, "https://github.com/");
22-
const httpUrl = convertGitToHttpUrl(remoteUrl).replace(
23-
/\.git$/,
24-
`/tree/main/modules${filePath.replace(path.resolve(__dirname, 'modules'), '').replace(/\/README\.md$/, '')}`
25-
);
26-
return {
27-
ssh: remoteUrl,
28-
https: httpUrl
29-
};
8+
const remoteUrl = execSync("git config --get remote.origin.url")
9+
.toString()
10+
.trim()
11+
.replace(/https?:\/\/.*?@github\.com\//, "https://github.com/");
12+
return remoteUrl.replace(/\.git$/, "");
3013
} catch (error) {
3114
console.error("Error getting GitHub remote URL:", error.message);
3215
return null;
3316
}
3417
}
3518

36-
/**
37-
* Recursively find all README.md files in “buildingblock” folders, excluding .github
38-
*/
39-
function findReadmes(dir) {
40-
let results = [];
41-
const files = fs.readdirSync(dir, { withFileTypes: true });
19+
function getBuildingBlockFolderUrl(filePath) {
20+
const remoteUrl = getGitHubRemoteUrl();
21+
if (!remoteUrl) return null;
4222

43-
for (const file of files) {
44-
const fullPath = path.join(dir, file.name);
23+
const relativePath = filePath
24+
.replace(path.resolve(__dirname, "modules"), "")
25+
.replace(/\/README\.md$/, "");
26+
return `${remoteUrl}/tree/main/modules${relativePath}`;
27+
}
4528

29+
function findReadmes(dir){
30+
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((file) => {
31+
const fullPath = path.join(dir, file.name);
4632
if (file.isDirectory()) {
47-
if (file.name === ".github") continue;
48-
results = results.concat(findReadmes(fullPath));
49-
} else if (file.name === "README.md" && dir.includes("buildingblock")) {
50-
results.push(fullPath);
33+
return file.name === ".github" ? [] : findReadmes(fullPath);
5134
}
52-
}
53-
54-
return results;
35+
return file.name === "README.md" && dir.includes("buildingblock")
36+
? [fullPath]
37+
: [];
38+
});
5539
}
5640

57-
/**
58-
* Path to platform logo image, excluding .github
59-
*/
60-
function findPlatformLogos() {
61-
const platformLogos = {};
62-
const modulesDir = path.resolve(__dirname, 'modules');
63-
const assetsDir = path.resolve(__dirname, 'website/public/assets/logos');
64-
const dirs = fs.readdirSync(modulesDir, { withFileTypes: true })
65-
.filter(dirent => dirent.isDirectory() && dirent.name !== ".github");
66-
67-
dirs.forEach((dir) => {
68-
const platformDir = path.join(modulesDir, dir.name);
69-
const files = fs.readdirSync(platformDir);
70-
71-
files.forEach((file) => {
72-
if (file.endsWith(".png") || file.endsWith(".svg")) {
73-
const sourcePath = path.join(platformDir, file);
74-
const destinationPath = path.join(assetsDir, `${dir.name}${path.extname(file)}`);
75-
76-
fs.mkdirSync(assetsDir, { recursive: true });
77-
78-
fs.copyFileSync(sourcePath, destinationPath);
79-
80-
platformLogos[dir.name] = destinationPath.replace(path.resolve(__dirname, 'website/public'), "").replace(/^\/+/g, "");
81-
}
41+
function copyFilesToAssets(
42+
sourceDir,
43+
destinationDir,
44+
fileFilter
45+
){
46+
const copiedFiles = {};
47+
48+
fs.readdirSync(sourceDir, { withFileTypes: true })
49+
.filter((dirent) => dirent.isDirectory() && dirent.name !== ".github")
50+
.forEach((dir) => {
51+
const platformDir = path.join(sourceDir, dir.name);
52+
fs.readdirSync(platformDir)
53+
.filter(fileFilter)
54+
.forEach((file) => {
55+
const sourcePath = path.join(platformDir, file);
56+
const destinationPath = path.join(
57+
destinationDir,
58+
`${dir.name}${path.extname(file)}`
59+
);
60+
61+
fs.mkdirSync(destinationDir, { recursive: true });
62+
fs.copyFileSync(sourcePath, destinationPath);
63+
64+
copiedFiles[dir.name] = destinationPath
65+
.replace(path.resolve(__dirname, "website/public"), "")
66+
.replace(/^\/+/g, "");
67+
});
8268
});
83-
});
8469

85-
return platformLogos;
70+
return copiedFiles;
8671
}
8772

88-
/**
89-
* Path to buildingblock logo image in the same directory as README.md
90-
*/
91-
function findBuildingBlockLogo(buildingBlockDir) {
92-
const logoFiles = [];
93-
const assetsDir = path.resolve(__dirname, 'website/public/assets/building-block-logos');
94-
const files = fs.readdirSync(buildingBlockDir);
73+
function copyPlatformLogosToAssets() {
74+
const modulesDir = path.resolve(__dirname, "modules");
75+
const assetsDir = path.resolve(__dirname, "website/public/assets/logos");
76+
return copyFilesToAssets(modulesDir, assetsDir, (file) =>
77+
file.endsWith(".png") || file.endsWith(".svg")
78+
);
79+
}
9580

96-
files.forEach((file) => {
97-
if (file.endsWith(".png") || file.endsWith(".svg")) {
98-
const { id, platform } = getIdAndPlatform(buildingBlockDir);
99-
const sourcePath = path.join(buildingBlockDir, file);
100-
const destinationPath = path.join(assetsDir, `${id}${path.extname(file)}`);
81+
function copyBuildingBlockLogoToAssets(buildingBlockDir) {
82+
const assetsDir = path.resolve(
83+
__dirname,
84+
"website/public/assets/building-block-logos"
85+
);
10186

102-
fs.mkdirSync(assetsDir, { recursive: true });
103-
fs.copyFileSync(sourcePath, destinationPath);
87+
const logoFile = fs
88+
.readdirSync(buildingBlockDir)
89+
.find((file) => file.endsWith(".png"));
10490

105-
logoFiles.push(destinationPath.replace(path.resolve(__dirname, 'website/public'), "").replace(/^\/+/g, ""));
106-
}
107-
});
91+
if (!logoFile) return null;
10892

109-
return logoFiles.length > 0 ? logoFiles[0] : null;
93+
const { id } = getIdAndPlatform(buildingBlockDir);
94+
const sourcePath = path.join(buildingBlockDir, logoFile);
95+
const destinationPath = path.join(assetsDir, `${id}${path.extname(logoFile)}`);
96+
97+
fs.mkdirSync(assetsDir, { recursive: true });
98+
fs.copyFileSync(sourcePath, destinationPath);
99+
100+
return destinationPath
101+
.replace(path.resolve(__dirname, "website/public"), "")
102+
.replace(/^\/+/g, "");
110103
}
111104

112-
/**
113-
* Parse README.md and extract relevant data
114-
*/
115105
function parseReadme(filePath) {
116106
const buildingBlockDir = path.dirname(filePath);
117107
const content = fs.readFileSync(filePath, "utf-8");
118108
const { data, content: body } = matter(content);
119109
const { id, platform } = getIdAndPlatform(buildingBlockDir);
120-
const howToMatch = body.match(/## How to Use([\s\S]*?)(##|$)/);
121-
const resourcesMatch = body.match(/## Resources([\s\S]*)/);
122-
const inputsMatch = body.match(/## Inputs([\s\S]*?)## Outputs/);
123-
const outputsMatch = body.match(/## Outputs([\s\S]*)/);
110+
111+
const extractSection = (regex) =>
112+
body.match(regex)?.[1]?.trim() || null;
124113

125114
const parseTable = (match) =>
126115
match
127116
? match[1]
128-
.split("\n")
129-
.filter((line) => line.startsWith("| <a name"))
130-
.map((line) => line.split("|").map((s) => s.trim()))
131-
.map(([name, description, type, _default, required]) => ({
132-
name: name.replace(/<a name=".*?_(.*?)".*?>/, "$1"),
133-
description,
134-
type,
135-
required: required === "yes",
136-
}))
117+
.split("\n")
118+
.filter((line) => line.startsWith("| <a name"))
119+
.map((line) => line.split("|").map((s) => s.trim()))
120+
.map(([name, description, type, _default, required]) => ({
121+
name: name.replace(/<a name=".*?_(.*?)".*?>/, "$1"),
122+
description,
123+
type,
124+
required: required === "yes",
125+
}))
137126
: [];
138127

139-
const githubUrls = getGithubRemoteUrls(filePath);
140-
console.log(`🔗 GitHub remote URLs: ${JSON.stringify(githubUrls)}`);
141-
console.log(`🔗 File path: ${filePath}`);
128+
const buildingBlockUrl = getBuildingBlockFolderUrl(filePath);
129+
const buildingBlockLogoPath = copyBuildingBlockLogoToAssets(buildingBlockDir);
142130

143-
const buildingBlockLogoPath = findBuildingBlockLogo(buildingBlockDir);
131+
const backplaneDir = path.join(buildingBlockDir, "../backplane");
132+
const backplaneUrl =
133+
fs.existsSync(backplaneDir) && fs.statSync(backplaneDir).isDirectory()
134+
? getBuildingBlockFolderUrl(backplaneDir)
135+
: null;
144136

145137
return {
146-
id: id,
138+
id,
147139
platformType: platform,
148140
logo: buildingBlockLogoPath,
149-
githubUrls,
141+
buildingBlockUrl,
142+
backplaneUrl,
150143
...data,
151-
howToUse: howToMatch ? howToMatch[1].trim() : null,
152-
resources: parseTable(resourcesMatch),
153-
inputs: parseTable(inputsMatch),
154-
outputs: parseTable(outputsMatch),
144+
howToUse: extractSection(/## How to Use([\s\S]*?)(##|$)/),
145+
resources: parseTable(body.match(/## Resources([\s\S]*)/)),
146+
inputs: parseTable(body.match(/## Inputs([\s\S]*?)## Outputs/)),
147+
outputs: parseTable(body.match(/## Outputs([\s\S]*)/)),
148+
155149
};
156150
}
157151

158-
/**
159-
* This returns the id and platform type from the file path.
160-
*
161-
* @param filePath The buildingblock directory
162-
*/
163152
function getIdAndPlatform(filePath) {
164-
const relativePath = filePath.replace(process.cwd(), "").replace(/\\/g, "/");
153+
const relativePath = filePath
154+
.replace(process.cwd(), "")
155+
.replace(/\\/g, "/");
165156
const pathParts = relativePath.split(path.sep).filter(Boolean);
166-
// pathParts = [modules, <platform>, <module-name>, buildingblock]
167157
const id = pathParts.slice(1, pathParts.length - 1).join("-");
168-
const platform = pathParts.length > 1 ? pathParts[1] : "unknown";
158+
const platform = pathParts[1] || "unknown";
169159

170160
return { id, platform };
171161
}
172162

173-
const repoRoot = path.resolve(__dirname, 'modules');
174-
const platformLogos = findPlatformLogos();
175-
const readmeFiles = findReadmes(repoRoot);
176-
const jsonData = readmeFiles.map((file) => parseReadme(file));
177-
178-
const templatesData = {
179-
templates: jsonData,
180-
};
181-
182-
fs.writeFileSync("website/public/assets/templates.json", JSON.stringify(templatesData, null, 2));
183-
console.log(`✅ Successfully processed ${readmeFiles.length} README.md files. Output saved to templates.json`);
163+
// Main execution
164+
function main() {
165+
const repoRoot = path.resolve(__dirname, "modules");
166+
167+
const platformLogos = copyPlatformLogosToAssets();
168+
fs.writeFileSync(
169+
"website/public/assets/platform-logos.json",
170+
JSON.stringify(platformLogos, null, 2)
171+
);
172+
console.log(
173+
`✅ Successfully processed ${Object.entries(platformLogos).length} platform logos. Output saved to platform-logos.json`
174+
);
175+
176+
const readmeFiles = findReadmes(repoRoot);
177+
const jsonData = readmeFiles.map(parseReadme);
178+
fs.writeFileSync(
179+
"website/public/assets/templates.json",
180+
JSON.stringify({ templates: jsonData }, null, 2)
181+
);
182+
console.log(
183+
`✅ Successfully processed ${readmeFiles.length} README.md files. Output saved to templates.json`
184+
);
185+
}
184186

185-
fs.writeFileSync("website/public/assets/platform-logos.json", JSON.stringify(platformLogos, null, 2));
186-
console.log(`✅ Successfully processed ${Object.entries(platformLogos).length} platform logos. Output saved to platform-logos.json`);
187+
main();
36.2 KB
Loading
76.8 KB
Loading
1.95 KB
Loading
9.65 KB
Loading
24 KB
Loading
14.6 KB
Loading
5.57 KB
Loading

0 commit comments

Comments
 (0)