- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
183 lines
4.5 KiB
JavaScript
Executable File
183 lines
4.5 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import { spawn } from "node:child_process";
|
|
import { existsSync } from "node:fs";
|
|
import { dirname, join } from "node:path";
|
|
import { createInterface } from "node:readline/promises";
|
|
import { stdin as input, stdout as output } from "node:process";
|
|
import process from "node:process";
|
|
import packageJson from "../package.json" with { type: "json" };
|
|
|
|
const args = new Set(process.argv.slice(2));
|
|
const dryRun = args.has("--dry-run");
|
|
const skipTests = args.has("--skip-tests");
|
|
const yes = args.has("--yes") || process.env.CI === "true";
|
|
const version = packageJson.version;
|
|
const packageName = packageJson.name;
|
|
|
|
function npmCommand(commandArgs) {
|
|
const npmCli = join(dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js");
|
|
if (existsSync(npmCli)) {
|
|
return {
|
|
command: process.execPath,
|
|
args: [npmCli, ...commandArgs],
|
|
rendered: ["npm", ...commandArgs].join(" "),
|
|
};
|
|
}
|
|
|
|
return {
|
|
command: "npm",
|
|
args: commandArgs,
|
|
rendered: ["npm", ...commandArgs].join(" "),
|
|
};
|
|
}
|
|
|
|
function run(command, commandArgs, options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const invocation = command === "npm"
|
|
? npmCommand(commandArgs)
|
|
: { command, args: commandArgs, rendered: [command, ...commandArgs].join(" ") };
|
|
const child = spawn(invocation.command, invocation.args, {
|
|
shell: false,
|
|
stdio: options.capture ? ["ignore", "pipe", "pipe"] : "inherit",
|
|
env: { ...process.env, ...options.env },
|
|
});
|
|
|
|
let stdout = "";
|
|
let stderr = "";
|
|
|
|
if (options.capture) {
|
|
child.stdout?.on("data", (chunk) => {
|
|
stdout += chunk;
|
|
});
|
|
child.stderr?.on("data", (chunk) => {
|
|
stderr += chunk;
|
|
});
|
|
}
|
|
|
|
child.on("error", reject);
|
|
child.on("close", (code) => {
|
|
if (code === 0) {
|
|
resolve({ stdout: stdout.trim(), stderr: stderr.trim() });
|
|
return;
|
|
}
|
|
|
|
reject(new Error(`${invocation.rendered} failed with exit code ${code}\n${stderr.trim()}`));
|
|
});
|
|
});
|
|
}
|
|
|
|
async function npmViewVersion() {
|
|
try {
|
|
const { stdout } = await run("npm", ["view", `${packageName}@${version}`, "version"], {
|
|
capture: true,
|
|
});
|
|
return stdout || null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function npmWhoami() {
|
|
const token = process.env.NODE_AUTH_TOKEN || process.env.NPM_TOKEN;
|
|
if (token) {
|
|
return "token auth";
|
|
}
|
|
|
|
try {
|
|
const { stdout } = await run("npm", ["whoami"], { capture: true });
|
|
return stdout;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function promptForOtp() {
|
|
if (process.env.NPM_OTP) {
|
|
return process.env.NPM_OTP;
|
|
}
|
|
|
|
if (yes) {
|
|
return null;
|
|
}
|
|
|
|
const rl = createInterface({ input, output });
|
|
try {
|
|
const otp = await rl.question(
|
|
"npm 2FA code, if your account requires one. Press Enter to try without it: ",
|
|
);
|
|
return otp.trim() || null;
|
|
} finally {
|
|
rl.close();
|
|
}
|
|
}
|
|
|
|
async function confirmPublish() {
|
|
if (yes || dryRun) {
|
|
return;
|
|
}
|
|
|
|
const rl = createInterface({ input, output });
|
|
try {
|
|
const answer = await rl.question(`Publish ${packageName}@${version} to npm latest? Type yes: `);
|
|
if (answer.trim().toLowerCase() !== "yes") {
|
|
throw new Error("Publish cancelled.");
|
|
}
|
|
} finally {
|
|
rl.close();
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
console.log(`Preparing ${packageName}@${version} for npm ${dryRun ? "dry run" : "publish"}...`);
|
|
|
|
const existingVersion = await npmViewVersion();
|
|
if (existingVersion === version && !dryRun) {
|
|
throw new Error(`${packageName}@${version} is already published on npm.`);
|
|
}
|
|
|
|
const identity = await npmWhoami();
|
|
if (!identity && !dryRun) {
|
|
throw new Error(
|
|
"npm is not authenticated. Run npm login --auth-type=web, or set NPM_TOKEN/NODE_AUTH_TOKEN.",
|
|
);
|
|
}
|
|
|
|
if (identity) {
|
|
console.log(`npm auth: ${identity}`);
|
|
}
|
|
|
|
await run("npm", ["run", "build"]);
|
|
|
|
if (!skipTests) {
|
|
await run("npm", ["test"]);
|
|
}
|
|
|
|
await run("npm", ["pack", "--dry-run"]);
|
|
|
|
if (dryRun) {
|
|
console.log(`Dry run complete for ${packageName}@${version}.`);
|
|
return;
|
|
}
|
|
|
|
await confirmPublish();
|
|
|
|
const otp = await promptForOtp();
|
|
const publishArgs = ["publish", "--access", "public"];
|
|
if (otp) {
|
|
publishArgs.push(`--otp=${otp}`);
|
|
}
|
|
|
|
await run("npm", publishArgs, {
|
|
env: process.env.NPM_TOKEN ? { NODE_AUTH_TOKEN: process.env.NPM_TOKEN } : {},
|
|
});
|
|
|
|
const { stdout } = await run("npm", ["view", packageName, "version"], { capture: true });
|
|
console.log(`${packageName} latest is now ${stdout}.`);
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(error.message);
|
|
process.exit(1);
|
|
});
|