mirror of
https://github.com/expo/config-plugins.git
synced 2026-11-14 10:08:06 -10:00
173 lines
4.4 KiB
TypeScript
173 lines
4.4 KiB
TypeScript
#!/usr/bin/env ts-node
|
|
|
|
import assert from "assert";
|
|
import * as fs from "fs";
|
|
import * as path from "path";
|
|
import prompts from "prompts";
|
|
// @ts-ignore
|
|
import replaceAll from "string.prototype.replaceall";
|
|
import * as PackageManager from "@expo/package-manager";
|
|
const packagesDir = path.join(__dirname, "../packages");
|
|
const templateDir = path.join(__dirname, "./template");
|
|
|
|
// Style like DT: @foo/bar -> foo__bar
|
|
function convertOrgName(name: string) {
|
|
const match = name.match(/^@(\w+)\/(\w+)/gi);
|
|
if (match?.length === 3) {
|
|
return [match[1], match[2]].join("__");
|
|
}
|
|
return name;
|
|
}
|
|
|
|
(async () => {
|
|
const { name } = await prompts({
|
|
initial: process.argv[2],
|
|
type: "text",
|
|
name: "name",
|
|
message: "Package to extend, ex: react-native-reanimated",
|
|
validate: (value) =>
|
|
/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(value),
|
|
});
|
|
|
|
assert(name, "name must be defined");
|
|
const pluginName = convertOrgName(name);
|
|
|
|
const packageName = `@config-plugins/${pluginName}`;
|
|
|
|
console.log(`Using name: ${packageName}`);
|
|
|
|
const outputDir = path.join(packagesDir, pluginName);
|
|
|
|
// assert(!fs.existsSync(outputDir), `package already exists at: ${outputDir}`);
|
|
|
|
if (fs.existsSync(outputDir)) {
|
|
if (
|
|
(
|
|
await prompts({
|
|
type: "confirm",
|
|
message: "overwrite existing module?",
|
|
initial: true,
|
|
name: "value",
|
|
})
|
|
).value
|
|
) {
|
|
// Nuke
|
|
fs.rmSync(outputDir, { recursive: true });
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
const moduleName = camelize(["with", name].join("-"));
|
|
|
|
const settings: Props = {
|
|
MODULE_NAME: moduleName,
|
|
CONFIG_PLUGIN: pluginName,
|
|
|
|
SDK_VERSION: "42",
|
|
NPM_MODULE: name,
|
|
};
|
|
console.log(`Module name: ${moduleName}`);
|
|
|
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
fs.writeFileSync(
|
|
path.join(outputDir, "package.json"),
|
|
JSON.stringify(getPackageJson(settings), null, 2)
|
|
);
|
|
|
|
fs.copyFileSync(
|
|
path.join(templateDir, "tsconfig.json"),
|
|
path.join(outputDir, "tsconfig.json")
|
|
);
|
|
|
|
const srcFolder = path.join(outputDir, "src");
|
|
fs.mkdirSync(srcFolder, { recursive: true });
|
|
|
|
fs.writeFileSync(
|
|
path.join(srcFolder, `${moduleName}.ts`),
|
|
createTemplatePlugin(settings)
|
|
);
|
|
|
|
fs.writeFileSync(
|
|
path.join(outputDir, `README.md`),
|
|
createTemplateREADME(settings)
|
|
);
|
|
fs.writeFileSync(
|
|
path.join(outputDir, "app.plugin.js"),
|
|
`module.exports = require("./build/${moduleName}");`
|
|
);
|
|
|
|
const manager = new PackageManager.YarnPackageManager({
|
|
cwd: outputDir,
|
|
silent: false,
|
|
});
|
|
await manager.installAsync();
|
|
})();
|
|
|
|
function camelize(str: string) {
|
|
const arr = str.split("-");
|
|
const capital = arr.map((item, index) =>
|
|
index
|
|
? item.charAt(0).toUpperCase() + item.slice(1).toLowerCase()
|
|
: item.toLowerCase()
|
|
);
|
|
return capital.join("");
|
|
}
|
|
|
|
type Props = {
|
|
NPM_MODULE: string;
|
|
SDK_VERSION: string;
|
|
MODULE_NAME: string;
|
|
CONFIG_PLUGIN: string;
|
|
};
|
|
|
|
function createTemplatePlugin({
|
|
MODULE_NAME,
|
|
SDK_VERSION,
|
|
CONFIG_PLUGIN,
|
|
NPM_MODULE,
|
|
}: Props) {
|
|
let template = fs.readFileSync(path.join(templateDir, "index.ts"), "utf8");
|
|
|
|
template = replaceAll(template, /%NPM_MODULE%/g, NPM_MODULE);
|
|
template = replaceAll(template, /%CONFIG_PLUGIN%/g, CONFIG_PLUGIN);
|
|
template = replaceAll(template, /_MODULE_NAME_/g, MODULE_NAME);
|
|
template = replaceAll(template, /%SDK_VERSION%/g, SDK_VERSION);
|
|
|
|
return template;
|
|
}
|
|
|
|
function createTemplateREADME({
|
|
MODULE_NAME,
|
|
SDK_VERSION,
|
|
CONFIG_PLUGIN,
|
|
NPM_MODULE,
|
|
}: Props) {
|
|
let template = fs.readFileSync(path.join(templateDir, "README.md"), "utf8");
|
|
|
|
template = replaceAll(template, /%NPM_MODULE%/g, NPM_MODULE);
|
|
template = replaceAll(template, /%CONFIG_PLUGIN%/g, CONFIG_PLUGIN);
|
|
template = replaceAll(template, /%MODULE_NAME%/g, MODULE_NAME);
|
|
template = replaceAll(template, /%SDK_VERSION%/g, SDK_VERSION);
|
|
|
|
return template;
|
|
}
|
|
|
|
function getPackageJson({
|
|
MODULE_NAME,
|
|
SDK_VERSION,
|
|
CONFIG_PLUGIN,
|
|
NPM_MODULE,
|
|
}: Props) {
|
|
const templatePackageJson = JSON.parse(
|
|
fs.readFileSync(path.join(templateDir, "package.json"), "utf8")
|
|
);
|
|
|
|
templatePackageJson.name = `@config-plugins/${CONFIG_PLUGIN}`;
|
|
templatePackageJson.description = `Config plugin for ${NPM_MODULE} package`;
|
|
templatePackageJson.main = `build/${MODULE_NAME}.js`;
|
|
templatePackageJson.types = `build/${MODULE_NAME}.d.ts`;
|
|
templatePackageJson.keywords.push(NPM_MODULE, `expo-${SDK_VERSION}`);
|
|
return templatePackageJson;
|
|
}
|