mirror of
https://github.com/jlengrand/create-1.git
synced 2026-03-10 08:11:25 +00:00
chore: move create into separate repo
This commit is contained in:
15
.eslintrc.js
Normal file
15
.eslintrc.js
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
extends: [require.resolve('@open-wc/eslint-config'), require.resolve('eslint-config-prettier')],
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/test/**/*.js', '**/*.config.js'],
|
||||
rules: {
|
||||
'no-console': 'off',
|
||||
'no-unused-expressions': 'off',
|
||||
'class-methods-use-this': 'off',
|
||||
'max-classes-per-file': 'off',
|
||||
'import/no-extraneous-dependencies': 'off', // we moved all devDependencies to root
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
29
.gitignore
vendored
Normal file
29
.gitignore
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
## editors
|
||||
/.idea
|
||||
/.vscode
|
||||
|
||||
## system files
|
||||
.DS_Store
|
||||
|
||||
## code coverage folders
|
||||
coverage/
|
||||
|
||||
## npm
|
||||
node_modules
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
## temp folders
|
||||
/.tmp/
|
||||
|
||||
## we prefer yarn.lock
|
||||
package-lock.json
|
||||
|
||||
## build output
|
||||
dist
|
||||
build-stats.json
|
||||
stats.html
|
||||
.rpt2_cache
|
||||
|
||||
## browserstack
|
||||
local.log
|
||||
1211
CHANGELOG.md
Normal file
1211
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
99
README.md
Normal file
99
README.md
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
permalink: 'init/index.html'
|
||||
title: Create Open Web Components
|
||||
section: guides
|
||||
tags:
|
||||
- guides
|
||||
---
|
||||
|
||||
# Create Open Web Components
|
||||
|
||||
Web component project scaffolding.
|
||||
|
||||
[//]: # 'AUTO INSERT HEADER PREPUBLISH'
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
npm init @open-wc
|
||||
```
|
||||
|
||||
<div class="custom-block warning"><p class="custom-block-title">WARNING</p> <p><code>npm init</code> requires node 10 & npm 6 or higher</p></div>
|
||||
|
||||
This will kickstart a menu guiding you through all available actions.
|
||||
|
||||
```
|
||||
$ npm init @open-wc
|
||||
npx: installed 14 in 4.074s
|
||||
_.,,,,,,,,,._
|
||||
.d'' ``b. Open Web Components Recommendations
|
||||
.p' Open `q.
|
||||
.d' Web Components `b. Start or upgrade your web component project with
|
||||
.d' `b. ease. All our recommendations at your fingertips.
|
||||
:: ................. ::
|
||||
`p. .q' See more details at https://open-wc.org/init/
|
||||
`p. open-wc.org .q'
|
||||
`b. @openWc .d'
|
||||
`q.. ..,' Note: you can exit any time with Ctrl+C or Esc
|
||||
'',,,,,,,,,,''
|
||||
|
||||
|
||||
? What would you like to do today? › - Use arrow-keys. Return to submit.
|
||||
❯ Scaffold a new project
|
||||
Upgrade an existing project
|
||||
```
|
||||
|
||||
Our generators are very modular you can pick and choose as you see fit.
|
||||
|
||||
## Scaffold generators
|
||||
|
||||
These generators help you kickstart a new app or web component.
|
||||
They will create a new folder and set up everything you need to get started immediately.
|
||||
|
||||
Example usage:
|
||||
|
||||
```bash
|
||||
npm init @open-wc
|
||||
# Select "Scaffold a new project"
|
||||
```
|
||||
|
||||
### Available scaffold generators:
|
||||
|
||||
- `Web Component`<br/>
|
||||
This generator scaffolds a starting point for a web component. We recommend using this generator when you want to develop and publish a single web component.
|
||||
<br/>
|
||||
|
||||
- `Application`<br/>
|
||||
This generator scaffolds a new starter application. We recommend using this generator at the start of your web component project.
|
||||
<br/>
|
||||
|
||||
## Features
|
||||
|
||||
The above generators are the perfect playgrounds to prototype.
|
||||
Add linting, testing, demoing and building whenever the need arises.
|
||||
|
||||
Example usage:
|
||||
|
||||
```bash
|
||||
cd existing-web-component
|
||||
npm init @open-wc
|
||||
# select "Upgrade an existing project" or add features while scaffolding
|
||||
```
|
||||
|
||||
### Available Upgrade features
|
||||
|
||||
- `Linting`<br>
|
||||
This generator adds a complete linting setup with ESLint, Prettier, Husky and commitlint.
|
||||
<br/>
|
||||
|
||||
- `Testing`<br>
|
||||
This generator adds a complete testing setup with Web Test Runner.
|
||||
<br/>
|
||||
|
||||
- `Demoing`<br>
|
||||
This generator adds a complete demoing setup with Storybook.
|
||||
<br/>
|
||||
|
||||
- `Building`<br>
|
||||
This generator adds a complete building setup with rollup.
|
||||
<br/>
|
||||
16
babel.config.js
Normal file
16
babel.config.js
Normal file
@@ -0,0 +1,16 @@
|
||||
module.exports = {
|
||||
plugins: ['babel-plugin-transform-dynamic-import'],
|
||||
ignore: ['./src/generators/*/templates/**/*'],
|
||||
presets: [
|
||||
[
|
||||
'@babel/env',
|
||||
{
|
||||
targets: {
|
||||
node: '10',
|
||||
},
|
||||
corejs: 2,
|
||||
useBuiltIns: 'usage',
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
29
owc-app/.editorconfig
Normal file
29
owc-app/.editorconfig
Normal file
@@ -0,0 +1,29 @@
|
||||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# Change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# We recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
|
||||
[*.{html,js,md}]
|
||||
block_comment_start = /**
|
||||
block_comment = *
|
||||
block_comment_end = */
|
||||
20
owc-app/.gitignore
vendored
Normal file
20
owc-app/.gitignore
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
## editors
|
||||
/.idea
|
||||
/.vscode
|
||||
|
||||
## system files
|
||||
.DS_Store
|
||||
|
||||
## npm
|
||||
/node_modules/
|
||||
/npm-debug.log
|
||||
|
||||
## testing
|
||||
/coverage/
|
||||
|
||||
## temp folders
|
||||
/.tmp/
|
||||
|
||||
# build
|
||||
/_site/
|
||||
/dist/
|
||||
21
owc-app/LICENSE
Normal file
21
owc-app/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 owc-app
|
||||
|
||||
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.
|
||||
30
owc-app/README.md
Normal file
30
owc-app/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
<p align="center">
|
||||
<img width="200" src="https://open-wc.org/hero.png"></img>
|
||||
</p>
|
||||
|
||||
## Open-wc Starter App
|
||||
|
||||
[](https://github.com/open-wc)
|
||||
|
||||
## Quickstart
|
||||
|
||||
To get started:
|
||||
|
||||
```bash
|
||||
npm init @open-wc
|
||||
# requires node 10 & npm 6 or higher
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
- `start` runs your app for development, reloading on file changes
|
||||
- `start:build` runs your app after it has been built using the build command
|
||||
- `build` builds your app and outputs it in your `dist` directory
|
||||
- `test` runs your test suite with Web Test Runner
|
||||
- `lint` runs the linter for your project
|
||||
|
||||
## Tooling configs
|
||||
|
||||
For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project.
|
||||
|
||||
If you customize the configuration a lot, you can consider moving them to individual files.
|
||||
26
owc-app/custom-elements.json
Normal file
26
owc-app/custom-elements.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 2,
|
||||
"tags": [
|
||||
{
|
||||
"name": "owc-app",
|
||||
"description": "An application with a title and an action counter",
|
||||
"properties": [
|
||||
{
|
||||
"name": "title",
|
||||
"type": "String",
|
||||
"description": "The title of your application",
|
||||
"default": "Hey there"
|
||||
},
|
||||
{
|
||||
"name": "page",
|
||||
"type": "String",
|
||||
"description": "Which page to show",
|
||||
"default": "main"
|
||||
}
|
||||
],
|
||||
"events": [],
|
||||
"slots": [],
|
||||
"cssProperties": []
|
||||
}
|
||||
]
|
||||
}
|
||||
28
owc-app/index.html
Normal file
28
owc-app/index.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<meta name="Description" content="Put your description here.">
|
||||
<base href="/">
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
background-color: #ededed;
|
||||
}
|
||||
</style>
|
||||
<title>owc-app</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<owc-app></owc-app>
|
||||
|
||||
<script type="module" src="./src/owc-app.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
49
owc-app/package.json
Normal file
49
owc-app/package.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "owc-app",
|
||||
"version": "0.0.0",
|
||||
"description": "Webcomponent owc-app following open-wc recommendations",
|
||||
"license": "MIT",
|
||||
"author": "owc-app",
|
||||
"scripts": {
|
||||
"format": "npm run format:eslint && npm run format:prettier",
|
||||
"format:eslint": "eslint --ext .js,.html . --fix --ignore-path .gitignore",
|
||||
"format:prettier": "prettier \"**/*.js\" --write --ignore-path .gitignore",
|
||||
"lint": "npm run lint:eslint && npm run lint:prettier",
|
||||
"lint:eslint": "eslint --ext .js,.html . --ignore-path .gitignore",
|
||||
"lint:prettier": "prettier \"**/*.js\" --check --ignore-path .gitignore",
|
||||
"start": "web-dev-server --app-index index.html --node-resolve --open --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"lit-element": "^2.0.1",
|
||||
"lit-html": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@open-wc/eslint-config": "^2.0.0",
|
||||
"@web/dev-server": "^0.0.12",
|
||||
"husky": "^1.0.0",
|
||||
"lint-staged": "^10.0.0",
|
||||
"prettier": "^2.0.4"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"@open-wc/eslint-config",
|
||||
"eslint-config-prettier"
|
||||
]
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"eslint --fix",
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
}
|
||||
84
owc-app/src/OwcApp.js
Normal file
84
owc-app/src/OwcApp.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import { LitElement, html, css } from 'lit-element';
|
||||
import { openWcLogo } from './open-wc-logo.js';
|
||||
|
||||
export class OwcApp extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
title: { type: String },
|
||||
page: { type: String },
|
||||
};
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: #1a2b42;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
main {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.logo > svg {
|
||||
margin-top: 36px;
|
||||
animation: app-logo-spin infinite 20s linear;
|
||||
}
|
||||
|
||||
@keyframes app-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.app-footer {
|
||||
font-size: calc(12px + 0.5vmin);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.app-footer a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<main>
|
||||
<div class="logo">${openWcLogo}</div>
|
||||
<h1>My app</h1>
|
||||
|
||||
<p>Edit <code>src/OwcApp.js</code> and save to reload.</p>
|
||||
<a
|
||||
class="app-link"
|
||||
href="https://open-wc.org/developing/#code-examples"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Code examples
|
||||
</a>
|
||||
</main>
|
||||
|
||||
<p class="app-footer">
|
||||
🚽 Made with love by
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://github.com/open-wc"
|
||||
>open-wc</a
|
||||
>.
|
||||
</p>
|
||||
`;
|
||||
}
|
||||
}
|
||||
33
owc-app/src/open-wc-logo.js
Normal file
33
owc-app/src/open-wc-logo.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { html } from 'lit-html';
|
||||
|
||||
export const openWcLogo = html`
|
||||
<svg
|
||||
width="244px"
|
||||
height="244px"
|
||||
viewBox="0 0 244 244"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#9B00FF" offset="0%"></stop>
|
||||
<stop stop-color="#0077FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
id="Page-1"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<path
|
||||
d="M205.639259,176.936244 C207.430887,174.217233 209.093339,171.405629 210.617884,168.510161 M215.112174,158.724316 C216.385153,155.50304 217.495621,152.199852 218.433474,148.824851 M220.655293,138.874185 C221.231935,135.482212 221.637704,132.03207 221.863435,128.532919 M222,118.131039 C221.860539,114.466419 221.523806,110.85231 221.000113,107.299021 M218.885321,96.8583653 C218.001583,93.4468963 216.942225,90.1061026 215.717466,86.8461994 M211.549484,77.3039459 C209.957339,74.1238901 208.200597,71.0404957 206.290425,68.0649233 M200.180513,59.5598295 C181.848457,36.6639805 153.655709,22 122.036748,22 C66.7879774,22 22,66.771525 22,122 C22,177.228475 66.7879774,222 122.036748,222 C152.914668,222 180.52509,208.015313 198.875424,186.036326"
|
||||
id="Shape"
|
||||
stroke="url(#linearGradient-1)"
|
||||
stroke-width="42.0804674"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
3
owc-app/src/owc-app.js
Normal file
3
owc-app/src/owc-app.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import { OwcApp } from './OwcApp.js';
|
||||
|
||||
customElements.define('owc-app', OwcApp);
|
||||
61
package.json
Normal file
61
package.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"name": "@open-wc/create",
|
||||
"version": "0.36.0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"description": "Easily setup all the tools of Open Web Components.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/open-wc/open-wc.git",
|
||||
"directory": "packages/create"
|
||||
},
|
||||
"author": "open-wc",
|
||||
"homepage": "https://github.com/open-wc/open-wc/tree/master/packages/create",
|
||||
"bin": {
|
||||
"create-open-wc": "./dist/create.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rm -rf dist && babel src --out-dir dist --copy-files --include-dotfiles",
|
||||
"prepublishOnly": "npm run build && ../../scripts/insert-header.js",
|
||||
"start": "npm run build && node ./dist/create.js",
|
||||
"test": "npm run test:node",
|
||||
"test:node": "mocha --require @babel/register",
|
||||
"test:update-snapshots": "node -r @babel/register ./test/update-snapshots.js",
|
||||
"test:watch": "onchange 'src/**/*.js' 'test/**/*.js' -- npm run test --silent"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"keywords": [
|
||||
"open-wc",
|
||||
"owc",
|
||||
"generator",
|
||||
"starter-app"
|
||||
],
|
||||
"dependencies": {
|
||||
"chalk": "^2.4.2",
|
||||
"command-line-args": "^5.0.2",
|
||||
"dedent": "^0.7.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"glob": "^7.1.3",
|
||||
"prompts": "^2.1.0",
|
||||
"semver": "^6.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.8.4",
|
||||
"@babel/core": "^7.11.1",
|
||||
"@babel/preset-env": "^7.9.0",
|
||||
"@babel/register": "^7.9.0",
|
||||
"@open-wc/building-rollup": "^1.9.3",
|
||||
"@open-wc/eslint-config": "^3.0.0",
|
||||
"babel-plugin-transform-dynamic-import": "^2.1.0",
|
||||
"chai": "^4.2.0",
|
||||
"chai-fs": "^2.0.0",
|
||||
"eslint": "^7.11.0",
|
||||
"eslint-config-prettier": "^6.13.0",
|
||||
"mocha": "^6.2.2",
|
||||
"onchange": "^5.2.0"
|
||||
}
|
||||
}
|
||||
121
src/Generator.js
Normal file
121
src/Generator.js
Normal file
@@ -0,0 +1,121 @@
|
||||
/* eslint-disable no-console, import/no-cycle */
|
||||
import prompts from 'prompts';
|
||||
import path from 'path';
|
||||
|
||||
import {
|
||||
copyTemplates,
|
||||
copyTemplate,
|
||||
copyTemplateJsonInto,
|
||||
installNpm,
|
||||
writeFilesToDisk,
|
||||
optionsToCommand,
|
||||
} from './core.js';
|
||||
|
||||
/**
|
||||
* Options for the generator
|
||||
* @typedef {object} GeneratorOptions
|
||||
* @property {string} [tagName] the dash-case tag name
|
||||
* @property {string} [destinationPath='auto'] path to output to. default value 'auto' will output to current working directory
|
||||
* @property {'scaffold'} [type='scaffold'] path to output to. default value 'auto' will output to current working directory
|
||||
* @property {'true'|'false'} [writeToDisk] whether to write to disk
|
||||
* @property {'yarn'|'npm'|'false'} [installDependencies] whether and with which tool to install dependencies
|
||||
*/
|
||||
|
||||
/**
|
||||
* dash-case to PascalCase
|
||||
* @param {string} tagName dash-case tag name
|
||||
* @return {string} PascalCase class name
|
||||
*/
|
||||
function getClassName(tagName) {
|
||||
return tagName
|
||||
.split('-')
|
||||
.reduce((previous, part) => previous + part.charAt(0).toUpperCase() + part.slice(1), '');
|
||||
}
|
||||
|
||||
class Generator {
|
||||
constructor() {
|
||||
/**
|
||||
* @type {GeneratorOptions}
|
||||
*/
|
||||
this.options = {
|
||||
destinationPath: 'auto',
|
||||
};
|
||||
this.templateData = {};
|
||||
this.wantsNpmInstall = true;
|
||||
this.wantsWriteToDisk = true;
|
||||
this.wantsRecreateInfo = true;
|
||||
this.generatorName = '@open-wc';
|
||||
}
|
||||
|
||||
execute() {
|
||||
if (this.options.tagName) {
|
||||
const { tagName } = this.options;
|
||||
const className = getClassName(tagName);
|
||||
this.templateData = { ...this.templateData, tagName, className };
|
||||
|
||||
if (this.options.destinationPath === 'auto') {
|
||||
this.options.destinationPath = process.cwd();
|
||||
if (this.options.type === 'scaffold') {
|
||||
this.options.destinationPath = path.join(process.cwd(), tagName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destinationPath(destination = '') {
|
||||
return path.join(this.options.destinationPath, destination);
|
||||
}
|
||||
|
||||
copyTemplate(from, to) {
|
||||
copyTemplate(from, to, this.templateData);
|
||||
}
|
||||
|
||||
copyTemplateJsonInto(from, to, options = { mode: 'merge' }) {
|
||||
copyTemplateJsonInto(from, to, this.templateData, options);
|
||||
}
|
||||
|
||||
async copyTemplates(from, to = this.destinationPath()) {
|
||||
return copyTemplates(from, to, this.templateData);
|
||||
}
|
||||
|
||||
async end() {
|
||||
if (this.wantsWriteToDisk) {
|
||||
this.options.writeToDisk = await writeFilesToDisk();
|
||||
}
|
||||
|
||||
if (this.wantsNpmInstall) {
|
||||
const answers = await prompts(
|
||||
[
|
||||
{
|
||||
type: 'select',
|
||||
name: 'installDependencies',
|
||||
message: 'Do you want to install dependencies?',
|
||||
choices: [
|
||||
{ title: 'No', value: 'false' },
|
||||
{ title: 'Yes, with yarn', value: 'yarn' },
|
||||
{ title: 'Yes, with npm', value: 'npm' },
|
||||
],
|
||||
},
|
||||
],
|
||||
{
|
||||
onCancel: () => {
|
||||
process.exit();
|
||||
},
|
||||
},
|
||||
);
|
||||
this.options.installDependencies = answers.installDependencies;
|
||||
const { installDependencies } = this.options;
|
||||
if (installDependencies === 'yarn' || installDependencies === 'npm') {
|
||||
await installNpm(this.options.destinationPath, installDependencies);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.wantsRecreateInfo) {
|
||||
console.log('');
|
||||
console.log('If you want to rerun this exact same generator you can do so by executing:');
|
||||
console.log(optionsToCommand(this.options, this.generatorName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Generator;
|
||||
430
src/core.js
Normal file
430
src/core.js
Normal file
@@ -0,0 +1,430 @@
|
||||
/* eslint-disable no-console, import/no-cycle */
|
||||
|
||||
import { spawn } from 'child_process';
|
||||
import deepmerge from 'deepmerge';
|
||||
import fs from 'fs';
|
||||
import glob from 'glob';
|
||||
import path from 'path';
|
||||
import prompts from 'prompts';
|
||||
import Generator from './Generator.js';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Function[]} mixins
|
||||
* @param {typeof Generator} Base
|
||||
*/
|
||||
export async function executeMixinGenerator(mixins, options = {}, Base = Generator) {
|
||||
class Start extends Base {}
|
||||
mixins.forEach(mixin => {
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-class-assign
|
||||
Start = mixin(Start);
|
||||
});
|
||||
|
||||
// class Do extends mixins(Base) {}
|
||||
const inst = new Start();
|
||||
inst.options = { ...inst.options, ...options };
|
||||
|
||||
await inst.execute();
|
||||
if (!options.noEnd) {
|
||||
await inst.end();
|
||||
}
|
||||
}
|
||||
|
||||
export const virtualFiles = [];
|
||||
|
||||
export function resetVirtualFiles() {
|
||||
virtualFiles.length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal template system.
|
||||
* Replaces <%= name %> if provides as template
|
||||
*
|
||||
* @example
|
||||
* processTemplate('prefix <%= name %> suffix', { name: 'foo' })
|
||||
* // prefix foo suffix
|
||||
*
|
||||
* @param {string} _fileContent Template as a string
|
||||
* @param {object} data Object of all the variables to repalce
|
||||
* @returns {string} Template with all replacements
|
||||
*/
|
||||
export function processTemplate(_fileContent, data = {}) {
|
||||
let fileContent = _fileContent;
|
||||
Object.keys(data).forEach(key => {
|
||||
fileContent = fileContent.replace(new RegExp(`<%= ${key} %>`, 'g'), data[key]);
|
||||
});
|
||||
return fileContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal virtual file system
|
||||
* Stores files to write in an array
|
||||
*
|
||||
* @param {string} filePath
|
||||
* @param {string} content
|
||||
*/
|
||||
export function writeFileToPath(filePath, content) {
|
||||
let addNewFile = true;
|
||||
virtualFiles.forEach((fileMeta, index) => {
|
||||
if (fileMeta.path === filePath) {
|
||||
virtualFiles[index].content = content;
|
||||
addNewFile = false;
|
||||
}
|
||||
});
|
||||
if (addNewFile === true) {
|
||||
virtualFiles.push({ path: filePath, content });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} filePath
|
||||
*/
|
||||
export function readFileFromPath(filePath) {
|
||||
let content = false;
|
||||
virtualFiles.forEach((fileMeta, index) => {
|
||||
if (fileMeta.path === filePath) {
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
content = virtualFiles[index].content;
|
||||
}
|
||||
});
|
||||
if (content) {
|
||||
return content;
|
||||
}
|
||||
if (fs.existsSync(filePath)) {
|
||||
return fs.readFileSync(filePath, 'utf-8');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} filePath
|
||||
*/
|
||||
export function deleteVirtualFile(filePath) {
|
||||
const index = virtualFiles.findIndex(fileMeta => fileMeta.path === filePath);
|
||||
if (index !== -1) {
|
||||
virtualFiles.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
let overwriteAllFiles = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {boolean} value
|
||||
*/
|
||||
export function setOverrideAllFiles(value) {
|
||||
overwriteAllFiles = value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} toPath
|
||||
* @param {string} fileContent
|
||||
* @param {object} obj Options
|
||||
*/
|
||||
export async function writeFileToPathOnDisk(
|
||||
toPath,
|
||||
fileContent,
|
||||
{ override = false, ask = true } = {},
|
||||
) {
|
||||
const toPathDir = path.dirname(toPath);
|
||||
if (!fs.existsSync(toPathDir)) {
|
||||
fs.mkdirSync(toPathDir, { recursive: true });
|
||||
}
|
||||
if (fs.existsSync(toPath)) {
|
||||
if (override || overwriteAllFiles) {
|
||||
fs.writeFileSync(toPath, fileContent);
|
||||
} else if (ask) {
|
||||
let wantOverride = overwriteAllFiles;
|
||||
if (!wantOverride) {
|
||||
const answers = await prompts(
|
||||
[
|
||||
{
|
||||
type: 'select',
|
||||
name: 'overwriteFile',
|
||||
message: `Do you want to overwrite ${toPath}?`,
|
||||
choices: [
|
||||
{ title: 'Yes', value: 'true' },
|
||||
{
|
||||
title: 'Yes for all files',
|
||||
value: 'always',
|
||||
},
|
||||
{ title: 'No', value: 'false' },
|
||||
],
|
||||
},
|
||||
],
|
||||
{
|
||||
onCancel: () => {
|
||||
process.exit();
|
||||
},
|
||||
},
|
||||
);
|
||||
if (answers.overwriteFile === 'always') {
|
||||
setOverrideAllFiles(true);
|
||||
wantOverride = true;
|
||||
}
|
||||
if (answers.overwriteFile === 'true') {
|
||||
wantOverride = true;
|
||||
}
|
||||
}
|
||||
if (wantOverride) {
|
||||
fs.writeFileSync(toPath, fileContent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fs.writeFileSync(toPath, fileContent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String[]} allFiles pathes to files
|
||||
* @param {Number} [level] internal to track nesting level
|
||||
*/
|
||||
export function filesToTree(allFiles, level = 0) {
|
||||
const files = allFiles.filter(file => !file.includes('/'));
|
||||
const dirFiles = allFiles.filter(file => file.includes('/'));
|
||||
|
||||
let indent = '';
|
||||
for (let i = 1; i < level; i += 1) {
|
||||
indent += '│ ';
|
||||
}
|
||||
|
||||
let output = '';
|
||||
const processed = [];
|
||||
|
||||
if (dirFiles.length > 0) {
|
||||
dirFiles.forEach(dirFile => {
|
||||
if (!processed.includes(dirFile)) {
|
||||
const dir = `${dirFile.split('/').shift()}/`;
|
||||
const subFiles = [];
|
||||
allFiles.forEach(file => {
|
||||
if (file.startsWith(dir)) {
|
||||
subFiles.push(file.substr(dir.length));
|
||||
processed.push(file);
|
||||
}
|
||||
});
|
||||
output += level === 0 ? `${dir}\n` : `${indent}├── ${dir}\n`;
|
||||
output += filesToTree(subFiles, level + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (files.length === 1) {
|
||||
output += `${indent}└── ${files[0]}\n`;
|
||||
}
|
||||
if (files.length > 1) {
|
||||
const last = files.pop();
|
||||
output += `${indent}├── `;
|
||||
output += files.join(`\n${indent}├── `);
|
||||
output += `\n${indent}└── ${last}\n`;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export async function writeFilesToDisk() {
|
||||
const treeFiles = [];
|
||||
const root = process.cwd();
|
||||
virtualFiles.sort((a, b) => {
|
||||
const pathA = a.path.toLowerCase();
|
||||
const pathB = b.path.toLowerCase();
|
||||
if (pathA < pathB) return -1;
|
||||
if (pathA > pathB) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
virtualFiles.forEach(vFile => {
|
||||
if (vFile.path.startsWith(root)) {
|
||||
let vFilePath = './';
|
||||
vFilePath += vFile.path.substr(root.length + 1);
|
||||
treeFiles.push(vFilePath);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('');
|
||||
console.log(filesToTree(treeFiles));
|
||||
|
||||
const answers = await prompts(
|
||||
[
|
||||
{
|
||||
type: 'select',
|
||||
name: 'writeToDisk',
|
||||
message: 'Do you want to write this file structure to disk?',
|
||||
choices: [
|
||||
{ title: 'Yes', value: 'true' },
|
||||
{ title: 'No', value: 'false' },
|
||||
],
|
||||
},
|
||||
],
|
||||
{
|
||||
onCancel: () => {
|
||||
process.exit();
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (answers.writeToDisk === 'true') {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fileMeta of virtualFiles) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await writeFileToPathOnDisk(fileMeta.path, fileMeta.content);
|
||||
}
|
||||
console.log('Writing..... done');
|
||||
}
|
||||
|
||||
return answers.writeToDisk;
|
||||
}
|
||||
|
||||
export function optionsToCommand(options, generatorName = '@open-wc') {
|
||||
let command = `npm init ${generatorName} `;
|
||||
Object.keys(options).forEach(key => {
|
||||
const value = options[key];
|
||||
if (typeof value === 'string' || typeof value === 'number') {
|
||||
command += `--${key} ${value} `;
|
||||
} else if (typeof value === 'boolean' && value === true) {
|
||||
command += `--${key} `;
|
||||
} else if (Array.isArray(value)) {
|
||||
command += `--${key} ${value.join(' ')} `;
|
||||
}
|
||||
});
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} fromPath
|
||||
* @param {string} toPath
|
||||
* @param {object} data
|
||||
*/
|
||||
export function copyTemplate(fromPath, toPath, data) {
|
||||
const fileContent = readFileFromPath(fromPath);
|
||||
if (fileContent) {
|
||||
const processed = processTemplate(fileContent, data);
|
||||
writeFileToPath(toPath, processed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} fromGlob
|
||||
* @param {string} [toDir] Directory to copy into
|
||||
* @param {object} data Replace parameters in files
|
||||
*/
|
||||
export function copyTemplates(fromGlob, toDir = process.cwd(), data = {}) {
|
||||
return new Promise(resolve => {
|
||||
glob(fromGlob, { dot: true }, (er, files) => {
|
||||
const copiedFiles = [];
|
||||
files.forEach(filePath => {
|
||||
if (!fs.lstatSync(filePath).isDirectory()) {
|
||||
const fileContent = readFileFromPath(filePath);
|
||||
if (fileContent !== false) {
|
||||
const processed = processTemplate(fileContent, data);
|
||||
|
||||
// find path write to (force / also on windows)
|
||||
const replace = path.join(fromGlob.replace(/\*/g, '')).replace(/\\(?! )/g, '/');
|
||||
const toPath = filePath.replace(replace, `${toDir}/`);
|
||||
|
||||
copiedFiles.push({ toPath, processed });
|
||||
writeFileToPath(toPath, processed);
|
||||
}
|
||||
}
|
||||
});
|
||||
resolve(copiedFiles);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} fromPath
|
||||
* @param {string} toPath
|
||||
* @param {object} data
|
||||
*/
|
||||
export function copyTemplateJsonInto(
|
||||
fromPath,
|
||||
toPath,
|
||||
data = {},
|
||||
{ mode = 'merge' } = { mode: 'merge' },
|
||||
) {
|
||||
const content = readFileFromPath(fromPath);
|
||||
if (content === false) {
|
||||
return;
|
||||
}
|
||||
const processed = processTemplate(content, data);
|
||||
const mergeMeObj = JSON.parse(processed);
|
||||
|
||||
const overwriteMerge = (destinationArray, sourceArray) => sourceArray;
|
||||
|
||||
const emptyTarget = value => (Array.isArray(value) ? [] : {});
|
||||
const clone = (value, options) => deepmerge(emptyTarget(value), value, options);
|
||||
|
||||
const combineMerge = (target, source, options) => {
|
||||
const destination = target.slice();
|
||||
|
||||
source.forEach((item, index) => {
|
||||
if (typeof destination[index] === 'undefined') {
|
||||
const cloneRequested = options.clone !== false;
|
||||
const shouldClone = cloneRequested && options.isMergeableObject(item);
|
||||
destination[index] = shouldClone ? clone(item, options) : item;
|
||||
} else if (options.isMergeableObject(item)) {
|
||||
destination[index] = deepmerge(target[index], item, options);
|
||||
} else if (target.indexOf(item) === -1) {
|
||||
destination.push(item);
|
||||
}
|
||||
});
|
||||
return destination;
|
||||
};
|
||||
|
||||
const mergeOptions = { arrayMerge: combineMerge };
|
||||
if (mode === 'override') {
|
||||
mergeOptions.arrayMerge = overwriteMerge;
|
||||
}
|
||||
|
||||
let finalObj = mergeMeObj;
|
||||
const sourceContent = readFileFromPath(toPath);
|
||||
if (sourceContent) {
|
||||
finalObj = deepmerge(JSON.parse(sourceContent), finalObj, mergeOptions);
|
||||
}
|
||||
|
||||
writeFileToPath(toPath, JSON.stringify(finalObj, null, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} command
|
||||
* @param {object} options
|
||||
*/
|
||||
function _install(command = 'npm', options) {
|
||||
return new Promise(resolve => {
|
||||
const install = spawn(command, ['install'], options);
|
||||
install.stdout.on('data', data => {
|
||||
console.log(`${data}`.trim());
|
||||
});
|
||||
|
||||
install.stderr.on('data', data => {
|
||||
console.log(`${command}: ${data}`);
|
||||
});
|
||||
|
||||
install.on('close', () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} where
|
||||
* @param {string} command
|
||||
*/
|
||||
export async function installNpm(where, command) {
|
||||
console.log('');
|
||||
console.log('Installing dependencies...');
|
||||
console.log('This might take some time...');
|
||||
console.log(`Using ${command} to install...`);
|
||||
await _install(command, { cwd: where, shell: true });
|
||||
console.log('');
|
||||
}
|
||||
26
src/create.js
Normal file
26
src/create.js
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import semver from 'semver';
|
||||
import chalk from 'chalk';
|
||||
import { executeMixinGenerator } from './core.js';
|
||||
import { AppMixin } from './generators/app/index.js';
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
if (semver.lte(process.version, '10.12.0')) {
|
||||
console.log(chalk.bgRed('\nUh oh! Looks like you dont have Node v10.12.0 installed!\n'));
|
||||
console.log(`You can do this by going to ${chalk.underline.blue(`https://nodejs.org/`)}
|
||||
|
||||
Or if you use nvm:
|
||||
$ nvm install node ${chalk.gray(`# "node" is an alias for the latest version`)}
|
||||
$ nvm use node
|
||||
`);
|
||||
} else {
|
||||
await executeMixinGenerator([AppMixin]);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
})();
|
||||
81
src/generators/app-lit-element-ts/index.js
Normal file
81
src/generators/app-lit-element-ts/index.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import { CommonRepoMixin } from '../common-repo/index.js';
|
||||
|
||||
/* eslint-disable no-console */
|
||||
export const TsAppLitElementMixin = subclass =>
|
||||
class extends CommonRepoMixin(subclass) {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
const { tagName, className } = this.templateData;
|
||||
|
||||
// write & rename el class template
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_my-app.ts`,
|
||||
this.destinationPath(`src//${tagName}.ts`),
|
||||
);
|
||||
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_MyApp.ts`,
|
||||
this.destinationPath(`src/${className}.ts`),
|
||||
);
|
||||
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_open-wc-logo.ts`,
|
||||
this.destinationPath(`src/open-wc-logo.ts`),
|
||||
);
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_tsconfig.json`,
|
||||
this.destinationPath('tsconfig.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/custom-elements.json`,
|
||||
this.destinationPath('custom-elements.json'),
|
||||
);
|
||||
|
||||
if (this.options.features && this.options.features.includes('testing')) {
|
||||
await this.copyTemplates(`${__dirname}/templates/static-testing/**/*`);
|
||||
}
|
||||
|
||||
if (this.options.features && this.options.features.includes('demoing')) {
|
||||
await this.copyTemplates(`${__dirname}/templates/static-demoing/**/*`);
|
||||
}
|
||||
|
||||
if (this.options.scaffoldFilesFor && this.options.scaffoldFilesFor.includes('demoing')) {
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_my-app.stories.ts`,
|
||||
this.destinationPath(`./stories/${tagName}.stories.ts`),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static-scaffold-demoing/**/*`);
|
||||
}
|
||||
|
||||
if (this.options.scaffoldFilesFor && this.options.scaffoldFilesFor.includes('testing')) {
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_my-app.test.ts`,
|
||||
this.destinationPath(`./test/${tagName}.test.ts`),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static-scaffold-testing/**/*`);
|
||||
}
|
||||
}
|
||||
|
||||
async end() {
|
||||
await super.end();
|
||||
console.log('');
|
||||
console.log('You are all set up now!');
|
||||
console.log('');
|
||||
console.log('All you need to do is run:');
|
||||
console.log(` cd ${this.templateData.tagName}`);
|
||||
console.log(' npm run start');
|
||||
console.log('');
|
||||
}
|
||||
};
|
||||
80
src/generators/app-lit-element-ts/templates/_MyApp.ts
Normal file
80
src/generators/app-lit-element-ts/templates/_MyApp.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { LitElement, html, css, property } from 'lit-element';
|
||||
import { openWcLogo } from './open-wc-logo.js';
|
||||
|
||||
export class <%= className %> extends LitElement {
|
||||
|
||||
@property({type: String}) page = 'main';
|
||||
|
||||
@property({type: String}) title = '';
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: #1a2b42;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
main {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.logo > svg {
|
||||
margin-top: 36px;
|
||||
animation: app-logo-spin infinite 20s linear;
|
||||
}
|
||||
|
||||
@keyframes app-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.app-footer {
|
||||
font-size: calc(12px + 0.5vmin);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.app-footer a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
`;
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<main>
|
||||
<div class="logo">${openWcLogo}</div>
|
||||
<h1>My app</h1>
|
||||
|
||||
<p>Edit <code>src/<%= className %>.js</code> and save to reload.</p>
|
||||
<a
|
||||
class="app-link"
|
||||
href="https://open-wc.org/developing/#code-examples"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Code examples
|
||||
</a>
|
||||
</main>
|
||||
|
||||
<p class="app-footer">
|
||||
🚽 Made with love by
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://github.com/open-wc"
|
||||
>open-wc</a
|
||||
>.
|
||||
</p>
|
||||
`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { html } from 'lit-html';
|
||||
import '../src/<%= tagName %>.js';
|
||||
|
||||
export default {
|
||||
title: '<%= tagName %>',
|
||||
};
|
||||
|
||||
export const App = () =>
|
||||
html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`;
|
||||
23
src/generators/app-lit-element-ts/templates/_my-app.test.ts
Normal file
23
src/generators/app-lit-element-ts/templates/_my-app.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { html, fixture, expect } from '@open-wc/testing';
|
||||
|
||||
import {<%= className %>} from '../src/<%= className %>.js';
|
||||
import '../src/<%= tagName %>.js';
|
||||
|
||||
describe('<%= className %>', () => {
|
||||
let element: <%= className %>;
|
||||
beforeEach(async () => {
|
||||
element = await fixture(html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`);
|
||||
});
|
||||
|
||||
it('renders a h1', () => {
|
||||
const h1 = element.shadowRoot!.querySelector('h1')!;
|
||||
expect(h1).to.exist;
|
||||
expect(h1.textContent).to.equal('My app');
|
||||
});
|
||||
|
||||
it('passes the a11y audit', async () => {
|
||||
await expect(element).shadowDom.to.be.accessible();
|
||||
});
|
||||
});
|
||||
3
src/generators/app-lit-element-ts/templates/_my-app.ts
Normal file
3
src/generators/app-lit-element-ts/templates/_my-app.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { <%= className %> } from './<%= className %>.js';
|
||||
|
||||
customElements.define('<%= tagName %>', <%= className %>);
|
||||
33
src/generators/app-lit-element-ts/templates/_open-wc-logo.ts
Normal file
33
src/generators/app-lit-element-ts/templates/_open-wc-logo.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { html } from 'lit-html';
|
||||
|
||||
export const openWcLogo = html`
|
||||
<svg
|
||||
width="244px"
|
||||
height="244px"
|
||||
viewBox="0 0 244 244"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#9B00FF" offset="0%"></stop>
|
||||
<stop stop-color="#0077FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
id="Page-1"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<path
|
||||
d="M205.639259,176.936244 C207.430887,174.217233 209.093339,171.405629 210.617884,168.510161 M215.112174,158.724316 C216.385153,155.50304 217.495621,152.199852 218.433474,148.824851 M220.655293,138.874185 C221.231935,135.482212 221.637704,132.03207 221.863435,128.532919 M222,118.131039 C221.860539,114.466419 221.523806,110.85231 221.000113,107.299021 M218.885321,96.8583653 C218.001583,93.4468963 216.942225,90.1061026 215.717466,86.8461994 M211.549484,77.3039459 C209.957339,74.1238901 208.200597,71.0404957 206.290425,68.0649233 M200.180513,59.5598295 C181.848457,36.6639805 153.655709,22 122.036748,22 C66.7879774,22 22,66.771525 22,122 C22,177.228475 66.7879774,222 122.036748,222 C152.914668,222 180.52509,208.015313 198.875424,186.036326"
|
||||
id="Shape"
|
||||
stroke="url(#linearGradient-1)"
|
||||
stroke-width="42.0804674"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
19
src/generators/app-lit-element-ts/templates/_package.json
Normal file
19
src/generators/app-lit-element-ts/templates/_package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "<%= tagName %>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "concurrently --kill-others --names tsc,web-dev-server \"npm run tsc:watch\" \"web-dev-server --app-index index.html --node-resolve --open --watch\"",
|
||||
"tsc:watch": "tsc --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"lit-html": "^1.0.0",
|
||||
"lit-element": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "13.11.1",
|
||||
"@web/dev-server": "^0.0.12",
|
||||
"typescript": "~4.0.3",
|
||||
"concurrently": "^5.1.0",
|
||||
"tslib": "^1.11.0"
|
||||
}
|
||||
}
|
||||
19
src/generators/app-lit-element-ts/templates/_tsconfig.json
Normal file
19
src/generators/app-lit-element-ts/templates/_tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2018",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noEmitOnError": true,
|
||||
"lib": ["es2017", "dom"],
|
||||
"strict": true,
|
||||
"esModuleInterop": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true,
|
||||
"importHelpers": true,
|
||||
"outDir": "out-tsc",
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
"rootDir": "./"
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 2,
|
||||
"tags": [
|
||||
{
|
||||
"name": "<%= tagName %>",
|
||||
"description": "An application with a title and an action counter",
|
||||
"properties": [
|
||||
{
|
||||
"name": "title",
|
||||
"type": "String",
|
||||
"description": "The title of your application",
|
||||
"default": "Hey there"
|
||||
},
|
||||
{
|
||||
"name": "page",
|
||||
"type": "String",
|
||||
"description": "Which page to show",
|
||||
"default": "main"
|
||||
}
|
||||
],
|
||||
"events": [],
|
||||
"slots": [],
|
||||
"cssProperties": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
stories: ['../**/stories/*.stories.{js,md,mdx}'],
|
||||
addons: [
|
||||
'storybook-prebuilt/addon-knobs/register.js',
|
||||
'storybook-prebuilt/addon-docs/register.js',
|
||||
'storybook-prebuilt/addon-viewport/register.js',
|
||||
],
|
||||
esDevServer: {
|
||||
// custom es-dev-server options
|
||||
nodeResolve: true,
|
||||
watch: true,
|
||||
open: true
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import { addParameters, setCustomElements } from '@open-wc/demoing-storybook';
|
||||
|
||||
addParameters({
|
||||
docs: {
|
||||
iframeHeight: '200px',
|
||||
}
|
||||
});
|
||||
|
||||
async function run() {
|
||||
const customElements = await (
|
||||
await fetch(new URL('../custom-elements.json', import.meta.url))
|
||||
).json();
|
||||
|
||||
setCustomElements(customElements);
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
files: 'out-tsc/test/**/*.test.js',
|
||||
nodeResolve: true
|
||||
};
|
||||
30
src/generators/app-lit-element-ts/templates/static/README.md
Normal file
30
src/generators/app-lit-element-ts/templates/static/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
<p align="center">
|
||||
<img width="200" src="https://open-wc.org/hero.png"></img>
|
||||
</p>
|
||||
|
||||
## Open-wc Starter App
|
||||
|
||||
[](https://github.com/open-wc)
|
||||
|
||||
## Quickstart
|
||||
|
||||
To get started:
|
||||
|
||||
```sh
|
||||
npm init @open-wc
|
||||
# requires node 10 & npm 6 or higher
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
- `start` runs your app for development, reloading on file changes
|
||||
- `start:build` runs your app after it has been built using the build command
|
||||
- `build` builds your app and outputs it in your `dist` directory
|
||||
- `test` runs your test suite with Web Test Runner
|
||||
- `lint` runs the linter for your project
|
||||
|
||||
## Tooling configs
|
||||
|
||||
For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project.
|
||||
|
||||
If you customize the configuration a lot, you can consider moving them to individual files.
|
||||
@@ -0,0 +1,28 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<meta name="Description" content="Put your description here.">
|
||||
<base href="/">
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
background-color: #ededed;
|
||||
}
|
||||
</style>
|
||||
<title><%= tagName %></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
|
||||
<script type="module" src="./out-tsc/src/<%= tagName %>.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
76
src/generators/app-lit-element/index.js
Normal file
76
src/generators/app-lit-element/index.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { CommonRepoMixin } from '../common-repo/index.js';
|
||||
|
||||
/* eslint-disable no-console */
|
||||
export const AppLitElementMixin = subclass =>
|
||||
class extends CommonRepoMixin(subclass) {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
const { tagName, className } = this.templateData;
|
||||
|
||||
// write & rename el class template
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_my-app.js`,
|
||||
this.destinationPath(`src//${tagName}.js`),
|
||||
);
|
||||
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_MyApp.js`,
|
||||
this.destinationPath(`src/${className}.js`),
|
||||
);
|
||||
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_open-wc-logo.js`,
|
||||
this.destinationPath(`src/open-wc-logo.js`),
|
||||
);
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/custom-elements.json`,
|
||||
this.destinationPath('custom-elements.json'),
|
||||
);
|
||||
|
||||
if (this.options.features && this.options.features.includes('testing')) {
|
||||
await this.copyTemplates(`${__dirname}/templates/static-testing/**/*`);
|
||||
}
|
||||
|
||||
if (this.options.features && this.options.features.includes('demoing')) {
|
||||
await this.copyTemplates(`${__dirname}/templates/static-demoing/**/*`);
|
||||
}
|
||||
|
||||
if (this.options.scaffoldFilesFor && this.options.scaffoldFilesFor.includes('demoing')) {
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_my-app.stories.js`,
|
||||
this.destinationPath(`./stories/${tagName}.stories.js`),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static-scaffold-demoing/**/*`);
|
||||
}
|
||||
|
||||
if (this.options.scaffoldFilesFor && this.options.scaffoldFilesFor.includes('testing')) {
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_my-app.test.js`,
|
||||
this.destinationPath(`./test/${tagName}.test.js`),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static-scaffold-testing/**/*`);
|
||||
}
|
||||
}
|
||||
|
||||
async end() {
|
||||
await super.end();
|
||||
console.log('');
|
||||
console.log('You are all set up now!');
|
||||
console.log('');
|
||||
console.log('All you need to do is run:');
|
||||
console.log(` cd ${this.templateData.tagName}`);
|
||||
console.log(' npm run start');
|
||||
console.log('');
|
||||
}
|
||||
};
|
||||
84
src/generators/app-lit-element/templates/_MyApp.js
Normal file
84
src/generators/app-lit-element/templates/_MyApp.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import { LitElement, html, css } from 'lit-element';
|
||||
import { openWcLogo } from './open-wc-logo.js';
|
||||
|
||||
export class <%= className %> extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
title: { type: String },
|
||||
page: { type: String },
|
||||
};
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: #1a2b42;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
main {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.logo > svg {
|
||||
margin-top: 36px;
|
||||
animation: app-logo-spin infinite 20s linear;
|
||||
}
|
||||
|
||||
@keyframes app-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.app-footer {
|
||||
font-size: calc(12px + 0.5vmin);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.app-footer a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<main>
|
||||
<div class="logo">${openWcLogo}</div>
|
||||
<h1>My app</h1>
|
||||
|
||||
<p>Edit <code>src/<%= className %>.js</code> and save to reload.</p>
|
||||
<a
|
||||
class="app-link"
|
||||
href="https://open-wc.org/developing/#code-examples"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Code examples
|
||||
</a>
|
||||
</main>
|
||||
|
||||
<p class="app-footer">
|
||||
🚽 Made with love by
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://github.com/open-wc"
|
||||
>open-wc</a
|
||||
>.
|
||||
</p>
|
||||
`;
|
||||
}
|
||||
}
|
||||
3
src/generators/app-lit-element/templates/_my-app.js
Normal file
3
src/generators/app-lit-element/templates/_my-app.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import { <%= className %> } from './<%= className %>.js';
|
||||
|
||||
customElements.define('<%= tagName %>', <%= className %>);
|
||||
11
src/generators/app-lit-element/templates/_my-app.stories.js
Normal file
11
src/generators/app-lit-element/templates/_my-app.stories.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import { html } from 'lit-html';
|
||||
import '../src/<%= tagName %>.js';
|
||||
|
||||
export default {
|
||||
title: '<%= tagName %>',
|
||||
};
|
||||
|
||||
export const App = () =>
|
||||
html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`;
|
||||
22
src/generators/app-lit-element/templates/_my-app.test.js
Normal file
22
src/generators/app-lit-element/templates/_my-app.test.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { html, fixture, expect } from '@open-wc/testing';
|
||||
|
||||
import '../src/<%= tagName %>.js';
|
||||
|
||||
describe('<%= className %>', () => {
|
||||
let element;
|
||||
beforeEach(async () => {
|
||||
element = await fixture(html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`);
|
||||
});
|
||||
|
||||
it('renders a h1', () => {
|
||||
const h1 = element.shadowRoot.querySelector('h1');
|
||||
expect(h1).to.exist;
|
||||
expect(h1.textContent).to.equal('My app');
|
||||
});
|
||||
|
||||
it('passes the a11y audit', async () => {
|
||||
await expect(element).shadowDom.to.be.accessible();
|
||||
});
|
||||
});
|
||||
33
src/generators/app-lit-element/templates/_open-wc-logo.js
Normal file
33
src/generators/app-lit-element/templates/_open-wc-logo.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { html } from 'lit-html';
|
||||
|
||||
export const openWcLogo = html`
|
||||
<svg
|
||||
width="244px"
|
||||
height="244px"
|
||||
viewBox="0 0 244 244"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#9B00FF" offset="0%"></stop>
|
||||
<stop stop-color="#0077FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
id="Page-1"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<path
|
||||
d="M205.639259,176.936244 C207.430887,174.217233 209.093339,171.405629 210.617884,168.510161 M215.112174,158.724316 C216.385153,155.50304 217.495621,152.199852 218.433474,148.824851 M220.655293,138.874185 C221.231935,135.482212 221.637704,132.03207 221.863435,128.532919 M222,118.131039 C221.860539,114.466419 221.523806,110.85231 221.000113,107.299021 M218.885321,96.8583653 C218.001583,93.4468963 216.942225,90.1061026 215.717466,86.8461994 M211.549484,77.3039459 C209.957339,74.1238901 208.200597,71.0404957 206.290425,68.0649233 M200.180513,59.5598295 C181.848457,36.6639805 153.655709,22 122.036748,22 C66.7879774,22 22,66.771525 22,122 C22,177.228475 66.7879774,222 122.036748,222 C152.914668,222 180.52509,208.015313 198.875424,186.036326"
|
||||
id="Shape"
|
||||
stroke="url(#linearGradient-1)"
|
||||
stroke-width="42.0804674"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
14
src/generators/app-lit-element/templates/_package.json
Normal file
14
src/generators/app-lit-element/templates/_package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "<%= tagName %>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "web-dev-server --app-index index.html --node-resolve --open --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"lit-html": "^1.0.0",
|
||||
"lit-element": "^2.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@web/dev-server": "^0.0.12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 2,
|
||||
"tags": [
|
||||
{
|
||||
"name": "<%= tagName %>",
|
||||
"description": "An application with a title and an action counter",
|
||||
"properties": [
|
||||
{
|
||||
"name": "title",
|
||||
"type": "String",
|
||||
"description": "The title of your application",
|
||||
"default": "Hey there"
|
||||
},
|
||||
{
|
||||
"name": "page",
|
||||
"type": "String",
|
||||
"description": "Which page to show",
|
||||
"default": "main"
|
||||
}
|
||||
],
|
||||
"events": [],
|
||||
"slots": [],
|
||||
"cssProperties": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
stories: ['../**/stories/*.stories.{js,md,mdx}'],
|
||||
addons: [
|
||||
'storybook-prebuilt/addon-knobs/register.js',
|
||||
'storybook-prebuilt/addon-docs/register.js',
|
||||
'storybook-prebuilt/addon-viewport/register.js',
|
||||
],
|
||||
esDevServer: {
|
||||
// custom es-dev-server options
|
||||
nodeResolve: true,
|
||||
watch: true,
|
||||
open: true
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import { addParameters, setCustomElements } from '@open-wc/demoing-storybook';
|
||||
|
||||
addParameters({
|
||||
docs: {
|
||||
iframeHeight: '200px',
|
||||
}
|
||||
});
|
||||
|
||||
async function run() {
|
||||
const customElements = await (
|
||||
await fetch(new URL('../custom-elements.json', import.meta.url))
|
||||
).json();
|
||||
|
||||
setCustomElements(customElements);
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
files: 'test/**/*.test.js',
|
||||
nodeResolve: true
|
||||
};
|
||||
30
src/generators/app-lit-element/templates/static/README.md
Normal file
30
src/generators/app-lit-element/templates/static/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
<p align="center">
|
||||
<img width="200" src="https://open-wc.org/hero.png"></img>
|
||||
</p>
|
||||
|
||||
## Open-wc Starter App
|
||||
|
||||
[](https://github.com/open-wc)
|
||||
|
||||
## Quickstart
|
||||
|
||||
To get started:
|
||||
|
||||
```bash
|
||||
npm init @open-wc
|
||||
# requires node 10 & npm 6 or higher
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
- `start` runs your app for development, reloading on file changes
|
||||
- `start:build` runs your app after it has been built using the build command
|
||||
- `build` builds your app and outputs it in your `dist` directory
|
||||
- `test` runs your test suite with Web Test Runner
|
||||
- `lint` runs the linter for your project
|
||||
|
||||
## Tooling configs
|
||||
|
||||
For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project.
|
||||
|
||||
If you customize the configuration a lot, you can consider moving them to individual files.
|
||||
28
src/generators/app-lit-element/templates/static/index.html
Normal file
28
src/generators/app-lit-element/templates/static/index.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<meta name="Description" content="Put your description here.">
|
||||
<base href="/">
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
background-color: #ededed;
|
||||
}
|
||||
</style>
|
||||
<title><%= tagName %></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
|
||||
<script type="module" src="./src/<%= tagName %>.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
8
src/generators/app/executeViaOptions.js
Normal file
8
src/generators/app/executeViaOptions.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import { executeMixinGenerator } from '../../core.js';
|
||||
import { gatherMixins } from './gatherMixins.js';
|
||||
|
||||
export async function executeViaOptions(options) {
|
||||
const mixins = gatherMixins(options);
|
||||
|
||||
await executeMixinGenerator(mixins, options);
|
||||
}
|
||||
112
src/generators/app/gatherMixins.js
Normal file
112
src/generators/app/gatherMixins.js
Normal file
@@ -0,0 +1,112 @@
|
||||
import { WcLitElementMixin, WcLitElementPackageMixin } from '../wc-lit-element/index.js';
|
||||
import { LintingMixin } from '../linting/index.js';
|
||||
import { TestingMixin, TestingScaffoldMixin } from '../testing/index.js';
|
||||
import {
|
||||
DemoingStorybookMixin,
|
||||
DemoingStorybookScaffoldMixin,
|
||||
} from '../demoing-storybook/index.js';
|
||||
import { BuildingRollupMixin } from '../building-rollup/index.js';
|
||||
// ts
|
||||
import { TsWcLitElementMixin, TsWcLitElementPackageMixin } from '../wc-lit-element-ts/index.js';
|
||||
import { TsLintingMixin } from '../linting-ts/index.js';
|
||||
import { TsTestingMixin, TsTestingScaffoldMixin } from '../testing-ts/index.js';
|
||||
import {
|
||||
TsDemoingStorybookMixin,
|
||||
TsDemoingStorybookScaffoldMixin,
|
||||
} from '../demoing-storybook-ts/index.js';
|
||||
import { TsBuildingRollupMixin } from '../building-rollup-ts/index.js';
|
||||
|
||||
export function gatherMixins(options) {
|
||||
let considerScaffoldFilesFor = false;
|
||||
const mixins = [];
|
||||
|
||||
if (options.type === 'scaffold') {
|
||||
if (options.typescript === 'true') {
|
||||
switch (options.scaffoldType) {
|
||||
case 'wc':
|
||||
mixins.push(TsWcLitElementPackageMixin);
|
||||
considerScaffoldFilesFor = true;
|
||||
break;
|
||||
case 'wc-lit-element':
|
||||
mixins.push(TsWcLitElementMixin);
|
||||
considerScaffoldFilesFor = true;
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
} else {
|
||||
switch (options.scaffoldType) {
|
||||
case 'wc':
|
||||
mixins.push(WcLitElementPackageMixin);
|
||||
considerScaffoldFilesFor = true;
|
||||
break;
|
||||
case 'wc-lit-element':
|
||||
mixins.push(WcLitElementMixin);
|
||||
considerScaffoldFilesFor = true;
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.features && options.features.length > 0) {
|
||||
if (options.typescript === 'true') {
|
||||
options.features.forEach(feature => {
|
||||
if (feature === 'linting') {
|
||||
mixins.push(TsLintingMixin);
|
||||
}
|
||||
if (feature === 'testing') {
|
||||
mixins.push(TsTestingMixin);
|
||||
}
|
||||
if (feature === 'demoing') {
|
||||
mixins.push(TsDemoingStorybookMixin);
|
||||
}
|
||||
if (feature === 'building') {
|
||||
mixins.push(TsBuildingRollupMixin);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
options.features.forEach(feature => {
|
||||
if (feature === 'linting') {
|
||||
mixins.push(LintingMixin);
|
||||
}
|
||||
if (feature === 'testing') {
|
||||
mixins.push(TestingMixin);
|
||||
}
|
||||
if (feature === 'demoing') {
|
||||
mixins.push(DemoingStorybookMixin);
|
||||
}
|
||||
if (feature === 'building') {
|
||||
mixins.push(BuildingRollupMixin);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (considerScaffoldFilesFor && options.scaffoldFilesFor && options.scaffoldFilesFor.length > 0) {
|
||||
options.scaffoldFilesFor.forEach(feature => {
|
||||
if (options.typescript === 'true') {
|
||||
switch (feature) {
|
||||
case 'testing':
|
||||
mixins.push(TsTestingScaffoldMixin);
|
||||
break;
|
||||
case 'demoing':
|
||||
mixins.push(TsDemoingStorybookScaffoldMixin);
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
} else {
|
||||
switch (feature) {
|
||||
case 'testing':
|
||||
mixins.push(TestingScaffoldMixin);
|
||||
break;
|
||||
case 'demoing':
|
||||
mixins.push(DemoingStorybookScaffoldMixin);
|
||||
break;
|
||||
// no default
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return mixins;
|
||||
}
|
||||
16
src/generators/app/header.js
Normal file
16
src/generators/app/header.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
export default `
|
||||
_.,,,,,,,,,._
|
||||
.d'' \`\`b. ${chalk.underline('Open Web Components Recommendations')}
|
||||
.p' Open \`q.
|
||||
.d' Web Components \`b. Start or upgrade your web component project with
|
||||
.d' \`b. ease. All our recommendations at your fingertips.
|
||||
:: ................. ::
|
||||
\`p. .q' See more details at https://open-wc.org/init/
|
||||
\`p. open-wc.org .q'
|
||||
\`b. @openWc .d'
|
||||
\`q.. ..,' Note: you can exit any time with Ctrl+C or Esc
|
||||
'',,,,,,,,,,''
|
||||
|
||||
`;
|
||||
147
src/generators/app/index.js
Normal file
147
src/generators/app/index.js
Normal file
@@ -0,0 +1,147 @@
|
||||
/* eslint-disable no-console */
|
||||
import prompts from 'prompts';
|
||||
import commandLineArgs from 'command-line-args';
|
||||
import { executeMixinGenerator } from '../../core.js';
|
||||
import { AppLitElementMixin } from '../app-lit-element/index.js';
|
||||
import { TsAppLitElementMixin } from '../app-lit-element-ts/index.js';
|
||||
|
||||
import header from './header.js';
|
||||
import { gatherMixins } from './gatherMixins.js';
|
||||
|
||||
/**
|
||||
* Allows to control the data via command line
|
||||
*
|
||||
* example:
|
||||
* npm init @open-wc --type scaffold --scaffoldType app --tagName foo-bar --installDependencies false
|
||||
* npm init @open-wc --type upgrade --features linting demoing --tagName foo-bar --scaffoldFilesFor demoing --installDependencies false
|
||||
*/
|
||||
const optionDefinitions = [
|
||||
{ name: 'destinationPath', type: String }, // path
|
||||
{ name: 'type', type: String }, // scaffold, upgrade
|
||||
{ name: 'scaffoldType', type: String }, // wc, app
|
||||
{ name: 'features', type: String, multiple: true }, // linting, testing, demoing, building
|
||||
{ name: 'scaffoldFilesFor', type: String, multiple: true }, // testing, demoing, building
|
||||
{ name: 'typescript', type: String },
|
||||
{ name: 'tagName', type: String },
|
||||
{ name: 'installDependencies', type: String }, // yarn, npm, false
|
||||
{ name: 'writeToDisk', type: String }, // true, false
|
||||
];
|
||||
const overrides = commandLineArgs(optionDefinitions);
|
||||
prompts.override(overrides);
|
||||
|
||||
export const AppMixin = subclass =>
|
||||
// eslint-disable-next-line no-shadow
|
||||
class AppMixin extends subclass {
|
||||
constructor() {
|
||||
super();
|
||||
this.wantsNpmInstall = false;
|
||||
this.wantsWriteToDisk = false;
|
||||
this.wantsRecreateInfo = false;
|
||||
}
|
||||
|
||||
async execute() {
|
||||
console.log(header);
|
||||
const scaffoldOptions = [];
|
||||
const questions = [
|
||||
{
|
||||
type: 'select',
|
||||
name: 'type',
|
||||
message: 'What would you like to do today?',
|
||||
choices: [
|
||||
{ title: 'Scaffold a new project', value: 'scaffold' },
|
||||
{ title: 'Upgrade an existing project', value: 'upgrade' },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: (prev, all) => (all.type === 'scaffold' ? 'select' : null),
|
||||
name: 'scaffoldType',
|
||||
message: 'What would you like to scaffold?',
|
||||
choices: [
|
||||
{ title: 'Web Component', value: 'wc' },
|
||||
{ title: 'Application', value: 'app' },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: (prev, all) =>
|
||||
all.scaffoldType === 'wc' || all.scaffoldType === 'app' || all.type === 'upgrade'
|
||||
? 'multiselect'
|
||||
: null,
|
||||
name: 'features',
|
||||
message: 'What would you like to add?',
|
||||
choices: (prev, all) =>
|
||||
[
|
||||
{ title: 'Linting (eslint & prettier)', value: 'linting' },
|
||||
{ title: 'Testing (web-test-runner)', value: 'testing' },
|
||||
{ title: 'Demoing (storybook)', value: 'demoing' },
|
||||
all.scaffoldType !== 'wc' && {
|
||||
title: 'Building (rollup)',
|
||||
value: 'building',
|
||||
},
|
||||
].filter(_ => !!_),
|
||||
onState: state => {
|
||||
state.value.forEach(meta => {
|
||||
if (meta.selected === true && meta.value !== 'linting') {
|
||||
scaffoldOptions.push({
|
||||
title: meta.title,
|
||||
value: meta.value,
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
name: 'typescript',
|
||||
message: 'Would you like to use typescript?',
|
||||
choices: [
|
||||
{ title: 'No', value: 'false' },
|
||||
{ title: 'Yes', value: 'true' },
|
||||
],
|
||||
},
|
||||
{
|
||||
type: () => (scaffoldOptions.length > 0 ? 'multiselect' : null),
|
||||
name: 'scaffoldFilesFor',
|
||||
message: 'Would you like to scaffold examples files for?',
|
||||
choices: scaffoldOptions,
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'tagName',
|
||||
message: 'What is the tag name of your application/web component?',
|
||||
validate: tagName =>
|
||||
!/^([a-z])(?!.*[<>])(?=.*-).+$/.test(tagName)
|
||||
? 'You need a minimum of two words separated by dashes (e.g. foo-bar)'
|
||||
: true,
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* {
|
||||
* type: 'scaffold',
|
||||
* scaffoldType: 'wc',
|
||||
* features: [ 'testing', 'building' ],
|
||||
* scaffoldFilesFor: [ 'testing' ],
|
||||
* tagName: 'foo-bar',
|
||||
* installDependencies: 'false'
|
||||
* }
|
||||
*/
|
||||
this.options = await prompts(questions, {
|
||||
onCancel: () => {
|
||||
process.exit();
|
||||
},
|
||||
});
|
||||
|
||||
const mixins = gatherMixins(this.options);
|
||||
// app is separate to prevent circular imports
|
||||
if (this.options.type === 'scaffold' && this.options.scaffoldType === 'app') {
|
||||
if (this.options.typescript === 'true') {
|
||||
mixins.push(TsAppLitElementMixin);
|
||||
} else {
|
||||
mixins.push(AppLitElementMixin);
|
||||
}
|
||||
}
|
||||
await executeMixinGenerator(mixins, this.options);
|
||||
}
|
||||
};
|
||||
|
||||
export default AppMixin;
|
||||
13
src/generators/building-rollup-ts/index.js
Normal file
13
src/generators/building-rollup-ts/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const TsBuildingRollupMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
12
src/generators/building-rollup-ts/templates/_package.json
Normal file
12
src/generators/building-rollup-ts/templates/_package.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "rimraf dist && tsc && rollup -c rollup.config.js",
|
||||
"start:build": "npm run build && web-dev-server --root-dir dist --app-index index.html --open --compatibility none"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@open-wc/building-rollup": "^1.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"rimraf": "^2.6.3",
|
||||
"rollup": "^2.3.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import merge from 'deepmerge';
|
||||
// use createSpaConfig for bundling a Single Page App
|
||||
import { createSpaConfig } from '@open-wc/building-rollup';
|
||||
|
||||
// use createBasicConfig to do regular JS to JS bundling
|
||||
// import { createBasicConfig } from '@open-wc/building-rollup';
|
||||
|
||||
const baseConfig = createSpaConfig({
|
||||
// use the outputdir option to modify where files are output
|
||||
// outputDir: 'dist',
|
||||
|
||||
// if you need to support older browsers, such as IE11, set the legacyBuild
|
||||
// option to generate an additional build just for this browser
|
||||
// legacyBuild: true,
|
||||
|
||||
// development mode creates a non-minified build for debugging or development
|
||||
developmentMode: process.env.ROLLUP_WATCH === 'true',
|
||||
|
||||
// set to true to inject the service worker registration into your index.html
|
||||
injectServiceWorker: false,
|
||||
});
|
||||
|
||||
export default merge(baseConfig, {
|
||||
// if you use createSpaConfig, you can use your index.html as entrypoint,
|
||||
// any <script type="module"> inside will be bundled by rollup
|
||||
input: './index.html',
|
||||
|
||||
// alternatively, you can use your JS as entrypoint for rollup and
|
||||
// optionally set a HTML template manually
|
||||
// input: './app.js',
|
||||
});
|
||||
13
src/generators/building-rollup/index.js
Normal file
13
src/generators/building-rollup/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const BuildingRollupMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
12
src/generators/building-rollup/templates/_package.json
Normal file
12
src/generators/building-rollup/templates/_package.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "rimraf dist && rollup -c rollup.config.js",
|
||||
"start:build": "npm run build && web-dev-server --root-dir dist --app-index index.html --open --compatibility none"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@open-wc/building-rollup": "^1.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"rimraf": "^2.6.3",
|
||||
"rollup": "^2.3.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import merge from 'deepmerge';
|
||||
// use createSpaConfig for bundling a Single Page App
|
||||
import { createSpaConfig } from '@open-wc/building-rollup';
|
||||
|
||||
// use createBasicConfig to do regular JS to JS bundling
|
||||
// import { createBasicConfig } from '@open-wc/building-rollup';
|
||||
|
||||
const baseConfig = createSpaConfig({
|
||||
// use the outputdir option to modify where files are output
|
||||
// outputDir: 'dist',
|
||||
|
||||
// if you need to support older browsers, such as IE11, set the legacyBuild
|
||||
// option to generate an additional build just for this browser
|
||||
// legacyBuild: true,
|
||||
|
||||
// development mode creates a non-minified build for debugging or development
|
||||
developmentMode: process.env.ROLLUP_WATCH === 'true',
|
||||
|
||||
// set to true to inject the service worker registration into your index.html
|
||||
injectServiceWorker: false,
|
||||
});
|
||||
|
||||
export default merge(baseConfig, {
|
||||
// if you use createSpaConfig, you can use your index.html as entrypoint,
|
||||
// any <script type="module"> inside will be bundled by rollup
|
||||
input: './index.html',
|
||||
|
||||
// alternatively, you can use your JS as entrypoint for rollup and
|
||||
// optionally set a HTML template manually
|
||||
// input: './app.js',
|
||||
});
|
||||
22
src/generators/common-repo/index.js
Normal file
22
src/generators/common-repo/index.js
Normal file
@@ -0,0 +1,22 @@
|
||||
export const CommonRepoMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
this.templateData = {
|
||||
...this.templateData,
|
||||
year: new Date().getFullYear(),
|
||||
};
|
||||
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
// write and rename .gitignore
|
||||
this.copyTemplate(`${__dirname}/templates/_gitignore`, this.destinationPath(`.gitignore`));
|
||||
|
||||
// copy all other files
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
21
src/generators/common-repo/templates/_gitignore
Normal file
21
src/generators/common-repo/templates/_gitignore
Normal file
@@ -0,0 +1,21 @@
|
||||
## editors
|
||||
/.idea
|
||||
/.vscode
|
||||
|
||||
## system files
|
||||
.DS_Store
|
||||
|
||||
## npm
|
||||
/node_modules/
|
||||
/npm-debug.log
|
||||
|
||||
## testing
|
||||
/coverage/
|
||||
|
||||
## temp folders
|
||||
/.tmp/
|
||||
|
||||
# build
|
||||
/_site/
|
||||
/dist/
|
||||
/out-tsc/
|
||||
7
src/generators/common-repo/templates/_package.json
Normal file
7
src/generators/common-repo/templates/_package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "<%= tagName %>",
|
||||
"version": "0.0.0",
|
||||
"description": "Webcomponent <%= tagName %> following open-wc recommendations",
|
||||
"author": "<%= tagName %>",
|
||||
"license": "MIT"
|
||||
}
|
||||
29
src/generators/common-repo/templates/static/.editorconfig
Normal file
29
src/generators/common-repo/templates/static/.editorconfig
Normal file
@@ -0,0 +1,29 @@
|
||||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# Change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# We recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
|
||||
[*.{html,js,md}]
|
||||
block_comment_start = /**
|
||||
block_comment = *
|
||||
block_comment_end = */
|
||||
21
src/generators/common-repo/templates/static/LICENSE
Normal file
21
src/generators/common-repo/templates/static/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) <%= year %> <%= tagName %>
|
||||
|
||||
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.
|
||||
22
src/generators/demoing-storybook-ts/index.js
Normal file
22
src/generators/demoing-storybook-ts/index.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
export const TsDemoingStorybookMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
|
||||
export const TsDemoingStorybookScaffoldMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
await this.copyTemplates(`${__dirname}/templates/static-scaffold/**/*`);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"scripts": {
|
||||
"storybook": "concurrently --kill-others --names tsc,storybook \"npm run tsc:watch\" \"start-storybook --node-resolve --watch --open\"",
|
||||
"storybook:build": "build-storybook"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@open-wc/demoing-storybook": "^2.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
```js script
|
||||
import { html } from '@open-wc/demoing-storybook';
|
||||
import '../dist/<%= tagName %>.js';
|
||||
|
||||
export default {
|
||||
title: '<%= className %>',
|
||||
component: '<%= tagName %>',
|
||||
options: { selectedPanel: "storybookjs/knobs/panel" },
|
||||
};
|
||||
```
|
||||
|
||||
# <%= className %>
|
||||
|
||||
A component for...
|
||||
|
||||
## Features:
|
||||
|
||||
- a
|
||||
- b
|
||||
- ...
|
||||
|
||||
## How to use
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
yarn add <%= tagName %>
|
||||
```
|
||||
|
||||
```js
|
||||
import '<%= tagName %>/<%= tagName %>.js';
|
||||
```
|
||||
|
||||
```js preview-story
|
||||
export const Simple = () => html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`;
|
||||
```
|
||||
|
||||
## Variations
|
||||
|
||||
###### Custom Title
|
||||
|
||||
```js preview-story
|
||||
export const CustomTitle = () => html`
|
||||
<<%= tagName %> title="Hello World"></<%= tagName %>>
|
||||
`;
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
stories: ['../stories/**/*.stories.{js,md,mdx}'],
|
||||
addons: [
|
||||
'storybook-prebuilt/addon-knobs/register.js',
|
||||
'storybook-prebuilt/addon-docs/register.js',
|
||||
'storybook-prebuilt/addon-viewport/register.js',
|
||||
],
|
||||
esDevServer: {
|
||||
// custom es-dev-server options
|
||||
nodeResolve: true,
|
||||
watch: true,
|
||||
open: true
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import { addParameters, setCustomElements } from '@open-wc/demoing-storybook';
|
||||
|
||||
addParameters({
|
||||
docs: {
|
||||
iframeHeight: '200px',
|
||||
}
|
||||
});
|
||||
|
||||
async function run() {
|
||||
const customElements = await (
|
||||
await fetch(new URL('../custom-elements.json', import.meta.url))
|
||||
).json();
|
||||
|
||||
setCustomElements(customElements);
|
||||
}
|
||||
|
||||
run();
|
||||
22
src/generators/demoing-storybook/index.js
Normal file
22
src/generators/demoing-storybook/index.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
export const DemoingStorybookMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
|
||||
export const DemoingStorybookScaffoldMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
await this.copyTemplates(`${__dirname}/templates/static-scaffold/**/*`);
|
||||
}
|
||||
};
|
||||
9
src/generators/demoing-storybook/templates/_package.json
Normal file
9
src/generators/demoing-storybook/templates/_package.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"scripts": {
|
||||
"storybook": "start-storybook",
|
||||
"storybook:build": "build-storybook"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@open-wc/demoing-storybook": "^2.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
```js script
|
||||
import { html } from '@open-wc/demoing-storybook';
|
||||
import '../<%= tagName %>.js';
|
||||
|
||||
export default {
|
||||
title: '<%= className %>',
|
||||
component: '<%= tagName %>',
|
||||
options: { selectedPanel: "storybookjs/knobs/panel" },
|
||||
};
|
||||
```
|
||||
|
||||
# <%= className %>
|
||||
|
||||
A component for...
|
||||
|
||||
## Features:
|
||||
|
||||
- a
|
||||
- b
|
||||
- ...
|
||||
|
||||
## How to use
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
yarn add <%= tagName %>
|
||||
```
|
||||
|
||||
```js
|
||||
import '<%= tagName %>/<%= tagName %>.js';
|
||||
```
|
||||
|
||||
```js preview-story
|
||||
export const Simple = () => html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`;
|
||||
```
|
||||
|
||||
## Variations
|
||||
|
||||
###### Custom Title
|
||||
|
||||
```js preview-story
|
||||
export const CustomTitle = () => html`
|
||||
<<%= tagName %> title="Hello World"></<%= tagName %>>
|
||||
`;
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
stories: ['../stories/**/*.stories.{js,md,mdx}'],
|
||||
addons: [
|
||||
'storybook-prebuilt/addon-knobs/register.js',
|
||||
'storybook-prebuilt/addon-docs/register.js',
|
||||
'storybook-prebuilt/addon-viewport/register.js',
|
||||
],
|
||||
esDevServer: {
|
||||
// custom es-dev-server options
|
||||
nodeResolve: true,
|
||||
watch: true,
|
||||
open: true
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import { addParameters, setCustomElements } from '@open-wc/demoing-storybook';
|
||||
|
||||
addParameters({
|
||||
docs: {
|
||||
iframeHeight: '200px',
|
||||
}
|
||||
});
|
||||
|
||||
async function run() {
|
||||
const customElements = await (
|
||||
await fetch(new URL('../custom-elements.json', import.meta.url))
|
||||
).json();
|
||||
|
||||
setCustomElements(customElements);
|
||||
}
|
||||
|
||||
run();
|
||||
3
src/generators/git-ignore-lock-files-in-diff/static/.gitattributes
vendored
Normal file
3
src/generators/git-ignore-lock-files-in-diff/static/.gitattributes
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# do not show lock files while doing git diff
|
||||
package-lock.json -diff
|
||||
yarn.lock -diff
|
||||
13
src/generators/linting-commitlint/index.js
Normal file
13
src/generators/linting-commitlint/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const LintingCommitlintMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^7.0.0",
|
||||
"@commitlint/config-conventional": "^7.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: ['@commitlint/config-conventional'],
|
||||
};
|
||||
16
src/generators/linting-eslint-ts/index.js
Normal file
16
src/generators/linting-eslint-ts/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export const TsLintingEsLintMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_.eslintrc.js`,
|
||||
this.destinationPath('.eslintrc.js'),
|
||||
);
|
||||
}
|
||||
};
|
||||
20
src/generators/linting-eslint-ts/templates/_.eslintrc.js
Normal file
20
src/generators/linting-eslint-ts/templates/_.eslintrc.js
Normal file
@@ -0,0 +1,20 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint', 'import', 'html'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:import/errors',
|
||||
'plugin:import/warnings',
|
||||
],
|
||||
rules: {
|
||||
// disable the rule for all files
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'import/named': 'off',
|
||||
'import/no-unresolved': 'off',
|
||||
'import/extensions': ['error', 'always', { ignorePackages: true }],
|
||||
},
|
||||
};
|
||||
17
src/generators/linting-eslint-ts/templates/_package.json
Normal file
17
src/generators/linting-eslint-ts/templates/_package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"scripts": {
|
||||
"lint:eslint": "eslint --ext .ts,.html . --ignore-path .gitignore",
|
||||
"format:eslint": "eslint --ext .ts,.html . --fix --ignore-path .gitignore"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^6.1.0",
|
||||
"@open-wc/eslint-config": "^2.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.20.0",
|
||||
"@typescript-eslint/parser": "^2.20.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"@open-wc/eslint-config"
|
||||
]
|
||||
}
|
||||
}
|
||||
11
src/generators/linting-eslint/index.js
Normal file
11
src/generators/linting-eslint/index.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export const LintingEsLintMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
}
|
||||
};
|
||||
15
src/generators/linting-eslint/templates/_package.json
Normal file
15
src/generators/linting-eslint/templates/_package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"scripts": {
|
||||
"lint:eslint": "eslint --ext .js,.html . --ignore-path .gitignore",
|
||||
"format:eslint": "eslint --ext .js,.html . --fix --ignore-path .gitignore"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^6.1.0",
|
||||
"@open-wc/eslint-config": "^2.0.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"@open-wc/eslint-config"
|
||||
]
|
||||
}
|
||||
}
|
||||
11
src/generators/linting-prettier-ts/index.js
Normal file
11
src/generators/linting-prettier-ts/index.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export const TsLintingPrettierMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
}
|
||||
};
|
||||
19
src/generators/linting-prettier-ts/templates/_package.json
Normal file
19
src/generators/linting-prettier-ts/templates/_package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"scripts": {
|
||||
"lint:prettier": "prettier \"**/*.js\" \"**/*.ts\" --check --ignore-path .gitignore",
|
||||
"format:prettier": "prettier \"**/*.js\" \"**/*.ts\" --write --ignore-path .gitignore"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^2.0.4",
|
||||
"eslint-config-prettier": "^6.11.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"eslint-config-prettier"
|
||||
]
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
}
|
||||
11
src/generators/linting-prettier/index.js
Normal file
11
src/generators/linting-prettier/index.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export const LintingPrettierMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
}
|
||||
};
|
||||
19
src/generators/linting-prettier/templates/_package.json
Normal file
19
src/generators/linting-prettier/templates/_package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"scripts": {
|
||||
"lint:prettier": "prettier \"**/*.js\" --check --ignore-path .gitignore",
|
||||
"format:prettier": "prettier \"**/*.js\" --write --ignore-path .gitignore"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^2.0.4",
|
||||
"eslint-config-prettier": "^6.11.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"eslint-config-prettier"
|
||||
]
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
}
|
||||
16
src/generators/linting-ts/index.js
Normal file
16
src/generators/linting-ts/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/* eslint-disable no-console */
|
||||
import { TsLintingEsLintMixin } from '../linting-eslint-ts/index.js';
|
||||
import { TsLintingPrettierMixin } from '../linting-prettier-ts/index.js';
|
||||
|
||||
export const TsLintingMixin = subclass =>
|
||||
class extends TsLintingPrettierMixin(TsLintingEsLintMixin(subclass)) {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
// extend package.json
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
}
|
||||
};
|
||||
22
src/generators/linting-ts/templates/_package.json
Normal file
22
src/generators/linting-ts/templates/_package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.ts": [
|
||||
"eslint --fix",
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "npm run lint:eslint && npm run lint:prettier",
|
||||
"format": "npm run format:eslint && npm run format:prettier"
|
||||
},
|
||||
"devDependencies": {
|
||||
"husky": "^1.0.0",
|
||||
"lint-staged": "^10.0.0"
|
||||
}
|
||||
}
|
||||
13
src/generators/linting-types-js/index.js
Normal file
13
src/generators/linting-types-js/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const LintingTypesJsMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
8
src/generators/linting-types-js/templates/_package.json
Normal file
8
src/generators/linting-types-js/templates/_package.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"scripts": {
|
||||
"lint:types": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "~4.0.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"lib": ["es2017", "dom"],
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"noEmit": true,
|
||||
"strict": false,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true,
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"include": [
|
||||
"**/*.js",
|
||||
"node_modules/@open-wc/**/*.js"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules/!(@open-wc)"
|
||||
]
|
||||
}
|
||||
16
src/generators/linting/index.js
Normal file
16
src/generators/linting/index.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/* eslint-disable no-console */
|
||||
import { LintingEsLintMixin } from '../linting-eslint/index.js';
|
||||
import { LintingPrettierMixin } from '../linting-prettier/index.js';
|
||||
|
||||
export const LintingMixin = subclass =>
|
||||
class extends LintingPrettierMixin(LintingEsLintMixin(subclass)) {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
// extend package.json
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
}
|
||||
};
|
||||
22
src/generators/linting/templates/_package.json
Normal file
22
src/generators/linting/templates/_package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"eslint --fix",
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "npm run lint:eslint && npm run lint:prettier",
|
||||
"format": "npm run format:eslint && npm run format:prettier"
|
||||
},
|
||||
"devDependencies": {
|
||||
"husky": "^1.0.0",
|
||||
"lint-staged": "^10.0.0"
|
||||
}
|
||||
}
|
||||
27
src/generators/testing-ts/index.js
Normal file
27
src/generators/testing-ts/index.js
Normal file
@@ -0,0 +1,27 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import { TsTestingWebTestRunnerMixin } from '../testing-wtr-ts/index.js';
|
||||
|
||||
export const TsTestingMixin = subclass =>
|
||||
class extends TsTestingWebTestRunnerMixin(subclass) {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const TsTestingScaffoldMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
const { tagName } = this.templateData;
|
||||
this.copyTemplate(
|
||||
`${__dirname}/templates/_my-el.test.ts`,
|
||||
this.destinationPath(`test/${tagName}.test.ts`),
|
||||
);
|
||||
}
|
||||
};
|
||||
40
src/generators/testing-ts/templates/_my-el.test.ts
Normal file
40
src/generators/testing-ts/templates/_my-el.test.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { html, fixture, expect } from '@open-wc/testing';
|
||||
|
||||
import {<%= className %>} from '../src/<%= className %>.js';
|
||||
import '../<%= tagName %>.js';
|
||||
|
||||
describe('<%= className %>', () => {
|
||||
it('has a default title "Hey there" and counter 5', async () => {
|
||||
const el: <%= className %> = await fixture(html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`);
|
||||
|
||||
expect(el.title).to.equal('Hey there');
|
||||
expect(el.counter).to.equal(5);
|
||||
});
|
||||
|
||||
it('increases the counter on button click', async () => {
|
||||
const el: <%= className %> = await fixture(html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`);
|
||||
el.shadowRoot!.querySelector('button')!.click();
|
||||
|
||||
expect(el.counter).to.equal(6);
|
||||
});
|
||||
|
||||
it('can override the title via attribute', async () => {
|
||||
const el: <%= className %> = await fixture(html`
|
||||
<<%= tagName %> title="attribute title"></<%= tagName %>>
|
||||
`);
|
||||
|
||||
expect(el.title).to.equal('attribute title');
|
||||
});
|
||||
|
||||
it('passes the a11y audit', async () => {
|
||||
const el: <%= className %> = await fixture(html`
|
||||
<<%= tagName %>></<%= tagName %>>
|
||||
`);
|
||||
|
||||
await expect(el).shadowDom.to.be.accessible();
|
||||
});
|
||||
});
|
||||
5
src/generators/testing-ts/templates/_package.json
Normal file
5
src/generators/testing-ts/templates/_package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@open-wc/testing": "^2.0.0"
|
||||
}
|
||||
}
|
||||
13
src/generators/testing-wallaby/index.js
Normal file
13
src/generators/testing-wallaby/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const TestingWallabyMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
5
src/generators/testing-wallaby/templates/_package.json
Normal file
5
src/generators/testing-wallaby/templates/_package.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@open-wc/testing-wallaby": "^0.1.3"
|
||||
}
|
||||
}
|
||||
23
src/generators/testing-wallaby/templates/static/wallaby.js
Normal file
23
src/generators/testing-wallaby/templates/static/wallaby.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const wallabyWebpack = require('wallaby-webpack'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
const path = require('path');
|
||||
|
||||
const wallabyPostprocessor = wallabyWebpack({
|
||||
resolve: {
|
||||
modules: [path.resolve(__dirname, 'bower_components'), 'node_modules'],
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = () => ({
|
||||
files: [{ pattern: '*.js', load: false }, '!wallaby.js', '!*.config.js', '!*.conf.js'],
|
||||
tests: [{ pattern: 'test/*.test.js', load: false }],
|
||||
testFramework: 'mocha',
|
||||
debug: true,
|
||||
env: {
|
||||
kind: 'chrome',
|
||||
},
|
||||
postprocessor: wallabyPostprocessor,
|
||||
setup: () => {
|
||||
// required to trigger test loading
|
||||
window.__moduleBundler.loadTests();
|
||||
},
|
||||
});
|
||||
13
src/generators/testing-wtr-ts/index.js
Normal file
13
src/generators/testing-wtr-ts/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
export const TsTestingWebTestRunnerMixin = subclass =>
|
||||
class extends subclass {
|
||||
async execute() {
|
||||
await super.execute();
|
||||
|
||||
this.copyTemplateJsonInto(
|
||||
`${__dirname}/templates/_package.json`,
|
||||
this.destinationPath('package.json'),
|
||||
);
|
||||
|
||||
await this.copyTemplates(`${__dirname}/templates/static/**/*`);
|
||||
}
|
||||
};
|
||||
9
src/generators/testing-wtr-ts/templates/_package.json
Normal file
9
src/generators/testing-wtr-ts/templates/_package.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"scripts": {
|
||||
"test": "tsc && web-test-runner --coverage",
|
||||
"test:watch": "web-test-runner --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@web/test-runner": "^0.7.41"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
files: 'dist/**/test/**/*.test.js',
|
||||
nodeResolve: true
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user