diff --git a/.gitignore b/.gitignore index 7d2c487b..bff76756 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ vite.config.ts.timestamp-**.mjs /packages/* !/packages/skeleton +!/packages/create-skeleton-app /sites/* !/sites/skeleton.dev \ No newline at end of file diff --git a/packages/create-skeleton-app/.eslintrc.cjs b/packages/create-skeleton-app/.eslintrc.cjs new file mode 100644 index 00000000..5eb6f4ae --- /dev/null +++ b/packages/create-skeleton-app/.eslintrc.cjs @@ -0,0 +1,14 @@ +module.exports = { + root: true, + extends: ['eslint:recommended', 'prettier'], + ignorePatterns: ['*.cjs'], + parserOptions: { + sourceType: 'module', + ecmaVersion: 2020, + }, + env: { + browser: false, + es2017: true, + node: true, + }, +}; \ No newline at end of file diff --git a/packages/create-skeleton-app/.gitignore b/packages/create-skeleton-app/.gitignore new file mode 100644 index 00000000..cca9fbd3 --- /dev/null +++ b/packages/create-skeleton-app/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +node_modules +dist +package +.turbo \ No newline at end of file diff --git a/packages/create-skeleton-app/.prettierignore b/packages/create-skeleton-app/.prettierignore new file mode 100644 index 00000000..749bb905 --- /dev/null +++ b/packages/create-skeleton-app/.prettierignore @@ -0,0 +1,13 @@ +.DS_Store + node_modules + /build + /.svelte-kit + /package + .env + .env.* + !.env.example + + # Ignore files for PNPM, NPM and YARN + pnpm-lock.yaml + package-lock.json + yarn.lock \ No newline at end of file diff --git a/packages/create-skeleton-app/.prettierrc b/packages/create-skeleton-app/.prettierrc new file mode 100644 index 00000000..0e951f04 --- /dev/null +++ b/packages/create-skeleton-app/.prettierrc @@ -0,0 +1,7 @@ +{ + "tabWidth": 4, + "useTabs": true, + "semi": true, + "singleQuote": true, + "trailingComma": "all" +} diff --git a/packages/create-skeleton-app/CODE_OF_CONDUCT.md b/packages/create-skeleton-app/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..adae0062 --- /dev/null +++ b/packages/create-skeleton-app/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +This repository is governed by the Skeleton Code of Conduct. + +https://github.com/skeletonlabs/community/blob/main/CODE_OF_CONDUCT.md diff --git a/packages/create-skeleton-app/LICENSE b/packages/create-skeleton-app/LICENSE new file mode 100644 index 00000000..63267b02 --- /dev/null +++ b/packages/create-skeleton-app/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Skeleton Labs + +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. diff --git a/packages/create-skeleton-app/README-MONO.md b/packages/create-skeleton-app/README-MONO.md new file mode 100644 index 00000000..cc88a2c4 --- /dev/null +++ b/packages/create-skeleton-app/README-MONO.md @@ -0,0 +1,23 @@ +# create-skeleton-app + +This is a special multi-repo version of the site created by CSA. + +Differences from a normal CSA site: +- Vite alias to the @skeletonlabs/skeleton project +- Removed @skeletonlabs/skeleton from package.json +- Added Vercel deploy command to package.json + +At this point it only supports deploying to Vercel. + +## Reminder +Since you have just created this site with `pnpm site `, make sure to `git init`, `git add .`, `gh repo create` and run `pnpm dev` at least once so that the alias gets setup in .svelte-kit + +## Deploying a site to Vercel +Repos that are not part of the main Skeleton repo will not work independently of the monorepo due to the adjustments to the @skeletonlabs/skeleton package noted above. Therefore to deploy a site, it is necessary to take advantage of the `vercel build` and `vercel deploy` of a local production build (or you can have fun setting up a GH deploy pipeline) + +```bash +# ensure you have the vercel cli tool +pnpm i -g vercel +``` + +Two scripts have been added to package.json \ No newline at end of file diff --git a/packages/create-skeleton-app/README.md b/packages/create-skeleton-app/README.md new file mode 100644 index 00000000..1f8d720b --- /dev/null +++ b/packages/create-skeleton-app/README.md @@ -0,0 +1,35 @@ +[![Skeleton](https://user-images.githubusercontent.com/1509726/199282306-7454adcb-b765-4618-8438-67655a7dee47.png)](https://www.skeleton.dev/) + +[![npm version](https://img.shields.io/npm/v/create-skeleton-app?logo=npm&color=cb3837)](https://www.npmjs.com/package/create-skeleton-app) +[![Chat](https://img.shields.io/discord/1003691521280856084?label=chat&logo=discord&color=7289da)](https://discord.gg/EXqV7W8MtY) +[![Twitter Follow](https://img.shields.io/twitter/follow/SkeletonUI?style=social)](https://twitter.com/SkeletonUI) +[![license](https://img.shields.io/badge/license-MIT-%23bada55)](https://github.com/Brain-Bones/skeleton/blob/master/LICENSE) + +# 💀 Create Skeleton App + +This is the CLI tool for setting up a new Skeleton App that uses [Skeleton](https://skeleton.dev/), [SvelteKit](https://kit.svelte.dev/) and [Tailwind CSS](https://tailwindcss.com/). + +`npm create skeleton-app@latest` + +Is all you need to get started. It also supports using `npm`, `pnpm` and `yarn`. + +While it largely mirrors the standard Svelte-Kit [create-svelte](https://github.com/sveltejs/kit/tree/master/packages/create-svelte) app, it adds some additional choices that are relevant to Skeleton. + +# Info + +You can see all command line options by running `npm create skeleton-app@latest -h` + +The `Enable Svelte-Kit experimental inspector?` option allows you to press ctrl-shift or opt-shift in the browser window of your running project to see an outline of each component - clicking will then launch you directly to the source of that component in VSCode. More information about this option can be found [here](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#inspector). + +The Tailwind plugins are purely optional, see their [docs](https://tailwindcss.com/docs/plugins#official-plugins) for more information. You can also use those docs to add the plugins after initially creating your project with the CLI. + + + +## 👋 Community + +- [Join the Discord](https://discord.gg/EXqV7W8MtY) +- [Follow on Twitter](https://twitter.com/SkeletonUI) + +## 🐞 Report an Issue + +- [Submit Issue](https://github.com/skeleton/create-skeleton-app/issues/new/choose) diff --git a/packages/create-skeleton-app/package.json b/packages/create-skeleton-app/package.json new file mode 100644 index 00000000..535f853d --- /dev/null +++ b/packages/create-skeleton-app/package.json @@ -0,0 +1,53 @@ +{ + "name": "create-skeleton-app", + "version": "0.0.38", + "description": "Use this CLI app to setup a new Skeleton application in a new SvelteKit project.", + "keywords": [ + "skeleton", + "svelte", + "sveltekit", + "svelte-kit" + ], + "homepage": "https://www.skeleton.dev", + "repository": { + "type": "git", + "url": "https://github.com/skeletonlabs/skeleton", + "directory": "packages/create-skeleton-app/" + }, + "license": "MIT", + "author": "Skeleton Admin ", + "type": "module", + "main": "./src/index.js", + "bin": "./src/index.js", + "files": [ + "src/**", + "templates/**" + ], + "engines": { + "node": ">=14.16" + }, + "scripts": { + "dev": "node src/index.js", + "long": "node src/index.js --types=typescript --prettier --eslint --playwright=false --vitest=false --codeblocks=true --popups=true --typography=false --forms=false -t crimson --skeletontemplate=welcome", + "pub:beta": "npm publish --tag beta", + "pub:next": "npm publish --tag next", + "pub:release": "npm publish", + "release": "npm publish", + "lint": "prettier --plugin-search-dir . --check . && eslint .", + "format": "prettier --plugin-search-dir . --write ." + }, + "dependencies": { + "@clack/prompts": "^0.6.3", + "create-svelte": "^4.2.0", + "fs-extra": "^11.1.1", + "got": "^12.6.0", + "kleur": "^4.1.5", + "mri": "^1.2.0", + "semver": "^7.5.1" + }, + "devDependencies": { + "eslint": "^8.40.0", + "prettier": "^2.8.8", + "svelte": "^3.59.1" + } +} \ No newline at end of file diff --git a/packages/create-skeleton-app/pnpm-lock.yaml b/packages/create-skeleton-app/pnpm-lock.yaml new file mode 100644 index 00000000..be59a0df --- /dev/null +++ b/packages/create-skeleton-app/pnpm-lock.yaml @@ -0,0 +1,911 @@ +lockfileVersion: '6.0' + +dependencies: + '@clack/prompts': + specifier: ^0.6.3 + version: 0.6.3 + create-svelte: + specifier: ^4.2.0 + version: 4.2.0 + fs-extra: + specifier: ^11.1.1 + version: 11.1.1 + got: + specifier: ^12.6.0 + version: 12.6.0 + kleur: + specifier: ^4.1.5 + version: 4.1.5 + mri: + specifier: ^1.2.0 + version: 1.2.0 + semver: + specifier: ^7.5.1 + version: 7.5.1 + +devDependencies: + eslint: + specifier: ^8.40.0 + version: 8.40.0 + prettier: + specifier: ^2.8.8 + version: 2.8.8 + svelte: + specifier: ^3.59.1 + version: 3.59.1 + +packages: + + /@clack/core@0.3.2: + resolution: {integrity: sha512-FZnsNynwGDIDktx6PEZK1EuCkFpY4ldEX6VYvfl0dqeoLPb9Jpw1xoUXaVcGR8ExmYNm1w2vdGdJkEUYD/2pqg==} + dependencies: + picocolors: 1.0.0 + sisteransi: 1.0.5 + dev: false + + /@clack/prompts@0.6.3: + resolution: {integrity: sha512-AM+kFmAHawpUQv2q9+mcB6jLKxXGjgu/r2EQjEwujgpCdzrST6BJqYw00GRn56/L/Izw5U7ImoLmy00X/r80Pw==} + dependencies: + '@clack/core': 0.3.2 + picocolors: 1.0.0 + sisteransi: 1.0.5 + dev: false + bundledDependencies: + - is-unicode-supported + + /@eslint-community/eslint-utils@4.4.0(eslint@8.40.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.40.0 + eslint-visitor-keys: 3.4.1 + dev: true + + /@eslint-community/regexpp@4.5.1: + resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.0.3: + resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.5.2 + globals: 13.20.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.40.0: + resolution: {integrity: sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.8: + resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@sindresorhus/is@5.3.0: + resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==} + engines: {node: '>=14.16'} + dev: false + + /@szmarczak/http-timer@5.0.1: + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + dependencies: + defer-to-connect: 2.0.1 + dev: false + + /@types/http-cache-semantics@4.0.1: + resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} + dev: false + + /acorn-jsx@5.3.2(acorn@8.8.2): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.8.2 + dev: true + + /acorn@8.8.2: + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + dev: false + + /cacheable-request@10.2.10: + resolution: {integrity: sha512-v6WB+Epm/qO4Hdlio/sfUn69r5Shgh39SsE9DSd4bIezP0mblOlObI+I0kUEM7J0JFc+I7pSeMeYaOYtX1N/VQ==} + engines: {node: '>=14.16'} + dependencies: + '@types/http-cache-semantics': 4.0.1 + get-stream: 6.0.1 + http-cache-semantics: 4.1.1 + keyv: 4.5.2 + mimic-response: 4.0.0 + normalize-url: 8.0.0 + responselike: 3.0.0 + dev: false + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /create-svelte@4.2.0: + resolution: {integrity: sha512-jngi/IOM4NIGL4A61fN6diilrxcNe1iH3pziK6QmsL95h3B2p8gFyc4xZ7Oi9UbxO74o/kivrd3cIwqefWd0bA==} + hasBin: true + dependencies: + '@clack/prompts': 0.6.3 + kleur: 4.1.5 + dev: false + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: false + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + dev: false + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-scope@7.2.0: + resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-visitor-keys@3.4.1: + resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.40.0: + resolution: {integrity: sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.40.0) + '@eslint-community/regexpp': 4.5.1 + '@eslint/eslintrc': 2.0.3 + '@eslint/js': 8.40.0 + '@humanwhocodes/config-array': 0.11.8 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.0 + eslint-visitor-keys: 3.4.1 + espree: 9.5.2 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.20.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.4 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-sdsl: 4.4.0 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.5.2: + resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.2 + acorn-jsx: 5.3.2(acorn@8.8.2) + eslint-visitor-keys: 3.4.1 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.7 + rimraf: 3.0.2 + dev: true + + /flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true + + /form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + dev: false + + /fs-extra@11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: false + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: false + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals@13.20.0: + resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /got@12.6.0: + resolution: {integrity: sha512-WTcaQ963xV97MN3x0/CbAriXFZcXCfgxVp91I+Ze6pawQOa7SgzwSx2zIJJsX+kTajMnVs0xcFD1TxZKFqhdnQ==} + engines: {node: '>=14.16'} + dependencies: + '@sindresorhus/is': 5.3.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.10 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.0 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + dev: false + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: false + + /grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + dev: false + + /http2-wrapper@2.2.0: + resolution: {integrity: sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + dev: false + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /js-sdsl@4.4.0: + resolution: {integrity: sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: false + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + + /keyv@4.5.2: + resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==} + dependencies: + json-buffer: 3.0.1 + dev: false + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: false + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: false + + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: false + + /mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: false + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /normalize-url@8.0.0: + resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} + engines: {node: '>=14.16'} + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /optionator@0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.3 + dev: true + + /p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + dev: false + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: false + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: false + + /resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + dev: false + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + dependencies: + lowercase-keys: 3.0.0 + dev: false + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /semver@7.5.1: + resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: false + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /svelte@3.59.1: + resolution: {integrity: sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==} + engines: {node: '>= 8'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: false + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /word-wrap@1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: false + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/packages/create-skeleton-app/src/creator.js b/packages/create-skeleton-app/src/creator.js new file mode 100644 index 00000000..77049508 --- /dev/null +++ b/packages/create-skeleton-app/src/creator.js @@ -0,0 +1,294 @@ +// Types +import { create } from 'create-svelte'; +import fs from 'fs-extra'; +import got from 'got'; +import { bold, cyan, red } from 'kleur/colors'; +import { spawnSync } from 'node:child_process'; +import path from 'path'; +import process from 'process'; +import { dist, mkdirp, removeFilesExceptSync, whichPMRuns } from './utils.js'; +import * as url from 'url'; +const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); + +// NOTE: Any changes here must also be reflected in the --help output in utils.js and shortcut expansions in index.js. +// Probably a good idea to do a search on the values you are changing to catch any other areas they are used in + +export class SkeletonOptions { + // svelte-create expects these options, do not change the names or values. + constructor() { + this.name = 'new-skel-app'; + this.template = 'skeleton'; + this.types = 'typescript'; + this.prettier = true; + this.eslint = true; + this.playwright = false; + this.vitest = false; + + // create-skeleton-app additions + this._ = []; //catch all for extraneous params from mri, used to capture project name. + this.help = false; + this.quiet = false; + this.path = '.'; + this.forms = false; + this.typography = false; + this.lineclamp = false; + this.skeletontheme = 'skeleton'; + this.skeletontemplate = 'bare'; + this.packagemanager = 'npm'; + this.packages = []; + this.codeblocks = false; + this.popups = true; + + // props below are private to the Skeleton team + this.verbose = false; + this.monorepo = false; + this.packages = []; + this.skeletontemplatedir = '../templates'; + this.workspace = ''; + } +} + +export async function createSkeleton(opts) { + //create-svelte will happily overwrite an existing directory, foot guns are bad mkay + opts.path = path.resolve( + opts?.path, + opts.name.replace(/\s+/g, '-').toLowerCase(), + ); + + if (fs.existsSync(opts.path) && fs.readdirSync(opts.path).length != 0) { + console.error(red(bold('Install directory already exists!'))); + process.exit(); + } + + fs.mkdirp(opts.path); + + //create-svelte will build the base install for us + await create(opts.path, opts); + process.chdir(opts.path); + + // install packages + opts.packagemanager = whichPMRuns()?.name || 'npm'; + + // the order matters due to dependency resolution, because yarn + let packages = [ + 'postcss', + 'autoprefixer', + 'tailwindcss', + + ]; + if (!opts.monorepo) packages.push('@skeletonlabs/skeleton') + if (opts?.monorepo) packages.push('@sveltejs/adapter-vercel') + + // Tailwind Packages + if (opts?.typography) packages.push('@tailwindcss/typography'); + if (opts?.forms) packages.push('@tailwindcss/forms'); + + // Component dependencies + if (opts?.codeblocks) packages.push('highlight.js'); + if (opts?.popups) packages.push('@floating-ui/dom'); + + let result = spawnSync(opts.packagemanager, ['add', '-D', ...packages], { + shell: true, + }); + + if (opts?.monorepo) spawnSync('pnpm', ['-F', opts?.name, `exec`, `pnpm`, `i`, `-D`, `@skeletonlabs/skeleton@latest`, `--workspace`]) + + // Capture any errors from stderr and display for the user to report it to us + if (result?.stderr.toString().length) { + console.log(red(bold( + 'The following was reported to stderr - please read carefully to determine whether it actually affects your install:\n')), + result?.stderr.toString() + ); + } + + // Just to help with any user error reports + if (opts.verbose) { + const stdout = result?.stdout.toString(); + if (stdout.length) console.log(bold(cyan('stdout:')), stdout); + const stderr = result?.stderr.toString(); + if (stderr.length) console.log(bold(red('stderr:')), stderr); + } + + // write out config files + out("svelte.config.js", createSvelteConfig(opts)); + out('.vscode/settings.json', await createVSCodeSettings()); + out('tailwind.config.cjs', createTailwindConfig(opts)); + out('postcss.config.cjs', createPostCssConfig()); + + // Monorepo additions + if (opts?.monorepo) { + fs.copySync(__dirname + '../README-MONO.md', process.cwd() + '/README.md', { overwrite: true }); + let pkg = JSON.parse(fs.readFileSync('package.json')); + pkg.scripts['dep'] = 'vercel build && vercel deploy --prebuilt'; + pkg.scripts['prod'] = 'vercel build --prod && vercel deploy --prebuilt --prod'; + fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2)); + } + // copy over selected template + copyTemplate(opts); + // creating the missing lib folder... + mkdirp(path.join('src', 'lib')) + return opts; +} + +async function createVSCodeSettings() { + try { + mkdirp('.vscode') + const data = await got('https://raw.githubusercontent.com/skeletonlabs/skeleton/master/scripts/tw-settings.json').text() + return data + } catch (error) { + console.error('Unable to download settings file for VSCode, please read manual instructions at https://skeleton.dev/guides/install') + } +} + +function createSvelteConfig(opts) { + // For some reason create-svelte will turn off preprocessing for jsdoc and no type checking + // this will break the using of all CSS preprocessing as well, which is undesirable. + // Here we will just return the typescript default setup + let str = ""; + if (opts?.monorepo) { + str += `import adapter from '@sveltejs/adapter-vercel';\n` + } else { + str += `import adapter from '@sveltejs/adapter-auto';\n` + } + str +=`import { vitePreprocess } from '@sveltejs/kit/vite';` + if (opts?.monorepo) { str += `\nimport path from 'path';` } + str += ` +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://kit.svelte.dev/docs/integrations#preprocessors + // for more information about preprocessors + preprocess: vitePreprocess(), + + kit: { + // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. + // If your environment is not supported or you settled on a specific environment, switch out the adapter. + // See https://kit.svelte.dev/docs/adapters for more information about adapters. + adapter: adapter() + } +}; +export default config;` + return str; +}; + +function createTailwindConfig(opts) { + let plugins = []; + if (opts.forms == true) plugins.push(`require('@tailwindcss/forms')`); + if (opts.typography == true) + plugins.push(`require('@tailwindcss/typography')`); + plugins.push(`...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()`); + + const str = `/** @type {import('tailwindcss').Config} */ +module.exports = { + darkMode: 'class', + content: ['./src/**/*.{html,js,svelte,ts}', require('path').join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')], + theme: { + extend: {}, + }, + plugins: [${plugins.join(',')}], +} +`; + return str; +} + +function createPostCssConfig() { + const str = `module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}`; + return str; +} + +function copyTemplate(opts) { + const src = path.resolve( + dist(opts.skeletontemplatedir), + opts.skeletontemplate, + ); + + fs.copySync(src + '/src', './src', { overwrite: true }); + fs.copySync(src + '/static', './static', { overwrite: true }); + + // All fonts are in the template static folder, so we need to remove the ones that are not relevant to the theme + // and then update the app.postcss file to include the correct font + let fontFamily = ''; + let fontFile = ''; + switch (opts.skeletontheme) { + case 'gold-nouveau': + case 'modern': + case 'seasonal': + fontFamily = 'Quicksand'; + fontFile = ['Quicksand.ttf']; + break; + case 'rocket': + fontFamily = 'Space Grotesk'; + fontFile = ['SpaceGrotesk.ttf']; + break; + case 'seafoam': + fontFamily = 'Playfair Display'; + fontFile = ['PlayfairDisplay-Italic.ttf']; + break; + case 'vintage': + fontFamily = 'Abril Fatface'; + fontFile = ['AbrilFatface.ttf']; + break; + default: + fontFamily = ''; + fontFile = ''; + } + if (fontFamily !== '') { + fs.appendFileSync('./src/app.postcss', ` +@font-face { + font-family: '${fontFamily}'; + src: url('/fonts/${fontFile}'); + font-display: swap; +}`); + removeFilesExceptSync('./static/fonts/', fontFile); + } else { + fs.removeSync('./static/fonts'); + } + + + // patch back in their theme choice - it may have been replaced by the theme template, it may still be the correct auto-genned one, depends on the template - we don't care, this fixes it. + let content = fs.readFileSync('./src/routes/+layout.svelte', { + encoding: 'utf8', + flag: 'r', + }); + const themeReg = /theme-.*\.css';$/gim; + content = content.replace(themeReg, `theme-${opts.skeletontheme}.css';`); + content = (opts.types === "typescript" ? "`); + } + + if (opts?.highlightjs) { + content = content.replace(scriptEndReg, ` + // Floating UI for Popups + import { computePosition, autoUpdate, flip, shift, offset, arrow } from '@floating-ui/dom'; + import { storePopup } from '@skeletonlabs/skeleton'; + storePopup.set({ computePosition, autoUpdate, flip, shift, offset, arrow }); +`); + } + + fs.writeFileSync('./src/routes/+layout.svelte', content); + + // update the to have the data-theme + content = fs.readFileSync('./src/app.html', { encoding: 'utf8', flag: 'r' }); + fs.writeFileSync( + './src/app.html', + content.replace('', ``), + ); +} + +function out(filename, data) { + if (data == undefined) return + fs.writeFileSync(filename, data); +} \ No newline at end of file diff --git a/packages/create-skeleton-app/src/index.js b/packages/create-skeleton-app/src/index.js new file mode 100755 index 00000000..e11ea6d2 --- /dev/null +++ b/packages/create-skeleton-app/src/index.js @@ -0,0 +1,247 @@ +#!/usr/bin/env node +import { SkeletonOptions, createSkeleton } from './creator.js'; +export { SkeletonOptions, createSkeleton } +import fs from 'fs-extra'; +import mri from 'mri'; +import { bold, cyan, gray, grey, red } from 'kleur/colors'; +import { intro, outro, text, select, multiselect, spinner, confirm, cancel, isCancel } from '@clack/prompts'; +import events from 'events' +import { dist, getHelpText, goodbye } from './utils.js'; +import path from 'path'; +import semver from 'semver'; +// Minimum version required for Svelte Kit +const requiredVersion = '16.14.0'; + +async function main() { + if (semver.lt(process.version, requiredVersion)) { + console.error(`You need to be running Node ${requiredVersion} to use Svelte Kit`) + process.exit(1) + } + + // This is required to handle spawning processes + events.EventEmitter.defaultMaxListeners = 15; + + // grab any passed arguments from the command line + const startPath = process.cwd() + let opts = await parseArgs(); + + if ('quiet' in opts) { + // in quiet mode we prefill the defaults, then overlay the passed options and bypass all of askForMissingParams so that it + // doesn't have to constantly check for quietmode all the time. + let defaults = new SkeletonOptions(); + opts = Object.assign(defaults, opts); + } else { + // in interactive mode we ask the user to fill anything not passed in + opts = await askForMissingParams(opts); + } + + // Now that we have all of the options, lets create it. + const s = spinner() + s.start("Installing") + await createSkeleton(opts); + s.stop("Done installing") + // And give the user some final information on what to do Next + if (!(opts?.quiet)) { + const pm = opts.packagemanager; + let runString = `${pm} dev\n`; + + if (pm == 'npm') { + runString = 'npm run dev\n'; + } + let finalInstructions = bold(cyan(`\nDone! You can now:\n\n`)); + if (startPath != opts.path) { + finalInstructions += bold(cyan(`cd ${path.relative(startPath, opts.path)}\n`)); + } + finalInstructions += bold(cyan(runString)) + finalInstructions += grey(`Need some help or found an issue? Visit us on Discord https://discord.gg/EXqV7W8MtY`); + console.log(finalInstructions); + } + process.exit(); +} + +async function parseArgs() { + const argv = process.argv.slice(2); + + // mri will parse argv and expand any shorthand args. Accepted args are the literal props of SkelOptions + /** @type {SkeletonOptions} */ + const opts = mri(argv, { + alias: { + h: 'help', + n: 'name', + p: 'path', + t: 'skeletontheme', + m: 'monorepo', + q: 'quiet', + v: 'verbose', + }, + boolean: [ + 'help', + 'quiet', + 'monorepo', + 'skeletonui', + 'prettier', + 'eslint', + 'playwright', + 'vitest', + 'codeblocks', + 'popups', + 'forms', + 'typography', + 'verbose' + ], + }); + + // If a user invokes 'create-app blah foo', it falls into the _ catch all list, the best we can do is take the first one and use that as the name + // if args are passed in incorrectly such as --prettier=0 instead of --prettier=false then a 0 will be added to the _ collection, we check that the + // first one isn't a bungled arg set to 0 + if (opts._.length && opts._[0] != 0) { + opts.name = opts._[0]; + } + // Show help if specified regardless of how many other options are specified, have fun updating the text string in utils.ts :( + if ('help' in opts) { + console.log(getHelpText()); + process.exit(); + } + return opts; +} +/** + * @param {SkeletonOptions} opts + */ +export async function askForMissingParams(opts) { + const { version } = JSON.parse(fs.readFileSync(dist('../package.json'), 'utf-8')); + + intro(`Create Skeleton App ${gray(`(version ${version})`)} + +${bold(cyan('Welcome to Skeleton 💀! A UI toolkit for Svelte + Tailwind'))} + +Problems? Open an issue on ${cyan('https://github.com/skeletonlabs/skeleton/issues')} if none exists already.`) + + //NOTE: When doing checks here, make sure to test for the presence of the prop, not the prop value as it may be set to false deliberately. + if (!('name' in opts)) { + opts.name = await text({ + message: "Name for your new project:?", + placeholder: "my-app", + validate(value) { + if (value.length === 0) return `App name is required!`; + }, + }); + goodbye(opts.name) + } + + if (!('types' in opts)) { + opts.types = await select({ + message: 'Add type checking with TypeScript?', + options: [ + { + label: 'Yes, using TypeScript syntax', + value: 'typescript', + }, + { + label: 'Yes, using JavaScript with JSDoc comments', + value: 'checkjs', + }, + { label: 'No', value: null }, + ] + }) + goodbye(opts.type) + } + + if (!('eslint' in opts)) { + opts.eslint = await confirm({ + message: 'Add ESLint for code linting?' + }); + goodbye(opts.eslint) + } + + if (!('prettier' in opts)) { + opts.prettier = await confirm({ message: 'Add Prettier for code formatting ?' }); + goodbye(opts.prettier) + } + + if (!('playwright' in opts)) { + opts.playwright = await confirm({ message: 'Add Playwright for browser testing ?' }); + goodbye(opts.playwright) + } + + if (!('vitest' in opts)) { + opts.vitest = await confirm({ message: 'Add Vitest for unit testing ?' }); + goodbye(opts.vitest) + } + + // Component Package Selection + if (!(['codeblocks', 'popups'].every(value => { return Object.keys(opts).includes(value) }))) { + const componentPackages = await multiselect({ + message: "Install component dependencies:", + options: [ + { value: "codeblocks", label: "CodeBlock (installs highlight.js)", }, + { value: "popups", label: "Popups (installs floating-ui)" }, + ], + required: false + }); + goodbye(componentPackages) + componentPackages.every(value => opts[value] = true) + } + + // Tailwind Plugin Selection + if (!(['forms', 'typography'].every(value => { return Object.keys(opts).includes(value) }))) { + const twplugins = await multiselect({ + message: "Pick tailwind plugins to add:", + options: [ + { value: "forms", label: "forms" }, + { value: "typography", label: "typography" } + ], + required: false + }); + goodbye(opts.twplugins) + twplugins.every(value => opts[value] = true) + } + + // Skeleton Theme Selection + if (!('skeletontheme' in opts)) { + opts.skeletontheme = await select({ + message: "Select a theme:", + options: [ + { label: 'Skeleton', value: 'skeleton' }, + { label: 'Modern', value: 'modern' }, + { label: 'Hamlindigo', value: 'hamlindigo' }, + { label: 'Rocket', value: 'rocket' }, + { label: 'Sahara', value: 'sahara' }, + { label: 'Gold Nouveau', value: 'gold-nouveau' }, + { label: 'Vintage', value: 'vintage' }, + { label: 'Seafoam', value: 'seafoam' }, + { label: 'Crimson', value: 'crimson' }, + ], + }); + goodbye(opts.skeletontheme) + } + + //Skeleton Template Selection + if (!('skeletontemplate' in opts)) { + // need to check whether a templatedir has been passed in (might be from a script in package.json pointing to real template projects) + const templateDir = opts.skeletontemplatedir || '../templates'; + let parsedChoices = []; + fs.readdirSync(dist(templateDir)).forEach((dir) => { + const meta_file = dist(`${templateDir}/${dir}/csa-meta.json`); + const { position, label, description, enabled } = JSON.parse(fs.readFileSync(meta_file, 'utf8')); + if (enabled) { + parsedChoices.push({ + position, + label, + description, + value: dir, + }); + } + }); + parsedChoices.sort((a, b) => a.position - b.position); + opts.skeletontemplate = await select({ + message: 'Which Skeleton app template?', + options: parsedChoices + }); + goodbye(opts.skeletontemplate) + } + + const skelOpts = new SkeletonOptions(); + Object.assign(skelOpts, opts); + return skelOpts; +} +await main(); diff --git a/packages/create-skeleton-app/src/utils.js b/packages/create-skeleton-app/src/utils.js new file mode 100644 index 00000000..d978a994 --- /dev/null +++ b/packages/create-skeleton-app/src/utils.js @@ -0,0 +1,94 @@ +import { fileURLToPath } from 'url'; +import { cancel, isCancel } from '@clack/prompts'; +import path from 'path'; +import fs from 'fs-extra' + +export function whichPMRuns() { + const userAgent = process.env.npm_config_user_agent; + if (!userAgent) { + return undefined; + } + const pmSpec = userAgent.split(' ')[0] || ''; + const separatorPos = pmSpec.lastIndexOf('/'); + const name = pmSpec?.substring(0, separatorPos); + return { + name: name === 'npminstall' ? 'cnpm' : name, + version: pmSpec?.substring(separatorPos + 1), + }; +} + +/** @param {string} dir */ +export function mkdirp(dir) { + try { + fs.mkdirSync(dir, { recursive: true }); + } catch (e) { + if (e.code === 'EEXIST') return; + throw e; + } +} + +export function dist(pathToFind) { + let pathAdjust = ''; + let base = fileURLToPath(new URL(`./`, import.meta.url).href); + if (base.endsWith('shared', base.length - 1)) { + pathAdjust = '../'; + } + + const res = path.resolve(base, pathAdjust, pathToFind); + return res; +} + +export function removeFilesExceptSync(directoryPath, filesToKeep) { + const files = fs.readdirSync(directoryPath); + const filesToRemove = files.filter(file => !filesToKeep.includes(file)); + for (const file of filesToRemove) { + const filePath = path.join(directoryPath, file); + fs.removeSync(filePath); + } +} + +export function goodbye(option) { + if (isCancel(option)) { + cancel('Install cancelled, nothing written to disk'); + process.exit(0); + } +} + +export function getHelpText() { + // Must use spaces for adjustments as output can get very wonky with tab output + // Why not array of arrays, TBH it's more readable in source like this and easy to edit with column selection etc. + // But the advantage would be that padEnd could be adjusted to the console.width... will wait for feedback. + return ` +Option Short Quiet Default Values Description +--help -h This help screen +--quiet -q Quiet mode - see below +--verbose -v Show shell output for troubleshooting +--name -n new-skel-app string, no spaces Name of the directory for the project +--types typescript typescript|checkjs TypeScript or JavaScript with JSDoc +--prettier true true|false Whether Prettier is added +--eslint true true|false Whether ESLint is added +--playwright false true|false Whether Playwright is added +--vitest false true|false Whether Vitest is added +--codeblocks false true|false Install codeblock optional dependencies +--popups true true|false Install popups dependencies +--path -p '' relative or absolute path Location to install, name is appended +--forms false true|false Add Tailwinds Forms plugin +--typography false true|false Add Tailwinds Typography plugin +--skeletontheme -t skeleton skeleton Choose one for the Skeleton theme + modern + hamlindigo + rocket + sahara + gold-nouveau + vintage + seafoam + crimson +--skeletontemplate bare bare The Skeleton template to use + welcome + +Quiet mode is for automated installs for testing, CI/CD. It will take all of the default values in the +Quiet Default column, but you can provide any other flags to override as you see fit. If you just want +to generate a new project but still ask for a name, you need to provide all the other args except the +ones to be filled in by the user. +`; +} diff --git a/packages/create-skeleton-app/templates/bare/csa-meta.json b/packages/create-skeleton-app/templates/bare/csa-meta.json new file mode 100644 index 00000000..8828c1ff --- /dev/null +++ b/packages/create-skeleton-app/templates/bare/csa-meta.json @@ -0,0 +1,6 @@ +{ + "position": 5, + "label": "Bare Bones", + "description": "A blank slate for you to create your app", + "enabled": true +} diff --git a/packages/create-skeleton-app/templates/bare/src/app.d.ts b/packages/create-skeleton-app/templates/bare/src/app.d.ts new file mode 100644 index 00000000..8f4d6389 --- /dev/null +++ b/packages/create-skeleton-app/templates/bare/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + // interface Platform {} +} diff --git a/packages/create-skeleton-app/templates/bare/src/app.html b/packages/create-skeleton-app/templates/bare/src/app.html new file mode 100644 index 00000000..77e65f20 --- /dev/null +++ b/packages/create-skeleton-app/templates/bare/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/packages/create-skeleton-app/templates/bare/src/app.postcss b/packages/create-skeleton-app/templates/bare/src/app.postcss new file mode 100644 index 00000000..795f91d5 --- /dev/null +++ b/packages/create-skeleton-app/templates/bare/src/app.postcss @@ -0,0 +1,2 @@ +/*place global styles here */ +html, body { @apply h-full; } \ No newline at end of file diff --git a/packages/create-skeleton-app/templates/bare/src/routes/+layout.svelte b/packages/create-skeleton-app/templates/bare/src/routes/+layout.svelte new file mode 100644 index 00000000..3a331d8a --- /dev/null +++ b/packages/create-skeleton-app/templates/bare/src/routes/+layout.svelte @@ -0,0 +1,10 @@ + + + diff --git a/packages/create-skeleton-app/templates/bare/src/routes/+page.svelte b/packages/create-skeleton-app/templates/bare/src/routes/+page.svelte new file mode 100644 index 00000000..b856d97f --- /dev/null +++ b/packages/create-skeleton-app/templates/bare/src/routes/+page.svelte @@ -0,0 +1,13 @@ + + +
+
+

