@voxelio/deploy 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{configExists as e,createChangeset as t,createDefaultConfig as n,createWorkflow as r,isValidDatapack as i,workflowExists as a,writeConfig as o}from"./workflow-D_9q4YIy.js";import{spawn as s}from"node:child_process";import{writeFile as c}from"node:fs/promises";import{tmpdir as l}from"node:os";import{join as u}from"node:path";import*as d from"@clack/prompts";const f=[`1.21.10`,`1.21.9`,`1.21.8`,`1.21.7`,`1.21.6`,`1.21.5`,`1.21.4`,`1.21.3`,`1.21.2`,`1.21.1`,`1.21`,`1.20.6`,`1.20.5`,`1.20.4`,`1.20.3`,`1.20.2`,`1.20.1`,`1.20`];async function p(){await i()||(d.log.error(`The current directory is not a valid datapack. Check that there is a pack.mcmeta file with a 'description' and 'pack_format' field.`),process.exit(1));let t=await e(),n=await a();if(!t)await m();else if(n){d.intro(`Voxelio Deploy`),d.note(`Ready to create a new changeset.
2
+ import{configExists as e,createChangeset as t,createDefaultConfig as n,createWorkflow as r,isValidDatapack as i,workflowExists as a,writeConfig as o}from"./workflow-JsUijDQh.js";import{spawn as s}from"node:child_process";import{writeFile as c}from"node:fs/promises";import{tmpdir as l}from"node:os";import{join as u}from"node:path";import*as d from"@clack/prompts";const f=[`1.21.10`,`1.21.9`,`1.21.8`,`1.21.7`,`1.21.6`,`1.21.5`,`1.21.4`,`1.21.3`,`1.21.2`,`1.21.1`,`1.21`,`1.20.6`,`1.20.5`,`1.20.4`,`1.20.3`,`1.20.2`,`1.20.1`,`1.20`];async function p(){await i()||(d.log.error(`The current directory is not a valid datapack. Check that there is a pack.mcmeta file with a 'description' and 'pack_format' field.`),process.exit(1));let t=await e(),n=await a();if(!t)await m();else if(n){d.intro(`Voxelio Deploy`),d.note(`Ready to create a new changeset.
3
3
 
4
4
  This will create a markdown file in the .changeset folder.
5
5
  The deployment will be triggered on the next commit containing this file.`,`Create Changeset`);let e=await d.confirm({message:`Do you want to continue?`});(d.isCancel(e)||!e)&&(d.cancel(`Operation cancelled`),process.exit(0)),await h(),d.outro(`Changeset created successfully!`)}else{d.intro(`Voxelio Deploy`);let e=d.spinner();e.start(`Creating workflow file...`),await r(),e.stop(`Workflow file created successfully!`),d.note(`Ready to create a new changeset.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["readFile"],"sources":["../src/commands/init.ts","../src/cli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as clack from \"@clack/prompts\";\nimport type { ChangesetFrontmatter, VersionBump, VersionType } from \"@/types/schema\";\nimport { createChangeset } from \"@/utils/changeset\";\nimport { configExists, createDefaultConfig, writeConfig } from \"@/utils/config\";\nimport { isValidDatapack } from \"@/utils/datapack\";\nimport { createWorkflow, workflowExists } from \"@/utils/workflow\";\n\nconst MINECRAFT_VERSIONS = [\n \"1.21.10\",\n \"1.21.9\",\n \"1.21.8\",\n \"1.21.7\",\n \"1.21.6\",\n \"1.21.5\",\n \"1.21.4\",\n \"1.21.3\",\n \"1.21.2\",\n \"1.21.1\",\n \"1.21\",\n \"1.20.6\",\n \"1.20.5\",\n \"1.20.4\",\n \"1.20.3\",\n \"1.20.2\",\n \"1.20.1\",\n \"1.20\"\n];\n\nexport async function init(): Promise<void> {\n const isDatapack = await isValidDatapack();\n if (!isDatapack) {\n clack.log.error(\n \"The current directory is not a valid datapack. Check that there is a pack.mcmeta file with a 'description' and 'pack_format' field.\"\n );\n process.exit(1);\n }\n\n const hasConfig = await configExists();\n const hasWorkflow = await workflowExists();\n\n if (!hasConfig) {\n await runFullSetup();\n } else if (!hasWorkflow) {\n clack.intro(\"Voxelio Deploy\");\n\n const spinner = clack.spinner();\n spinner.start(\"Creating workflow file...\");\n await createWorkflow();\n spinner.stop(\"Workflow file created successfully!\");\n\n clack.note(\n \"Ready to create a new changeset.\\n\\nThis will create a markdown file in the .changeset folder.\\nThe deployment will be triggered on the next commit containing this file.\",\n \"Create Changeset\"\n );\n\n const wantsChangeset = await clack.confirm({\n message: \"Do you want to continue?\"\n });\n\n if (clack.isCancel(wantsChangeset) || !wantsChangeset) {\n clack.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n await createNewChangeset();\n clack.outro(\"Changeset created successfully!\");\n } else {\n clack.intro(\"Voxelio Deploy\");\n\n clack.note(\n \"Ready to create a new changeset.\\n\\nThis will create a markdown file in the .changeset folder.\\nThe deployment will be triggered on the next commit containing this file.\",\n \"Create Changeset\"\n );\n\n const wantsChangeset = await clack.confirm({\n message: \"Do you want to continue?\"\n });\n\n if (clack.isCancel(wantsChangeset) || !wantsChangeset) {\n clack.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n await createNewChangeset();\n clack.outro(\"Changeset created successfully!\");\n }\n}\n\nasync function runFullSetup(): Promise<void> {\n clack.intro(\"Voxelio Deploy - Configuration\");\n\n clack.note(\n \"Hello, welcome to the Voxelio Deploy configuration. We will prepare the environment together to easily deploy to Modrinth and CurseForge.\\n\\nA few things to know:\\n- If you want to stop, you can press Escape or Ctrl+C\\n- You will need a Modrinth and/or CurseForge account\",\n \"Welcome\"\n );\n\n const continueSetup = await clack.confirm({\n message: \"Ready to start configuration?\"\n });\n\n if (clack.isCancel(continueSetup) || !continueSetup) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n clack.note(\n 'Don\\'t forget to set environment variables in your GitHub project!\\n\\nYou need to define in Settings > Secrets and Variables > Actions > Secrets > Repository secrets:\\n- CURSEFORGE_TOKEN: https://legacy.curseforge.com/account/api-tokens\\n- MODRINTH_TOKEN: https://modrinth.com/settings/pats with \"Create Version\" permission',\n \"Environment Variables\"\n );\n\n const envVarConfirm = await clack.confirm({\n message: \"All set, shall we continue?\"\n });\n\n if (clack.isCancel(envVarConfirm) || !envVarConfirm) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n clack.note(\n \"Do you want your datapack to be automatically converted to a mod?\\n\\n- For Modrinth this will create 2 versions on the same project\\n- For CurseForge this will create 2 separate projects\",\n \"Package as mod\"\n );\n\n const packageAsMod = await clack.confirm({\n message: \"Do you want package your datapack as a mod?\"\n });\n\n if (clack.isCancel(packageAsMod)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n const platformOptions = [{ value: \"modrinth\", label: \"Modrinth\" }];\n\n if (packageAsMod) {\n platformOptions.push({ value: \"curseforge_datapack\", label: \"CurseForge (Datapack)\" });\n platformOptions.push({ value: \"curseforge_mod\", label: \"CurseForge (Mod)\" });\n }\n\n if (!packageAsMod) {\n platformOptions.push({ value: \"curseforge_datapack\", label: \"CurseForge\" });\n }\n\n const platforms = await clack.multiselect({\n message: \"Choose platforms\",\n options: platformOptions,\n required: true\n });\n\n if (clack.isCancel(platforms)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n const projectName = await clack.text({\n message: \"Project name (appears in CurseForge)\",\n placeholder: \"My Datapack\",\n validate: (value) => (value.length === 0 ? \"Required\" : undefined)\n });\n\n if (clack.isCancel(projectName)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n const versionPreview = \"1.0.0\";\n\n const projectFilename = await clack.text({\n message: `Project Filename (For zipped datapack) - Preview: ${projectName}-${versionPreview}.zip`,\n placeholder: projectName as string,\n defaultValue: projectName as string\n });\n\n if (clack.isCancel(projectFilename)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n let modFilename = projectFilename;\n if (packageAsMod) {\n const modFilenameInput = await clack.text({\n message: `Mod Filename (For JAR file) - Preview: ${projectFilename}-${versionPreview}.jar`,\n placeholder: projectFilename as string,\n defaultValue: projectFilename as string\n });\n\n if (clack.isCancel(modFilenameInput)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n modFilename = modFilenameInput;\n }\n\n const version = await clack.text({\n message: \"Initial version\",\n placeholder: \"1.0.0\",\n defaultValue: \"1.0.0\",\n validate: (value) => (value.length === 0 || /^\\d+\\.\\d+\\.\\d+$/.test(value) ? undefined : \"Format: X.Y.Z\")\n });\n\n if (clack.isCancel(version)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n const config = createDefaultConfig();\n config.project.name = projectName as string;\n config.project.filename = projectFilename as string;\n config.project.version = version as string;\n\n const platformList = platforms as string[];\n\n if (platformList.includes(\"modrinth\")) {\n const modrinthId = await clack.text({\n message: \"Modrinth Project ID - https://modrinth.com/dashboard/projects\",\n placeholder: \"AABBCCDD\",\n validate: (value) => {\n if (value.length === 0) return \"Required\";\n if (value.length !== 8) return \"Must be exactly 8 characters\";\n return undefined;\n }\n });\n\n if (clack.isCancel(modrinthId)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n config.modrinth.enabled = true;\n config.modrinth.project_id = modrinthId as string;\n }\n\n if (platformList.includes(\"curseforge_datapack\")) {\n const curseforgeDatapackId = await clack.text({\n message:\n \"CurseForge Datapack Project ID - Can be found on the Public Page e.g https://www.curseforge.com/minecraft/mc-mods/neoenchant\",\n placeholder: \"12345678\",\n validate: (value) => {\n if (value.length === 0) return \"Required\";\n if (!/^\\d+$/.test(value)) return \"Must be a number\";\n return undefined;\n }\n });\n\n if (clack.isCancel(curseforgeDatapackId)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n config.curseforge.datapack.enabled = true;\n config.curseforge.datapack.project_id = Number.parseInt(curseforgeDatapackId as string, 10);\n }\n\n if (platformList.includes(\"curseforge_mod\")) {\n const curseforgeModId = await clack.text({\n message: \"CurseForge Mod Project ID\",\n placeholder: \"12345678\",\n validate: (value) => {\n if (value.length === 0) return \"Required\";\n if (!/^\\d+$/.test(value)) return \"Must be a number\";\n return undefined;\n }\n });\n\n if (clack.isCancel(curseforgeModId)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n config.curseforge.mod.enabled = true;\n config.curseforge.mod.project_id = Number.parseInt(curseforgeModId as string, 10);\n }\n\n if (packageAsMod) {\n config.package_as_mod.enabled = true;\n config.package_as_mod.filename = modFilename as string;\n\n const loaders = await clack.multiselect({\n message: \"Mod loaders\",\n options: [\n { value: \"fabric\", label: \"Fabric\" },\n { value: \"forge\", label: \"Forge\" },\n { value: \"neoforge\", label: \"NeoForge\" },\n { value: \"quilt\", label: \"Quilt\" }\n ],\n required: true\n });\n\n if (clack.isCancel(loaders)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n config.package_as_mod.loaders = loaders as string[];\n\n const modId = await clack.text({\n message: \"Mod ID\",\n placeholder: toCamelCase(projectName as string),\n defaultValue: toCamelCase(projectName as string)\n });\n\n if (clack.isCancel(modId)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n config.package_as_mod.id = modId as string;\n }\n\n const wantsExtra = await clack.confirm({\n message: \"Do you want to configure additional information (author, homepage, sources, issues)?\"\n });\n\n if (clack.isCancel(wantsExtra)) {\n clack.cancel(\"Configuration cancelled\");\n process.exit(0);\n }\n\n if (wantsExtra) {\n const authors = await clack.text({\n message: \"Authors (comma-separated)\",\n placeholder: \"Author1, Author2\"\n });\n\n if (!clack.isCancel(authors) && authors && (authors as string).trim() !== \"\") {\n config.package_as_mod.authors = (authors as string).split(\",\").map((a) => a.trim());\n }\n\n const homepage = await clack.text({\n message: \"Homepage URL\",\n placeholder: \"https://example.com\",\n validate: (value) => {\n if (!value || value.trim() === \"\") return undefined;\n if (!value.startsWith(\"https://\")) return \"Must start with https://\";\n try {\n const url = new URL(value);\n if (!url.hostname.includes(\".\")) return \"Must be a valid domain (e.g., example.com)\";\n return undefined;\n } catch {\n return \"Invalid URL format\";\n }\n }\n });\n\n if (!clack.isCancel(homepage) && homepage && (homepage as string).trim() !== \"\") {\n config.package_as_mod.homepage = homepage as string;\n }\n\n const sources = await clack.text({\n message: \"Sources URL\",\n placeholder: \"https://github.com/user/repo\",\n validate: (value) => {\n if (!value || value.trim() === \"\") return undefined;\n if (!value.startsWith(\"https://\")) return \"Must start with https://\";\n try {\n const url = new URL(value);\n if (!url.hostname.includes(\".\")) return \"Must be a valid domain (e.g., github.com)\";\n return undefined;\n } catch {\n return \"Invalid URL format\";\n }\n }\n });\n\n if (!clack.isCancel(sources) && sources && (sources as string).trim() !== \"\") {\n config.package_as_mod.sources = sources as string;\n }\n\n const issues = await clack.text({\n message: \"Issues URL\",\n placeholder: \"https://github.com/user/repo/issues\",\n validate: (value) => {\n if (!value || value.trim() === \"\") return undefined;\n if (!value.startsWith(\"https://\")) return \"Must start with https://\";\n try {\n const url = new URL(value);\n if (!url.hostname.includes(\".\")) return \"Must be a valid domain (e.g., github.com)\";\n return undefined;\n } catch {\n return \"Invalid URL format\";\n }\n }\n });\n\n if (!clack.isCancel(issues) && issues && (issues as string).trim() !== \"\") {\n config.package_as_mod.issues = issues as string;\n }\n }\n\n const spinner = clack.spinner();\n spinner.start(\"Creating configuration...\");\n\n await writeConfig(config);\n await createWorkflow();\n\n spinner.stop(\"Configuration created successfully!\");\n\n clack.note(\n \"The deploy.yaml file has been created at the root of your project.\\n\\nYou can edit this file to configure advanced settings such as:\\n- Excluding files from the build\\n- Java versions for CurseForge\\n- Environment settings (client/server)\\n- And more...\",\n \"Configuration Complete\"\n );\n\n clack.outro(\"Thank you for your participation, we're done! šŸŽ‰\");\n\n const wantsChangeset = await clack.confirm({\n message: \"Do you want to create a changeset now?\\n\\n (It will be deployed on the next commit)\"\n });\n\n if (clack.isCancel(wantsChangeset) || !wantsChangeset) {\n return;\n }\n\n clack.intro(\"Create Changeset\");\n await createNewChangeset();\n clack.outro(\"Changeset created successfully!\");\n}\n\nasync function createNewChangeset(): Promise<void> {\n const gameVersions = await clack.multiselect({\n message: \"Select Minecraft versions\",\n options: MINECRAFT_VERSIONS.map((version) => ({\n value: version,\n label: version\n })),\n required: true\n });\n\n if (clack.isCancel(gameVersions)) {\n clack.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n const versionType = await clack.select({\n message: \"Version type\",\n options: [\n { value: \"release\", label: \"Release\" },\n { value: \"beta\", label: \"Beta\" },\n { value: \"alpha\", label: \"Alpha\" }\n ]\n });\n\n if (clack.isCancel(versionType)) {\n clack.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n const versionBump = await clack.select({\n message: \"Version bump\",\n options: [\n { value: \"patch\", label: \"Patch (0.0.X)\" },\n { value: \"minor\", label: \"Minor (0.X.0)\" },\n { value: \"major\", label: \"Major (X.0.0)\" }\n ]\n });\n\n if (clack.isCancel(versionBump)) {\n clack.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n let changelog = await clack.text({\n message: \"Changelog (press Enter to open editor)\",\n placeholder: \"Added new features...\"\n });\n\n if (clack.isCancel(changelog)) {\n clack.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n if (!changelog || (changelog as string).trim() === \"\") {\n clack.note(\"Opening editor...\\n\\nāš ļø IMPORTANT: Save your changes (Ctrl+S) before closing the editor!\", \"Editor\");\n\n const editedChangelog = await openEditor();\n\n if (editedChangelog === null) {\n clack.cancel(\"Operation cancelled\");\n process.exit(0);\n }\n\n if (editedChangelog.trim() === \"\") {\n clack.log.error(\"Changelog cannot be empty. Please provide a changelog.\");\n process.exit(1);\n }\n\n changelog = editedChangelog;\n }\n\n const frontmatter: ChangesetFrontmatter = {\n game_versions: gameVersions as string[],\n version_type: versionType as VersionType,\n version_bump: versionBump as VersionBump\n };\n\n const filepath = await createChangeset(frontmatter, changelog as string);\n clack.log.success(`Created ${filepath}`);\n}\n\nasync function openEditor(): Promise<string | null> {\n const tmpFile = join(tmpdir(), `voxset-${Date.now()}.md`);\n await writeFile(tmpFile, \"# Write your changelog here\\n\", \"utf-8\");\n\n const editor = process.env.EDITOR || (process.platform === \"win32\" ? \"notepad\" : \"nano\");\n\n return new Promise((resolve) => {\n const child = spawn(editor, [tmpFile], { stdio: \"inherit\" });\n\n child.on(\"exit\", async (code) => {\n if (code === 0) {\n const { readFile } = await import(\"node:fs/promises\");\n const content = await readFile(tmpFile, \"utf-8\");\n const cleaned = content.replace(/^# Write your changelog here\\n/, \"\").trim();\n resolve(cleaned);\n } else {\n resolve(null);\n }\n });\n });\n}\n\nfunction toCamelCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[^a-z0-9]+(.)/g, (_, char) => char.toUpperCase())\n .replace(/^(.)/, (char) => char.toLowerCase());\n}\n","#!/usr/bin/env node\nimport { init } from \"@/commands/init\";\n\ntry {\n await init();\n} catch (error) {\n console.error(\"Error:\", error instanceof Error ? error.message : error);\n process.exit(1);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["readFile"],"sources":["../src/commands/init.ts","../src/cli.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\r\nimport { writeFile } from \"node:fs/promises\";\r\nimport { tmpdir } from \"node:os\";\r\nimport { join } from \"node:path\";\r\nimport * as clack from \"@clack/prompts\";\r\nimport type { ChangesetFrontmatter, VersionBump, VersionType } from \"@/types/schema\";\r\nimport { createChangeset } from \"@/utils/changeset\";\r\nimport { configExists, createDefaultConfig, writeConfig } from \"@/utils/config\";\r\nimport { isValidDatapack } from \"@/utils/datapack\";\r\nimport { createWorkflow, workflowExists } from \"@/utils/workflow\";\r\n\r\nconst MINECRAFT_VERSIONS = [\r\n \"1.21.10\",\r\n \"1.21.9\",\r\n \"1.21.8\",\r\n \"1.21.7\",\r\n \"1.21.6\",\r\n \"1.21.5\",\r\n \"1.21.4\",\r\n \"1.21.3\",\r\n \"1.21.2\",\r\n \"1.21.1\",\r\n \"1.21\",\r\n \"1.20.6\",\r\n \"1.20.5\",\r\n \"1.20.4\",\r\n \"1.20.3\",\r\n \"1.20.2\",\r\n \"1.20.1\",\r\n \"1.20\"\r\n];\r\n\r\nexport async function init(): Promise<void> {\r\n const isDatapack = await isValidDatapack();\r\n if (!isDatapack) {\r\n clack.log.error(\r\n \"The current directory is not a valid datapack. Check that there is a pack.mcmeta file with a 'description' and 'pack_format' field.\"\r\n );\r\n process.exit(1);\r\n }\r\n\r\n const hasConfig = await configExists();\r\n const hasWorkflow = await workflowExists();\r\n\r\n if (!hasConfig) {\r\n await runFullSetup();\r\n } else if (!hasWorkflow) {\r\n clack.intro(\"Voxelio Deploy\");\r\n\r\n const spinner = clack.spinner();\r\n spinner.start(\"Creating workflow file...\");\r\n await createWorkflow();\r\n spinner.stop(\"Workflow file created successfully!\");\r\n\r\n clack.note(\r\n \"Ready to create a new changeset.\\n\\nThis will create a markdown file in the .changeset folder.\\nThe deployment will be triggered on the next commit containing this file.\",\r\n \"Create Changeset\"\r\n );\r\n\r\n const wantsChangeset = await clack.confirm({\r\n message: \"Do you want to continue?\"\r\n });\r\n\r\n if (clack.isCancel(wantsChangeset) || !wantsChangeset) {\r\n clack.cancel(\"Operation cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n await createNewChangeset();\r\n clack.outro(\"Changeset created successfully!\");\r\n } else {\r\n clack.intro(\"Voxelio Deploy\");\r\n\r\n clack.note(\r\n \"Ready to create a new changeset.\\n\\nThis will create a markdown file in the .changeset folder.\\nThe deployment will be triggered on the next commit containing this file.\",\r\n \"Create Changeset\"\r\n );\r\n\r\n const wantsChangeset = await clack.confirm({\r\n message: \"Do you want to continue?\"\r\n });\r\n\r\n if (clack.isCancel(wantsChangeset) || !wantsChangeset) {\r\n clack.cancel(\"Operation cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n await createNewChangeset();\r\n clack.outro(\"Changeset created successfully!\");\r\n }\r\n}\r\n\r\nasync function runFullSetup(): Promise<void> {\r\n clack.intro(\"Voxelio Deploy - Configuration\");\r\n\r\n clack.note(\r\n \"Hello, welcome to the Voxelio Deploy configuration. We will prepare the environment together to easily deploy to Modrinth and CurseForge.\\n\\nA few things to know:\\n- If you want to stop, you can press Escape or Ctrl+C\\n- You will need a Modrinth and/or CurseForge account\",\r\n \"Welcome\"\r\n );\r\n\r\n const continueSetup = await clack.confirm({\r\n message: \"Ready to start configuration?\"\r\n });\r\n\r\n if (clack.isCancel(continueSetup) || !continueSetup) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n clack.note(\r\n 'Don\\'t forget to set environment variables in your GitHub project!\\n\\nYou need to define in Settings > Secrets and Variables > Actions > Secrets > Repository secrets:\\n- CURSEFORGE_TOKEN: https://legacy.curseforge.com/account/api-tokens\\n- MODRINTH_TOKEN: https://modrinth.com/settings/pats with \"Create Version\" permission',\r\n \"Environment Variables\"\r\n );\r\n\r\n const envVarConfirm = await clack.confirm({\r\n message: \"All set, shall we continue?\"\r\n });\r\n\r\n if (clack.isCancel(envVarConfirm) || !envVarConfirm) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n clack.note(\r\n \"Do you want your datapack to be automatically converted to a mod?\\n\\n- For Modrinth this will create 2 versions on the same project\\n- For CurseForge this will create 2 separate projects\",\r\n \"Package as mod\"\r\n );\r\n\r\n const packageAsMod = await clack.confirm({\r\n message: \"Do you want package your datapack as a mod?\"\r\n });\r\n\r\n if (clack.isCancel(packageAsMod)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n const platformOptions = [{ value: \"modrinth\", label: \"Modrinth\" }];\r\n\r\n if (packageAsMod) {\r\n platformOptions.push({ value: \"curseforge_datapack\", label: \"CurseForge (Datapack)\" });\r\n platformOptions.push({ value: \"curseforge_mod\", label: \"CurseForge (Mod)\" });\r\n }\r\n\r\n if (!packageAsMod) {\r\n platformOptions.push({ value: \"curseforge_datapack\", label: \"CurseForge\" });\r\n }\r\n\r\n const platforms = await clack.multiselect({\r\n message: \"Choose platforms\",\r\n options: platformOptions,\r\n required: true\r\n });\r\n\r\n if (clack.isCancel(platforms)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n const projectName = await clack.text({\r\n message: \"Project name (appears in CurseForge)\",\r\n placeholder: \"My Datapack\",\r\n validate: (value) => (value.length === 0 ? \"Required\" : undefined)\r\n });\r\n\r\n if (clack.isCancel(projectName)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n const versionPreview = \"1.0.0\";\r\n\r\n const projectFilename = await clack.text({\r\n message: `Project Filename (For zipped datapack) - Preview: ${projectName}-${versionPreview}.zip`,\r\n placeholder: projectName as string,\r\n defaultValue: projectName as string\r\n });\r\n\r\n if (clack.isCancel(projectFilename)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n let modFilename = projectFilename;\r\n if (packageAsMod) {\r\n const modFilenameInput = await clack.text({\r\n message: `Mod Filename (For JAR file) - Preview: ${projectFilename}-${versionPreview}.jar`,\r\n placeholder: projectFilename as string,\r\n defaultValue: projectFilename as string\r\n });\r\n\r\n if (clack.isCancel(modFilenameInput)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n modFilename = modFilenameInput;\r\n }\r\n\r\n const version = await clack.text({\r\n message: \"Initial version\",\r\n placeholder: \"1.0.0\",\r\n defaultValue: \"1.0.0\",\r\n validate: (value) => (value.length === 0 || /^\\d+\\.\\d+\\.\\d+$/.test(value) ? undefined : \"Format: X.Y.Z\")\r\n });\r\n\r\n if (clack.isCancel(version)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n const config = createDefaultConfig();\r\n config.project.name = projectName as string;\r\n config.project.filename = projectFilename as string;\r\n config.project.version = version as string;\r\n\r\n const platformList = platforms as string[];\r\n\r\n if (platformList.includes(\"modrinth\")) {\r\n const modrinthId = await clack.text({\r\n message: \"Modrinth Project ID - https://modrinth.com/dashboard/projects\",\r\n placeholder: \"AABBCCDD\",\r\n validate: (value) => {\r\n if (value.length === 0) return \"Required\";\r\n if (value.length !== 8) return \"Must be exactly 8 characters\";\r\n return undefined;\r\n }\r\n });\r\n\r\n if (clack.isCancel(modrinthId)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n config.modrinth.enabled = true;\r\n config.modrinth.project_id = modrinthId as string;\r\n }\r\n\r\n if (platformList.includes(\"curseforge_datapack\")) {\r\n const curseforgeDatapackId = await clack.text({\r\n message:\r\n \"CurseForge Datapack Project ID - Can be found on the Public Page e.g https://www.curseforge.com/minecraft/mc-mods/neoenchant\",\r\n placeholder: \"12345678\",\r\n validate: (value) => {\r\n if (value.length === 0) return \"Required\";\r\n if (!/^\\d+$/.test(value)) return \"Must be a number\";\r\n return undefined;\r\n }\r\n });\r\n\r\n if (clack.isCancel(curseforgeDatapackId)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n config.curseforge.datapack.enabled = true;\r\n config.curseforge.datapack.project_id = Number.parseInt(curseforgeDatapackId as string, 10);\r\n }\r\n\r\n if (platformList.includes(\"curseforge_mod\")) {\r\n const curseforgeModId = await clack.text({\r\n message: \"CurseForge Mod Project ID\",\r\n placeholder: \"12345678\",\r\n validate: (value) => {\r\n if (value.length === 0) return \"Required\";\r\n if (!/^\\d+$/.test(value)) return \"Must be a number\";\r\n return undefined;\r\n }\r\n });\r\n\r\n if (clack.isCancel(curseforgeModId)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n config.curseforge.mod.enabled = true;\r\n config.curseforge.mod.project_id = Number.parseInt(curseforgeModId as string, 10);\r\n }\r\n\r\n if (packageAsMod) {\r\n config.package_as_mod.enabled = true;\r\n config.package_as_mod.filename = modFilename as string;\r\n\r\n const loaders = await clack.multiselect({\r\n message: \"Mod loaders\",\r\n options: [\r\n { value: \"fabric\", label: \"Fabric\" },\r\n { value: \"forge\", label: \"Forge\" },\r\n { value: \"neoforge\", label: \"NeoForge\" },\r\n { value: \"quilt\", label: \"Quilt\" }\r\n ],\r\n required: true\r\n });\r\n\r\n if (clack.isCancel(loaders)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n config.package_as_mod.loaders = loaders as string[];\r\n\r\n const modId = await clack.text({\r\n message: \"Mod ID\",\r\n placeholder: toCamelCase(projectName as string),\r\n defaultValue: toCamelCase(projectName as string)\r\n });\r\n\r\n if (clack.isCancel(modId)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n config.package_as_mod.id = modId as string;\r\n }\r\n\r\n const wantsExtra = await clack.confirm({\r\n message: \"Do you want to configure additional information (author, homepage, sources, issues)?\"\r\n });\r\n\r\n if (clack.isCancel(wantsExtra)) {\r\n clack.cancel(\"Configuration cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n if (wantsExtra) {\r\n const authors = await clack.text({\r\n message: \"Authors (comma-separated)\",\r\n placeholder: \"Author1, Author2\"\r\n });\r\n\r\n if (!clack.isCancel(authors) && authors && (authors as string).trim() !== \"\") {\r\n config.package_as_mod.authors = (authors as string).split(\",\").map((a) => a.trim());\r\n }\r\n\r\n const homepage = await clack.text({\r\n message: \"Homepage URL\",\r\n placeholder: \"https://example.com\",\r\n validate: (value) => {\r\n if (!value || value.trim() === \"\") return undefined;\r\n if (!value.startsWith(\"https://\")) return \"Must start with https://\";\r\n try {\r\n const url = new URL(value);\r\n if (!url.hostname.includes(\".\")) return \"Must be a valid domain (e.g., example.com)\";\r\n return undefined;\r\n } catch {\r\n return \"Invalid URL format\";\r\n }\r\n }\r\n });\r\n\r\n if (!clack.isCancel(homepage) && homepage && (homepage as string).trim() !== \"\") {\r\n config.package_as_mod.homepage = homepage as string;\r\n }\r\n\r\n const sources = await clack.text({\r\n message: \"Sources URL\",\r\n placeholder: \"https://github.com/user/repo\",\r\n validate: (value) => {\r\n if (!value || value.trim() === \"\") return undefined;\r\n if (!value.startsWith(\"https://\")) return \"Must start with https://\";\r\n try {\r\n const url = new URL(value);\r\n if (!url.hostname.includes(\".\")) return \"Must be a valid domain (e.g., github.com)\";\r\n return undefined;\r\n } catch {\r\n return \"Invalid URL format\";\r\n }\r\n }\r\n });\r\n\r\n if (!clack.isCancel(sources) && sources && (sources as string).trim() !== \"\") {\r\n config.package_as_mod.sources = sources as string;\r\n }\r\n\r\n const issues = await clack.text({\r\n message: \"Issues URL\",\r\n placeholder: \"https://github.com/user/repo/issues\",\r\n validate: (value) => {\r\n if (!value || value.trim() === \"\") return undefined;\r\n if (!value.startsWith(\"https://\")) return \"Must start with https://\";\r\n try {\r\n const url = new URL(value);\r\n if (!url.hostname.includes(\".\")) return \"Must be a valid domain (e.g., github.com)\";\r\n return undefined;\r\n } catch {\r\n return \"Invalid URL format\";\r\n }\r\n }\r\n });\r\n\r\n if (!clack.isCancel(issues) && issues && (issues as string).trim() !== \"\") {\r\n config.package_as_mod.issues = issues as string;\r\n }\r\n }\r\n\r\n const spinner = clack.spinner();\r\n spinner.start(\"Creating configuration...\");\r\n\r\n await writeConfig(config);\r\n await createWorkflow();\r\n\r\n spinner.stop(\"Configuration created successfully!\");\r\n\r\n clack.note(\r\n \"The deploy.yaml file has been created at the root of your project.\\n\\nYou can edit this file to configure advanced settings such as:\\n- Excluding files from the build\\n- Java versions for CurseForge\\n- Environment settings (client/server)\\n- And more...\",\r\n \"Configuration Complete\"\r\n );\r\n\r\n clack.outro(\"Thank you for your participation, we're done! šŸŽ‰\");\r\n\r\n const wantsChangeset = await clack.confirm({\r\n message: \"Do you want to create a changeset now?\\n\\n (It will be deployed on the next commit)\"\r\n });\r\n\r\n if (clack.isCancel(wantsChangeset) || !wantsChangeset) {\r\n return;\r\n }\r\n\r\n clack.intro(\"Create Changeset\");\r\n await createNewChangeset();\r\n clack.outro(\"Changeset created successfully!\");\r\n}\r\n\r\nasync function createNewChangeset(): Promise<void> {\r\n const gameVersions = await clack.multiselect({\r\n message: \"Select Minecraft versions\",\r\n options: MINECRAFT_VERSIONS.map((version) => ({\r\n value: version,\r\n label: version\r\n })),\r\n required: true\r\n });\r\n\r\n if (clack.isCancel(gameVersions)) {\r\n clack.cancel(\"Operation cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n const versionType = await clack.select({\r\n message: \"Version type\",\r\n options: [\r\n { value: \"release\", label: \"Release\" },\r\n { value: \"beta\", label: \"Beta\" },\r\n { value: \"alpha\", label: \"Alpha\" }\r\n ]\r\n });\r\n\r\n if (clack.isCancel(versionType)) {\r\n clack.cancel(\"Operation cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n const versionBump = await clack.select({\r\n message: \"Version bump\",\r\n options: [\r\n { value: \"patch\", label: \"Patch (0.0.X)\" },\r\n { value: \"minor\", label: \"Minor (0.X.0)\" },\r\n { value: \"major\", label: \"Major (X.0.0)\" }\r\n ]\r\n });\r\n\r\n if (clack.isCancel(versionBump)) {\r\n clack.cancel(\"Operation cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n let changelog = await clack.text({\r\n message: \"Changelog (press Enter to open editor)\",\r\n placeholder: \"Added new features...\"\r\n });\r\n\r\n if (clack.isCancel(changelog)) {\r\n clack.cancel(\"Operation cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n if (!changelog || (changelog as string).trim() === \"\") {\r\n clack.note(\"Opening editor...\\n\\nāš ļø IMPORTANT: Save your changes (Ctrl+S) before closing the editor!\", \"Editor\");\r\n\r\n const editedChangelog = await openEditor();\r\n\r\n if (editedChangelog === null) {\r\n clack.cancel(\"Operation cancelled\");\r\n process.exit(0);\r\n }\r\n\r\n if (editedChangelog.trim() === \"\") {\r\n clack.log.error(\"Changelog cannot be empty. Please provide a changelog.\");\r\n process.exit(1);\r\n }\r\n\r\n changelog = editedChangelog;\r\n }\r\n\r\n const frontmatter: ChangesetFrontmatter = {\r\n game_versions: gameVersions as string[],\r\n version_type: versionType as VersionType,\r\n version_bump: versionBump as VersionBump\r\n };\r\n\r\n const filepath = await createChangeset(frontmatter, changelog as string);\r\n clack.log.success(`Created ${filepath}`);\r\n}\r\n\r\nasync function openEditor(): Promise<string | null> {\r\n const tmpFile = join(tmpdir(), `voxset-${Date.now()}.md`);\r\n await writeFile(tmpFile, \"# Write your changelog here\\n\", \"utf-8\");\r\n\r\n const editor = process.env.EDITOR || (process.platform === \"win32\" ? \"notepad\" : \"nano\");\r\n\r\n return new Promise((resolve) => {\r\n const child = spawn(editor, [tmpFile], { stdio: \"inherit\" });\r\n\r\n child.on(\"exit\", async (code) => {\r\n if (code === 0) {\r\n const { readFile } = await import(\"node:fs/promises\");\r\n const content = await readFile(tmpFile, \"utf-8\");\r\n const cleaned = content.replace(/^# Write your changelog here\\n/, \"\").trim();\r\n resolve(cleaned);\r\n } else {\r\n resolve(null);\r\n }\r\n });\r\n });\r\n}\r\n\r\nfunction toCamelCase(str: string): string {\r\n return str\r\n .toLowerCase()\r\n .replace(/[^a-z0-9]+(.)/g, (_, char) => char.toUpperCase())\r\n .replace(/^(.)/, (char) => char.toLowerCase());\r\n}\r\n","#!/usr/bin/env node\r\nimport { init } from \"@/commands/init\";\r\n\r\ntry {\r\n await init();\r\n} catch (error) {\r\n console.error(\"Error:\", error instanceof Error ? error.message : error);\r\n process.exit(1);\r\n}\r\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/schema.ts","../src/utils/changeset.ts","../src/utils/config.ts","../src/utils/datapack.ts","../src/utils/frontmatter.ts","../src/utils/workflow.ts"],"sourcesContent":[],"mappings":";;;;cAEa,aAA6C,oCAAA,CAAlC;KACZ,WAAA,UAAqB,WAAA,CAAY;cAEhC,aAA8C,oCAAA,CAAnC;KACZ,WAAA,UAAqB,WAAA,CAAY;AAJhC,cAMA,WAN6C,EAMjB,oCAAA,CAAjB,UANA,CAAA,MAAA,EAAA,CAAA,CAAA,CAAA;AACZ,KAMA,WAAA,GANW,OAMU,WAAA,CAAY,KANK;AAErC,cAMA,MAN8C,EAMM,oCAAA,CAA9C,UANK,CAAA,QAAA,GAAA,OAAA,GAAA,UAAA,GAAA,OAAA,EAAA,CAAA,CAAA,CAAA;AACZ,KAMA,MAAA,GANW,OAMK,MAAA,CAAO,KANU;AAEhC,cAMA,oBAN4B,EAWvC,oCAAA,CAL+B,UANT,CAAA;EACZ,aAAA,EAAW,MAAA,EAAA;EAEV,YAAoD,EAAA,SAAA,GAAA,MAAA,GAAA,OAAA;EACrD,YAAM,EAAA,OAAU,GAAA,OAAO,GAAK,OAAA;EAE3B,OAAA,CAAA,EAAA,MAAA,EAAA,GAAA,SAKX;AACF,CAAA,EAAA,CAAY,CAAA,CAAA;AAEC,KAFD,oBAAA,GAsCV,OAtCwC,oBAAA,CAAqB,KAEtC;AAqCb,cArCC,YAqCqB,EADhC,oCAAA,CApCuB,UAqC2B,CAAA;;;;ICrD9B,QAAA,EAAA,MAAe;EAAA,CAAA;UAAO,EAAA;IAA0C,OAAA,EAAA,OAAA;IAAO,UAAA,EAAA,MAAA;;;;ICFvE,QAAA,EAAA;MASA,OAAU,EAAA,OAAA;MAAA,UAAA,CAAA,EAAA,MAAA,GAAA,IAAA,GAAA,SAAA;IAAY,CAAA;IAAR,GAAA,EAAA;MAAO,OAAA,EAAA,OAAA;MAWrB,UAAW,CAAA,EAAA,MAAA,GAAA,IAAA,GAAA,SAAA;MAAA,aAAA,CAAA,EAAA,MAAA,EAAA,GAAA,SAAA;MAAS,YAAA,CAAA,EAAA,MAAA,EAAA,GAAA,SAAA;IAAe,CAAA;EAAO,CAAA;EAUhD,cAAA,EAAA;;;;ICzBM,OAAA,EAAA,MAAe,EAAA;;;;ICNrB,OAAA,CAAA,EAAA,MAAA,GAAA,SAAwB;EAexB,CAAA;;;;ACNhB,CAAA,EAAA,CAAsB,CAAA,CAAA;AASA,KLsCV,YAAA,GKtCwB,OLsCF,YAAA,CAAa,KKtCA;;;iBJfzB,eAAA,OAAsB,0CAA0C;;;iBCFhE,YAAA,CAAA,GAAgB;iBAShB,UAAA,CAAA,GAAc,QAAQ;iBAWtB,WAAA,SAAoB,eAAe;AFtB5C,iBEgCG,mBAAA,CAAA,CFhC0C,EEgCnB,YFhCmB;;;iBGOpC,eAAA,CAAA,GAAmB;;;iBCNzB,wBAAA;QAAmD;;AJDnE,CAAA;AACY,iBIeI,6BAAA,CJfkC,IAAA,EIeE,oBJfF,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;iBKS5B,cAAA,CAAA,GAAkB;iBASlB,cAAA,CAAA,GAAkB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/schema.ts","../src/utils/changeset.ts","../src/utils/config.ts","../src/utils/datapack.ts","../src/utils/frontmatter.ts","../src/utils/workflow.ts"],"sourcesContent":[],"mappings":";;;;cAEa,aAA6C,oCAAA,CAAlC;KACZ,WAAA,UAAqB,WAAA,CAAY;cAEhC,aAA8C,oCAAA,CAAnC;KACZ,WAAA,UAAqB,WAAA,CAAY;AAJhC,cAMA,WAN6C,EAMjB,oCAAA,CAAjB,UANA,CAAA,MAAA,EAAA,CAAA,CAAA,CAAA;AACZ,KAMA,WAAA,GANW,OAMU,WAAA,CAAY,KANK;AAErC,cAMA,MAN8C,EAMM,oCAAA,CAA9C,UANK,CAAA,QAAA,GAAA,OAAA,GAAA,UAAA,GAAA,OAAA,EAAA,CAAA,CAAA,CAAA;AACZ,KAMA,MAAA,GANW,OAMK,MAAA,CAAO,KANU;AAEhC,cAMA,oBAN4B,EAWvC,oCAAA,CAL+B,UANT,CAAA;EACZ,aAAA,EAAW,MAAA,EAAA;EAEV,YAAoD,EAAA,SAAA,GAAA,MAAA,GAAA,OAAA;EACrD,YAAM,EAAA,OAAU,GAAA,OAAO,GAAK,OAAA;EAE3B,OAAA,CAAA,EAAA,MAAA,EAAA,GAAA,SAKX;AACF,CAAA,EAAA,CAAY,CAAA,CAAA;AAEC,KAFD,oBAAA,GAsCV,OAtCwC,oBAAA,CAAqB,KAEtC;AAqCb,cArCC,YAqCqB,EADhC,oCAAA,CApCuB,UAqC2B,CAAA;;;;ICrD9B,QAAA,EAAA,MAAe;EAAA,CAAA;UAAO,EAAA;IAA0C,OAAA,EAAA,OAAA;IAAO,UAAA,EAAA,MAAA;;;;ICFvE,QAAA,EAAA;MASA,OAAU,EAAA,OAAA;MAAA,UAAA,CAAA,EAAA,MAAA,GAAA,IAAA,GAAA,SAAA;IAAY,CAAA;IAAR,GAAA,EAAA;MAAO,OAAA,EAAA,OAAA;MAWrB,UAAW,CAAA,EAAA,MAAA,GAAA,IAAA,GAAA,SAAA;MAAA,aAAA,CAAA,EAAA,MAAA,EAAA,GAAA,SAAA;MAAS,YAAA,CAAA,EAAA,MAAA,EAAA,GAAA,SAAA;IAAe,CAAA;EAAO,CAAA;EAUhD,cAAA,EAAA;;;;ICzBM,OAAA,EAAA,MAAe,EAAA;;;;ICNrB,OAAA,CAAA,EAAA,MAAA,GAAA,SAAwB;EAexB,CAAA;;;;ACJhB,CAAA,EAAA,CAAsB,CAAA,CAAA;AASA,KLoCV,YAAA,GKpCwB,OLoCF,YAAA,CAAa,KKpCA;;;iBJjBzB,eAAA,OAAsB,0CAA0C;;;iBCFhE,YAAA,CAAA,GAAgB;iBAShB,UAAA,CAAA,GAAc,QAAQ;iBAWtB,WAAA,SAAoB,eAAe;AFtB5C,iBEgCG,mBAAA,CAAA,CFhC0C,EEgCnB,YFhCmB;;;iBGOpC,eAAA,CAAA,GAAmB;;;iBCNzB,wBAAA;QAAmD;;AJDnE,CAAA;AACY,iBIeI,6BAAA,CJfkC,IAAA,EIeE,oBJfF,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;iBKW5B,cAAA,CAAA,GAAkB;iBASlB,cAAA,CAAA,GAAkB"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{configExists as e,createChangeset as t,createDefaultConfig as n,createMarkdownWithFrontmatter as r,createWorkflow as i,isValidDatapack as a,parseMarkdownFrontmatter as o,readConfig as s,workflowExists as c,writeConfig as l}from"./workflow-D_9q4YIy.js";export{e as configExists,t as createChangeset,n as createDefaultConfig,r as createMarkdownWithFrontmatter,i as createWorkflow,a as isValidDatapack,o as parseMarkdownFrontmatter,s as readConfig,c as workflowExists,l as writeConfig};
1
+ import{configExists as e,createChangeset as t,createDefaultConfig as n,createMarkdownWithFrontmatter as r,createWorkflow as i,isValidDatapack as a,parseMarkdownFrontmatter as o,readConfig as s,workflowExists as c,writeConfig as l}from"./workflow-JsUijDQh.js";export{e as configExists,t as createChangeset,n as createDefaultConfig,r as createMarkdownWithFrontmatter,i as createWorkflow,a as isValidDatapack,o as parseMarkdownFrontmatter,s as readConfig,c as workflowExists,l as writeConfig};
@@ -0,0 +1,2 @@
1
+ import{access as e,constants as t,copyFile as n,mkdir as r,readFile as i,writeFile as a}from"node:fs/promises";import{dirname as o,join as s,resolve as c}from"node:path";import{parse as l,stringify as u}from"yaml";import{type as d}from"arktype";import{fileURLToPath as f}from"node:url";function p(e){let t=e.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);if(!t)throw Error(`Invalid markdown frontmatter format`);let[,n,r]=t;return{data:l(n),content:r.trim()}}function m(e,t){return`---\n${u(e)}---\n\n${t}`}const h=`.changeset`;async function g(e,t){await r(h,{recursive:!0});let n=`${h}/${_()}`;return await a(n,m(e,t),`utf-8`),n}function _(){let e=[`happy`,`silly`,`brave`,`calm`,`bright`,`clever`,`fair`,`gentle`,`kind`,`lovely`],t=[`pandas`,`tigers`,`dragons`,`wolves`,`eagles`,`foxes`,`bears`,`lions`,`owls`,`hawks`],n=[`dance`,`jump`,`fly`,`swim`,`run`,`sing`,`play`,`rest`,`hunt`,`soar`];return`${e[Math.floor(Math.random()*e.length)]}-${t[Math.floor(Math.random()*t.length)]}-${n[Math.floor(Math.random()*n.length)]}.md`}const v=d(`'major'|'minor'|'patch'`),y=d(`'release'|'beta'|'alpha'`);d(`string`),d(`'fabric'|'forge'|'neoforge'|'quilt'`),d({game_versions:`string[]`,version_type:y,version_bump:v,"loaders?":`string[]`});const b=d({project:{version:`string`,name:`string`,filename:`string`},modrinth:{enabled:`boolean`,project_id:`string`,"featured?":`boolean`},curseforge:{datapack:{enabled:`boolean`,"project_id?":`number | null`},mod:{enabled:`boolean`,"project_id?":`number | null`,"java_versions?":`string[]`,"environments?":`string[]`}},package_as_mod:{enabled:`boolean`,loaders:`string[]`,id:`string`,"filename?":`string`,authors:`string[]`,"homepage?":`string`,"issues?":`string`,"sources?":`string`},"build?":{"exclude?":`string[]`}});async function x(){try{return await e(`deploy.yaml`,t.F_OK),!0}catch{return!1}}async function S(){let e=b(l(await i(`deploy.yaml`,`utf-8`)));if(e instanceof Error)throw Error(`Invalid deploy.yaml: ${e.message}`);return e}async function C(e){let t=b(e);if(t instanceof Error)throw Error(`Invalid config: ${t.message}`);await a(`deploy.yaml`,u(e),`utf-8`)}function w(){return{project:{version:`0.1.0`,name:``,filename:``},modrinth:{enabled:!1,project_id:``,featured:!1},curseforge:{datapack:{enabled:!1,project_id:null},mod:{enabled:!1,project_id:null,java_versions:[`Java 21`],environments:[`server`]}},package_as_mod:{enabled:!1,loaders:[`fabric`,`forge`,`neoforge`,`quilt`],id:``,authors:[]},build:{exclude:[`.git`,`.github`,`.changeset`,`.vscode`,`.cursor`,`node_modules`,`README.md`,`.gitignore`,`deploy.yaml`]}}}async function T(){try{await e(`pack.mcmeta`,t.F_OK);let n=await i(`pack.mcmeta`,`utf-8`),r=JSON.parse(n);return!!r.pack?.description&&!!r.pack?.pack_format}catch{return!1}}const E=`.github/workflows/voxset.yaml`;function D(){let e=o(f(import.meta.url));return s(e.includes(`src`)?c(e,`../..`):c(e,`..`),`examples/deploy.yml`)}async function O(){try{return await e(E,t.F_OK),!0}catch{return!1}}async function k(){await r(o(E),{recursive:!0}),await n(D(),E)}export{x as configExists,g as createChangeset,w as createDefaultConfig,m as createMarkdownWithFrontmatter,k as createWorkflow,T as isValidDatapack,p as parseMarkdownFrontmatter,S as readConfig,O as workflowExists,C as writeConfig};
2
+ //# sourceMappingURL=workflow-JsUijDQh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-JsUijDQh.js","names":[],"sources":["../src/utils/frontmatter.ts","../src/utils/changeset.ts","../src/types/schema.ts","../src/utils/config.ts","../src/utils/datapack.ts","../src/utils/workflow.ts"],"sourcesContent":["import { parse, stringify } from \"yaml\";\r\nimport type { ChangesetFrontmatter } from \"@/types/schema\";\r\n\r\nexport function parseMarkdownFrontmatter(content: string): { data: ChangesetFrontmatter; content: string } {\r\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\r\n if (!match) {\r\n throw new Error(\"Invalid markdown frontmatter format\");\r\n }\r\n\r\n const [, frontmatter, markdownContent] = match;\r\n const data = parse(frontmatter) as ChangesetFrontmatter;\r\n\r\n return {\r\n data,\r\n content: markdownContent.trim()\r\n };\r\n}\r\n\r\nexport function createMarkdownWithFrontmatter(data: ChangesetFrontmatter, content: string): string {\r\n const frontmatter = stringify(data);\r\n return `---\\n${frontmatter}---\\n\\n${content}`;\r\n}\r\n","import { mkdir, writeFile } from \"node:fs/promises\";\r\nimport type { ChangesetFrontmatter } from \"@/types/schema\";\r\nimport { createMarkdownWithFrontmatter } from \"@/utils/frontmatter\";\r\n\r\nconst CHANGESET_DIR = \".changeset\";\r\n\r\nexport async function createChangeset(data: ChangesetFrontmatter, changelog: string): Promise<string> {\r\n await mkdir(CHANGESET_DIR, { recursive: true });\r\n\r\n const filename = generateChangesetFilename();\r\n const filepath = `${CHANGESET_DIR}/${filename}`;\r\n const content = createMarkdownWithFrontmatter(data, changelog);\r\n\r\n await writeFile(filepath, content, \"utf-8\");\r\n\r\n return filepath;\r\n}\r\n\r\nfunction generateChangesetFilename(): string {\r\n const adjectives = [\"happy\", \"silly\", \"brave\", \"calm\", \"bright\", \"clever\", \"fair\", \"gentle\", \"kind\", \"lovely\"];\r\n const nouns = [\"pandas\", \"tigers\", \"dragons\", \"wolves\", \"eagles\", \"foxes\", \"bears\", \"lions\", \"owls\", \"hawks\"];\r\n const verbs = [\"dance\", \"jump\", \"fly\", \"swim\", \"run\", \"sing\", \"play\", \"rest\", \"hunt\", \"soar\"];\r\n\r\n const adj = adjectives[Math.floor(Math.random() * adjectives.length)];\r\n const noun = nouns[Math.floor(Math.random() * nouns.length)];\r\n const verb = verbs[Math.floor(Math.random() * verbs.length)];\r\n\r\n return `${adj}-${noun}-${verb}.md`;\r\n}\r\n","import { type } from \"arktype\";\r\n\r\nexport const VersionBump = type(\"'major'|'minor'|'patch'\");\r\nexport type VersionBump = typeof VersionBump.infer;\r\n\r\nexport const VersionType = type(\"'release'|'beta'|'alpha'\");\r\nexport type VersionType = typeof VersionType.infer;\r\n\r\nexport const GameVersion = type(\"string\");\r\nexport type GameVersion = typeof GameVersion.infer;\r\n\r\nexport const Loader = type(\"'fabric'|'forge'|'neoforge'|'quilt'\");\r\nexport type Loader = typeof Loader.infer;\r\n\r\nexport const ChangesetFrontmatter = type({\r\n game_versions: \"string[]\",\r\n version_type: VersionType,\r\n version_bump: VersionBump,\r\n \"loaders?\": \"string[]\"\r\n});\r\nexport type ChangesetFrontmatter = typeof ChangesetFrontmatter.infer;\r\n\r\nexport const DeployConfig = type({\r\n project: {\r\n version: \"string\",\r\n name: \"string\",\r\n filename: \"string\"\r\n },\r\n modrinth: {\r\n enabled: \"boolean\",\r\n project_id: \"string\",\r\n \"featured?\": \"boolean\"\r\n },\r\n curseforge: {\r\n datapack: {\r\n enabled: \"boolean\",\r\n \"project_id?\": \"number | null\"\r\n },\r\n mod: {\r\n enabled: \"boolean\",\r\n \"project_id?\": \"number | null\",\r\n \"java_versions?\": \"string[]\",\r\n \"environments?\": \"string[]\"\r\n }\r\n },\r\n package_as_mod: {\r\n enabled: \"boolean\",\r\n loaders: \"string[]\",\r\n id: \"string\",\r\n \"filename?\": \"string\",\r\n authors: \"string[]\",\r\n \"homepage?\": \"string\",\r\n \"issues?\": \"string\",\r\n \"sources?\": \"string\"\r\n },\r\n \"build?\": {\r\n \"exclude?\": \"string[]\"\r\n }\r\n});\r\nexport type DeployConfig = typeof DeployConfig.infer;\r\n","import { access, constants, readFile, writeFile } from \"node:fs/promises\";\r\nimport { parse, stringify } from \"yaml\";\r\nimport { DeployConfig } from \"@/types/schema\";\r\n\r\nexport async function configExists(): Promise<boolean> {\r\n try {\r\n await access(\"deploy.yaml\", constants.F_OK);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport async function readConfig(): Promise<DeployConfig> {\r\n const content = await readFile(\"deploy.yaml\", \"utf-8\");\r\n const config = parse(content);\r\n const validation = DeployConfig(config);\r\n if (validation instanceof Error) {\r\n throw new Error(`Invalid deploy.yaml: ${validation.message}`);\r\n }\r\n\r\n return validation as DeployConfig;\r\n}\r\n\r\nexport async function writeConfig(config: DeployConfig): Promise<void> {\r\n const validation = DeployConfig(config);\r\n if (validation instanceof Error) {\r\n throw new Error(`Invalid config: ${validation.message}`);\r\n }\r\n\r\n const content = stringify(config);\r\n await writeFile(\"deploy.yaml\", content, \"utf-8\");\r\n}\r\n\r\nexport function createDefaultConfig(): DeployConfig {\r\n return {\r\n project: {\r\n version: \"0.1.0\",\r\n name: \"\",\r\n filename: \"\"\r\n },\r\n modrinth: {\r\n enabled: false,\r\n project_id: \"\",\r\n featured: false\r\n },\r\n curseforge: {\r\n datapack: {\r\n enabled: false,\r\n project_id: null\r\n },\r\n mod: {\r\n enabled: false,\r\n project_id: null,\r\n java_versions: [\"Java 21\"],\r\n environments: [\"server\"]\r\n }\r\n },\r\n package_as_mod: {\r\n enabled: false,\r\n loaders: [\"fabric\", \"forge\", \"neoforge\", \"quilt\"],\r\n id: \"\",\r\n authors: []\r\n },\r\n build: {\r\n exclude: [\".git\", \".github\", \".changeset\", \".vscode\", \".cursor\", \"node_modules\", \"README.md\", \".gitignore\", \"deploy.yaml\"]\r\n }\r\n };\r\n}\r\n","import { access, constants, readFile } from \"node:fs/promises\";\r\n\r\ninterface PackMcmeta {\r\n pack?: {\r\n description?: string;\r\n pack_format?: number;\r\n };\r\n}\r\n\r\nexport async function isValidDatapack(): Promise<boolean> {\r\n try {\r\n await access(\"pack.mcmeta\", constants.F_OK);\r\n const content = await readFile(\"pack.mcmeta\", \"utf-8\");\r\n const data = JSON.parse(content) as PackMcmeta;\r\n return !!data.pack?.description && !!data.pack?.pack_format;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n","import { access, constants, copyFile, mkdir } from \"node:fs/promises\";\r\nimport { dirname, join, resolve } from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\n\r\nconst WORKFLOW_PATH = \".github/workflows/voxset.yaml\";\r\n\r\nfunction getExampleWorkflowPath(): string {\r\n const currentFile = fileURLToPath(import.meta.url);\r\n const currentDir = dirname(currentFile);\r\n const isSrcDir = currentDir.includes(\"src\");\r\n const packageRoot = isSrcDir ? resolve(currentDir, \"../..\") : resolve(currentDir, \"..\");\r\n return join(packageRoot, \"examples/deploy.yml\");\r\n}\r\n\r\nexport async function workflowExists(): Promise<boolean> {\r\n try {\r\n await access(WORKFLOW_PATH, constants.F_OK);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport async function createWorkflow(): Promise<void> {\r\n const dir = dirname(WORKFLOW_PATH);\r\n await mkdir(dir, { recursive: true });\r\n const examplePath = getExampleWorkflowPath();\r\n await copyFile(examplePath, WORKFLOW_PATH);\r\n}\r\n"],"mappings":"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"}