Compare commits
3 commits
main
...
update-to-
| Author | SHA1 | Date | |
|---|---|---|---|
| 2833177428 | |||
| 65bf094b9f | |||
| ab00a1e976 |
9 changed files with 2292 additions and 1604 deletions
16
package.json
16
package.json
|
|
@ -20,20 +20,20 @@
|
||||||
"prepare": "husky"
|
"prepare": "husky"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/compat": "^2.0.2",
|
"@eslint/compat": "^2.0.5",
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@types/node": "^22.13.11",
|
"@types/node": "^25.6.0",
|
||||||
"eslint": "^10.0.1",
|
"eslint": "^10.2.1",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-prettier": "^5.5.5",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"globals": "^17.3.0",
|
"globals": "^17.5.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"netlify-cli": "^23.15.1",
|
"netlify-cli": "^25.6.0",
|
||||||
"prettier": "^3.8.1",
|
"prettier": "^3.8.3",
|
||||||
"tsup": "^8.5.1",
|
"tsup": "^8.5.1",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^6.0.3",
|
||||||
"vitest": "^4.0.18"
|
"vitest": "^4.1.5"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js,ts,mjs,cjs,json,.*rc}": [
|
"*.{js,ts,mjs,cjs,json,.*rc}": [
|
||||||
|
|
|
||||||
11
packages/create-component/.gitignore
vendored
Normal file
11
packages/create-component/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
dist
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
.env
|
||||||
|
|
||||||
|
*~
|
||||||
|
*swp
|
||||||
|
*swo
|
||||||
|
|
||||||
|
# default wc name
|
||||||
|
hello-world
|
||||||
21
packages/create-component/LICENSE
Normal file
21
packages/create-component/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Ayo Ayco
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
12
packages/create-component/README.md
Normal file
12
packages/create-component/README.md
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Create WC
|
||||||
|
|
||||||
|
```
|
||||||
|
npm create webcomponent@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a new web component powered by [webcomponent.io](https://webcomponent.io)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_Just keep building._<br>
|
||||||
|
_A project by [Ayo](https://ayo.ayco.io)_
|
||||||
36
packages/create-component/package.json
Normal file
36
packages/create-component/package.json
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"name": "@mcflyjs/create-component",
|
||||||
|
"version": "0.0.1-alpha",
|
||||||
|
"description": "Create a new web component",
|
||||||
|
"type": "module",
|
||||||
|
"bin": {
|
||||||
|
"create-mcfly-component": "./dist/index.js"
|
||||||
|
},
|
||||||
|
"main": "./dist/index.js",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc --erasableSyntaxOnly",
|
||||||
|
"dev": "npx jiti ./src/index.ts",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"prepare": "husky"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.ayo.run/ayo/mcfly",
|
||||||
|
"directory": "packates/create-component"
|
||||||
|
},
|
||||||
|
"author": "Ayo Ayco",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"consola": "^3.4.2",
|
||||||
|
"giget": "^3.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^25.6.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
48
packages/create-component/pnpm-lock.yaml
Normal file
48
packages/create-component/pnpm-lock.yaml
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
lockfileVersion: '9.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.:
|
||||||
|
dependencies:
|
||||||
|
consola:
|
||||||
|
specifier: ^3.4.2
|
||||||
|
version: 3.4.2
|
||||||
|
giget:
|
||||||
|
specifier: ^3.2.0
|
||||||
|
version: 3.2.0
|
||||||
|
devDependencies:
|
||||||
|
'@types/node':
|
||||||
|
specifier: ^25.6.0
|
||||||
|
version: 25.6.2
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
'@types/node@25.6.2':
|
||||||
|
resolution: {integrity: sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw==}
|
||||||
|
|
||||||
|
consola@3.4.2:
|
||||||
|
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
|
||||||
|
engines: {node: ^14.18.0 || >=16.10.0}
|
||||||
|
|
||||||
|
giget@3.2.0:
|
||||||
|
resolution: {integrity: sha512-GvHTWcykIR/fP8cj8dMpuMMkvaeJfPvYnhq0oW+chSeIr+ldX21ifU2Ms6KBoyKZQZmVaUAAhQ2EZ68KJF8a7A==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
undici-types@7.19.2:
|
||||||
|
resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==}
|
||||||
|
|
||||||
|
snapshots:
|
||||||
|
|
||||||
|
'@types/node@25.6.2':
|
||||||
|
dependencies:
|
||||||
|
undici-types: 7.19.2
|
||||||
|
|
||||||
|
consola@3.4.2: {}
|
||||||
|
|
||||||
|
giget@3.2.0: {}
|
||||||
|
|
||||||
|
undici-types@7.19.2: {}
|
||||||
197
packages/create-component/src/index.ts
Executable file
197
packages/create-component/src/index.ts
Executable file
|
|
@ -0,0 +1,197 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import { consola } from 'consola'
|
||||||
|
import { colorize } from 'consola/utils'
|
||||||
|
import { downloadTemplate } from 'giget'
|
||||||
|
import { spawnSync } from 'node:child_process'
|
||||||
|
import * as path from 'node:path'
|
||||||
|
|
||||||
|
const [, , directoryArg] = process.argv
|
||||||
|
|
||||||
|
type PromptAction = {
|
||||||
|
prompt: string
|
||||||
|
info?: string
|
||||||
|
startMessage: string
|
||||||
|
command: string
|
||||||
|
subCommand: string
|
||||||
|
error: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Web Component
|
||||||
|
*/
|
||||||
|
async function create() {
|
||||||
|
const defaultDirectory = 'hello-world'
|
||||||
|
consola.box(`Hello! Let's build a new ${colorize('bold', 'Web Component')}!`)
|
||||||
|
let directory = directoryArg
|
||||||
|
|
||||||
|
if (!directory) {
|
||||||
|
directory =
|
||||||
|
(await consola.prompt('Give your new project a name:', {
|
||||||
|
placeholder: defaultDirectory,
|
||||||
|
})) ?? defaultDirectory
|
||||||
|
} else {
|
||||||
|
consola.success(`Using ${directory} as name.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof directory !== 'string') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
directory = getSafeDirectory(directory)
|
||||||
|
const hasErrors = await downloadTemplateToDirectory(directory)
|
||||||
|
|
||||||
|
if (!hasErrors) {
|
||||||
|
const prompts: PromptAction[] = [
|
||||||
|
{
|
||||||
|
prompt: `Would you like to install the dependencies to ${colorize(
|
||||||
|
'bold',
|
||||||
|
directory
|
||||||
|
)}?`,
|
||||||
|
info: 'This might take some time depending on your connectivity.',
|
||||||
|
startMessage: 'Installing dependencies using npm...',
|
||||||
|
command: `npm`,
|
||||||
|
subCommand: 'install',
|
||||||
|
error: `Install dependencies later with ${colorize(
|
||||||
|
'yellow',
|
||||||
|
'npm install'
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prompt: 'Would you like to initialize your git repository?',
|
||||||
|
startMessage: 'Initializing git repository...',
|
||||||
|
command: `git`,
|
||||||
|
subCommand: 'init',
|
||||||
|
error: `Initialize git repository later with ${colorize(
|
||||||
|
'yellow',
|
||||||
|
'git init'
|
||||||
|
)}`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const intentions = await askPrompts(prompts, directory)
|
||||||
|
if (!!intentions && intentions.length > 0)
|
||||||
|
showResults(directory, intentions[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns string that is safe for commands
|
||||||
|
* @param {string} directory
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
function getSafeDirectory(directory: string): string {
|
||||||
|
const { platform } = process
|
||||||
|
const locale = path[platform === `win32` ? `win32` : `posix`]
|
||||||
|
const localePath = directory.split(path.sep).join(locale.sep)
|
||||||
|
return path.normalize(localePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to download the template to the directory and returns a Promise whether the operation resulted to errors
|
||||||
|
* @param {string} directory
|
||||||
|
* @returns Promise<boolean> hasErrors
|
||||||
|
*/
|
||||||
|
async function downloadTemplateToDirectory(
|
||||||
|
directory: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
let hasErrors = false
|
||||||
|
|
||||||
|
try {
|
||||||
|
consola.start(
|
||||||
|
`Copying template to ${colorize('bold', getSafeDirectory(directory))}...`
|
||||||
|
)
|
||||||
|
await downloadTemplate('github:ayo-run/web-component', {
|
||||||
|
dir: directory,
|
||||||
|
})
|
||||||
|
} catch (ㆆ_ㆆ) {
|
||||||
|
if (ㆆ_ㆆ instanceof Error) {
|
||||||
|
consola.error(ㆆ_ㆆ.message)
|
||||||
|
} else {
|
||||||
|
consola.error(ㆆ_ㆆ)
|
||||||
|
}
|
||||||
|
consola.info('Try a different name.\n')
|
||||||
|
hasErrors = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasErrors
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterate over an array of prompts and ask for user intention
|
||||||
|
* @param {Array<PromptAction>} prompts
|
||||||
|
* @param {string} cwd
|
||||||
|
* @returns Promise<Array<boolean> | undefined>
|
||||||
|
*/
|
||||||
|
async function askPrompts(
|
||||||
|
prompts: PromptAction[],
|
||||||
|
cwd: string
|
||||||
|
): Promise<boolean[] | undefined> {
|
||||||
|
const results: boolean[] = []
|
||||||
|
|
||||||
|
for (const p of prompts) {
|
||||||
|
const userIntends = await consola.prompt(p.prompt, {
|
||||||
|
type: 'confirm',
|
||||||
|
})
|
||||||
|
|
||||||
|
if (typeof userIntends !== 'boolean') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userIntends) {
|
||||||
|
p.info && consola.info(p.info)
|
||||||
|
consola.start(p.startMessage)
|
||||||
|
try {
|
||||||
|
spawnSync(p.command, [p.subCommand], {
|
||||||
|
cwd,
|
||||||
|
shell: true,
|
||||||
|
timeout: 100_000,
|
||||||
|
stdio: 'inherit',
|
||||||
|
})
|
||||||
|
consola.success('Done!')
|
||||||
|
} catch (ㆆ_ㆆ) {
|
||||||
|
if (ㆆ_ㆆ instanceof Error) {
|
||||||
|
consola.error(ㆆ_ㆆ.message)
|
||||||
|
} else {
|
||||||
|
consola.error(ㆆ_ㆆ)
|
||||||
|
}
|
||||||
|
consola.info(p.error + '\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
results.push(userIntends)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the success result string based on directory and choices
|
||||||
|
* @param {string} directory
|
||||||
|
* @param {boolean} installDeps
|
||||||
|
*/
|
||||||
|
function showResults(directory: string, installDeps: boolean) {
|
||||||
|
let nextActions = [
|
||||||
|
`Go to your project by running ${colorize('yellow', `cd ${directory}`)}`,
|
||||||
|
]
|
||||||
|
|
||||||
|
if (!installDeps) {
|
||||||
|
nextActions.push(
|
||||||
|
`Install the dependencies with ${colorize('yellow', 'npm install')}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
nextActions = nextActions.concat([
|
||||||
|
`Start the dev server with ${colorize('yellow', 'npm start')}`,
|
||||||
|
])
|
||||||
|
|
||||||
|
const result = `🎉 Your new ${colorize(
|
||||||
|
'bold',
|
||||||
|
'Web Commponent'
|
||||||
|
)} app is ready: ${directory}\n\nNext actions: ${nextActions
|
||||||
|
.map((action, index) => `\n${++index}. ${action}`)
|
||||||
|
.join('')}`
|
||||||
|
|
||||||
|
consola.box(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
create()
|
||||||
|
|
@ -32,9 +32,9 @@
|
||||||
"homepage": "https://mcfly.js.org",
|
"homepage": "https://mcfly.js.org",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"consola": "^3.4.2",
|
"consola": "^3.4.2",
|
||||||
"giget": "^2.0.0"
|
"giget": "^3.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.13.11"
|
"@types/node": "^25.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3551
pnpm-lock.yaml
3551
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue