create-pluto 0.0.1-alpha.3 → 0.1.0

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/index.mjs CHANGED
@@ -1,144 +1,2 @@
1
- import { cancel, confirm, isCancel, log, select, spinner, text as text$1 } from "@clack/prompts";
2
- import { downloadTemplate } from "giget";
3
- import fs from "fs";
4
-
5
- //#region src/choices/supabase-template.ts
6
- async function setupSupabase() {
7
- let supabaseUrl;
8
- let supabaseKey;
9
- while (!supabaseUrl) {
10
- supabaseUrl = await text$1({ message: "Type/Paste your Supabase URL:" });
11
- if (!supabaseUrl || typeof supabaseUrl !== "string") log.error("Supabase URL is required.");
12
- }
13
- while (!supabaseKey) {
14
- supabaseKey = await text$1({ message: "Type/Paste your Supabase Key:" });
15
- if (!supabaseKey || typeof supabaseKey !== "string") log.error("Supabase Key is required.");
16
- }
17
- return {
18
- supabaseUrl,
19
- supabaseKey
20
- };
21
- }
22
- function setupSupabaseEnvVars(supabaseUrl, supabaseKey) {
23
- let envVars = {};
24
- envVars.SUPABASE_PROJECT_ID = supabaseUrl ? supabaseUrl.toString().split("//")[1]?.split(".")[0] ?? "" : "";
25
- envVars.SUPABASE_URL = supabaseUrl?.toString() ?? "";
26
- envVars.SUPABASE_KEY = supabaseKey?.toString() ?? "";
27
- return { envVars };
28
- }
29
-
30
- //#endregion
31
- //#region src/index.ts
32
- const cwd = process.cwd();
33
- const color = {
34
- blue: (text) => `\x1b[34m${text}\x1b[0m`,
35
- green: (text) => `\x1b[32m${text}\x1b[0m`
36
- };
37
- const menu = {
38
- databases: [{
39
- value: "supabase",
40
- label: "Supabase",
41
- hint: "Hosted Postgres Database"
42
- }],
43
- templates: [{
44
- value: "shop",
45
- label: "Shop (e-commerce)",
46
- hint: "A full-featured online store template"
47
- }]
48
- };
49
- const templateDir = await text$1({
50
- message: "Where do you want to create your Pluto project?",
51
- placeholder: "./my-pluto-project",
52
- defaultValue: "my-pluto-project"
53
- });
54
- if (isCancel(templateDir)) {
55
- cancel("Operation cancelled.");
56
- process.exit(0);
57
- }
58
- const templatePath = `${cwd}/${templateDir}`;
59
- if (!fs.existsSync(templatePath)) fs.mkdirSync(templatePath, { recursive: true });
60
- const websiteTitle = await text$1({
61
- message: "Website title:",
62
- placeholder: "My Awesome Website",
63
- defaultValue: "My Awesome Website"
64
- });
65
- if (isCancel(websiteTitle)) {
66
- cancel("Operation cancelled.");
67
- process.exit(0);
68
- }
69
- const databaseProvider = await select({
70
- message: "Pick a database provider.",
71
- options: menu.databases
72
- });
73
- if (isCancel(databaseProvider)) {
74
- cancel("Operation cancelled.");
75
- process.exit(0);
76
- }
77
- let supabaseUrl;
78
- let supabaseKey;
79
- if (databaseProvider === "supabase") {
80
- log.warn(`You must have a Supabase project set up. If you do not have one, please create it at:\n${color.blue("https://database.new/")}.`);
81
- const { supabaseUrl: url, supabaseKey: key } = await setupSupabase();
82
- if (!url || !key) {
83
- log.error("Supabase setup failed.");
84
- process.exit(1);
85
- }
86
- supabaseUrl = url;
87
- supabaseKey = key;
88
- }
89
- const s = spinner();
90
- if (fs.existsSync(`${cwd}/nuxt.config.ts`)) {
91
- if (!await confirm({ message: "Nuxt project detected. Do you want to add Pluto environment variables?" })) process.exit(0);
92
- }
93
- const templateChoice = await select({
94
- message: "Select a template to use. You can add more layers as needed.",
95
- options: menu.templates
96
- });
97
- if (isCancel(templateChoice)) {
98
- cancel("Operation cancelled.");
99
- process.exit(0);
100
- }
101
- if (fs.readdirSync(templatePath).length > 0) {
102
- if (!await confirm({ message: `The folder ${color.green(templateDir)} is not empty. Do you want to continue and potentially overwrite existing files?` })) {
103
- cancel("Operation cancelled.");
104
- process.exit(0);
105
- }
106
- }
107
- s.start(`Downloading Pluto template...`);
108
- const { source } = await downloadTemplate(`gh:plutocms/pluto-${databaseProvider}-${templateChoice}-template`, {
109
- dir: templatePath,
110
- force: true
111
- });
112
- log.info(`Template downloaded from ${color.green(source)}`);
113
- const envPath = `${cwd}/${templateDir}/.env`;
114
- const envVars = { PLUTO_WEBSITE_TITLE: websiteTitle?.toString() ?? "" };
115
- if (databaseProvider === "supabase") {
116
- const { envVars: supabaseEnvVars } = setupSupabaseEnvVars(supabaseUrl, supabaseKey);
117
- Object.assign(envVars, supabaseEnvVars);
118
- }
119
- try {
120
- let envContent = "";
121
- if (fs.existsSync(envPath)) {
122
- envContent = fs.readFileSync(envPath, "utf-8");
123
- Object.entries(envVars).forEach(([key, value]) => {
124
- const regex = new RegExp(`^${key}=.*$`, "m");
125
- if (regex.test(envContent)) envContent = envContent.replace(regex, `${key}="${value}"`);
126
- else envContent += `\n${key}="${value}"`;
127
- });
128
- } else {
129
- envContent = "# Pluto Configurations\n";
130
- Object.entries(envVars).forEach(([key, value]) => {
131
- envContent += `${key}="${value}"\n`;
132
- });
133
- }
134
- fs.writeFileSync(envPath, envContent.trim() + "\n");
135
- } catch (error) {
136
- log.error(`Failed to write to .env file: ${error}`);
137
- process.exit(1);
138
- }
139
- s.stop("All done!");
140
- log.success("Setup complete! 🎉");
141
- log.info(`Nuxt project created in: ${color.green(templateDir)}`);
142
-
143
- //#endregion
144
- export { };
1
+ import e from"node:fs";import t from"node:path";import{cancel as n,confirm as r,isCancel as i,log as a,select as o,spinner as s,text as c}from"@clack/prompts";import{downloadTemplate as l}from"giget";async function u(){let e,t;for(;!e;)e=await c({message:`Type/Paste your Supabase URL:`}),(!e||typeof e!=`string`)&&a.error(`Supabase URL is required.`);for(;!t;)t=await c({message:`Type/Paste your Supabase Key:`}),(!t||typeof t!=`string`)&&a.error(`Supabase Key is required.`);return{supabaseUrl:e,supabaseKey:t}}function d(e,t){let n={};return n.SUPABASE_PROJECT_ID=e?e.toString().split(`//`)[1]?.split(`.`)[0]??``:``,n.SUPABASE_URL=e?.toString()??``,n.SUPABASE_KEY=t?.toString()??``,{envVars:n}}const f=process.cwd(),p={blue:e=>`\x1B[34m${e}\x1B[0m`,green:e=>`\x1B[32m${e}\x1B[0m`},m={databases:[{value:`supabase`,label:`Supabase`,hint:`Hosted Postgres Database`}],templates:[{value:`shop`,label:`Shop (e-commerce)`,hint:`A full-featured online store template`}]};function h(e){let t={};for(let n=0;n<e.length;n+=1){let r=e[n];if(r===`-t`||r===`--template`){t.templateShortcut=e[n+1],n+=1;continue}if(r?.startsWith(`--template=`)){t.templateShortcut=r.split(`=`)[1];continue}!r?.startsWith(`-`)&&!t.projectDir&&(t.projectDir=r)}return t}function g(e){let[t,n]=e.split(`-`,2),r=m.databases.some(e=>e.value===t),i=m.templates.some(e=>e.value===n);if(!r||!i){let t=m.databases.flatMap(e=>m.templates.map(t=>`${e.value}-${t.value}`));a.error(`Unknown template \"${e}\". Available options: ${t.join(`, `)}`),process.exit(1)}return{databaseProvider:t,templateChoice:n}}const _=h(process.argv.slice(2)),v=_.templateShortcut?g(_.templateShortcut):void 0,y=_.projectDir?_.projectDir:await c({message:`Where do you want to create your Pluto project?`,placeholder:`./my-pluto-project`,defaultValue:`my-pluto-project`});i(y)&&(n(`Operation cancelled.`),process.exit(0));const b=t.resolve(f,y);e.existsSync(b)||e.mkdirSync(b,{recursive:!0});const x=await c({message:`Website title:`,placeholder:`My Awesome Website`,defaultValue:`My Awesome Website`});i(x)&&(n(`Operation cancelled.`),process.exit(0));const S=v?v.databaseProvider:await o({message:`Pick a database provider.`,options:m.databases});i(S)&&(n(`Operation cancelled.`),process.exit(0));let C,w;if(S===`supabase`){a.warn(`You must have a Supabase project set up. If you do not have one, please create it at:\n${p.blue(`https://database.new/`)}.`);let{supabaseUrl:e,supabaseKey:t}=await u();(!e||!t)&&(a.error(`Supabase setup failed.`),process.exit(1)),C=e,w=t}const T=s();e.existsSync(`${f}/nuxt.config.ts`)&&(await r({message:`Nuxt project detected. Do you want to add Pluto environment variables?`})||process.exit(0));const E=v?v.templateChoice:await o({message:`Select a template to use. You can add more layers as needed.`,options:m.templates});i(E)&&(n(`Operation cancelled.`),process.exit(0)),e.readdirSync(b).length>0&&(await r({message:`The folder ${p.green(y)} is not empty. Do you want to continue and potentially overwrite existing files?`})||(n(`Operation cancelled.`),process.exit(0))),T.start(`Downloading Pluto template...`);const{source:D}=await l(`gh:plutocms/pluto-${S}-${E}-template`,{dir:b,force:!0});a.info(`Template downloaded from ${p.green(D)}`);const O=t.resolve(b,`.env`),k={PLUTO_WEBSITE_TITLE:x?.toString()??``};if(S===`supabase`){let{envVars:e}=d(C,w);Object.assign(k,e)}try{let t=``;e.existsSync(O)?(t=e.readFileSync(O,`utf-8`),Object.entries(k).forEach(([e,n])=>{let r=RegExp(`^${e}=.*$`,`m`);r.test(t)?t=t.replace(r,`${e}="${n}"`):t+=`\n${e}="${n}"`})):(t=`# Pluto Configurations
2
+ `,Object.entries(k).forEach(([e,n])=>{t+=`${e}="${n}"\n`})),e.writeFileSync(O,`${t.trim()}\n`)}catch(e){a.error(`Failed to write to .env file: ${e}`),process.exit(1)}T.stop(`All done!`),a.success(`Setup complete! 🎉`),a.info(`Nuxt project created in: ${p.green(y)}`);export{};
@@ -0,0 +1,30 @@
1
+ // @ts-check
2
+ import antfu from '@antfu/eslint-config'
3
+
4
+ export default antfu({
5
+ ignores: ['**/*.md', '.github/**'],
6
+
7
+ rules: {
8
+ 'node/prefer-global/process': ['off', 'never'],
9
+
10
+ 'style/arrow-parens': ['warn', 'always'],
11
+
12
+ 'style/brace-style': ['warn', '1tbs'],
13
+
14
+ 'style/comma-dangle': [
15
+ 'warn',
16
+ {
17
+ arrays: 'always-multiline',
18
+ objects: 'always-multiline',
19
+ functions: 'never',
20
+ imports: 'always-multiline',
21
+ },
22
+ ],
23
+
24
+ 'style/operator-linebreak': 'off',
25
+
26
+ // This CLI's entry point is a top-level script, not a module with a main()
27
+ // wrapper, so top-level await is the idiomatic way to run it.
28
+ 'antfu/no-top-level-await': 'off',
29
+ },
30
+ })
package/package.json CHANGED
@@ -1,21 +1,18 @@
1
1
  {
2
2
  "name": "create-pluto",
3
- "version": "0.0.1-alpha.3",
4
- "module": "./bin/cli.mjs",
5
3
  "type": "module",
6
- "bin": {
7
- "create-pluto": "bin/cli.mjs"
8
- },
4
+ "version": "0.1.0",
5
+ "description": "CLI Wizard for creating a Pluto App",
6
+ "author": "https://github.com/ojvribeiro",
9
7
  "license": "MIT",
8
+ "homepage": "https://github.com/plutocms/create-pluto#readme",
10
9
  "repository": {
11
10
  "type": "git",
12
- "url": "git+https://github.com/plutocms/pluto.git"
11
+ "url": "git+https://github.com/plutocms/create-pluto.git"
13
12
  },
14
13
  "bugs": {
15
- "url": "https://github.com/plutocms/pluto/issues"
14
+ "url": "https://github.com/plutocms/create-pluto/issues"
16
15
  },
17
- "description": "CLI Wizard for creating a Pluto App",
18
- "homepage": "https://github.com/plutocms/pluto#readme",
19
16
  "keywords": [
20
17
  "pluto",
21
18
  "plutocms",
@@ -26,19 +23,28 @@
26
23
  "headless",
27
24
  "cms"
28
25
  ],
29
- "author": "https://github.com/ojvribeiro",
26
+ "main": "./src/index.ts",
27
+ "module": "./bin/cli.mjs",
28
+ "bin": {
29
+ "create-pluto": "bin/cli.mjs"
30
+ },
30
31
  "scripts": {
31
32
  "setup": "node src/index.ts",
32
- "build": "tsdown"
33
+ "build": "tsdown",
34
+ "prettier": "prettier --write .",
35
+ "lint": "eslint .",
36
+ "lint:fix": "eslint . --fix && prettier --write ."
33
37
  },
34
- "main": "./src/index.ts",
35
38
  "dependencies": {
36
39
  "@clack/prompts": "^0.11.0",
37
40
  "giget": "^3.1.1"
38
41
  },
39
42
  "devDependencies": {
43
+ "@antfu/eslint-config": "^7.4.3",
40
44
  "@types/node": "^25.0.10",
45
+ "eslint": "^10.0.0",
41
46
  "prettier": "^3.8.1",
42
- "tsdown": "^0.20.1"
47
+ "tsdown": "^0.20.1",
48
+ "typescript": "^5.9.3"
43
49
  }
44
50
  }
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3
+ "release-type": "node",
4
+ "bump-minor-pre-major": true,
5
+ "include-component-in-tag": false,
6
+ "packages": {
7
+ ".": {}
8
+ }
9
+ }
package/tsconfig.json CHANGED
@@ -1,28 +1,34 @@
1
1
  {
2
2
  "compilerOptions": {
3
+ "target": "ESNext",
3
4
  // Environment setup & latest features
4
5
  "lib": ["ESNext"],
5
- "target": "ESNext",
6
- "module": "nodenext",
7
6
  "moduleDetection": "force",
8
- "allowJs": true,
7
+ "module": "nodenext",
9
8
 
10
9
  // Bundler mode
11
10
  "moduleResolution": "nodenext",
11
+
12
+ // Make Node built-in globals/modules (process, fs, path, etc.) available
13
+ "types": ["node"],
12
14
  "allowImportingTsExtensions": true,
13
- "verbatimModuleSyntax": true,
14
- "noEmit": true,
15
+ "allowJs": true,
15
16
 
16
17
  // Best practices
17
18
  "strict": true,
18
- "skipLibCheck": true,
19
19
  "noFallthroughCasesInSwitch": true,
20
- "noUncheckedIndexedAccess": true,
21
20
  "noImplicitOverride": true,
22
21
 
22
+ "noPropertyAccessFromIndexSignature": false,
23
+ "noUncheckedIndexedAccess": true,
23
24
  // Some stricter flags (disabled by default)
24
25
  "noUnusedLocals": false,
25
26
  "noUnusedParameters": false,
26
- "noPropertyAccessFromIndexSignature": false
27
- }
27
+ "noEmit": true,
28
+ "verbatimModuleSyntax": true,
29
+ "skipLibCheck": true
30
+ },
31
+ "include": ["src/**/*.ts", "bin/**/*.mjs"],
32
+ // Downloaded/generated by the CLI itself when run locally - not part of this package's own source
33
+ "exclude": ["node_modules", "dist", "my-pluto-project"]
28
34
  }
package/tsdown.config.ts CHANGED
@@ -2,4 +2,5 @@ import { defineConfig } from 'tsdown'
2
2
 
3
3
  export default defineConfig({
4
4
  entry: ['./src/index.ts'],
5
+ minify: true,
5
6
  })
package/.env DELETED
@@ -1 +0,0 @@
1
- GIGET_AUTH=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