@wondercraft/create-wonderplate-shopify
Advanced tools
Comparing version 0.0.27 to 0.0.28
#!/usr/bin/env node | ||
import y from"ora";import s from"fs-extra";import e from"path";import a from"path";import{fileURLToPath as d}from"url";var f=d(import.meta.url),h=a.dirname(f),c=a.join(h,"../");import*as t from"@clack/prompts";var p="wonderplate-shopify",m=async()=>{let o=await t.group({name:()=>t.text({message:"What is the name of your project? This will be used in package.json",placeholder:p}),storeName:()=>t.text({message:"What is the handle of your Shopify store (without myshopify.com)?",placeholder:"my-store-handle",validate:_=>{if(_.includes("myshopify.com"))return"Please enter the handle of your store without the myshopify.com";if(_.includes("/")||_.includes("."))return"Please enter the handle of your store without slashes or dots"}}),tailwind:()=>t.confirm({message:"Will you be using Tailwind CSS for styling?"})});return{...o,name:o.name||p}};console.log(` | ||
import a from"fs-extra";import E from"ora";import o from"path";import u from"path";import{fileURLToPath as S}from"url";var T=S(import.meta.url),v=u.dirname(T),m=u.join(v,"../");import*as i from"@clack/prompts";var w="wonderplate-shopify",y=async()=>{let n=await i.group({name:()=>i.text({message:"What is the name of your project? This will be used in package.json",placeholder:w}),storeName:()=>i.text({message:"What is the handle of your Shopify store (without myshopify.com)?",placeholder:"my-store-handle",validate:t=>{if(t.includes("myshopify.com"))return"Please enter the handle of your store without the myshopify.com";if(t.includes("/")||t.includes("."))return"Please enter the handle of your store without slashes or dots"}}),jsFramework:()=>i.select({message:"Which JS framework will you be using?",options:[{label:"None",value:"none"},{label:"Alpine",value:"alpine"},{label:"React",value:"react",hint:"NOT YET IMPLEMENTED"},{label:"Vue",value:"vue",hint:"NOT YET IMPLEMENTED"},{label:"HTMX",value:"htmx",hint:"NOT YET IMPLEMENTED"}],initialValue:"none"}),downloadTheme:()=>i.select({message:"Do you want to download a theme?",options:[{label:"None",value:"none"},{label:"Dawn",value:"dawn"}],initialValue:"none"}),tailwind:()=>i.confirm({message:"Will you be using Tailwind CSS for styling?"})},{onCancel:()=>{i.cancel("Exiting setup..."),process.exit(0)}});return{...n,name:n.name||w}};import{execSync as k}from"child_process";import O from"extract-zip";import _ from"fs-extra";import l from"path";var g={dawn:{zip:"https://github.com/Shopify/dawn/archive/master.zip",extracted:"dawn-main"}};async function f(n,t){let s=`curl --output theme.zip -L -O ${g[n].zip}`;k(s),await O(l.join(t,"theme.zip"),{dir:t}).then(()=>console.log("Extraction complete")).catch(e=>console.error("Error occurred while extracting zip file",e));let r=l.join(t,g[n].extracted);_.readdirSync(r).forEach(e=>{!e.startsWith(".")&&_.lstatSync(l.join(r,e)).isDirectory()&&_.moveSync(l.join(r,e),l.join(t,e))}),_.removeSync(r),_.removeSync(l.join(t,"theme.zip"))}console.log(` | ||
_ _ _____ _ _ ____ ____ ____ ____ __ __ ____ ____ | ||
@@ -8,3 +8,8 @@ ( \\/\\/ )( _ )( \\( )( _ \\( ___)( _ \\( _ \\( ) /__\\ (_ _)( ___) | ||
`);var u=async()=>{let o=e.resolve(process.cwd()),_=e.join(c,"template"),r=await m(),l=y(`Scaffolding in: ${o}... | ||
`).start();["package.json","vite.config.ts"].forEach(i=>{s.copySync(e.join(_,i),e.join(o,i))}),s.copySync(e.join(_,"src"),e.join(o,"src"));let n=s.readJSONSync(e.join(o,"package.json"));n.name=r.name,r.storeName&&(n.config.store=r.storeName),r.tailwind?["tailwind.config.js","postcss.config.js"].forEach(i=>{s.copySync(e.join(_,i),e.join(o,i))}):(delete n.devDependencies.tailwindcss,delete n.devDependencies.autoprefixer,delete n.devDependencies.postcss,s.removeSync(e.join(o,"src/styles/tailwind.css"))),s.writeJSONSync(e.join(o,"package.json"),n,{spaces:2}),l.succeed("Scaffolding complete!"),process.exit(0)};u(); | ||
`);var b=async()=>{let n=o.resolve(process.cwd()),t=o.join(m,"template"),s=await y(),r=E(`Scaffolding in: ${n}... | ||
`).start();["package.json","vite.config.ts",".shopifyignore",".gitignore"].forEach(c=>{a.copySync(o.join(t,c),o.join(n,c))}),a.copySync(o.join(t,"_src"),o.join(n,"_src"));let e=a.readJSONSync(o.join(n,"package.json"));if(e.name=s.name,s.storeName&&(e.config.store=s.storeName),s.tailwind){["tailwind.config.js","postcss.config.js"].forEach(p=>{a.copySync(o.join(t,p),o.join(n,p))});let c=a.readJSONSync(o.join(m,"src/packageMappers/package.tailwind.json"));e.dependencies={...e.dependencies,...c.dependencies},e.devDependencies={...e.devDependencies,...c.devDependencies},await a.appendFileSync(o.join(n,"_src/styles/main.scss"),`@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities;`,function(p){if(p)throw p;console.log("Saved!")})}else a.removeSync(o.join(n,"_src/styles/tailwind.css"));let d=s.downloadTheme;d==="dawn"&&(r.info(`Downloading ${d} theme...`),await f(d,n));let h=s.jsFramework;if(h=="alpine"){r.info(`Installing ${h}...`);let c=a.readJSONSync(o.join(m,`src/packageMappers/package.${h}.json`));e.dependencies={...e.dependencies,...c.dependencies},e.devDependencies={...e.devDependencies,...c.devDependencies},await a.appendFileSync(o.join(n,"_src/js/app.js"),`import Alpine from 'alpinejs' | ||
window.Alpine = Alpine | ||
Alpine.start() | ||
`,function(p){if(p)throw p;console.log("Saved!")})}a.writeJSONSync(o.join(n,"package.json"),e,{spaces:2}),r.succeed("Scaffolding complete!"),process.exit(0)};b(); |
{ | ||
"name": "@wondercraft/create-wonderplate-shopify", | ||
"version": "0.0.27", | ||
"version": "0.0.28", | ||
"description": "", | ||
@@ -9,3 +9,6 @@ "main": "./dist/index.js", | ||
"build": "tsup", | ||
"pub": "npm run build && npm publish" | ||
"pub": "npm run build && npm publish", | ||
"docs:dev": "vitepress dev docs", | ||
"docs:build": "vitepress build docs", | ||
"docs:preview": "vitepress preview docs" | ||
}, | ||
@@ -19,3 +22,3 @@ "type": "module", | ||
"author": "", | ||
"license": "ISC", | ||
"license": "MIT", | ||
"engines": { | ||
@@ -26,2 +29,3 @@ "node": ">=18.17.0" | ||
"@clack/prompts": "^0.7.0", | ||
"extract-zip": "^2.0.1", | ||
"fs-extra": "^11.2.0", | ||
@@ -34,4 +38,5 @@ "ora": "^8.0.1" | ||
"type-fest": "^4.9.0", | ||
"typescript": "^5.3.3" | ||
"typescript": "^5.3.3", | ||
"vitepress": "^1.0.0-rc.35" | ||
} | ||
} |
@@ -9,6 +9,10 @@ # Wonderplate Shopify CLI | ||
- Tailwind CSS | ||
- A set of scripts to create new components using plop (TODO) | ||
- A set of scripts to create new components using plop | ||
You do not get a full shopify theme, you will need to add the required files yourself. You can [download Dawn](https://github.com/Shopify/dawn) from the shopify git page. or it can be provided by the client. | ||
This CLI is heavily inspired by the [create-t3-app](https://github.com/t3-oss/create-t3-app) project. | ||
For more information check the [documentation](https://wondercraft-co.github.io/wonderplate-shopify-cli/). | ||
## Usage | ||
@@ -28,1 +32,22 @@ | ||
TODO: look into how to make this easier with `npm link`. | ||
### How to add new dependencies | ||
TODO: Explain how the `/packageMappers` folder works. | ||
#### Checking dependency updates with Vscode's Version Lens | ||
To help us keep dependencies up to date we like to use [Version Lens](https://marketplace.visualstudio.com/items?itemName=pflannery.vscode-versionlens) in vscode. This will show you the latest version of a dependency in the package.json file. | ||
But to work with the mapping files in the folder `/packageMappers` you have to update the settings following these steps: | ||
1. Open the settings in vscode | ||
2. Search for `@ext:pflannery.vscode-versionlens npm` | ||
3. Change the **Version Lens > Npm: Files** value to `**/package*.json` | ||
## Documentation | ||
We are using [VitePress](https://vitepress.dev/) to generate the documentation site. You can find the docs in the `/docs` folder. |
@@ -5,34 +5,73 @@ import * as p from "@clack/prompts"; | ||
type ThemeOptionsLabels = "dawn" | "none"; | ||
type FrameworkOptionsLabels = "react" | "vue" | "alpine" | "htmx" | "none"; | ||
type ThemeOptions<T> = { | ||
value: T; | ||
hint?: string; | ||
label?: string; | ||
}[]; | ||
export const runCli = async () => { | ||
const project = await p.group({ | ||
name: () => { | ||
return p.text({ | ||
message: | ||
"What is the name of your project? This will be used in package.json", | ||
placeholder: DEFAULT_PROJECT_NAME, | ||
}); | ||
const project = await p.group( | ||
{ | ||
name: () => { | ||
return p.text({ | ||
message: | ||
"What is the name of your project? This will be used in package.json", | ||
placeholder: DEFAULT_PROJECT_NAME, | ||
}); | ||
}, | ||
storeName: () => { | ||
return p.text({ | ||
message: | ||
"What is the handle of your Shopify store (without myshopify.com)?", | ||
placeholder: "my-store-handle", | ||
validate: (input) => { | ||
if (input.includes("myshopify.com")) { | ||
return "Please enter the handle of your store without the myshopify.com"; | ||
} | ||
if (input.includes("/") || input.includes(".")) { | ||
return "Please enter the handle of your store without slashes or dots"; | ||
} | ||
}, | ||
}); | ||
}, | ||
jsFramework: () => { | ||
return p.select<ThemeOptions<FrameworkOptionsLabels>, FrameworkOptionsLabels>({ | ||
message: "Which JS framework will you be using?", | ||
options: [ | ||
{ label: "None", value: "none" }, | ||
{ label: "Alpine", value: "alpine" }, | ||
{ label: "React", value: "react", hint: "NOT YET IMPLEMENTED" }, | ||
{ label: "Vue", value: "vue", hint: "NOT YET IMPLEMENTED" }, | ||
{ label: "HTMX", value: "htmx", hint: "NOT YET IMPLEMENTED" }, | ||
], | ||
initialValue: "none", | ||
}); | ||
}, | ||
downloadTheme: () => { | ||
return p.select<ThemeOptions<ThemeOptionsLabels>, ThemeOptionsLabels>({ | ||
message: "Do you want to download a theme?", | ||
options: [ | ||
{ label: "None", value: "none" }, | ||
{ label: "Dawn", value: "dawn" }, | ||
], | ||
initialValue: "none", | ||
}); | ||
}, | ||
tailwind: () => { | ||
return p.confirm({ | ||
message: "Will you be using Tailwind CSS for styling?", | ||
}); | ||
}, | ||
}, | ||
storeName: () => { | ||
return p.text({ | ||
message: | ||
"What is the handle of your Shopify store (without myshopify.com)?", | ||
placeholder: "my-store-handle", | ||
validate: (input) => { | ||
if (input.includes("myshopify.com")) { | ||
return "Please enter the handle of your store without the myshopify.com"; | ||
} | ||
if (input.includes("/") || input.includes(".")) { | ||
return "Please enter the handle of your store without slashes or dots"; | ||
} | ||
}, | ||
}); | ||
}, | ||
tailwind: () => { | ||
return p.confirm({ | ||
message: "Will you be using Tailwind CSS for styling?", | ||
}); | ||
}, | ||
}); | ||
{ | ||
onCancel: () => { | ||
p.cancel("Exiting setup..."); | ||
process.exit(0); | ||
}, | ||
} | ||
); | ||
return { ...project, name: project.name || DEFAULT_PROJECT_NAME }; | ||
}; |
#!/usr/bin/env node | ||
import fs from "fs-extra"; | ||
import ora from "ora"; | ||
import fs from "fs-extra"; | ||
import path from "path"; | ||
@@ -9,2 +9,3 @@ import { PKG_ROOT } from "~/consts.js"; | ||
import { type PackageJson } from "type-fest"; | ||
import downloadTheme from "./helpers/downloadTheme.js"; | ||
@@ -27,8 +28,10 @@ console.log(` | ||
// Copying root config files | ||
["package.json", "vite.config.ts"].forEach((file) => { | ||
fs.copySync(path.join(srcDir, file), path.join(projectDir, file)); | ||
}); | ||
["package.json", "vite.config.ts", ".shopifyignore", ".gitignore"].forEach( | ||
(file) => { | ||
fs.copySync(path.join(srcDir, file), path.join(projectDir, file)); | ||
} | ||
); | ||
//Copying src files | ||
fs.copySync(path.join(srcDir, "src"), path.join(projectDir, "src")); | ||
fs.copySync(path.join(srcDir, "_src"), path.join(projectDir, "_src")); | ||
@@ -50,9 +53,63 @@ const pkgJson = fs.readJSONSync( | ||
}); | ||
const pkgDeps = fs.readJSONSync( | ||
path.join(PKG_ROOT, "src/packageMappers/package.tailwind.json") | ||
) as PackageJson; | ||
pkgJson.dependencies = { | ||
...pkgJson.dependencies, | ||
...pkgDeps.dependencies, | ||
}; | ||
pkgJson.devDependencies = { | ||
...pkgJson.devDependencies, | ||
...pkgDeps.devDependencies, | ||
}; | ||
const tailwindStr = `@tailwind base;\n@tailwind components;\n@tailwind utilities;`; | ||
await fs.appendFileSync( | ||
path.join(projectDir, "_src/styles/main.scss"), | ||
tailwindStr, | ||
function (err) { | ||
if (err) throw err; | ||
console.log("Saved!"); | ||
} | ||
); | ||
} else { | ||
delete pkgJson.devDependencies["tailwindcss"]; | ||
delete pkgJson.devDependencies["autoprefixer"]; | ||
delete pkgJson.devDependencies["postcss"]; | ||
fs.removeSync(path.join(projectDir, "src/styles/tailwind.css")); | ||
fs.removeSync(path.join(projectDir, "_src/styles/tailwind.css")); | ||
} | ||
// Download theme | ||
const themeName = project.downloadTheme; | ||
if (themeName === "dawn") { | ||
spinner.info(`Downloading ${themeName} theme...`); | ||
await downloadTheme(themeName, projectDir); | ||
} | ||
// Install Js frameworks | ||
const jsFramework = project.jsFramework; | ||
if (jsFramework == "alpine") { | ||
spinner.info(`Installing ${jsFramework}...`); | ||
const pkgDeps = fs.readJSONSync( | ||
path.join(PKG_ROOT, `src/packageMappers/package.${jsFramework}.json`) | ||
) as PackageJson; | ||
pkgJson.dependencies = { | ||
...pkgJson.dependencies, | ||
...pkgDeps.dependencies, | ||
}; | ||
pkgJson.devDependencies = { | ||
...pkgJson.devDependencies, | ||
...pkgDeps.devDependencies, | ||
}; | ||
const appJsStr = `import Alpine from 'alpinejs'\nwindow.Alpine = Alpine\nAlpine.start()\n`; | ||
await fs.appendFileSync( | ||
path.join(projectDir, "_src/js/app.js"), | ||
appJsStr, | ||
function (err) { | ||
if (err) throw err; | ||
console.log("Saved!"); | ||
} | ||
); | ||
} | ||
//Update package.json | ||
@@ -59,0 +116,0 @@ fs.writeJSONSync(path.join(projectDir, "package.json"), pkgJson, { |
@@ -7,6 +7,7 @@ { | ||
"scripts": { | ||
"dev": "vite", | ||
"dev": "vite build --watch ", | ||
"build": "vite build", | ||
"shopify:dev": "shopify theme dev --store $npm_package_config_store --port $npm_package_config_port", | ||
"shopify:push": "shopify theme push --ignore=templates/*.json, config/*.json" | ||
"shopify:push": "shopify theme push --ignore=templates/*.json, config/*.json", | ||
"generate": "plop --plopfile _src/plop/plopfile.js" | ||
}, | ||
@@ -17,11 +18,12 @@ "config": { | ||
}, | ||
"dependencies": { | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@types/node": "^20.10.6", | ||
"plop": "^4.0.1", | ||
"sass": "^1.69.7", | ||
"vite": "^5.0.10" | ||
}, | ||
"devDependencies": { | ||
"autoprefixer": "^10.4.16", | ||
"postcss": "^8.4.33", | ||
"sass": "^1.69.7", | ||
"tailwindcss": "^3.4.0" | ||
"engines": { | ||
"node": ">=18.17.0" | ||
} | ||
} |
/** @type {import('vite').UserConfig} */ | ||
import fs from "fs"; | ||
import path from "path"; | ||
import { defineConfig } from "vite"; | ||
const inputDir = "./src"; | ||
const inputDir = "./_src"; | ||
@@ -10,6 +11,3 @@ const entries = (subDir = "") => | ||
.readdirSync(path.resolve(__dirname, inputDir, subDir)) | ||
.filter( | ||
(file) => | ||
file.endsWith(".js") || file.endsWith(".scss") || file.endsWith(".css") | ||
) | ||
.filter((file) => file.endsWith(".js")) | ||
.reduce((entries, file) => { | ||
@@ -21,10 +19,16 @@ const name = path.basename(file, ".js"); // get the file name without the extension | ||
export default { | ||
export default defineConfig({ | ||
build: { | ||
outDir: "assets", | ||
emptyOutDir: false, | ||
rollupOptions: { | ||
// Ensures entry points with modules do not remove the exported functions | ||
// Without this Vite tries to optimize and remove "unused" code which for | ||
// sections code is the exported class | ||
preserveEntrySignatures: "allow-extension", | ||
input: { | ||
app: "src/app.js", | ||
...entries("scripts/components"), | ||
...entries("styles"), | ||
app: "_src/js/app.js", | ||
styles: "_src/styles/main.scss", | ||
...entries("js/sections"), | ||
}, | ||
@@ -37,6 +41,6 @@ output: { | ||
}, | ||
rollupOutputOptions: { | ||
entryFileNames: "[name]", | ||
watch: { | ||
include: ["./_src/**"], | ||
}, | ||
}, | ||
}; | ||
}); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
36793
36
468
51
4
5
3
2
+ Addedextract-zip@^2.0.1
+ Added@types/node@22.13.4(transitive)
+ Added@types/yauzl@2.10.3(transitive)
+ Addedbuffer-crc32@0.2.13(transitive)
+ Addeddebug@4.4.0(transitive)
+ Addedend-of-stream@1.4.4(transitive)
+ Addedextract-zip@2.0.1(transitive)
+ Addedfd-slicer@1.1.0(transitive)
+ Addedget-stream@5.2.0(transitive)
+ Addedms@2.1.3(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpend@1.2.0(transitive)
+ Addedpump@3.0.2(transitive)
+ Addedundici-types@6.20.0(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedyauzl@2.10.0(transitive)