From 098d70e394d3cffa876fb2aced5dda0f987304c5 Mon Sep 17 00:00:00 2001 From: Patrick Volum Date: Fri, 9 Jul 2021 10:42:05 -0700 Subject: [PATCH 1/4] Adding fallback logic if readMe is not in the root of npm registry response --- .../packages/server/src/controllers/asset.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Composer/packages/server/src/controllers/asset.ts b/Composer/packages/server/src/controllers/asset.ts index 9610e899b7..529b847364 100644 --- a/Composer/packages/server/src/controllers/asset.ts +++ b/Composer/packages/server/src/controllers/asset.ts @@ -118,7 +118,23 @@ export async function getTemplateReadMe(req: any, res: any) { const moduleURL = `https://registry.npmjs.org/${moduleName}`; const response = await fetch(moduleURL); const data = await response.json(); - res.status(200).json(data?.readme || ''); + // check for readme at root of response obj + let readMe = data?.readme; + + // if no readme at root then pull readme from latest published version that has one + if (!readMe) { + const versionsDict = data?.versions; + if (versionsDict && Object.keys(versionsDict).length > 0) { + for (const versionKey of Object.keys(versionsDict).reverse()) { + if (versionsDict[versionKey] && versionsDict[versionKey]?.readme) { + readMe = versionsDict[versionKey].readme; + break; + } + } + } + } + + res.status(200).json(readMe || formatMessage('Read Me cannot be found for this template')); } } catch (error) { log('Failed getting template readMe', error); From b1dfae405becea840a8b81a5898b64af3dcd92da Mon Sep 17 00:00:00 2001 From: Patrick Volum Date: Fri, 9 Jul 2021 12:18:14 -0700 Subject: [PATCH 2/4] Fixing version order by ensuring correct order based on published timestamp --- .../packages/server/src/controllers/asset.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Composer/packages/server/src/controllers/asset.ts b/Composer/packages/server/src/controllers/asset.ts index 529b847364..b6373735f3 100644 --- a/Composer/packages/server/src/controllers/asset.ts +++ b/Composer/packages/server/src/controllers/asset.ts @@ -124,10 +124,21 @@ export async function getTemplateReadMe(req: any, res: any) { // if no readme at root then pull readme from latest published version that has one if (!readMe) { const versionsDict = data?.versions; - if (versionsDict && Object.keys(versionsDict).length > 0) { - for (const versionKey of Object.keys(versionsDict).reverse()) { - if (versionsDict[versionKey] && versionsDict[versionKey]?.readme) { - readMe = versionsDict[versionKey].readme; + const versionTimesObj = data?.time; + if (versionsDict && versionTimesObj) { + const items = Object.keys(versionTimesObj).map((key) => { + return [key, versionTimesObj[key]]; + }); + + items.sort((firstEntry, secondEntry) => { + const firstEntryDate = new Date(firstEntry[1]).getTime(); + const secondEntryDate = new Date(secondEntry[1]).getTime(); + return firstEntryDate > secondEntryDate ? 1 : -1; + }); + + for (let i = items.length - 1; i > -1; i--) { + if (versionsDict[items[i][0]] && versionsDict[items[i][0]]?.readme) { + readMe = versionsDict[items[i][0]]?.readme; break; } } From f6e7e46d3a5b3ed446c65b70751cedb028c88736 Mon Sep 17 00:00:00 2001 From: Patrick Volum Date: Fri, 9 Jul 2021 13:44:53 -0700 Subject: [PATCH 3/4] Adding comments to sort logic --- Composer/packages/server/src/controllers/asset.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Composer/packages/server/src/controllers/asset.ts b/Composer/packages/server/src/controllers/asset.ts index b6373735f3..121f6ac2c1 100644 --- a/Composer/packages/server/src/controllers/asset.ts +++ b/Composer/packages/server/src/controllers/asset.ts @@ -126,18 +126,23 @@ export async function getTemplateReadMe(req: any, res: any) { const versionsDict = data?.versions; const versionTimesObj = data?.time; if (versionsDict && versionTimesObj) { + // convert versionPublishTimes obj to a 2d array + // each entry is an array with two fields, version number and dateTime published const items = Object.keys(versionTimesObj).map((key) => { return [key, versionTimesObj[key]]; }); + // sort versionPublishTimes entries based on time published items.sort((firstEntry, secondEntry) => { const firstEntryDate = new Date(firstEntry[1]).getTime(); const secondEntryDate = new Date(secondEntry[1]).getTime(); return firstEntryDate > secondEntryDate ? 1 : -1; }); + // iterate, starting on most recently published version, and query versionDict for a readMe for the version in question for (let i = items.length - 1; i > -1; i--) { if (versionsDict[items[i][0]] && versionsDict[items[i][0]]?.readme) { + // if a readMe exists, set it as our result and break out of the loop readMe = versionsDict[items[i][0]]?.readme; break; } From 7f1810160fe572f0ac6f334c66821ea6beaf69ef Mon Sep 17 00:00:00 2001 From: Patrick Volum Date: Fri, 9 Jul 2021 14:22:22 -0700 Subject: [PATCH 4/4] Simplifying with Object.entries() --- Composer/packages/server/src/controllers/asset.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Composer/packages/server/src/controllers/asset.ts b/Composer/packages/server/src/controllers/asset.ts index 121f6ac2c1..4391159074 100644 --- a/Composer/packages/server/src/controllers/asset.ts +++ b/Composer/packages/server/src/controllers/asset.ts @@ -128,14 +128,12 @@ export async function getTemplateReadMe(req: any, res: any) { if (versionsDict && versionTimesObj) { // convert versionPublishTimes obj to a 2d array // each entry is an array with two fields, version number and dateTime published - const items = Object.keys(versionTimesObj).map((key) => { - return [key, versionTimesObj[key]]; - }); + const items = Object.entries(versionTimesObj); // sort versionPublishTimes entries based on time published items.sort((firstEntry, secondEntry) => { - const firstEntryDate = new Date(firstEntry[1]).getTime(); - const secondEntryDate = new Date(secondEntry[1]).getTime(); + const firstEntryDate = new Date(firstEntry[1] as string).getTime(); + const secondEntryDate = new Date(secondEntry[1] as string).getTime(); return firstEntryDate > secondEntryDate ? 1 : -1; });