Skip to content

Instantly share code, notes, and snippets.

@orta
Last active December 6, 2020 13:51
Show Gist options
  • Save orta/c75f3c326d6429e7271ddc883546de0c to your computer and use it in GitHub Desktop.
Save orta/c75f3c326d6429e7271ddc883546de0c to your computer and use it in GitHub Desktop.
A simple snowpack plugin for generating a .d.ts file for paths inside an asset folder
// @ts-check
const fs = require("fs")
const { join, basename } = require("path")
const { format } = require("prettier")
let log = undefined
/** @type {import("snowpack").SnowpackPluginFactory} */
function plugin(_snowpackConfig, _pluginOptions) {
return {
name: "snowpack-plugin-phaser-assets",
async run(opts) {
const backupLog = (_, opts) => opts.msg && console.log(opts.msg)
// @ts-ignore - This logging API is private, so it will change in the future
log = opts.log || backupLog
createTypedefs()
},
async onChange(opts) {
if (opts.filePath.includes("assets")) createTypedefs()
},
}
}
const createTypedefs = () => {
const publicRoot = join(__dirname, "..", "..", "public")
const sourceFile = join(__dirname, "..", "..", "src", "game")
const allFiles = getFilePaths(publicRoot)
const files = allFiles.map(f => f.replace(publicRoot + "/", ""))
const toID = str => {
if (!str.includes("/")) return false
return str.toLowerCase().replace(/\s/g, "-").split(".")[0].split("/").pop()
}
const code = `
/** All asset files */
export type Files = "${files.join('" | "')}"
/** IDs for any non-root file */
export type IDs = "${files.map(toID).filter(Boolean).join('" | "')}"
`
const typePath = join(sourceFile, "paths.d.ts")
fs.writeFileSync(typePath, format(code, { filepath: typePath }))
log("WORKER_RESET", {})
const date = new Intl.DateTimeFormat("en-US", { minute: "numeric", hour: "numeric", second: "numeric" }).format(new Date())
log("WORKER_MSG", { level: "log", msg: `${date} - Updated asset type definitions.` })
}
// prettier-ignore
const getFilePaths = folderPath => {
const entryPaths = fs.readdirSync(folderPath).map(entry => join(folderPath, entry));
const filePaths = entryPaths.filter(entryPath => fs.statSync(entryPath).isFile());
const dirPaths = entryPaths.filter(entryPath => !filePaths.includes(entryPath));
const dirFiles = dirPaths.reduce((prev, curr) => prev.concat(getFilePaths(curr)), []);
return [...filePaths, ...dirFiles].filter((f) => !basename(f).startsWith("."));
};
module.exports = plugin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment