diff --git a/README.md b/README.md index 4b93155..2bc080c 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,15 @@ This is than passed to the (awesome) [define api](https://codesandbox.io/docs/im // Customise the embedding iframe given the generated url // default: getIframe: url => `` + + + // Customise the ignored file / folder names + // default: + ignoredFiles: [ + 'node_modules', + 'yarn.lock', + 'package-lock.json' + ] } } ] diff --git a/package.json b/package.json index d2066e1..80e5029 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { - "name": "gatsby-remark-embedded-codesandbox", - "version": "1.2.0", - "description": "Gatsby Remark plugin for embedding Codesandbox given a folder of files", + "name": "@guy/gatsby-remark-embedded-codesandbox", + "version": "1.0.0", + "description": "Gatsby Remark plugin for embedding Codesandbox given a recursive folder of files", "main": "index.js", - "repository": "https://github.com/elboman/gatsby-remark-embedded-codesandbox", + "repository": "https://github.com/guyathomas/gatsby-remark-embedded-codesandbox", "author": "Marco Botto ", "bugs": { - "url": "https://github.com/elboman/gatsby-remark-embedded-codesandbox/issues" + "url": "https://github.com/guyathomas/gatsby-remark-embedded-codesandbox/issues" }, "keywords": [ "gatsby", diff --git a/src/__tests__/index.js b/src/__tests__/index.js index 6ee4faf..f47b38f 100644 --- a/src/__tests__/index.js +++ b/src/__tests__/index.js @@ -3,6 +3,9 @@ jest.mock(`fs`, () => { existsSync: jest.fn(), readdirSync: jest.fn(), readFileSync: jest.fn(), + statSync: jest.fn(() => ({ + isDirectory: jest.fn(() => false) + })) }; }); diff --git a/src/index.js b/src/index.js index f8fb78c..69c270e 100644 --- a/src/index.js +++ b/src/index.js @@ -13,6 +13,12 @@ const DEFAULT_EMBED_OPTIONS = { const DEFAULT_GET_IFRAME = url => ``; +const DEFAULT_IGNORED_FILES = [ + 'node_modules', + 'package-lock.json', + 'yarn.lock' +] + // Matches compression used in Babel and CodeSandbox REPLs // https://github.com/babel/website/blob/master/js/repl/UriUtils.js const compress = string => @@ -21,6 +27,8 @@ const compress = string => .replace(/\//g, `_`) // Convert '/' to '_' .replace(/=+$/, ``); // Remove ending '=' + + module.exports = ( { markdownAST }, { @@ -28,6 +36,7 @@ module.exports = ( protocol = DEFAULT_PROTOCOL, embedOptions = DEFAULT_EMBED_OPTIONS, getIframe = DEFAULT_GET_IFRAME, + ignoredFiles = DEFAULT_IGNORED_FILES, } ) => { if (!rootDirectory) { @@ -38,24 +47,37 @@ module.exports = ( rootDirectory += '/'; } + const ignoredFilesSet = new Set(ignoredFiles) + const getDirectoryPath = url => { let directoryPath = url.replace(protocol, ''); const fullPath = path.join(rootDirectory, directoryPath); return normalizePath(fullPath); }; + const getAllFiles = (dirPath) => + fs.readdirSync(dirPath).reduce((acc, file) => { + if (ignoredFilesSet.has(file)) return acc; + const relativePath = dirPath + '/' + file; + const isDirectory = fs.statSync(relativePath).isDirectory(); + const additions = isDirectory ? getAllFiles(relativePath) : [relativePath]; + return [...acc, ...additions]; + }, []); + const getFilesList = directory => { let packageJsonFound = false; - const folderFiles = fs.readdirSync(directory); + const folderFiles = getAllFiles(directory); + const basePathRE = new RegExp(`^${directory}/`); const sandboxFiles = folderFiles + .map(file => file.replace(basePathRE, '')) // we ignore the package.json file as it will // be handled separately - .filter(file => file !== 'package.json') - .map(file => { - const fullFilePath = path.resolve(directory, file); + .filter(file => !file.includes('package.json')) + .map(relativePath => { + const fullFilePath = path.resolve(__dirname, directory, relativePath); const content = fs.readFileSync(fullFilePath, 'utf-8'); return { - name: file, + name: relativePath, content, }; }); @@ -92,14 +114,13 @@ module.exports = ( }; const getPackageJsonFile = fileList => { - const found = fileList.filter(name => name === 'package.json'); - return found.length > null; + return fileList.find(file => file.includes('package.json')); }; const createParams = files => { const filesObj = files.reduce((prev, current) => { // parse package.json first - if (current.name === 'package.json') { + if (current.name.includes('package.json')) { prev[current.name] = { content: JSON.parse(current.content) }; } else { prev[current.name] = { content: current.content }; @@ -109,7 +130,6 @@ module.exports = ( const params = { files: filesObj, }; - return compress(JSON.stringify(params)); };