diff --git a/scripts/markdown.js b/scripts/markdown.js
index 5c106ad1..3aaa0f79 100644
--- a/scripts/markdown.js
+++ b/scripts/markdown.js
@@ -7,10 +7,7 @@ function capitalize(s) {
}
function normalizeName(name) {
- return name
- .split("_")
- .map((name) => capitalize(name))
- .join(" ");
+ return name.split("_").map(capitalize).join(" ");
}
export function renderMarkdown(solution, file) {
@@ -19,6 +16,9 @@ export function renderMarkdown(solution, file) {
// Convert Markdown to HTML
const htmlContent = marked(content);
+ const solutionId = basename(solution, extname(solution));
+ const fileId = basename(file, extname(file));
+
// Wrap the HTML content with the necessary HTML and CSS
const htmlTemplate = `
@@ -27,9 +27,8 @@ export function renderMarkdown(solution, file) {
-
TigerGraph - ${normalizeName(
- basename(solution, extname(solution))
- )} - ${normalizeName(basename(file, extname(file)))}
+ TigerGraph - ${normalizeName(solutionId)} - ${normalizeName(fileId)}
+
+
+ }
+
+
-
+
+
+
${htmlContent}
diff --git a/scripts/script.js b/scripts/script.js
index e3e6b3bd..6846b07c 100644
--- a/scripts/script.js
+++ b/scripts/script.js
@@ -85,7 +85,7 @@ async function syncFolder(folder, cacheControl = disableCacheControl) {
Prefix: folder,
})
.promise();
- const conents = result.Contents;
+ const conents = result.Contents || [];
// delete all remote file not existed on local
for (let content of conents) {
@@ -119,7 +119,7 @@ function getAllSolutions() {
return metaFiles.map((file) => file.slice(0, -"/meta/meta.yml".length));
}
-// Find a case-insensitive Readme.md file in the solution root
+
function findReadmeFile(solutionDir) {
try {
const files = fs.readdirSync(solutionDir);
@@ -163,16 +163,14 @@ async function getSolution(dir) {
await syncFolder(`${dir}/model`);
await syncFolder(`${dir}/doc`);
- const insightsFiles = await globSync(`${dir}/meta/Insights*.json`);
+ const insightsFiles = globSync(`${dir}/meta/Insights*.json`);
content.metadata.hasInsights = insightsFiles.length > 0;
- const markdownFiles = globSync([
- `${dir}/model/**/*.md`,
- `${dir}/doc/**/*.md`,
- ]);
+ const markdownFiles = globSync([`${dir}/model/**/*.md`, `${dir}/doc/**/*.md`]);
const htmlFiles = [];
for (let markdownFile of markdownFiles) {
const html = renderMarkdown(dir, markdownFile);
+
const htmlFile = path.join(
path.dirname(markdownFile),
path.basename(markdownFile, path.extname(markdownFile)) + ".html"
@@ -196,7 +194,7 @@ async function getSolution(dir) {
}
}
- // Handle root-level README (case-insensitive)
+
const readmeFile = findReadmeFile(dir);
if (readmeFile) {
const html = renderMarkdown(dir, readmeFile);
@@ -216,7 +214,6 @@ async function getSolution(dir) {
try {
const data = await s3.upload(params).promise();
console.log(`${htmlFile} => ${data.Location}`);
- // Expose README link separately
content.metadata.readme = data.Location;
} catch (error) {
console.error("Error uploading html file:", error);
@@ -256,9 +253,7 @@ function concatFilesForQuery(files, lastFiles, graphName, is_library) {
content += `INSTALL QUERY ALL\n`;
}
- const lastFileContents = lastFiles.map((file) =>
- fs.readFileSync(file, "utf8")
- );
+ const lastFileContents = lastFiles.map((file) => fs.readFileSync(file, "utf8"));
for (let i = 0; i < lastFiles.length; i++) {
content += "#File: " + lastFiles[i] + "\n";
content += lastFileContents[i];
@@ -278,9 +273,7 @@ function concatFilesForLastFile(lastFiles, graphName, is_library) {
}
let content = `USE GRAPH ${graphName}\n`;
- const lastFileContents = lastFiles.map((file) =>
- fs.readFileSync(file, "utf8")
- );
+ const lastFileContents = lastFiles.map((file) => fs.readFileSync(file, "utf8"));
for (let i = 0; i < lastFiles.length; i++) {
content += lastFileContents[i];
content += "\n";
@@ -294,9 +287,7 @@ function concatFilesForLastFile(lastFiles, graphName, is_library) {
function concatLoadingFiles(files) {
const fileContents = files
.map((file) => fs.readFileSync(file, "utf8"))
- .map((content) =>
- content.replaceAll("tigergraph-solution-kits", getBucketName())
- );
+ .map((content) => content.replaceAll("tigergraph-solution-kits", getBucketName()));
let content = "";
for (let i = 0; i < files.length; i++) {
@@ -321,28 +312,25 @@ async function getSolutionDetail(dir, first, last, graphName, is_library) {
styleJSON = fs.readFileSync(`${dir}/meta/style.json`, "utf8");
} catch (error) {}
- const queryFiles = globSync([
- `${dir}/queries/*.gsql`,
- `${dir}/queries/*/*.gsql`,
- ]);
+ const queryFiles = globSync([`${dir}/queries/*.gsql`, `${dir}/queries/*/*.gsql`]);
const firstFiles = [];
for (let file of first) {
- const path = `${dir}/queries/${file}`;
- if (queryFiles.includes(path)) {
- firstFiles.push(path);
+ const p = `${dir}/queries/${file}`;
+ if (queryFiles.includes(p)) {
+ firstFiles.push(p);
}
}
const lastFiles = [];
for (let file of last) {
- const path = `${dir}/queries/${file}`;
- if (queryFiles.includes(path)) {
- lastFiles.push(path);
+ const p = `${dir}/queries/${file}`;
+ if (queryFiles.includes(p)) {
+ lastFiles.push(p);
}
}
const middleFiles = queryFiles.filter(
- (file) => !firstFiles.includes(file) && !lastFiles.includes(file)
+ (f) => !firstFiles.includes(f) && !lastFiles.includes(f)
);
const query = concatFilesForQuery(
@@ -360,7 +348,7 @@ async function getSolutionDetail(dir, first, last, graphName, is_library) {
const resetFiles = globSync(`${dir}/reset/*.gsql`);
const reset = concatFiles(resetFiles);
- const insightsFiles = await globSync(`${dir}/meta/Insights*.json`);
+ const insightsFiles = globSync(`${dir}/meta/Insights*.json`);
const insightsApplications = [];
for (let insightsFile of insightsFiles) {
const application = JSON.parse(fs.readFileSync(`${insightsFile}`, "utf8"));
@@ -383,9 +371,7 @@ async function main() {
const solutions = getAllSolutions();
const metadataList = [];
for (let solution of solutions) {
- const { metadata, queries: { first, last } = {} } = await getSolution(
- solution
- );
+ const { metadata, queries: { first, last } = {} } = await getSolution(solution);
if (metadata.production === false) {
console.log("hide solution", metadata.name);
@@ -393,7 +379,7 @@ async function main() {
}
metadataList.push({
- ...metadata,
+ ...metadata, // includes metadata.images, metadata.docLinks, and ADDED metadata.readme when present
path: solution,
});
@@ -404,6 +390,7 @@ async function main() {
metadata.graph,
metadata.is_library
);
+
const params = {
...commonBucketConfig,
Key: `${solution}/meta.json`,
@@ -460,28 +447,16 @@ async function main() {
main();
-// Debug code
-// function decodeSolution(path) {
-// const file = fs.readFileSync(path, "utf8");
-// const content = JSON.parse(file);
-// const { schema, query, sampleLoadingJob, reset } = content;
-// console.log(schema);
-// console.log(query);
-// console.log(sampleLoadingJob);
-// console.log(reset);
-// }
-
async function generateFileForImportSolution() {
const dir = "solution_metadata";
const list_data = [];
- fs.mkdirSync(dir);
+ // (small safety: allow reruns without throwing)
+ fs.mkdirSync(dir, { recursive: true });
const solutions = getAllSolutions();
const metadataList = [];
for (let solution of solutions) {
- const { metadata, queries: { first, last } = {} } = await getSolution(
- solution
- );
+ const { metadata, queries: { first, last } = {} } = await getSolution(solution);
if (metadata.production === false) {
console.log("hide solution", metadata.name);
@@ -498,8 +473,7 @@ async function generateFileForImportSolution() {
// strip aws s3 url prefix
if (metadata.icon) {
- metadata.icon =
- dir + "/" + metadata.icon.slice(metadata.icon.indexOf(solution));
+ metadata.icon = dir + "/" + metadata.icon.slice(metadata.icon.indexOf(solution));
}
if (metadata.images) {
metadata.images = metadata.images.map((image) => {
@@ -513,8 +487,8 @@ async function generateFileForImportSolution() {
initQuery: solutionDetails.lastQuery,
});
- if (!solutionDetails.is_library) {
- // https://tigergraph-solution-kits-prod.s3.us-west-1.amazonaws.com/financial_crime/application_fraud/4.x/solution_with_data.tar.gz
+
+ if (!metadata.is_library) {
const solution_with_data = `https://tigergraph-solution-kits-prod.s3.us-west-1.amazonaws.com/${solution}/4.x/solution_with_data.tar.gz`;
const solution_without_data = `https://tigergraph-solution-kits-prod.s3.us-west-1.amazonaws.com/${solution}/4.x/solution_without_data.tar.gz`;
list_data.push({
@@ -529,23 +503,14 @@ async function generateFileForImportSolution() {
// copy images and icon
fs.mkdirSync(`${dir}/${solution}/meta`, { recursive: true });
if (fs.existsSync(`${solution}/meta/icon.png`)) {
- fs.copyFileSync(
- `${solution}/meta/icon.png`,
- `${dir}/${solution}/meta/icon.png`
- );
+ fs.copyFileSync(`${solution}/meta/icon.png`, `${dir}/${solution}/meta/icon.png`);
} else if (fs.existsSync(`${solution}/meta/icon.jpg`)) {
- fs.copyFileSync(
- `${solution}/meta/icon.jpg`,
- `${dir}/${solution}/meta/icon.jpg`
- );
+ fs.copyFileSync(`${solution}/meta/icon.jpg`, `${dir}/${solution}/meta/icon.jpg`);
} else if (fs.existsSync(`${solution}/meta/icon.svg`)) {
- fs.copyFileSync(
- `${solution}/meta/icon.svg`,
- `${dir}/${solution}/meta/icon.svg`
- );
+ fs.copyFileSync(`${solution}/meta/icon.svg`, `${dir}/${solution}/meta/icon.svg`);
}
if (fs.existsSync(`${solution}/meta/images`)) {
- fs.mkdirSync(`${dir}/${solution}/meta/images`);
+ fs.mkdirSync(`${dir}/${solution}/meta/images`, { recursive: true });
const images = globSync([`${solution}/meta/images/*`]);
for (let image of images) {
const fileName = path.basename(image);
@@ -554,15 +519,7 @@ async function generateFileForImportSolution() {
}
}
- fs.writeFileSync(
- `${dir}/solution_list.json`,
- JSON.stringify(metadataList, null, 2)
- );
- fs.writeFileSync(
- `${dir}/solution_data.json`,
- JSON.stringify(list_data, null, 2)
- );
+ fs.writeFileSync(`${dir}/solution_list.json`, JSON.stringify(metadataList, null, 2));
+ fs.writeFileSync(`${dir}/solution_data.json`, JSON.stringify(list_data, null, 2));
}
-// generate meta data for import solution, used by https://dl.tigergraph.com/?tab=solution
-// generateFileForImportSolution();