Compare commits
2 Commits
f521b261e6
...
97dde3bdfe
Author | SHA1 | Date |
---|---|---|
|
97dde3bdfe | |
|
141a7c0461 |
.editorconfig.gitignore
.husky
.storybook
README.mdassets
build.mjseslint.config.mjsindex.htmlpackage-lock.jsonpackage.jsonrollup.config.jsscripts
server
src
stories
test
tsconfig.base.jsontsconfig.jsonweb-dev-server.config.jsweb-test-runner.config.js
|
@ -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 = */
|
|
@ -1,115 +1,24 @@
|
|||
# Created by https://www.gitignore.io/api/node
|
||||
# Edit at https://www.gitignore.io/?templates=node
|
||||
## editors
|
||||
/.idea
|
||||
/.vscode
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
## system files
|
||||
.DS_Store
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
## npm
|
||||
/node_modules/
|
||||
/npm-debug.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
## testing
|
||||
/coverage/
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
## temp folders
|
||||
/.tmp/
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Uncomment the public line if your project uses Gatsby
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# https://create-react-app.dev/docs/using-the-public-folder/#docsNav
|
||||
# public
|
||||
|
||||
# Storybook build outputs
|
||||
.out
|
||||
.storybook-out
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# Temporary folders
|
||||
tmp/
|
||||
temp/
|
||||
|
||||
# End of https://www.gitignore.io/api/node
|
||||
api/**
|
||||
storybook-static/
|
||||
|
||||
# Wireit's cache
|
||||
.wireit
|
||||
# build
|
||||
/_site/
|
||||
/dist/
|
||||
/out-tsc/
|
||||
|
||||
storybook-static
|
||||
custom-elements.json
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
./node_modules/.bin/lint-staged
|
|
@ -0,0 +1,8 @@
|
|||
const config = {
|
||||
stories: ['../out-tsc/stories/**/*.stories.{js,md,mdx}'],
|
||||
framework: {
|
||||
name: '@web/storybook-framework-web-components',
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -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,29 @@
|
|||
<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>
|
After (image error) Size: 1.3 KiB |
133
build.mjs
133
build.mjs
|
@ -1,133 +0,0 @@
|
|||
import { execFileSync } from "child_process";
|
||||
import * as chokidar from "chokidar";
|
||||
import esbuild from "esbuild";
|
||||
import fs from "fs";
|
||||
import { globSync } from "glob";
|
||||
import path from "path";
|
||||
import { cwd } from "process";
|
||||
import process from "process";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
// Hack replaces what was lost when using Bun / later Node versions
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||||
|
||||
const isProdBuild = process.env.NODE_ENV === "production";
|
||||
|
||||
const definitions = {
|
||||
"process.env.NODE_ENV": JSON.stringify(isProdBuild ? "production" : "development"),
|
||||
"process.env.CWD": JSON.stringify(cwd()),
|
||||
};
|
||||
|
||||
// If you have assets in your src folder that won't be built/bundled, put them into "otherFiles" to
|
||||
// copy them. All this is a replacement for rollup-copy-plugin, which I used to use.
|
||||
|
||||
const otherFiles = [
|
||||
["./src/*.css", "."],
|
||||
["./src/*.png", "."]
|
||||
];
|
||||
|
||||
const isFile = (filePath) => fs.statSync(filePath).isFile();
|
||||
function nameCopyTarget(src, dest, strip) {
|
||||
const target = path.join(dest, strip ? src.replace(strip, "") : path.parse(src).base);
|
||||
return [src, target];
|
||||
}
|
||||
|
||||
function copyOthers() {
|
||||
for (const [source, rawdest, strip] of otherFiles) {
|
||||
const matchedPaths = globSync(source);
|
||||
const dest = path.join("dist", rawdest);
|
||||
const copyTargets = matchedPaths.map((path) => nameCopyTarget(path, dest, strip));
|
||||
for (const [src, dest] of copyTargets) {
|
||||
if (isFile(src)) {
|
||||
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
||||
fs.copyFileSync(src, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This starts the definitions used for esbuild: Targets, arguments, the function for running a
|
||||
// build, and the options for building: building or watching. If you're building more than one app,
|
||||
// order them by the approximately largest project to smallest to build even faster.
|
||||
|
||||
const apps = [
|
||||
["index.ts", "."]
|
||||
];
|
||||
|
||||
const baseArgs = {
|
||||
bundle: true,
|
||||
write: true,
|
||||
sourcemap: true,
|
||||
minify: isProdBuild,
|
||||
splitting: true,
|
||||
treeShaking: true,
|
||||
external: ["*.woff", "*.woff2"],
|
||||
tsconfig: "./tsconfig.json",
|
||||
loader: { ".css": "text", ".md": "text" },
|
||||
define: definitions,
|
||||
format: "esm",
|
||||
};
|
||||
|
||||
async function buildOneSource(source, dest) {
|
||||
const DIST = path.join(__dirname, "./dist", dest);
|
||||
console.log(`[${new Date(Date.now()).toISOString()}] Starting build for target ${source}`);
|
||||
|
||||
try {
|
||||
const start = Date.now();
|
||||
copyOthers();
|
||||
await esbuild.build({
|
||||
...baseArgs,
|
||||
entryPoints: [`./src/${source}`],
|
||||
entryNames: '[dir]/[name]',
|
||||
outdir: DIST,
|
||||
});
|
||||
const end = Date.now();
|
||||
console.log(
|
||||
`[${new Date(end).toISOString()}] Finished build for target ${source} in ${
|
||||
Date.now() - start
|
||||
}ms`,
|
||||
);
|
||||
} catch (exc) {
|
||||
console.error(`[${new Date(Date.now()).toISOString()}] Failed to build ${source}: ${exc}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function buildAll(apps) {
|
||||
await Promise.allSettled(apps.map(([source, dest]) => buildOneSource(source, dest)));
|
||||
}
|
||||
|
||||
let timeoutId = null;
|
||||
function debouncedBuild() {
|
||||
if (timeoutId !== null) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
timeoutId = setTimeout(() => {
|
||||
console.log("\x1bc");
|
||||
buildAll(apps);
|
||||
}, 250);
|
||||
}
|
||||
|
||||
if (process.argv.length > 2 && (process.argv[2] === "-h" || process.argv[2] === "--help")) {
|
||||
console.log(`Build:
|
||||
|
||||
options:
|
||||
-w, --watch: Build all ${apps.length} applications
|
||||
-h, --help: This help message
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (process.argv.length > 2 && (process.argv[2] === "-w" || process.argv[2] === "--watch")) {
|
||||
console.log("Watching ./src for changes");
|
||||
chokidar.watch("./src").on("all", (event, path) => {
|
||||
if (!["add", "change", "unlink"].includes(event)) {
|
||||
return;
|
||||
}
|
||||
if (!/(\.css|\.ts|\.js)$/.test(path)) {
|
||||
return;
|
||||
}
|
||||
debouncedBuild();
|
||||
});
|
||||
} else {
|
||||
await buildAll(apps);
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
import eslint from "@eslint/js";
|
||||
import tsparser from "@typescript-eslint/parser";
|
||||
import litconf from "eslint-plugin-lit";
|
||||
import wcconf from "eslint-plugin-wc";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
export default [
|
||||
// You would not believe how much this change has frustrated users: ["if an ignores key is used
|
||||
// without any other keys in the configuration object, then the patterns act as global
|
||||
// ignores"](https://eslint.org/docs/latest/use/configure/ignore)
|
||||
{
|
||||
ignores: [
|
||||
"dist/",
|
||||
// don't lint the cache
|
||||
".wireit/",
|
||||
// let packages have their own configurations
|
||||
"packages/",
|
||||
// don't ever lint node_modules
|
||||
"node_modules/",
|
||||
".storybook/*",
|
||||
// don't lint build output (make sure it's set to your correct build folder name)
|
||||
// don't lint nyc coverage output
|
||||
"coverage/",
|
||||
"src/locale-codes.ts",
|
||||
"storybook-static/",
|
||||
"src/locales/",
|
||||
],
|
||||
},
|
||||
eslint.configs.recommended,
|
||||
wcconf.configs["flat/recommended"],
|
||||
litconf.configs["flat/recommended"],
|
||||
...tseslint.configs.recommended,
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tsparser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 12,
|
||||
sourceType: "module",
|
||||
},
|
||||
},
|
||||
files: ["src/**"],
|
||||
rules: {
|
||||
"no-unused-vars": "off",
|
||||
"no-console": ["error", { allow: ["debug", "warn", "error"] }],
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tsparser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 12,
|
||||
sourceType: "module",
|
||||
},
|
||||
globals: {
|
||||
...globals.nodeBuiltin,
|
||||
},
|
||||
},
|
||||
files: ["scripts/*.mjs", "*.ts", "*.mjs"],
|
||||
rules: {
|
||||
"no-unused-vars": "off",
|
||||
// We WANT our scripts to output to the console!
|
||||
"no-console": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
43
index.html
43
index.html
|
@ -1,15 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en-GB">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400..900&display=swap" rel="stylesheet" />
|
||||
<script src="./dist/index.js" type="text/javascript"></script>
|
||||
<link href="./dist/styles.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<fridge-magnets id="fridgemagnets">
|
||||
</fridge-magnets>
|
||||
</body>
|
||||
</html>
|
||||
<!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>fridge-magnets</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<fridge-magnets></fridge-magnets>
|
||||
|
||||
<script type="module" src="./out-tsc/src/fridge-magnets.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
256
package.json
256
package.json
|
@ -1,168 +1,94 @@
|
|||
{
|
||||
"name": "elf-boilerplate",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@lit/localize": "^0.12.2",
|
||||
"@neodrag/vanilla": "^2.0.5",
|
||||
"lit": "^3.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/eslint__js": "^8.42.3",
|
||||
"@types/node": "^22.5.5",
|
||||
"@typescript-eslint/eslint-plugin": "^8.6.0",
|
||||
"@typescript-eslint/parser": "^8.6.0",
|
||||
"chokidar": "^4.0.1",
|
||||
"esbuild": "^0.24.0",
|
||||
"eslint": "^9.11.0",
|
||||
"eslint-plugin-lit": "^1.15.0",
|
||||
"eslint-plugin-wc": "^2.1.1",
|
||||
"glob": "^10.4.5",
|
||||
"http-server": "^14.1.1",
|
||||
"knip": "^5.30.4",
|
||||
"lit-analyzer": "^2.0.3",
|
||||
"lockfile-lint": "^4.14.0",
|
||||
"prettier": "^3.3.3",
|
||||
"rimraf": "^5.0.10",
|
||||
"syncpack": "^13.0.0",
|
||||
"typescript": "^5.6.2",
|
||||
"typescript-eslint": "^8.6.0",
|
||||
"wireit": "^0.14.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"license": "MIT",
|
||||
"optionalDependencies": {
|
||||
"@esbuild/darwin-arm64": "^0.23.0",
|
||||
"@esbuild/linux-amd64": "^0.18.11",
|
||||
"@esbuild/linux-arm64": "^0.23.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "wireit",
|
||||
"clean": "wireit",
|
||||
"demo": "wireit",
|
||||
"fix": "wireit",
|
||||
"format": "wireit",
|
||||
"lint": "wireit",
|
||||
"realclean": "wireit",
|
||||
"watch": "wireit"
|
||||
},
|
||||
"type": "module",
|
||||
"wireit": {
|
||||
"build": {
|
||||
"command": "${NODE_RUNNER} build.mjs",
|
||||
"files": [
|
||||
"./src/**/*.{css,ts,js}"
|
||||
],
|
||||
"output": [
|
||||
"dist/**"
|
||||
],
|
||||
"env": {
|
||||
"NODE_RUNNER": {
|
||||
"external": true,
|
||||
"default": "node"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clean": {
|
||||
"command": "rimraf ./dist"
|
||||
},
|
||||
"demo": {
|
||||
"command": "${NODE_RUNNER} ./node_modules/.bin/http-server . --port ${HTTP_DEMO_PORT}",
|
||||
"server": true,
|
||||
"env": {
|
||||
"NODE_RUNNER": {
|
||||
"external": true,
|
||||
"default": "node"
|
||||
},
|
||||
"HTTP_DEMO_PORT": {
|
||||
"external": true,
|
||||
"default": "8000"
|
||||
}
|
||||
}
|
||||
},
|
||||
"fix": {
|
||||
"command": "prettier --write .",
|
||||
"dependencies": [
|
||||
"fix:eslint",
|
||||
"fix:package"
|
||||
]
|
||||
},
|
||||
"format": {
|
||||
"command": "prettier --write ."
|
||||
},
|
||||
"fix:eslint": {
|
||||
"command": "${NODE_RUNNER ./scripts/eslint.mjs --fix",
|
||||
"env": {
|
||||
"NODE_RUNNER": {
|
||||
"external": true,
|
||||
"default": "node"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint:components": {
|
||||
"command": "lit-analyzer src"
|
||||
},
|
||||
"lint:eslint": {
|
||||
"command": "${NODE_RUNNER} ./scripts/eslint.mjs --precommit",
|
||||
"env": {
|
||||
"NODE_RUNNER": {
|
||||
"external": true,
|
||||
"default": "node"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint:lockfile": {
|
||||
"_comment": "Ensure every entry has a resolved hash",
|
||||
"shell": true,
|
||||
"command": "[ -z \"$(jq -r '.packages | to_entries[] | select((.key | startswith(\"node_modules\")) and (.value | has(\"resolved\") | not)) | .key' < package-lock.json)\" ]",
|
||||
"dependencies": [
|
||||
"lint:lockfile:base"
|
||||
]
|
||||
},
|
||||
"lint:lockfile:base": {
|
||||
"command": "lockfile-lint --path ./package-lock.json --allowed-hosts npm --validate-https --validate-integrity"
|
||||
},
|
||||
"lint:spelling": {
|
||||
"command": "${NODE_RUNNER} scripts/check-spelling.mjs",
|
||||
"env": {
|
||||
"NODE_RUNNER": {
|
||||
"external": true,
|
||||
"default": "node"
|
||||
}
|
||||
}
|
||||
},
|
||||
"prettier": {
|
||||
"command": "prettier ."
|
||||
},
|
||||
"lint": {
|
||||
"dependencies": [
|
||||
"lint:types",
|
||||
"lint:components",
|
||||
"lint:lit",
|
||||
"lint:lockfile",
|
||||
"lint:eslint",
|
||||
"prettier"
|
||||
]
|
||||
},
|
||||
"lint:imports": {
|
||||
"command": "knip --config scripts/knip.config.ts"
|
||||
},
|
||||
"lint:lit": {
|
||||
"command": "lit-analyzer src"
|
||||
},
|
||||
"lint:types": {
|
||||
"command": "tsc --noEmit -p ."
|
||||
},
|
||||
"watch": {
|
||||
"command": "${NODE_RUNNER} build.mjs --watch",
|
||||
"server": true,
|
||||
"env": {
|
||||
"NODE_RUNNER": {
|
||||
"external": true,
|
||||
"default": "node"
|
||||
}
|
||||
}
|
||||
"name": "fridge-magnets",
|
||||
"description": "Webcomponent fridge-magnets following open-wc recommendations",
|
||||
"license": "MIT",
|
||||
"author": "fridge-magnets",
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
|
||||
"format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
|
||||
"prepare": "husky",
|
||||
"test": "tsc && wtr --coverage",
|
||||
"test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\"",
|
||||
"storybook": "tsc && npm run analyze -- --exclude dist && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"storybook dev -p 8080\"",
|
||||
"storybook:build": "tsc && npm run analyze -- --exclude dist && storybook build",
|
||||
"build": "rimraf dist && tsc && rollup -c rollup.config.js && npm run analyze -- --exclude dist",
|
||||
"start:build": "web-dev-server --root-dir dist --app-index index.html --open",
|
||||
"analyze": "cem analyze --litelement",
|
||||
"start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"web-dev-server\""
|
||||
},
|
||||
"dependencies": {
|
||||
"lit": "^3.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@custom-elements-manifest/analyzer": "^0.10.3",
|
||||
"@open-wc/eslint-config": "^12.0.3",
|
||||
"@open-wc/testing": "^4.0.0",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@storybook/addon-a11y": "^7.6.20",
|
||||
"@storybook/addon-essentials": "^7.6.20",
|
||||
"@storybook/addon-links": "^7.6.20",
|
||||
"@storybook/web-components": "^7.6.20",
|
||||
"@types/mocha": "^10.0.7",
|
||||
"@typescript-eslint/eslint-plugin": "^7.16.0",
|
||||
"@typescript-eslint/parser": "^7.16.0",
|
||||
"@web/dev-server": "^0.4.6",
|
||||
"@web/rollup-plugin-html": "^2.3.0",
|
||||
"@web/rollup-plugin-import-meta-assets": "^2.2.1",
|
||||
"@web/storybook-builder": "^0.1.16",
|
||||
"@web/storybook-framework-web-components": "^0.1.2",
|
||||
"@web/test-runner": "^0.18.2",
|
||||
"babel-plugin-template-html-minifier": "^4.1.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"deepmerge": "^4.3.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"husky": "^9.0.11",
|
||||
"lint-staged": "^15.2.7",
|
||||
"prettier": "^3.3.2",
|
||||
"rimraf": "^5.0.9",
|
||||
"rollup": "^4.18.1",
|
||||
"rollup-plugin-esbuild": "^6.1.1",
|
||||
"rollup-plugin-workbox": "^8.1.0",
|
||||
"storybook": "^7.6.20",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.5.3"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"@open-wc",
|
||||
"prettier"
|
||||
],
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error"
|
||||
],
|
||||
"import/no-unresolved": "off",
|
||||
"import/extensions": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
"ignorePackages": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.ts": [
|
||||
"eslint --fix",
|
||||
"prettier --write"
|
||||
]
|
||||
},
|
||||
"customElements": "custom-elements.json"
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import nodeResolve from '@rollup/plugin-node-resolve';
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import { rollupPluginHTML as html } from '@web/rollup-plugin-html';
|
||||
import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets';
|
||||
import esbuild from 'rollup-plugin-esbuild';
|
||||
import { generateSW } from 'rollup-plugin-workbox';
|
||||
import path from 'path';
|
||||
|
||||
export default {
|
||||
input: 'index.html',
|
||||
output: {
|
||||
entryFileNames: '[hash].js',
|
||||
chunkFileNames: '[hash].js',
|
||||
assetFileNames: '[hash][extname]',
|
||||
format: 'es',
|
||||
dir: 'dist',
|
||||
},
|
||||
preserveEntrySignatures: false,
|
||||
|
||||
plugins: [
|
||||
/** Enable using HTML as rollup entrypoint */
|
||||
html({
|
||||
minify: true,
|
||||
injectServiceWorker: true,
|
||||
serviceWorkerPath: 'dist/sw.js',
|
||||
}),
|
||||
/** Resolve bare module imports */
|
||||
nodeResolve(),
|
||||
/** Minify JS, compile JS to a lower language target */
|
||||
esbuild({
|
||||
minify: true,
|
||||
target: ['chrome64', 'firefox67', 'safari11.1'],
|
||||
}),
|
||||
/** Bundle assets references via import.meta.url */
|
||||
importMetaAssets(),
|
||||
/** Minify html and css tagged template literals */
|
||||
babel({
|
||||
plugins: [
|
||||
[
|
||||
'babel-plugin-template-html-minifier',
|
||||
{
|
||||
modules: { lit: ['html', { name: 'css', encapsulation: 'style' }] },
|
||||
failOnError: false,
|
||||
strictCSS: true,
|
||||
htmlMinifier: {
|
||||
collapseWhitespace: true,
|
||||
conservativeCollapse: true,
|
||||
removeComments: true,
|
||||
caseSensitive: true,
|
||||
minifyCSS: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
/** Create and inject a service worker */
|
||||
generateSW({
|
||||
globIgnores: ['polyfills/*.js', 'nomodule-*.js'],
|
||||
navigateFallback: '/index.html',
|
||||
// where to output the generated sw
|
||||
swDest: path.join('dist', 'sw.js'),
|
||||
// directory to match patterns against to be precached
|
||||
globDirectory: path.join('dist'),
|
||||
// cache any html js and css by default
|
||||
globPatterns: ['**/*.{html,js,css,webmanifest}'],
|
||||
skipWaiting: true,
|
||||
clientsClaim: true,
|
||||
runtimeCaching: [{ urlPattern: 'polyfills/*.js', handler: 'CacheFirst' }],
|
||||
}),
|
||||
],
|
||||
};
|
|
@ -1,56 +0,0 @@
|
|||
import { execFileSync } from "child_process";
|
||||
import { ESLint } from "eslint";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import process from "process";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
function changedFiles() {
|
||||
const gitStatus = execFileSync("git", ["diff", "--name-only", "HEAD"], { encoding: "utf8" });
|
||||
const gitUntracked = execFileSync("git", ["ls-files", "--others", "--exclude-standard"], {
|
||||
encoding: "utf8",
|
||||
});
|
||||
|
||||
const changed = gitStatus
|
||||
.split("\n")
|
||||
.filter((line) => line.trim().substring(0, 4) === "web/")
|
||||
.filter((line) => /\.(m|c)?(t|j)s$/.test(line))
|
||||
.map((line) => line.substring(4))
|
||||
.filter((line) => fs.existsSync(line));
|
||||
|
||||
const untracked = gitUntracked
|
||||
.split("\n")
|
||||
.filter((line) => /\.(m|c)?(t|j)s$/.test(line))
|
||||
.filter((line) => fs.existsSync(line));
|
||||
|
||||
const sourceFiles = [...changed, ...untracked].filter((line) => /^src\//.test(line));
|
||||
const scriptFiles = [...changed, ...untracked].filter(
|
||||
(line) => /^scripts\//.test(line) || !/^src\//.test(line),
|
||||
);
|
||||
|
||||
return [...sourceFiles, ...scriptFiles];
|
||||
}
|
||||
|
||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||||
const projectRoot = path.join(__dirname, "..");
|
||||
process.chdir(projectRoot);
|
||||
|
||||
const hasFlag = (flags) => process.argv.length > 1 && flags.includes(process.argv[2]);
|
||||
|
||||
const [configFile, files] = hasFlag(["-n", "--nightmare"])
|
||||
? [path.join(__dirname, "eslint.nightmare.mjs"), changedFiles()]
|
||||
: hasFlag(["-p", "--precommit"])
|
||||
? [path.join(__dirname, "eslint.precommit.mjs"), changedFiles()]
|
||||
: [path.join(projectRoot, "eslint.config.mjs"), ["."]];
|
||||
|
||||
const eslint = new ESLint({
|
||||
overrideConfigFile: configFile,
|
||||
warnIgnored: false,
|
||||
});
|
||||
|
||||
const results = await eslint.lintFiles(files);
|
||||
const formatter = await eslint.loadFormatter("stylish");
|
||||
const resultText = formatter.format(results);
|
||||
const errors = results.reduce((acc, result) => acc + result.errorCount, 0);
|
||||
console.log(resultText);
|
||||
process.exit(errors > 1 ? 1 : 0);
|
|
@ -1,199 +0,0 @@
|
|||
import eslint from "@eslint/js";
|
||||
import tsparser from "@typescript-eslint/parser";
|
||||
import litconf from "eslint-plugin-lit";
|
||||
import wcconf from "eslint-plugin-wc";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
const MAX_DEPTH = 4;
|
||||
const MAX_NESTED_CALLBACKS = 4;
|
||||
const MAX_PARAMS = 5;
|
||||
|
||||
const rules = {
|
||||
"accessor-pairs": "error",
|
||||
"array-callback-return": "error",
|
||||
"block-scoped-var": "error",
|
||||
"consistent-return": "error",
|
||||
"consistent-this": ["error", "that"],
|
||||
"curly": ["error", "all"],
|
||||
"dot-notation": [
|
||||
"error",
|
||||
{
|
||||
allowKeywords: true,
|
||||
},
|
||||
],
|
||||
"eqeqeq": "error",
|
||||
"func-names": "error",
|
||||
"guard-for-in": "error",
|
||||
"max-depth": ["error", MAX_DEPTH],
|
||||
"max-nested-callbacks": ["error", MAX_NESTED_CALLBACKS],
|
||||
"max-params": ["error", MAX_PARAMS],
|
||||
"new-cap": "error",
|
||||
"no-alert": "error",
|
||||
"no-array-constructor": "error",
|
||||
"no-bitwise": "error",
|
||||
"no-caller": "error",
|
||||
"no-case-declarations": "error",
|
||||
"no-class-assign": "error",
|
||||
"no-cond-assign": "error",
|
||||
"no-const-assign": "error",
|
||||
"no-constant-condition": "error",
|
||||
"no-control-regex": "error",
|
||||
"no-debugger": "error",
|
||||
"no-delete-var": "error",
|
||||
"no-div-regex": "error",
|
||||
"no-dupe-args": "error",
|
||||
"no-dupe-keys": "error",
|
||||
"no-duplicate-case": "error",
|
||||
"no-else-return": "error",
|
||||
"no-empty": "error",
|
||||
"no-empty-character-class": "error",
|
||||
"no-empty-function": "error",
|
||||
"no-labels": "error",
|
||||
"no-eq-null": "error",
|
||||
"no-eval": "error",
|
||||
"no-ex-assign": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "error",
|
||||
"no-extra-boolean-cast": "error",
|
||||
"no-extra-label": "error",
|
||||
"no-fallthrough": "error",
|
||||
"no-func-assign": "error",
|
||||
"no-implied-eval": "error",
|
||||
"no-implicit-coercion": "error",
|
||||
"no-implicit-globals": "error",
|
||||
"no-inner-declarations": ["error", "functions"],
|
||||
"no-invalid-regexp": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"no-iterator": "error",
|
||||
"no-invalid-this": "error",
|
||||
"no-label-var": "error",
|
||||
"no-lone-blocks": "error",
|
||||
"no-lonely-if": "error",
|
||||
"no-loop-func": "error",
|
||||
"no-magic-numbers": ["error", { ignore: [0, 1, -1] }],
|
||||
"no-multi-str": "error",
|
||||
"no-negated-condition": "error",
|
||||
"no-nested-ternary": "error",
|
||||
"no-new": "error",
|
||||
"no-new-func": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-obj-calls": "error",
|
||||
"no-octal": "error",
|
||||
"no-octal-escape": "error",
|
||||
"no-param-reassign": "error",
|
||||
"no-proto": "error",
|
||||
"no-redeclare": "error",
|
||||
"no-regex-spaces": "error",
|
||||
"no-restricted-syntax": ["error", "WithStatement"],
|
||||
"no-script-url": "error",
|
||||
"no-self-assign": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-sequences": "error",
|
||||
"no-shadow": "error",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-sparse-arrays": "error",
|
||||
"no-this-before-super": "error",
|
||||
"no-throw-literal": "error",
|
||||
"no-trailing-spaces": "error",
|
||||
"no-undef": "error",
|
||||
"no-undef-init": "error",
|
||||
"no-unexpected-multiline": "error",
|
||||
"no-useless-constructor": "error",
|
||||
"no-unmodified-loop-condition": "error",
|
||||
"no-unneeded-ternary": "error",
|
||||
"no-unreachable": "error",
|
||||
"no-unused-expressions": "error",
|
||||
"no-unused-labels": "error",
|
||||
"no-use-before-define": "error",
|
||||
"no-useless-call": "error",
|
||||
"no-dupe-class-members": "error",
|
||||
"no-var": "error",
|
||||
"no-void": "error",
|
||||
"no-with": "error",
|
||||
"prefer-arrow-callback": "error",
|
||||
"prefer-const": "error",
|
||||
"prefer-rest-params": "error",
|
||||
"prefer-spread": "error",
|
||||
"prefer-template": "error",
|
||||
"radix": "error",
|
||||
"require-yield": "error",
|
||||
"strict": ["error", "global"],
|
||||
"use-isnan": "error",
|
||||
"valid-typeof": "error",
|
||||
"vars-on-top": "error",
|
||||
"yoda": ["error", "never"],
|
||||
|
||||
"no-unused-vars": "off",
|
||||
"no-console": ["error", { allow: ["debug", "warn", "error"] }],
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default [
|
||||
// You would not believe how much this change has frustrated users: ["if an ignores key is used
|
||||
// without any other keys in the configuration object, then the patterns act as global
|
||||
// ignores"](https://eslint.org/docs/latest/use/configure/ignore)
|
||||
{
|
||||
ignores: [
|
||||
"dist/",
|
||||
".wireit/",
|
||||
// don't ever lint node_modules
|
||||
"node_modules/",
|
||||
],
|
||||
},
|
||||
eslint.configs.recommended,
|
||||
wcconf.configs["flat/recommended"],
|
||||
litconf.configs["flat/recommended"],
|
||||
...tseslint.configs.recommended,
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tsparser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 12,
|
||||
sourceType: "module",
|
||||
},
|
||||
globals: {
|
||||
...globals.browser,
|
||||
},
|
||||
},
|
||||
files: ["src/**"],
|
||||
rules,
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tsparser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 12,
|
||||
sourceType: "module",
|
||||
},
|
||||
globals: {
|
||||
...globals.nodeBuiltin,
|
||||
},
|
||||
},
|
||||
files: ["scripts/*.mjs", "*.ts", "*.mjs"],
|
||||
rules,
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tsparser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 12,
|
||||
sourceType: "module",
|
||||
},
|
||||
globals: {
|
||||
...globals.nodeBuiltin,
|
||||
...globals.jest,
|
||||
},
|
||||
},
|
||||
files: ["src/**/*.test.ts"],
|
||||
rules,
|
||||
},
|
||||
];
|
|
@ -1,73 +0,0 @@
|
|||
import eslint from "@eslint/js";
|
||||
import tsparser from "@typescript-eslint/parser";
|
||||
import litconf from "eslint-plugin-lit";
|
||||
import wcconf from "eslint-plugin-wc";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
export default [
|
||||
// You would not believe how much this change has frustrated users: ["if an ignores key is used
|
||||
// without any other keys in the configuration object, then the patterns act as global
|
||||
// ignores"](https://eslint.org/docs/latest/use/configure/ignore)
|
||||
{
|
||||
ignores: [
|
||||
"dist/",
|
||||
".wireit/",
|
||||
// don't ever lint node_modules
|
||||
"node_modules/",
|
||||
],
|
||||
},
|
||||
eslint.configs.recommended,
|
||||
wcconf.configs["flat/recommended"],
|
||||
litconf.configs["flat/recommended"],
|
||||
...tseslint.configs.recommended,
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tsparser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 12,
|
||||
sourceType: "module",
|
||||
},
|
||||
},
|
||||
files: ["src/**"],
|
||||
rules: {
|
||||
"no-unused-vars": "off",
|
||||
"no-console": ["error", { allow: ["debug", "warn", "error"] }],
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
parser: tsparser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 12,
|
||||
sourceType: "module",
|
||||
},
|
||||
globals: {
|
||||
...globals.nodeBuiltin,
|
||||
},
|
||||
},
|
||||
files: ["scripts/*.mjs", "*.ts", "*.mjs"],
|
||||
rules: {
|
||||
"no-unused-vars": "off",
|
||||
"no-console": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_",
|
||||
caughtErrorsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
|
@ -1,29 +0,0 @@
|
|||
import { type KnipConfig } from "knip";
|
||||
|
||||
const config: KnipConfig = {
|
||||
"entry": [
|
||||
"./src/index.ts",
|
||||
],
|
||||
"project": ["src/**/*.ts", "src/**/*.js", "./scripts/*.mjs"],
|
||||
// "ignore": ["src/**/*.test.ts", "src/**/*.stories.ts"],
|
||||
// Prevent Knip from complaining about web components, which export their classes but also
|
||||
// export their registration, and we don't always use both.
|
||||
"ignoreExportsUsedInFile": true,
|
||||
"typescript": {
|
||||
config: ["tsconfig.json"],
|
||||
},
|
||||
"wireit": {
|
||||
config: ["package.json"],
|
||||
},
|
||||
"eslint": {
|
||||
entry: [
|
||||
"eslint.config.mjs",
|
||||
"scripts/eslint.precommit.mjs",
|
||||
"scripts/eslint.nightmare.mjs",
|
||||
"scripts/eslint.mjs",
|
||||
],
|
||||
config: ["package.json"],
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
|
@ -1,10 +0,0 @@
|
|||
module.exports =
|
||||
twitter:
|
||||
consumer_key: "YOUR TWITTER CONSUMER KEY"
|
||||
consumer_private_key: "YOUR TWITTER SECRET KEY"
|
||||
access_token_key: "YOUR TWITTER ONE TIME ACCESS KEY"
|
||||
access_token_secret: "YOUR TWITTER ONE TIME ACCESS SECRET"
|
||||
tracker:
|
||||
database: 'fridgemagnets'
|
||||
username: 'fridgemagnets'
|
||||
password: 'some witty password here'
|
|
@ -1,151 +0,0 @@
|
|||
express = require 'express'
|
||||
mysql = require('db-mysql')
|
||||
OAuth = require('oauth').OAuth
|
||||
util = require('util')
|
||||
config = require('./config')
|
||||
fs = require('fs')
|
||||
|
||||
wordlist = JSON.parse(fs.readFileSync('./wordlist.js', 'utf-8'))
|
||||
wordstream = (i.w for i in wordlist).join(' ')
|
||||
|
||||
body_to_haiku = (lines) ->
|
||||
ret = (for words in lines
|
||||
line = words[0].w
|
||||
for word in words[1...words.length]
|
||||
line += if word.s == 1 then word.w else ' ' + word.w
|
||||
line).join(" / ")
|
||||
console.log(ret)
|
||||
ret
|
||||
|
||||
|
||||
class AddressTracker
|
||||
|
||||
constructor: (database, username, password) ->
|
||||
@db = new mysql.Database({
|
||||
"hostname": "localhost"
|
||||
"user": username
|
||||
"password": password
|
||||
"database": database})
|
||||
@db.on('ready', () -> @connection = this)
|
||||
@db.on('error', () -> console.log(arguments))
|
||||
|
||||
connect: (cb) ->
|
||||
atrack = @
|
||||
@db.connect () ->
|
||||
atrack.connection = this
|
||||
cb.apply(this, arguments)
|
||||
|
||||
validate: (ip_address, message, cb) ->
|
||||
yesterday = new Date((new Date()).valueOf() - 1000 * 86400)
|
||||
connection = @connection
|
||||
|
||||
connection.query().
|
||||
select('*').
|
||||
from('tweets').
|
||||
where('address = ? and entered > ?', [ip_address, yesterday]).
|
||||
execute (err, rows, cols) ->
|
||||
|
||||
return cb(err, null) if (err)
|
||||
return cb("You've used up your allotted number of tweets today", null) if rows.length > 10
|
||||
|
||||
connection.query().
|
||||
select('*').
|
||||
from('tweets').
|
||||
where('tweet = ?', [body_to_haiku(message.message)]).
|
||||
execute (err, rows, cols) ->
|
||||
|
||||
return cb(err, null) if (err)
|
||||
return cb("You've already sent that poem!", null) if rows.length > 0
|
||||
|
||||
connection.query().
|
||||
insert('tweets', ['address', 'tweet', 'entered'], [ip_address, body_to_haiku(message.message), (new Date())]).
|
||||
execute (err, result) ->
|
||||
return cb(err, null) if err
|
||||
cb(null, result)
|
||||
|
||||
|
||||
class TwitterPoster
|
||||
constructor: ->
|
||||
@oauth = new OAuth(
|
||||
"https://api.twitter.com/oauth/request_token",
|
||||
"https://api.twitter.com/oauth/access_token",
|
||||
config.twitter.consumer_key,
|
||||
config.twitter.consumer_private_key,
|
||||
"1.0",
|
||||
null,
|
||||
"HMAC-SHA1"
|
||||
)
|
||||
|
||||
post: (message, callback) ->
|
||||
@oauth.post(
|
||||
"http://api.twitter.com/1/statuses/update.json",
|
||||
config.twitter.access_token_key,
|
||||
config.twitter.access_token_secret,
|
||||
{"status": body_to_haiku(message.message) },
|
||||
"application/json",
|
||||
(error, data, response2) ->
|
||||
if error
|
||||
console.log(error) if error
|
||||
callback(error, null)
|
||||
return
|
||||
callback(null, data)
|
||||
)
|
||||
|
||||
|
||||
app = module.exports = express.createServer()
|
||||
|
||||
# Configuration
|
||||
app.configure ->
|
||||
app.use express.bodyParser()
|
||||
app.use express.methodOverride()
|
||||
app.use express.logger()
|
||||
app.use app.router
|
||||
|
||||
|
||||
app.configure 'development', ->
|
||||
app.use express.errorHandler
|
||||
dumpExceptions: true
|
||||
showStack: true
|
||||
|
||||
app.configure 'production', ->
|
||||
app.use express.errorHandler()
|
||||
|
||||
all_good_words = (lines) ->
|
||||
for words in lines
|
||||
for word in words
|
||||
if not (new RegExp('\\b' + word + '\\b')).test(wordstream)
|
||||
return false
|
||||
return true
|
||||
|
||||
address_tracker = new AddressTracker(config.tracker.database, config.tracker.username, config.tracker.password)
|
||||
twitter_poster = new TwitterPoster()
|
||||
|
||||
# Our single route
|
||||
|
||||
app.post '/poems/', (req, res) ->
|
||||
if not req.body? or not req.body.message?
|
||||
res.send({error: true, code: -1, message: "We did not receive a poem."})
|
||||
return
|
||||
|
||||
if not all_good_words(req.body.message)
|
||||
res.send({error: true, code: -1, message: "ERROR -5: HACKSTOP."})
|
||||
return
|
||||
|
||||
address_tracker.validate req.headers['x-forwarded-for'], req.body, (err, result) ->
|
||||
if err != null
|
||||
console.log(err)
|
||||
res.send({error: true, code: 1, message: err})
|
||||
return
|
||||
|
||||
twitter_poster.post req.body, (err, result) ->
|
||||
if err != null
|
||||
console.log(err)
|
||||
res.send({error: true, code: 2, message: err})
|
||||
return
|
||||
res.send({error: false, message: result})
|
||||
|
||||
address_tracker.connect () ->
|
||||
app.listen 8012
|
||||
console.log "Express server listening on port %d in %s mode", app.address().port, app.settings.env
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"name": "FridgemagnetServer",
|
||||
"description": "A Twitter Forwarding Serverour CLI formatting friend.",
|
||||
"version": "0.0.1",
|
||||
"author": "Elf M. Sternberg <elf@pendorwright.com>",
|
||||
"dependencies": {
|
||||
"coffee-script": "1.2.0",
|
||||
"oauth": "0.9.6",
|
||||
"express": "2.5.8",
|
||||
"forever": "0.8.5",
|
||||
"db-mysql": "0.7.6"
|
||||
},
|
||||
"main": "./magnet_server",
|
||||
"engines": { "node": ">= 0.6.2" }
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
BEGIN;
|
||||
CREATE TABLE tweets (
|
||||
address CHAR(42) NOT NULL,
|
||||
tweet TEXT NOT NULL,
|
||||
entered DATETIME NOT NULL
|
||||
);
|
||||
COMMIT;
|
|
@ -1,4 +1,4 @@
|
|||
import type { Position } from "./types";
|
||||
import type { Position } from "./types.ts";
|
||||
|
||||
export class PointerLocationRequest extends Event {
|
||||
static readonly eventName = "fridge-pointer-location";
|
||||
|
|
|
@ -42,11 +42,18 @@ export class FridgeBoard extends LitElement {
|
|||
|
||||
fridge-tile {
|
||||
position: absolute;
|
||||
transition:
|
||||
scale 200ms ease-out,
|
||||
rotate 200ms ease-out;
|
||||
will-change: scale rotate translate;
|
||||
}
|
||||
|
||||
.ready-to-slide {
|
||||
transition: transform 1500ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
will-change: transform;
|
||||
transition:
|
||||
scale 1500ms ease-out,
|
||||
rotate 1500ms ease-out,
|
||||
translate 1500ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||
will-change: scale rotate translate;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
@ -84,7 +91,7 @@ export class FridgeBoard extends LitElement {
|
|||
const isPointInBox = (point: Point) =>
|
||||
point[0] >= box.xl && point[0] <= box.xr && point[1] >= box.yt && point[1] <= box.yb;
|
||||
|
||||
if (pointsAlreadyPositioned.find((p) => isPointInBox(p)) === undefined) {
|
||||
if (pointsAlreadyPositioned.find(p => isPointInBox(p)) === undefined) {
|
||||
tile.style.top = `${box.yt}px`;
|
||||
tile.style.left = `${box.xl}px`;
|
||||
return true;
|
||||
|
@ -106,19 +113,20 @@ export class FridgeBoard extends LitElement {
|
|||
|
||||
onPointerDown(ev: PointerEvent) {
|
||||
const node = ev.target;
|
||||
|
||||
if (!(isHTMLElement(node) && node.tagName.toLowerCase() === "fridge-tile")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The position of the board with respect to the viewport;
|
||||
// The position of the board relative to the viewport;
|
||||
const { left: fridgeLeft, top: fridgeTop } = this.getBoundingClientRect();
|
||||
|
||||
// The position of the node with respect to the viewport:
|
||||
// The position of the node relative to the viewport:
|
||||
const { left: nodeLeft, top: nodeTop } = node.getBoundingClientRect();
|
||||
|
||||
// Where the pointer was when the event started with respect to the viewport;
|
||||
const { x: pointerStartX, y: pointerStartY } = pointerLocation();
|
||||
// The position of the pointer when the event started relative to the viewport;
|
||||
const { clientX: pointerStartX, clientY: pointerStartY } = ev;
|
||||
let pointerX = pointerStartX;
|
||||
let pointerY = pointerStartY;
|
||||
|
||||
// Starting position of the *node* with respect to the board;
|
||||
const tileStart = {
|
||||
|
@ -131,33 +139,45 @@ export class FridgeBoard extends LitElement {
|
|||
|
||||
let tracking = true;
|
||||
|
||||
const pointer = (ev: PointerEvent) => {
|
||||
const { clientX, clientY } = ev;
|
||||
pointerX = clientX;
|
||||
pointerY = clientY;
|
||||
};
|
||||
|
||||
node.style.setProperty("scale", "1.3");
|
||||
node.style.setProperty("rotate", `${Math.random() * 30 - 15}deg`);
|
||||
|
||||
const stop = () => {
|
||||
console.log("Stop called?");
|
||||
controller.abort();
|
||||
tracking = false;
|
||||
const cursorPosition = pointerLocation();
|
||||
let newX = tileStart.x - (cursorPosition.x - pointerStartX);
|
||||
let newY = tileStart.y - (cursorPosition.y - pointerStartY);
|
||||
node.style.setProperty("transform", "");
|
||||
node.style.setProperty("top", `${newY}px`);
|
||||
node.style.setProperty("left", `${newX}px`);
|
||||
controller.abort();
|
||||
let delX = pointerX - pointerStartX;
|
||||
let delY = pointerY - pointerStartY;
|
||||
node.style.removeProperty("translate");
|
||||
node.style.setProperty("top", `${tileStart.y + delY}px`);
|
||||
node.style.setProperty("left", `${tileStart.x + delX}px`);
|
||||
requestAnimationFrame(() => {
|
||||
node.style.setProperty("scale", "1.0");
|
||||
node.style.setProperty("rotate", `${Math.random() * 30 - 15}deg`);
|
||||
});
|
||||
};
|
||||
|
||||
let animationFrame: number = -1;
|
||||
|
||||
const move = () => {
|
||||
const cursorPosition = pointerLocation();
|
||||
let delX = cursorPosition.x - pointerStartX;
|
||||
let delY = cursorPosition.y - pointerStartY;
|
||||
node.style.setProperty("transform", `translate3d(${+delX}px, ${+delY}px, 0)`);
|
||||
|
||||
if (tracking) {
|
||||
let delX = pointerX - pointerStartX;
|
||||
let delY = pointerY - pointerStartY;
|
||||
node.style.setProperty("translate", `${+delX}px ${+delY}px 0`);
|
||||
animationFrame = requestAnimationFrame(move);
|
||||
} else {
|
||||
cancelAnimationFrame(animationFrame);
|
||||
return;
|
||||
}
|
||||
|
||||
cancelAnimationFrame(animationFrame);
|
||||
return;
|
||||
};
|
||||
|
||||
window.addEventListener("pointermove", pointer, { signal });
|
||||
window.addEventListener("pointerup", stop, { signal });
|
||||
window.addEventListener("pointercancel", stop, { signal });
|
||||
animationFrame = requestAnimationFrame(move);
|
||||
|
@ -165,7 +185,7 @@ export class FridgeBoard extends LitElement {
|
|||
|
||||
render() {
|
||||
return html`<div id="fridge" @pointerdown=${this.onPointerDown}>
|
||||
${words.map((word) => html`<fridge-tile style="opacity: 0" word=${word.w}></fridge-tile>`)}
|
||||
${words.map(word => html`<fridge-tile style="opacity: 0" word=${word.w}></fridge-tile>`)}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
|
@ -178,30 +198,39 @@ export class FridgeBoard extends LitElement {
|
|||
return Math.random() < 0.5 ? newDelta + size : newDelta * -1;
|
||||
};
|
||||
|
||||
requestAnimationFrame(() =>
|
||||
this.tiles.forEach((tile) => {
|
||||
const lastTile = this.tiles[this.tiles.length - 1];
|
||||
|
||||
const slideEnd = (ev: TransitionEvent) => {
|
||||
if (ev.propertyName === "translate") {
|
||||
this.tiles.forEach(tile => {
|
||||
tile.classList.remove("ready-to-slide");
|
||||
});
|
||||
lastTile.removeEventListener("transitionend", slideEnd);
|
||||
}
|
||||
};
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
this.tiles.forEach(tile => {
|
||||
const outerX = fd(boardWidth);
|
||||
const outerY = fd(boardHeight);
|
||||
const [tileX, tileY] = tile.relativePosition;
|
||||
tile.style.transform = `translate(${outerX - tileX}px, ${outerY - tileY}px) rotate(${Math.random() * 30 - 15}deg) scale(1.5)`;
|
||||
tile.style.opacity = "100%";
|
||||
})
|
||||
);
|
||||
tile.style.setProperty("translate", `${outerX - tileX}px ${outerY - tileY}px 0`);
|
||||
tile.style.setProperty("scale", "1.5");
|
||||
tile.style.setProperty("rotate", `${Math.random() * 720}deg`);
|
||||
tile.style.setProperty("opacity", "100%");
|
||||
});
|
||||
|
||||
requestAnimationFrame(() =>
|
||||
this.tiles.forEach((tile) => {
|
||||
tile.classList.add("ready-to-slide");
|
||||
tile.style.transform = `translate(0, 0) rotate(${Math.random() * 30}deg) scale(1.0)`;
|
||||
})
|
||||
);
|
||||
lastTile.addEventListener("transitionend", slideEnd);
|
||||
|
||||
setTimeout(
|
||||
() =>
|
||||
this.tiles.forEach((tile) => {
|
||||
tile.classList.remove("ready-to-slide");
|
||||
}),
|
||||
1525
|
||||
);
|
||||
requestAnimationFrame(() =>
|
||||
this.tiles.forEach(tile => {
|
||||
tile.classList.add("ready-to-slide");
|
||||
tile.style.setProperty("translate", "0 0 0");
|
||||
tile.style.setProperty("rotate", `${Math.random() * 30 - 15}deg`);
|
||||
tile.style.setProperty("scale", "1.0");
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,29 +3,18 @@ import { customElement } from "lit/decorators/custom-element.js";
|
|||
import { property } from "lit/decorators/property.js";
|
||||
import { styleMap } from "lit/directives/style-map.js";
|
||||
import { ref, createRef, Ref } from "lit/directives/ref.js";
|
||||
import { LitDraggable } from "./lit-draggable.js";
|
||||
import { LitDragEvent } from "./types.js";
|
||||
import { LitDragStart, LitDragEnd } from "./lit-events.js";
|
||||
|
||||
@customElement("fridge-tile")
|
||||
export class FridgeTile extends LitElement {
|
||||
@property({ type: String })
|
||||
word = "";
|
||||
|
||||
dragHandle: LitDraggable;
|
||||
|
||||
transform = {
|
||||
rotate: Math.random() * 30 - 15,
|
||||
scale: 1.0,
|
||||
};
|
||||
|
||||
handle: Ref<HTMLDivElement> = createRef();
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
:host([data-dragging="idle"]) {
|
||||
|
@ -100,78 +89,3 @@ export class FridgeTile extends LitElement {
|
|||
return html`<div part="word ${ref(this.handle)} " style="${styleMap(styles)}" class="word">${this.word}</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// base_style:
|
||||
// 'font-size': "15px"
|
||||
//
|
||||
// drag_style:
|
||||
// 'font-size': "19px"
|
||||
//
|
||||
// visible: false
|
||||
//
|
||||
// # Initial tilt.
|
||||
// rotation: (Math.random() * 30) - 15
|
||||
//
|
||||
// constructor: (@word, @board, @master) ->
|
||||
// super()
|
||||
// @el = $('<div class="word">' + @word.w + '</div>')
|
||||
// @el.css @base_style
|
||||
// @board.append(@el)
|
||||
// @rotation = (Math.random() * 30) - 15
|
||||
//
|
||||
// @el.draggable
|
||||
// helper: "original"
|
||||
// refreshPositions: false
|
||||
// revertDuration: 1
|
||||
//
|
||||
// start: (event) =>
|
||||
// mod = (Math.random() * 16) - 8
|
||||
// @rotation = if Math.abs(@rotation + mod) > 15 then @rotation - mod else @rotation + mod
|
||||
// style = clone(@drag_style)
|
||||
// style.rotate = @rotation
|
||||
// @el.animate(style, 200, () => @new_width = @el.width())
|
||||
// true
|
||||
//
|
||||
// stop: (event) =>
|
||||
// # Drop the thing dead center, at least on the x-axis,
|
||||
// # and animate its return to the new font size.
|
||||
// mod = (Math.random() * 16) - 8
|
||||
// @rotation = if Math.abs(@rotation + mod) > 15 then @rotation - mod else @rotation + mod
|
||||
// style = clone(@base_style)
|
||||
// style.rotate = @rotation
|
||||
// style['left'] = parseInt(@el.position().left + (0.5 * (@new_width - @width())))
|
||||
// @el.animate style, 200, 'easeOutQuad', () =>
|
||||
// @reset_dims()
|
||||
// explode_hearts(@board, @)
|
||||
// @master.poemed(@)
|
||||
// true
|
||||
//
|
||||
// fadeOut: -> $.Deferred((d) => @el.fadeOut('fast', (() => @unset_dims(); @visible = false; d.resolve()))).promise()
|
||||
//
|
||||
// # Shape for deteriming poemed collision
|
||||
// fuzzyshape: -> shape @left() - WIDTH_FUZZ, @top() - HEIGHT_FUZZ, @width() + (2 * WIDTH_FUZZ), @height() + (2 * HEIGHT_FUZZ)
|
||||
//
|
||||
// get_new_pos: ->
|
||||
// bh = => parseInt(Math.random() * (@board.height() - @height()) * 0.985)
|
||||
// bw = => parseInt(Math.random() * (@board.width() - @width()) * 0.98)
|
||||
// [top, left] = [bh(), bw()]
|
||||
// [top, left] = [bh(), bw()] until @master.unoccupied(left, top, @width(), @height())
|
||||
// [top, left]
|
||||
//
|
||||
// flyIn: ->
|
||||
// fd = (mod) ->
|
||||
// m = parseInt(40 * Math.random())
|
||||
// if (Math.random() < 0.5) then mod + m else -1 * m
|
||||
// @el.css
|
||||
// left: fd(@board.width())
|
||||
// top: fd(@board.height())
|
||||
// dfd = $.Deferred()
|
||||
// x = Math.random()
|
||||
// [top, left] = @get_new_pos()
|
||||
// @el.fadeIn().animate {top: top, left: left, rotate: @rotation}, 1500, 'easeOutQuint', () =>
|
||||
// @visible = true
|
||||
// dfd.resolve()
|
||||
// dfd.promise()
|
||||
//
|
||||
//
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { html, css, LitElement } from "lit";
|
||||
|
||||
export class FixedFooter extends LitElement {
|
||||
static get styles() {
|
||||
return css``;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { LitDraggable, LitDragEvent } from "./types";
|
||||
import type { LitDraggable, LitDragEvent } from "./types.ts";
|
||||
|
||||
export class LitDragStart extends Event implements LitDragEvent {
|
||||
static readonly eventName = "lit-drag-start";
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import { html, TemplateResult } from 'lit';
|
||||
import '../src/fridge-magnets.js';
|
||||
|
||||
export default {
|
||||
title: 'FridgeMagnets',
|
||||
component: 'fridge-magnets',
|
||||
argTypes: {
|
||||
backgroundColor: { control: 'color' },
|
||||
},
|
||||
};
|
||||
|
||||
interface Story<T> {
|
||||
(args: T): TemplateResult;
|
||||
args?: Partial<T>;
|
||||
argTypes?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
interface ArgTypes {
|
||||
header?: string;
|
||||
backgroundColor?: string;
|
||||
}
|
||||
|
||||
const Template: Story<ArgTypes> = ({ header, backgroundColor = 'white' }: ArgTypes) => html`
|
||||
<fridge-magnets style="--fridge-magnets-background-color: ${backgroundColor}" .header=${header}></fridge-magnets>
|
||||
`;
|
||||
|
||||
export const App = Template.bind({});
|
||||
App.args = {
|
||||
header: 'My app',
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
import { html } from 'lit';
|
||||
import { fixture, expect } from '@open-wc/testing';
|
||||
|
||||
import type { FridgeMagnets } from '../src/fridge-magnets.js';
|
||||
import '../src/fridge-magnets.js';
|
||||
|
||||
describe('FridgeMagnets', () => {
|
||||
let element: FridgeMagnets;
|
||||
beforeEach(async () => {
|
||||
element = await fixture(html`<fridge-magnets></fridge-magnets>`);
|
||||
});
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
|
@ -1,61 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"baseUrl": ".",
|
||||
"esModuleInterop": true,
|
||||
"paths": {
|
||||
"@goauthentik/docs/*": ["../website/docs/*"]
|
||||
},
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"experimentalDecorators": true,
|
||||
"sourceMap": true,
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"lib": [
|
||||
"ES5",
|
||||
"ES2015",
|
||||
"ES2016",
|
||||
"ES2017",
|
||||
"ES2018",
|
||||
"ES2019",
|
||||
"ES2020",
|
||||
"ESNext",
|
||||
"DOM",
|
||||
"DOM.Iterable",
|
||||
"WebWorker"
|
||||
],
|
||||
"noUnusedLocals": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
"allowUnreachableCode": false,
|
||||
"allowUnusedLabels": false,
|
||||
"useDefineForClassFields": false,
|
||||
"alwaysStrict": true,
|
||||
"noImplicitAny": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "ts-lit-plugin",
|
||||
"strict": true,
|
||||
"rules": {
|
||||
"no-unknown-tag-name": "off",
|
||||
"no-missing-import": "off",
|
||||
"no-incompatible-type-binding": "off",
|
||||
"no-unknown-property": "off",
|
||||
"no-unknown-attribute": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "@genesiscommunitysuccess/custom-elements-lsp",
|
||||
"designSystemPrefix": "ak-",
|
||||
"parser": {
|
||||
"timeout": 2000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,17 +1,21 @@
|
|||
{
|
||||
"extends": "./tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@goauthentik/admin/*": ["./src/admin/*"],
|
||||
"@goauthentik/common/*": ["./src/common/*"],
|
||||
"@goauthentik/components/*": ["./src/components/*"],
|
||||
"@goauthentik/docs/*": ["../website/docs/*"],
|
||||
"@goauthentik/elements/*": ["./src/elements/*"],
|
||||
"@goauthentik/flow/*": ["./src/flow/*"],
|
||||
"@goauthentik/locales/*": ["./src/locales/*"],
|
||||
"@goauthentik/polyfill/*": ["./src/polyfill/*"],
|
||||
"@goauthentik/standalone/*": ["./src/standalone/*"],
|
||||
"@goauthentik/user/*": ["./src/user/*"]
|
||||
}
|
||||
}
|
||||
"compilerOptions": {
|
||||
"target": "es2021",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"noEmitOnError": true,
|
||||
"lib": ["es2021", "dom", "DOM.Iterable"],
|
||||
"strict": true,
|
||||
"esModuleInterop": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true,
|
||||
"importHelpers": true,
|
||||
"outDir": "out-tsc",
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
"rootDir": "./",
|
||||
"incremental": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// import { hmrPlugin, presets } from '@open-wc/dev-server-hmr';
|
||||
|
||||
/** Use Hot Module replacement by adding --hmr to the start command */
|
||||
const hmr = process.argv.includes('--hmr');
|
||||
|
||||
export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
|
||||
open: '/',
|
||||
watch: !hmr,
|
||||
/** Resolve bare module imports */
|
||||
nodeResolve: {
|
||||
exportConditions: ['browser', 'development'],
|
||||
},
|
||||
|
||||
/** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
|
||||
// esbuildTarget: 'auto'
|
||||
|
||||
/** Set appIndex to enable SPA routing */
|
||||
appIndex: './index.html',
|
||||
|
||||
plugins: [
|
||||
/** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */
|
||||
// hmr && hmrPlugin({ exclude: ['**/*/node_modules/**/*'], presets: [presets.litElement] }),
|
||||
],
|
||||
|
||||
// See documentation for all available options
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
// import { playwrightLauncher } from '@web/test-runner-playwright';
|
||||
|
||||
const filteredLogs = ['Running in dev mode', 'Lit is in dev mode'];
|
||||
|
||||
export default /** @type {import("@web/test-runner").TestRunnerConfig} */ ({
|
||||
/** Test files to run */
|
||||
files: 'out-tsc/test/**/*.test.js',
|
||||
|
||||
/** Resolve bare module imports */
|
||||
nodeResolve: {
|
||||
exportConditions: ['browser', 'development'],
|
||||
},
|
||||
|
||||
/** Filter out lit dev mode logs */
|
||||
filterBrowserLogs(log) {
|
||||
for (const arg of log.args) {
|
||||
if (typeof arg === 'string' && filteredLogs.some(l => arg.includes(l))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
|
||||
// esbuildTarget: 'auto',
|
||||
|
||||
/** Amount of browsers to run concurrently */
|
||||
// concurrentBrowsers: 2,
|
||||
|
||||
/** Amount of test files per browser to test concurrently */
|
||||
// concurrency: 1,
|
||||
|
||||
/** Browsers to run tests on */
|
||||
// browsers: [
|
||||
// playwrightLauncher({ product: 'chromium' }),
|
||||
// playwrightLauncher({ product: 'firefox' }),
|
||||
// playwrightLauncher({ product: 'webkit' }),
|
||||
// ],
|
||||
|
||||
// See documentation for all available options
|
||||
});
|
Loading…
Reference in New Issue