|
const { |
|
readFileSync, |
|
writeFileSync, |
|
mkdirSync, |
|
existsSync, |
|
readdirSync, |
|
} = require("node:fs"); |
|
const path = require("node:path"); |
|
|
|
/* -------------------------------------------------------------------------- */ |
|
/* Cli util to generate components, layout and services */ |
|
/* -------------------------------------------------------------------------- */ |
|
module.exports = function (/** @type {import('plop').NodePlopAPI} */ plop) { |
|
/* -------------------------------- Helpers; -------------------------------- */ |
|
function isChild(text) { |
|
return text.split("/").length >= 2; |
|
} |
|
/* ---------------------------------- Plop Helpers --------------------------------- */ |
|
// helper to give me component name from cli input, even handles child component like my-component/sub-component |
|
plop.setHelper("parseName", function (text) { |
|
return text.split("/").pop() || text; |
|
}); |
|
|
|
/* ------------------------------ Custom action ----------------------------- */ |
|
plop.setActionType("sort-index", function (_, { path }) { |
|
const sortedIndex = |
|
Array.from( |
|
readFileSync(path, "utf8") |
|
.split("\n") |
|
.filter((line) => line.trim().length > 0) |
|
.sort() |
|
.reduce((acc, line) => { |
|
return acc.add(line); |
|
}, new Set()) |
|
).join("\n") + "\n"; |
|
|
|
writeFileSync(path, sortedIndex); |
|
}); |
|
|
|
plop.setActionType("barrel", function ({ destination }, _) { |
|
const generatedIndex = |
|
readdirSync(destination) |
|
.filter( |
|
(file) => |
|
!( |
|
file.match(".test") || |
|
file.match(".story") || |
|
file.match("index.ts") || |
|
file.match("layouts") |
|
) |
|
) |
|
.map((file) => `export * from "./${path.parse(file).name}";`) |
|
.sort() |
|
.join("\n") + "\n"; |
|
|
|
writeFileSync(`${destination}/index.ts`, generatedIndex); |
|
}); |
|
|
|
/* ---------------------------- Create generator ---------------------------- */ |
|
const supportedTypes = [ |
|
"component", |
|
"function", |
|
"layout", |
|
"provider", |
|
"service", |
|
"session", |
|
]; |
|
|
|
const serverTypes = ["service", "session"]; |
|
|
|
function createGenerator(type, destination) { |
|
if (!supportedTypes.includes(type)) |
|
throw new Error(`Type ${type} is not supported`); |
|
if (!destination) throw new Error(`Destination is missing`); |
|
|
|
// create the initial index if not exists |
|
if (!existsSync(destination)) { |
|
mkdirSync(destination); |
|
} |
|
writeFileSync(`${destination}/index.ts`, "", { |
|
flag: "a", |
|
}); |
|
|
|
return { |
|
description: `Generate ${type} in ${destination}`, |
|
prompts: [ |
|
{ |
|
type: "input", |
|
name: "name", |
|
message: `${type} name`, |
|
}, |
|
], |
|
actions: [ |
|
{ |
|
type: "addMany", |
|
destination: `${destination}/{{name}}`, |
|
base: `templates/${type}`, |
|
templateFiles: [`templates/${type}/*`], |
|
}, |
|
{ |
|
type: "add", |
|
path: `${destination}/{{name}}/index.ts`, |
|
templateFile: `${ |
|
serverTypes.includes(type) |
|
? "templates/index.server.hbs" |
|
: "templates/index.hbs" |
|
}`, |
|
}, |
|
{ |
|
type: "append", |
|
path: `${destination}/index.ts`, |
|
templateFile: `templates/index.hbs`, |
|
separator: "", |
|
skip: ({ name }) => |
|
isChild(name) |
|
? `skip append in ${destination}/index.ts because it's a child ${type}` |
|
: false, |
|
}, |
|
{ |
|
type: "sort-index", |
|
path: `${destination}/index.ts`, |
|
skip: ({ name }) => |
|
isChild(name) |
|
? `skip sorting ${destination}/index.ts because it's a child ${type}` |
|
: false, |
|
}, |
|
], |
|
}; |
|
} |
|
|
|
/* ------------------------------ Plop commands ----------------------------- */ |
|
// npx plop new component my-component |
|
plop.setGenerator( |
|
"new component", |
|
createGenerator("component", "app/components") |
|
); |
|
// npx plop new layout provider my-layout/my-provider |
|
plop.setGenerator( |
|
"new component provider", |
|
createGenerator("provider", "app/components") |
|
); |
|
// npx plop new layout my-layout |
|
plop.setGenerator("new layout", createGenerator("layout", "app/components")); |
|
// npx plop new service my-service |
|
plop.setGenerator("new service", createGenerator("service", "app/services")); |
|
// npx plop new hook my-hook |
|
plop.setGenerator("new hook", createGenerator("function", "app/hooks")); |
|
// npx plop new util my-util |
|
plop.setGenerator("new util", createGenerator("function", "app/utils")); |
|
// npx plop new session my-session |
|
plop.setGenerator("new session", createGenerator("session", "app/sessions")); |
|
// npx plop new helper my-helper |
|
plop.setGenerator("new helper", createGenerator("function", "app/helpers")); |
|
// npx plop barrel app/folder-to-migrate |
|
plop.setGenerator("barrel", { |
|
description: `barrel a path`, |
|
prompts: [ |
|
{ |
|
type: "input", |
|
name: "destination", |
|
message: `destination to barrel`, |
|
}, |
|
], |
|
actions: [ |
|
{ |
|
type: "barrel", |
|
}, |
|
], |
|
}); |
|
}; |
This is my template needs. Make yours ⚡️