Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs-infra] Add recursively the relative modules in the demos #44150

Merged
merged 20 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions docs/data/material/components/autocomplete/top100Films.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top100Films = [
{ label: 'The Shawshank Redemption', year: 1994 },
{ label: 'The Godfather', year: 1972 },
{ label: 'The Godfather: Part II', year: 1974 },
{ label: 'The Dark Knight', year: 2008 },
{ label: '12 Angry Men', year: 1957 },
{ label: "Schindler's List", year: 1993 },
{ label: 'Pulp Fiction', year: 1994 },
{
label: 'The Lord of the Rings: The Return of the King',
year: 2003,
},
{ label: 'The Good, the Bad and the Ugly', year: 1966 },
{ label: 'Fight Club', year: 1999 },
{
label: 'The Lord of the Rings: The Fellowship of the Ring',
year: 2001,
},
{
label: 'Star Wars: Episode V - The Empire Strikes Back',
year: 1980,
},
{ label: 'Forrest Gump', year: 1994 },
{ label: 'Inception', year: 2010 },
{
label: 'The Lord of the Rings: The Two Towers',
year: 2002,
},
{ label: "One Flew Over the Cuckoo's Nest", year: 1975 },
{ label: 'Goodfellas', year: 1990 },
{ label: 'The Matrix', year: 1999 },
{ label: 'Seven Samurai', year: 1954 },
{
label: 'Star Wars: Episode IV - A New Hope',
year: 1977,
},
{ label: 'City of God', year: 2002 },
{ label: 'Se7en', year: 1995 },
{ label: 'The Silence of the Lambs', year: 1991 },
{ label: "It's a Wonderful Life", year: 1946 },
{ label: 'Life Is Beautiful', year: 1997 },
{ label: 'The Usual Suspects', year: 1995 },
{ label: 'Léon: The Professional', year: 1994 },
{ label: 'Spirited Away', year: 2001 },
{ label: 'Saving Private Ryan', year: 1998 },
{ label: 'Once Upon a Time in the West', year: 1968 },
{ label: 'American History X', year: 1998 },
{ label: 'Interstellar', year: 2014 },
{ label: 'Casablanca', year: 1942 },
{ label: 'City Lights', year: 1931 },
{ label: 'Psycho', year: 1960 },
{ label: 'The Green Mile', year: 1999 },
{ label: 'The Intouchables', year: 2011 },
{ label: 'Modern Times', year: 1936 },
{ label: 'Raiders of the Lost Ark', year: 1981 },
{ label: 'Rear Window', year: 1954 },
{ label: 'The Pianist', year: 2002 },
{ label: 'The Departed', year: 2006 },
{ label: 'Terminator 2: Judgment Day', year: 1991 },
{ label: 'Back to the Future', year: 1985 },
{ label: 'Whiplash', year: 2014 },
{ label: 'Gladiator', year: 2000 },
{ label: 'Memento', year: 2000 },
{ label: 'The Prestige', year: 2006 },
{ label: 'The Lion King', year: 1994 },
{ label: 'Apocalypse Now', year: 1979 },
{ label: 'Alien', year: 1979 },
{ label: 'Sunset Boulevard', year: 1950 },
{
label: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb',
year: 1964,
},
{ label: 'The Great Dictator', year: 1940 },
{ label: 'Cinema Paradiso', year: 1988 },
{ label: 'The Lives of Others', year: 2006 },
{ label: 'Grave of the Fireflies', year: 1988 },
{ label: 'Paths of Glory', year: 1957 },
{ label: 'Django Unchained', year: 2012 },
{ label: 'The Shining', year: 1980 },
{ label: 'WALL·E', year: 2008 },
{ label: 'American Beauty', year: 1999 },
{ label: 'The Dark Knight Rises', year: 2012 },
{ label: 'Princess Mononoke', year: 1997 },
{ label: 'Aliens', year: 1986 },
{ label: 'Oldboy', year: 2003 },
{ label: 'Once Upon a Time in America', year: 1984 },
{ label: 'Witness for the Prosecution', year: 1957 },
{ label: 'Das Boot', year: 1981 },
{ label: 'Citizen Kane', year: 1941 },
{ label: 'North by Northwest', year: 1959 },
{ label: 'Vertigo', year: 1958 },
{
label: 'Star Wars: Episode VI - Return of the Jedi',
year: 1983,
},
{ label: 'Reservoir Dogs', year: 1992 },
{ label: 'Braveheart', year: 1995 },
{ label: 'M', year: 1931 },
{ label: 'Requiem for a Dream', year: 2000 },
{ label: 'Amélie', year: 2001 },
{ label: 'A Clockwork Orange', year: 1971 },
{ label: 'Like Stars on Earth', year: 2007 },
{ label: 'Taxi Driver', year: 1976 },
{ label: 'Lawrence of Arabia', year: 1962 },
{ label: 'Double Indemnity', year: 1944 },
{
label: 'Eternal Sunshine of the Spotless Mind',
year: 2004,
},
{ label: 'Amadeus', year: 1984 },
{ label: 'To Kill a Mockingbird', year: 1962 },
{ label: 'Toy Story 3', year: 2010 },
{ label: 'Logan', year: 2017 },
{ label: 'Full Metal Jacket', year: 1987 },
{ label: 'Dangal', year: 2016 },
{ label: 'The Sting', year: 1973 },
{ label: '2001: A Space Odyssey', year: 1968 },
{ label: "Singin' in the Rain", year: 1952 },
{ label: 'Toy Story', year: 1995 },
{ label: 'Bicycle Thieves', year: 1948 },
{ label: 'The Kid', year: 1921 },
{ label: 'Inglourious Basterds', year: 2009 },
{ label: 'Snatch', year: 2000 },
{ label: '3 Idiots', year: 2009 },
{ label: 'Monty Python and the Holy Grail', year: 1975 },
];