Let's get cracking bones!

+

Start by exploring:

+
    +
  • /src/routes/+layout.svelte - barebones layout, the CSS import order is critical!
  • +
  • /src/app.postcss - minimal css to make the page full screen, may not be relevant for your project
  • +
  • /src/routes/+page.svelte - this page, you can replace the contents
  • +
+
+
diff --git a/packages/create-skeleton-app/templates/bare/static/favicon.png b/packages/create-skeleton-app/templates/bare/static/favicon.png new file mode 100644 index 00000000..d6c8e808 Binary files /dev/null and b/packages/create-skeleton-app/templates/bare/static/favicon.png differ diff --git a/packages/create-skeleton-app/templates/bare/static/fonts/AbrilFatface.ttf b/packages/create-skeleton-app/templates/bare/static/fonts/AbrilFatface.ttf new file mode 100644 index 00000000..a2917114 Binary files /dev/null and b/packages/create-skeleton-app/templates/bare/static/fonts/AbrilFatface.ttf differ diff --git a/packages/create-skeleton-app/templates/bare/static/fonts/PlayfairDisplay-Italic.ttf b/packages/create-skeleton-app/templates/bare/static/fonts/PlayfairDisplay-Italic.ttf new file mode 100644 index 00000000..f5c5f067 Binary files /dev/null and b/packages/create-skeleton-app/templates/bare/static/fonts/PlayfairDisplay-Italic.ttf differ diff --git a/packages/create-skeleton-app/templates/bare/static/fonts/Quicksand.ttf b/packages/create-skeleton-app/templates/bare/static/fonts/Quicksand.ttf new file mode 100644 index 00000000..0ec22199 Binary files /dev/null and b/packages/create-skeleton-app/templates/bare/static/fonts/Quicksand.ttf differ diff --git a/packages/create-skeleton-app/templates/bare/static/fonts/SpaceGrotesk.ttf b/packages/create-skeleton-app/templates/bare/static/fonts/SpaceGrotesk.ttf new file mode 100644 index 00000000..cf0b5034 Binary files /dev/null and b/packages/create-skeleton-app/templates/bare/static/fonts/SpaceGrotesk.ttf differ diff --git a/packages/create-skeleton-app/templates/welcome/csa-meta.json b/packages/create-skeleton-app/templates/welcome/csa-meta.json new file mode 100644 index 00000000..1580cee2 --- /dev/null +++ b/packages/create-skeleton-app/templates/welcome/csa-meta.json @@ -0,0 +1,6 @@ +{ + "position": 10, + "label": "Skeleton Welcome", + "description": "A single page to welcome you to Skeleton", + "enabled": true +} diff --git a/packages/create-skeleton-app/templates/welcome/src/app.d.ts b/packages/create-skeleton-app/templates/welcome/src/app.d.ts new file mode 100644 index 00000000..8f4d6389 --- /dev/null +++ b/packages/create-skeleton-app/templates/welcome/src/app.d.ts @@ -0,0 +1,9 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +// and what to do when importing types +declare namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + // interface Platform {} +} diff --git a/packages/create-skeleton-app/templates/welcome/src/app.html b/packages/create-skeleton-app/templates/welcome/src/app.html new file mode 100644 index 00000000..423dbd3c --- /dev/null +++ b/packages/create-skeleton-app/templates/welcome/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/packages/create-skeleton-app/templates/welcome/src/app.postcss b/packages/create-skeleton-app/templates/welcome/src/app.postcss new file mode 100644 index 00000000..95b488c0 --- /dev/null +++ b/packages/create-skeleton-app/templates/welcome/src/app.postcss @@ -0,0 +1,2 @@ +/*place global styles here */ +html, body { @apply h-full overflow-hidden; } \ No newline at end of file diff --git a/packages/create-skeleton-app/templates/welcome/src/routes/+layout.svelte b/packages/create-skeleton-app/templates/welcome/src/routes/+layout.svelte new file mode 100644 index 00000000..e9f609c8 --- /dev/null +++ b/packages/create-skeleton-app/templates/welcome/src/routes/+layout.svelte @@ -0,0 +1,49 @@ + + + + + + + + + Skeleton + + + + Discord + + + Twitter + + + GitHub + + + + + + + diff --git a/packages/create-skeleton-app/templates/welcome/src/routes/+page.svelte b/packages/create-skeleton-app/templates/welcome/src/routes/+page.svelte new file mode 100644 index 00000000..67c03533 --- /dev/null +++ b/packages/create-skeleton-app/templates/welcome/src/routes/+page.svelte @@ -0,0 +1,71 @@ + + +
+
+

Welcome to Skeleton.

+ +
+
+ + + +
+ + +
+

Try editing the following:

+

/src/routes/+layout.svelte

+

/src/routes/+page.svelte

+
+
+
+ + diff --git a/packages/create-skeleton-app/templates/welcome/static/favicon.png b/packages/create-skeleton-app/templates/welcome/static/favicon.png new file mode 100644 index 00000000..d6c8e808 Binary files /dev/null and b/packages/create-skeleton-app/templates/welcome/static/favicon.png differ diff --git a/packages/create-skeleton-app/templates/welcome/static/fonts/AbrilFatface.ttf b/packages/create-skeleton-app/templates/welcome/static/fonts/AbrilFatface.ttf new file mode 100644 index 00000000..a2917114 Binary files /dev/null and b/packages/create-skeleton-app/templates/welcome/static/fonts/AbrilFatface.ttf differ diff --git a/packages/create-skeleton-app/templates/welcome/static/fonts/PlayfairDisplay-Italic.ttf b/packages/create-skeleton-app/templates/welcome/static/fonts/PlayfairDisplay-Italic.ttf new file mode 100644 index 00000000..f5c5f067 Binary files /dev/null and b/packages/create-skeleton-app/templates/welcome/static/fonts/PlayfairDisplay-Italic.ttf differ diff --git a/packages/create-skeleton-app/templates/welcome/static/fonts/Quicksand.ttf b/packages/create-skeleton-app/templates/welcome/static/fonts/Quicksand.ttf new file mode 100644 index 00000000..0ec22199 Binary files /dev/null and b/packages/create-skeleton-app/templates/welcome/static/fonts/Quicksand.ttf differ diff --git a/packages/create-skeleton-app/templates/welcome/static/fonts/SpaceGrotesk.ttf b/packages/create-skeleton-app/templates/welcome/static/fonts/SpaceGrotesk.ttf new file mode 100644 index 00000000..cf0b5034 Binary files /dev/null and b/packages/create-skeleton-app/templates/welcome/static/fonts/SpaceGrotesk.ttf differ diff --git a/scripts/checkout.cjs b/scripts/checkout.cjs index f4c357c5..86d616f4 100644 --- a/scripts/checkout.cjs +++ b/scripts/checkout.cjs @@ -1,9 +1,10 @@ -var shell = require('shelljs'); +var shell = require("shelljs"); -if (!shell.which('git')) { - shell.echo('Sorry, this script requires git'); +if (!shell.which("git")) { + shell.echo("Sorry, this script requires git"); shell.exit(1); } -shell.exec('git clone https://github.com/skeletonlabs/create-skeleton-app packages/create-skeleton-app'); -shell.exec('git clone https://github.com/skeletonlabs/skeletonlabs.co sites/skeletonlabs.co'); +shell.exec( + "git clone https://github.com/skeletonlabs/skeletonlabs.co sites/skeletonlabs.co" +);