-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #157 from Shopify/compile-examples-for-playground
- Loading branch information
Showing
10 changed files
with
463 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export {components} from './components'; | ||
export type {Content} from './components'; |
99 changes: 99 additions & 0 deletions
99
scripts/typedoc/shopify-dev-renderer/components/utilities/compile-for-sandbox.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import * as fs from 'fs'; | ||
import {resolve, extname} from 'path'; | ||
import {rollup, ModuleFormat} from 'rollup'; | ||
import virtual from '@rollup/plugin-virtual'; | ||
import jsx from 'rollup-plugin-jsx'; | ||
|
||
import {skypackUrlResolve} from './skypack-url-resolve'; | ||
import type {Example} from './types'; | ||
|
||
export function renderSandboxComponentExamples( | ||
examples: Map<string, Example>, | ||
compiledPath: string, | ||
): string { | ||
let markdown = ''; | ||
|
||
const compiledFilename = getCompiledFilename(examples); | ||
|
||
markdown += `{% codeblock extensions_sandbox, compiled: "${compiledPath}/${compiledFilename}" %}\n\n`; | ||
|
||
examples.forEach((example, key) => { | ||
markdown += [ | ||
`{% code ${example.extension}, title: "${key}" %}`, | ||
`${example.content}`, | ||
'{% endcode %}', | ||
'\n', | ||
].join('\n'); | ||
}); | ||
|
||
markdown += '{% endcodeblock %}\n'; | ||
|
||
return markdown; | ||
} | ||
|
||
function getCompiledFilename(examples: Map<string, Example>): string { | ||
// we assume the first item in paths.packages is the one we want to feed to the compiler | ||
const key = [...examples.keys()][0]; | ||
const example = examples.get(key); | ||
return example.filename.replace(extname(example.filename), '.js'); | ||
} | ||
|
||
export function compileComponentExamples( | ||
examples: Map<string, Example>, | ||
examplesPath: string, | ||
) { | ||
if (!fs.existsSync(examplesPath)) { | ||
fs.mkdirSync(examplesPath, {recursive: true}); | ||
} | ||
|
||
// we actually only need one compiled file per example | ||
examples.forEach(async (example, key) => { | ||
if (key === 'React') return; | ||
|
||
try { | ||
const compiledContent = await compileForSandbox(example.content); | ||
|
||
const compiledFilename = example.filename.replace( | ||
extname(example.filename), | ||
'.js', | ||
); | ||
fs.writeFile( | ||
`${examplesPath}/${compiledFilename}`, | ||
compiledContent, | ||
function (err) { | ||
if (err) throw err; | ||
}, | ||
); | ||
} catch (error) { | ||
console.log(`error compiling ${example.filename}`); | ||
console.log(error); | ||
} | ||
}); | ||
} | ||
|
||
export async function compileForSandbox(inputCode: string): Promise<string> { | ||
const LOCAL_ID = 'INPUT'; | ||
const virtualModules = { | ||
[LOCAL_ID]: inputCode, | ||
}; | ||
|
||
const inputOptions = { | ||
input: LOCAL_ID, | ||
plugins: [ | ||
// The virtual plugin let us supply a string instead of a file as input | ||
virtual(virtualModules), | ||
skypackUrlResolve(), | ||
jsx({factory: 'React.createElement'}), | ||
], | ||
}; | ||
|
||
const outputOptions = { | ||
format: 'esm' as ModuleFormat, | ||
}; | ||
|
||
const bundle = await rollup(inputOptions); | ||
const {output} = await bundle.generate(outputOptions); | ||
|
||
const outputCode = `${output[0].code}`; | ||
return outputCode; | ||
} |
59 changes: 59 additions & 0 deletions
59
scripts/typedoc/shopify-dev-renderer/components/utilities/examples.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import * as fs from 'fs'; | ||
import {resolve, extname} from 'path'; | ||
|
||
import type {Packages} from '../../../types'; | ||
import type {Example} from './types'; | ||
|
||
export function findExamplesForComponent( | ||
componentName: string, | ||
packages: Packages, | ||
subPath: string, | ||
): Map<string, Example> { | ||
const examples = new Map(); | ||
|
||
Object.keys(packages).forEach((packageName) => { | ||
const packagePath = packages[packageName]; | ||
const componentExamplesFolder = resolve( | ||
`${packagePath}/src${subPath}/${componentName}/examples`, | ||
); | ||
|
||
if (fs.existsSync(componentExamplesFolder)) { | ||
fs.readdirSync(componentExamplesFolder).forEach((file) => { | ||
examples.set(packageName, { | ||
filename: file, | ||
extension: extname(file).split('.').pop(), | ||
content: fs.readFileSync( | ||
`${componentExamplesFolder}/${file}`, | ||
'utf8', | ||
), | ||
}); | ||
}); | ||
} | ||
}); | ||
|
||
return examples; | ||
} | ||
|
||
export function renderExamplesForComponent( | ||
examples: Map<string, Example>, | ||
): string { | ||
if (examples.size === 0) { | ||
return ''; | ||
} | ||
let markdown = ''; | ||
|
||
markdown += `{% codeblock %}\n\n`; | ||
|
||
examples.forEach((example, key) => { | ||
markdown += [ | ||
`{% code ${example.extension}, title: "${key}" %}{% raw %}`, | ||
`${example.content}`, | ||
'{% endraw %}{% endcode %}', | ||
'\n', | ||
].join('\n'); | ||
}); | ||
|
||
markdown += '{% endcodeblock %}\n\n'; | ||
|
||
return markdown; | ||
} |
6 changes: 6 additions & 0 deletions
6
scripts/typedoc/shopify-dev-renderer/components/utilities/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export {findExamplesForComponent, renderExamplesForComponent} from './examples'; | ||
|
||
export { | ||
renderSandboxComponentExamples, | ||
compileComponentExamples, | ||
} from './compile-for-sandbox'; |
73 changes: 73 additions & 0 deletions
73
scripts/typedoc/shopify-dev-renderer/components/utilities/skypack-url-resolve.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import fetch from 'node-fetch'; | ||
|
||
const SKYPACK_URL = 'https://cdn.skypack.dev'; | ||
|
||
const pinnedUrls = new Map<string, string>(); | ||
|
||
export function skypackUrlResolve() { | ||
return { | ||
async resolveId(source: string) { | ||
const convertedSource = await convertToSkypackSource(source); | ||
const maybeAbsoluteUrl = convertSkypackPathsToAbsoluteUrls( | ||
convertedSource, | ||
); | ||
const url = parseURL(maybeAbsoluteUrl); | ||
return url && isValidURL(url) ? url.href : null; | ||
}, | ||
async load(id: string) { | ||
const url = parseURL(id); | ||
const result = url && isValidURL(url) ? await loadURL(url) : null; | ||
return result; | ||
}, | ||
}; | ||
} | ||
|
||
function parseURL(source: string): URL | null { | ||
try { | ||
return new URL(source); | ||
} catch (error) { | ||
return null; | ||
} | ||
} | ||
|
||
function isValidURL(url: URL): boolean { | ||
return url !== null && ['http:', 'https:'].indexOf(url.protocol) >= 0; | ||
} | ||
|
||
async function loadURL(url: URL) { | ||
switch (url.protocol) { | ||
case 'http:': | ||
case 'https:': | ||
return fetch(url.href).then((res) => | ||
res.status === 404 ? null : res.text(), | ||
); | ||
default: | ||
throw new Error(`Cannot load URL protocol: ${url.protocol}`); | ||
} | ||
} | ||
|
||
/** Initial req to skypack returns a 'pinned' URL which loads faster on subsequent reqs */ | ||
async function pinnedUrl(pkg: string) { | ||
if (pinnedUrls.get(pkg) === undefined) { | ||
const res = await fetch(`${SKYPACK_URL}/${pkg}`); | ||
const importUrl = res.headers.get('x-import-url'); | ||
pinnedUrls.set(pkg, `${SKYPACK_URL}${importUrl}`); | ||
} | ||
return pinnedUrls.get(pkg); | ||
} | ||
|
||
async function convertToSkypackSource(pkg: string) { | ||
switch (pkg) { | ||
case '@shopify/admin-ui-extensions': | ||
case '@shopify/admin-ui-extensions-react': | ||
return pinnedUrl(`${pkg}`); | ||
default: | ||
return pkg; | ||
} | ||
} | ||
|
||
function convertSkypackPathsToAbsoluteUrls(path: string): string { | ||
return path.startsWith('/-/') || path.startsWith('/new/') | ||
? `${SKYPACK_URL}${path}` | ||
: path; | ||
} |
5 changes: 5 additions & 0 deletions
5
scripts/typedoc/shopify-dev-renderer/components/utilities/types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export interface Example { | ||
filename: string; | ||
extension: string; | ||
content: string; | ||
} |
Oops, something went wrong.