export default top100Films;
1 change: 1 addition & 0 deletions docs/scripts/formattedTSDemos.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ async function getFiles(root) {
} else if (
stat.isFile() &&
/\.tsx?$/.test(filePath) &&
!filePath.endsWith('types.ts') &&
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
!filePath.endsWith('.d.ts') &&
!ignoreList.some((ignorePath) => filePath.endsWith(path.normalize(ignorePath)))
) {
Expand Down
7 changes: 2 additions & 5 deletions docs/src/modules/sandbox/CodeSandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,7 @@ function createReactApp(demoData: DemoData) {
content: CRA.getRootIndex(demoData),
},
[`src/Demo.${ext}`]: {
content: flattenRelativeImports(
demoData.raw,
demoData.relativeModules?.map((file) => file.module),
),
content: flattenRelativeImports(demoData.raw),
},
// Spread the relative modules
...(demoData.relativeModules &&
Expand All @@ -60,7 +57,7 @@ function createReactApp(demoData: DemoData) {
...acc,
// Remove the path and keep the filename
[`src/${curr.module.replace(/^.*[\\/]/g, '')}`]: {
content: curr.raw,
content: flattenRelativeImports(curr.raw),
},
}),
{},
Expand Down
11 changes: 2 additions & 9 deletions docs/src/modules/sandbox/FlattenRelativeImports.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
export default function flattenRelativeImports(rawCode: string, modulePaths: string[] = []) {
let newCode = rawCode;
modulePaths.forEach((path: string) => {
const pathWithoutExtension = path.replace(/\.[a-z]*$/g, '');
// Move the relative import to the current directory
const newPath = `./${pathWithoutExtension.replace(/^.*[\\/]/g, '')}`;
newCode = newCode.replace(pathWithoutExtension, newPath);
});
return newCode;
export default function flattenRelativeImports(rawCode: string) {
return rawCode.replace(/from (['"])\..*\//g, `from $1./`);
}
7 changes: 2 additions & 5 deletions docs/src/modules/sandbox/StackBlitz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,15 @@ function createReactApp(demoData: DemoData) {
const files: Record<string, string> = {
'index.html': CRA.getHtml(demoData),
[`index.${ext}`]: CRA.getRootIndex(demoData),
[`Demo.${ext}`]: flattenRelativeImports(
demoData.raw,
demoData.relativeModules?.map((file) => file.module),
),
[`Demo.${ext}`]: flattenRelativeImports(demoData.raw),
// Spread the relative modules
...(demoData.relativeModules &&
// Transform the relative modules array into an object
demoData.relativeModules.reduce(
(acc, curr) => ({
...acc,
// Remove the path and keep the filename
[`${curr.module.replace(/^.*[\\/]/g, '')}`]: curr.raw,
[`${curr.module.replace(/^.*[\\/]/g, '')}`]: flattenRelativeImports(curr.raw),
}),
{},
)),
Expand Down
139 changes: 119 additions & 20 deletions packages/markdown/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ module.exports = async function demoLoader() {
* @example detectRelativeImports('ComboBox.js', '', JS', './top100Films') => relativeModules.set('ComboBox.js', new Map([['./top100Films.js', ['JS']]]))
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
*/
function detectRelativeImports(demoName, moduleFilepath, variant, importModuleID) {
let relativeModuleFilename = importModuleID;
if (importModuleID.startsWith('.')) {
let relativeModuleFilename = importModuleID;
const demoMap = relativeModules.get(demoName);
// If the moduleID does not end with an extension, or ends with an unsupported extension (e.g. ".styling") we need to resolve it
// Fastest way to get a file extension, see: https://stackoverflow.com/a/12900504/
Expand Down Expand Up @@ -198,6 +198,7 @@ module.exports = async function demoLoader() {
}
}
}
return relativeModuleFilename;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to update the method to return the file as it is needed when iterating the relative modules.

}

await Promise.all(
Expand Down Expand Up @@ -419,6 +420,27 @@ module.exports = async function demoLoader() {
// TS version of the demo doesn't exist. This is fine.
}

/**
* Inserts the moduleData into the relativeModules object
* @param {*} moduleData
* @param {*} variant
* @example updateRelativeModules({module: 'constants.js', raw: ... }, 'JS') => demos[demoName].relativeModules[variant].push(moduleData)
*/
function updateRelativeModules(moduleData, variant) {
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
if (demos[demoName].relativeModules[variant]) {
// Avoid duplicates
if (
!demos[demoName].relativeModules[variant].some(
(elem) => elem.module === moduleData.module,
)
) {
demos[demoName].relativeModules[variant].push(moduleData);
}
} else {
demos[demoName].relativeModules[variant] = [moduleData];
}
}

/* Map over relative import module IDs and resolve them
* while grouping by demo variant
* From:
Expand All @@ -438,32 +460,109 @@ module.exports = async function demoLoader() {
demos[demoName].relativeModules = {};
}

const addedModulesRelativeToModulePath = new Set();
await Promise.all(
Array.from(relativeModules.get(demoName)).map(async ([relativeModuleID, variants]) => {
let raw = '';
try {
raw = await fs.readFile(path.join(path.dirname(moduleFilepath), relativeModuleID), {
encoding: 'utf8',
});
} catch {
throw new Error(
`Could not find a module for the relative import "${relativeModuleID}" in the demo "${demoName}"`,
for (const variant of variants) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only iterates through ['JS', 'TS']

let raw = '';
const relativeModuleFilePath = path.join(
path.dirname(moduleFilepath),
relativeModuleID,
);
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
}

const moduleData = { module: relativeModuleID, raw };
const modules = demos[demoName].relativeModules;
// the file has already been processed
if (addedModulesRelativeToModulePath.has(relativeModuleFilePath)) {
continue;
}

variants.forEach((variant) => {
if (modules[variant]) {
// Avoid duplicates
if (!modules[variant].some((elem) => elem.module === relativeModuleID)) {
modules[variant].push(moduleData);
try {
// We are only iterating trough an array that looks
// like this: ['JS', 'TS'], so it is safe to await
// eslint-disable-next-line no-await-in-loop
raw = await fs.readFile(relativeModuleFilePath, {
encoding: 'utf8',
});

const importedProcessedModuleIDs = new Set();
const importedProcessedModulesIDsParents = new Map();
// Find the relative paths in the relative module
if (relativeModuleID.startsWith('.')) {
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
extractImports(raw).forEach((importModuleID) => {
// detect relative import
const importModuleIdWithExtension = detectRelativeImports(
importModuleID,
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
relativeModuleFilePath,
variant,
importModuleID,
);
if (importModuleID.startsWith('.')) {
importedProcessedModuleIDs.add(importModuleIdWithExtension);
importedProcessedModulesIDsParents.set(
importModuleIdWithExtension,
relativeModuleFilePath,
);
}
});

if (!addedModulesRelativeToModulePath.has(relativeModuleFilePath)) {
const moduleData = { module: relativeModuleID, raw };
updateRelativeModules(moduleData, variant);
addedModulesRelativeToModulePath.add(relativeModuleFilePath);
}
}
} else {
modules[variant] = [moduleData];
// iterate recursively over the relative imports
while (importedProcessedModuleIDs.size > 0) {
for (const entry of importedProcessedModuleIDs) {
if (entry.startsWith('.')) {
const entryModuleFilePath = path.join(
path.dirname(importedProcessedModulesIDsParents.get(entry)),
entry,
);

// We are only iterating trough an array that looks
// like this: ['JS', 'TS'], so it is safe to await
// eslint-disable-next-line no-await-in-loop
const rawEntry = await fs.readFile(entryModuleFilePath, { encoding: 'utf8' });

extractImports(rawEntry).forEach((importModuleID) => {
// detect relative import
const importModuleIdWithExtension = detectRelativeImports(
entry,
mnajdova marked this conversation as resolved.
Show resolved Hide resolved
entryModuleFilePath,
variant,
importModuleID,
);
if (importModuleID.startsWith('.')) {
importedProcessedModuleIDs.add(importModuleIdWithExtension);
importedProcessedModulesIDsParents.set(
importModuleIdWithExtension,
entryModuleFilePath,
);
}
});

if (!addedModulesRelativeToModulePath.has(entryModuleFilePath)) {
const modulePathDirectory = moduleFilepath
.split('/')
.slice(0, -1)
.join('/');
const moduleData = {
module: `.${entryModuleFilePath.replace(modulePathDirectory, '')}`,
raw: rawEntry,
};
updateRelativeModules(moduleData, variant);
addedModulesRelativeToModulePath.add(entryModuleFilePath);
}
}
importedProcessedModuleIDs.delete(entry);
}
}
} catch {
throw new Error(
`Could not find a module for the relative import "${relativeModuleID}" in the demo "${demoName}"`,
);
}
});
}
}),
);
}
Expand Down