Compare commits

...

6 Commits

Author SHA1 Message Date
754931b2f6 ScansOverview: migrate to datatable
All checks were successful
continuous-integration/drone/push Build is passing
close #168
2023-03-19 12:28:27 +01:00
2dc8ffba32 Merge branch 'dev' of https://git.odit.services/lfk/frontend into dev
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-15 15:05:29 +01:00
d0fe6a2e85 new license file version [CI SKIP] 2023-03-15 14:05:18 +00:00
85705b6e68 🚀RELEASE v0.17.3 2023-03-15 15:05:14 +01:00
3ea7a015a9 dependency fixes
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-15 15:04:55 +01:00
44329413ed set pnpm to @7 2023-03-15 15:02:54 +01:00
27 changed files with 1465 additions and 276 deletions

View File

@@ -29,7 +29,7 @@ steps:
depends_on: ["clone"]
image: registry.odit.services/hub/library/node:19.7.0-alpine3.16
commands:
- npm config set registry http://npm-cache.drone.svc.cluster.local:8080 && npm i -g pnpm
- npm config set registry http://npm-cache.drone.svc.cluster.local:8080 && npm i -g pnpm@7
- pnpm i
- pnpm licenses:export
- name: push new licenses file to repo

View File

@@ -0,0 +1 @@
{"version":3,"file":"es.js","sources":["../index.js"],"sourcesContent":["const defaultOptions = [\r\n {\r\n id: 0,\r\n value: \"Too weak\",\r\n minDiversity: 0,\r\n minLength: 0\r\n },\r\n {\r\n id: 1,\r\n value: \"Weak\",\r\n minDiversity: 2,\r\n minLength: 6\r\n },\r\n {\r\n id: 2,\r\n value: \"Medium\",\r\n minDiversity: 4,\r\n minLength: 8\r\n },\r\n {\r\n id: 3,\r\n value: \"Strong\",\r\n minDiversity: 4,\r\n minLength: 10\r\n }\r\n]\r\n\r\nconst passwordStrength = (password, options = defaultOptions, allowedSymbols=\"!\\\"#\\$%&'\\(\\)\\*\\+,-\\./:;<=>\\?@\\[\\\\\\\\\\\\]\\^_`\\{|\\}~\") => {\r\n \r\n let passwordCopy = password || ''\r\n\r\n options[0].minDiversity = 0,\r\n options[0].minLength = 0\r\n\r\n const rules = [\r\n {\r\n regex: \"[a-z]\",\r\n message: 'lowercase'\r\n },\r\n {\r\n regex: '[A-Z]',\r\n message: 'uppercase'\r\n },\r\n {\r\n regex: '[0-9]',\r\n message: 'number'\r\n },\r\n ]\r\n\r\n if (allowedSymbols) {\r\n rules.push({\r\n regex: `[${allowedSymbols}]`,\r\n message: 'symbol'\r\n })\r\n }\r\n\r\n let strength = {}\r\n\r\n strength.contains = rules\r\n .filter(rule => new RegExp(`${rule.regex}`).test(passwordCopy))\r\n .map(rule => rule.message)\r\n\r\n strength.length = passwordCopy.length;\r\n\r\n let fulfilledOptions = options\r\n .filter(option => strength.contains.length >= option.minDiversity)\r\n .filter(option => strength.length >= option.minLength)\r\n .sort((o1, o2) => o2.id - o1.id)\r\n .map(option => ({id: option.id, value: option.value}))\r\n\r\n Object.assign(strength, fulfilledOptions[0])\r\n\r\n return strength;\r\n};\r\n\r\nmodule.exports = { passwordStrength, defaultOptions }"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG;AACvB,EAAE;AACF,IAAI,EAAE,EAAE,CAAC;AACT,IAAI,KAAK,EAAE,UAAU;AACrB,IAAI,YAAY,EAAE,CAAC;AACnB,IAAI,SAAS,EAAE,CAAC;AAChB,GAAG;AACH,EAAE;AACF,IAAI,EAAE,EAAE,CAAC;AACT,IAAI,KAAK,EAAE,MAAM;AACjB,IAAI,YAAY,EAAE,CAAC;AACnB,IAAI,SAAS,EAAE,CAAC;AAChB,GAAG;AACH,EAAE;AACF,IAAI,EAAE,EAAE,CAAC;AACT,IAAI,KAAK,EAAE,QAAQ;AACnB,IAAI,YAAY,EAAE,CAAC;AACnB,IAAI,SAAS,EAAE,CAAC;AAChB,GAAG;AACH,EAAE;AACF,IAAI,EAAE,EAAE,CAAC;AACT,IAAI,KAAK,EAAE,QAAQ;AACnB,IAAI,YAAY,EAAE,CAAC;AACnB,IAAI,SAAS,EAAE,EAAE;AACjB,GAAG;AACH,EAAC;AACD;AACA,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,OAAO,GAAG,cAAc,EAAE,cAAc,CAAC,mDAAmD,KAAK;AACrI;AACA,EAAE,IAAI,YAAY,GAAG,QAAQ,IAAI,GAAE;AACnC;AACA,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC;AAC7B,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,EAAC;AAC1B;AACA,EAAE,MAAM,KAAK,GAAG;AAChB,IAAI;AACJ,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,OAAO,EAAE,WAAW;AAC1B,KAAK;AACL,IAAI;AACJ,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,OAAO,EAAE,WAAW;AAC1B,KAAK;AACL,IAAI;AACJ,MAAM,KAAK,EAAE,OAAO;AACpB,MAAM,OAAO,EAAE,QAAQ;AACvB,KAAK;AACL,IAAG;AACH;AACA,EAAE,IAAI,cAAc,EAAE;AACtB,IAAI,KAAK,CAAC,IAAI,CAAC;AACf,MAAM,KAAK,EAAE,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;AAClC,MAAM,OAAO,EAAE,QAAQ;AACvB,KAAK,EAAC;AACN,GAAG;AACH;AACA,EAAE,IAAI,QAAQ,GAAG,GAAE;AACnB;AACA,EAAE,QAAQ,CAAC,QAAQ,GAAG,KAAK;AAC3B,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AACnE,KAAK,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAC;AAC9B;AACA,EAAE,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;AACxC;AACA,EAAE,IAAI,gBAAgB,GAAG,OAAO;AAChC,KAAK,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC;AACtE,KAAK,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC;AAC1D,KAAK,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AACpC,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAC;AAC1D;AACA,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAC;AAC9C;AACA,EAAE,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AACF;AACA,MAAM,CAAC,OAAO,GAAG,EAAE,gBAAgB,EAAE,cAAc"}

View File

@@ -0,0 +1,49 @@
# This workflow checks out code, performs a Codacy security scan
# and integrates the results with the
# GitHub Advanced Security code scanning feature. For more information on
# the Codacy security scan action usage and parameters, see
# https://github.com/codacy/codacy-analysis-cli-action.
# For more information on Codacy Analysis CLI in general, see
# https://github.com/codacy/codacy-analysis-cli.
name: Codacy Security Scan
on:
push:
branches: [ master, releases/* ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '21 11 * * 2'
jobs:
codacy-security-scan:
name: Codacy Security Scan
runs-on: ubuntu-latest
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v2
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
uses: codacy/codacy-analysis-cli-action@1.1.0
with:
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
# You can also omit the token and run the tools that support default configurations
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
verbose: true
output: results.sarif
format: sarif
# Adjust severity of non-security issues
gh-code-scanning-compat: true
# Force 0 exit code to allow SARIF file generation
# This will handover control about PR rejection to the GitHub side
max-allowed-issues: 2147483647
# Upload the SARIF file generated in the previous step
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: results.sarif

View File

@@ -0,0 +1,20 @@
import pkg from './package.json';
export default [
{
input: 'index.js',
output: [
{
file: pkg.browser,
format: 'umd',
name: 'chyme',
sourcemap: true
},
{
file: pkg.module,
format: 'es',
sourcemap: true
}
]
}
];

View File

@@ -0,0 +1,68 @@
import { expectType } from "tsd";
import { DiversityType, passwordStrength } from "./index";
// Test result types
expectType<string>(passwordStrength("asdfasdf").value);
expectType<number>(passwordStrength("asdfasdf").id);
expectType<number>(passwordStrength("asdfasdf").length);
expectType<DiversityType[]>(passwordStrength("asdfasdf").contains);
// Test options with custom value (string)
expectType<string>(
passwordStrength("asdfasdf", [
{
id: 0,
value: "Too weak",
minDiversity: 0,
minLength: 0,
},
{
id: 1,
value: "Weak",
minDiversity: 2,
minLength: 6,
},
{
id: 2,
value: "Medium",
minDiversity: 4,
minLength: 8,
},
{
id: 3,
value: "Strong",
minDiversity: 4,
minLength: 10,
},
]).value
);
// Test options with custom value (object)
expectType<{ message: string, color: string }>(
passwordStrength("asdfasdf", [
{
id: 0,
value: {message: "Too weak", color: "red"},
minDiversity: 0,
minLength: 0,
},
{
id: 1,
value: {message: "Weak", color: "orange"},
minDiversity: 2,
minLength: 6,
},
{
id: 2,
value: {message: "Medium", color: "yellow"},
minDiversity: 4,
minLength: 8,
},
{
id: 3,
value: {message: "Strong", color: "green"},
minDiversity: 4,
minLength: 10,
},
]).value
);

View File

@@ -0,0 +1,48 @@
{
"name": "check-password-strength",
"version": "2.0.7",
"description": "A NPM Password strength checker based from Javascript RegExp. Check passphrase if it's \"Too weak\", \"Weak\", \"Medium\" or \"Strong\"",
"main": "index.js",
"browser": "dist/umd.js",
"module": "dist/es.js",
"types": "index.d.ts",
"scripts": {
"build": "rollup -c",
"test": "jest",
"test:types": "tsd"
},
"repository": {
"type": "git",
"url": "git+https://github.com/deanilvincent/check-password-strength.git"
},
"keywords": [
"npm",
"password",
"strength",
"checker",
"check password strength",
"password strength checker",
"strength checker",
"password checker",
"password checker strength",
"strength password checker",
"check-password-strength",
"password-strength-checker",
"strength-checker",
"password-checker",
"password-checker-strength",
"strength-password-checker",
"pass-strength"
],
"author": "deanilvincent",
"license": "MIT",
"bugs": {
"url": "https://github.com/deanilvincent/check-password-strength/issues"
},
"homepage": "https://github.com/deanilvincent/check-password-strength#readme",
"devDependencies": {
"jest": "^26.4.2",
"rollup": "^2.77.0",
"tsd": "^0.14.0"
}
}

View File

@@ -0,0 +1,22 @@
# Node.js
# Build a general Node.js project with npm.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- master
- releases/*
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install
npm test
displayName: 'npm install and test'

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenAPI = void 0;
exports.OpenAPI = {
BASE: '',
VERSION: '0.14.0',
WITH_CREDENTIALS: false,
TOKEN: undefined,
USERNAME: undefined,
PASSWORD: undefined,
HEADERS: undefined,
};

View File

@@ -0,0 +1 @@
{"name":"check-password-strength","version":"2.0.7","files":{"LICENSE.md":{"checkedAt":1678889113301,"integrity":"sha512-VqUVGe5gNe6lHbf6vQlrglCD3yHXeW/WGgJBcdrZ4YtPEZ3Sq/w1k6/rMPyQ37/Wq4/hfA8ljsFLRi6INnGN/g==","mode":420,"size":1097},".travis.yml":{"checkedAt":1678889113301,"integrity":"sha512-A/mMgoUpZ2zMgWjlq52EVnyxATfwM3PEbIdM3dujKBHRCalNEKu0rI0YV+F/2BX+XtS1fOsbGAQUmdY4NoTA+A==","mode":420,"size":41},"dist/es.js":{"checkedAt":1678889113300,"integrity":"sha512-6DE0rqS2y++vzS32+uvBzfqsuRuVIaiXqCUDWwWHFB+EigZIgFLKoBkXhBpeD4PfasskBO8ivUFlDXTkmsICvA==","mode":420,"size":1589},"index.js":{"checkedAt":1678889113301,"integrity":"sha512-l0UWsxSks3GIfoKpoKsVfdFBuE1Jv/QI86d23YRkWeqpN6X7LelkvCMOs3gdYJWlWuWTWTWzwRSYfvkuaWJQQQ==","mode":420,"size":1547},"index.test.js":{"checkedAt":1678889113301,"integrity":"sha512-+DNktajWOi93jla9dYdXRYz+Xji2o74RPFhhyml9UvfO8OnuJT9imKR+2qZityErntgBLP1BlEdMsIgfonqi1w==","mode":420,"size":13270},"rollup.config.js":{"checkedAt":1678889113301,"integrity":"sha512-MLFTq2547grcMy1L1IrAcN9iegfh8Y2S6NdeEjXUnfMp/Xs6yi4pBSK5fobmOarHTuvkMY96BdjDXDeaMwjdzw==","mode":420,"size":280},"dist/es.js.map":{"checkedAt":1678889113301,"integrity":"sha512-Cu1Ezu7irLBsUxaA05V0mixehmNYNgmfb8BGntBpyZi1ilG42TcTRYHC14h1P4U0+uxUXCZhokB2Sr2hMj3ltw==","mode":420,"size":3867},"package.json":{"checkedAt":1678889113301,"integrity":"sha512-NpAJqDlTDXOT8z419pt2zV9FGj/BTk8jU+KNaCkN+CrYvep9BqKeGMaRD0m/A6QO4sOjJg6uUtmt6zlu5EPqSg==","mode":420,"size":1353},"dist/umd.js":{"checkedAt":1678889113301,"integrity":"sha512-htBHZPnKsY10UAOzckkIo6ENf5SvYdI1hmby8ofKGYOx1biExxV5H2CNGIw66/mjWORZdRkxZTemPklU9JTlDQ==","mode":420,"size":1859},"dist/umd.js.map":{"checkedAt":1678889113303,"integrity":"sha512-cWU3RJM2WWqsUqk57fHfiAXmVE7XJktVTqGmC5yNImURVdl0yJoXzXihtI13d0XSPhUsC9lp9i9S745pO0TbSw==","mode":420,"size":3879},"README.md":{"checkedAt":1678889113303,"integrity":"sha512-ikko+p8xFvjT1I4E/dV9/hnib603h5+eetyKyoQnIevadSFXWIGedzr0m0HckqRazzqbjHEdyxP+JZy3t+JLeA==","mode":420,"size":7928},"index.d.ts":{"checkedAt":1678889113303,"integrity":"sha512-1GHeFi+GOpCUykLA7h4+hvmKgQGPlQOUSjOodANJ4gH+/uw3YPCGixKGcxKzLxTtonUlB5jV5AwNDIC5L36G4A==","mode":420,"size":644},"index.test-d.ts":{"checkedAt":1678889113303,"integrity":"sha512-MxqEDRwckvBDX6gP6luNlRrQk4wZdHYrm/mGyyBseF1zP1FrFezCb3DLMou9CNKZvQXY4NwMhw4z48nvtXneVA==","mode":420,"size":1513},"azure-pipelines.yml":{"checkedAt":1678889113304,"integrity":"sha512-RU6GklNtAAoveFPKcrvQCKkJNvmjaTfomdXw99mlHCJ2nIuSc1rm7U36KnO7l7nCTKaOqayhWMVIyLbul0JZvQ==","mode":420,"size":458},".github/workflows/codacy-analysis.yml":{"checkedAt":1678889113304,"integrity":"sha512-JbnO1GiKsXrRilYqOK0Ox5vWtugpn7RBq/bI3Nj3t4wH1jd1ZH8UmaZhOUQgU7rXD/4Ei+5Nz4cYhQ9bFe8t6Q==","mode":420,"size":1965}}}

View File

@@ -0,0 +1 @@
{"version":3,"file":"umd.js","sources":["../index.js"],"sourcesContent":["const defaultOptions = [\r\n {\r\n id: 0,\r\n value: \"Too weak\",\r\n minDiversity: 0,\r\n minLength: 0\r\n },\r\n {\r\n id: 1,\r\n value: \"Weak\",\r\n minDiversity: 2,\r\n minLength: 6\r\n },\r\n {\r\n id: 2,\r\n value: \"Medium\",\r\n minDiversity: 4,\r\n minLength: 8\r\n },\r\n {\r\n id: 3,\r\n value: \"Strong\",\r\n minDiversity: 4,\r\n minLength: 10\r\n }\r\n]\r\n\r\nconst passwordStrength = (password, options = defaultOptions, allowedSymbols=\"!\\\"#\\$%&'\\(\\)\\*\\+,-\\./:;<=>\\?@\\[\\\\\\\\\\\\]\\^_`\\{|\\}~\") => {\r\n \r\n let passwordCopy = password || ''\r\n\r\n options[0].minDiversity = 0,\r\n options[0].minLength = 0\r\n\r\n const rules = [\r\n {\r\n regex: \"[a-z]\",\r\n message: 'lowercase'\r\n },\r\n {\r\n regex: '[A-Z]',\r\n message: 'uppercase'\r\n },\r\n {\r\n regex: '[0-9]',\r\n message: 'number'\r\n },\r\n ]\r\n\r\n if (allowedSymbols) {\r\n rules.push({\r\n regex: `[${allowedSymbols}]`,\r\n message: 'symbol'\r\n })\r\n }\r\n\r\n let strength = {}\r\n\r\n strength.contains = rules\r\n .filter(rule => new RegExp(`${rule.regex}`).test(passwordCopy))\r\n .map(rule => rule.message)\r\n\r\n strength.length = passwordCopy.length;\r\n\r\n let fulfilledOptions = options\r\n .filter(option => strength.contains.length >= option.minDiversity)\r\n .filter(option => strength.length >= option.minLength)\r\n .sort((o1, o2) => o2.id - o1.id)\r\n .map(option => ({id: option.id, value: option.value}))\r\n\r\n Object.assign(strength, fulfilledOptions[0])\r\n\r\n return strength;\r\n};\r\n\r\nmodule.exports = { passwordStrength, defaultOptions }"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,84 @@
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';
const defaultOptions = [
{
id: 0,
value: "Too weak",
minDiversity: 0,
minLength: 0
},
{
id: 1,
value: "Weak",
minDiversity: 2,
minLength: 6
},
{
id: 2,
value: "Medium",
minDiversity: 4,
minLength: 8
},
{
id: 3,
value: "Strong",
minDiversity: 4,
minLength: 10
}
];
const passwordStrength = (password, options = defaultOptions, allowedSymbols="!\"#\$%&'\(\)\*\+,-\./:;<=>\?@\[\\\\\\]\^_`\{|\}~") => {
let passwordCopy = password || '';
options[0].minDiversity = 0,
options[0].minLength = 0;
const rules = [
{
regex: "[a-z]",
message: 'lowercase'
},
{
regex: '[A-Z]',
message: 'uppercase'
},
{
regex: '[0-9]',
message: 'number'
},
];
if (allowedSymbols) {
rules.push({
regex: `[${allowedSymbols}]`,
message: 'symbol'
});
}
let strength = {};
strength.contains = rules
.filter(rule => new RegExp(`${rule.regex}`).test(passwordCopy))
.map(rule => rule.message);
strength.length = passwordCopy.length;
let fulfilledOptions = options
.filter(option => strength.contains.length >= option.minDiversity)
.filter(option => strength.length >= option.minLength)
.sort((o1, o2) => o2.id - o1.id)
.map(option => ({id: option.id, value: option.value}));
Object.assign(strength, fulfilledOptions[0]);
return strength;
};
module.exports = { passwordStrength, defaultOptions };
}));
//# sourceMappingURL=umd.js.map

View File

@@ -0,0 +1,192 @@
# Overview
A simple way to check that password strength of a certain passphrase. A password strength checker based from [Javascript RegEx](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions).
[![Build Status](https://travis-ci.org/deanilvincent/check-password-strength.svg?branch=master)](https://travis-ci.org/deanilvincent/check-password-strength)
[![npm](https://img.shields.io/npm/dm/check-password-strength.svg)](https://img.shields.io/npm/dm/check-password-strength.svg)
[![Downloads](https://img.shields.io/npm/dt/check-password-strength.svg)](https://img.shields.io/npm/dt/check-password-strength.svg)
[DEMO 1](https://svelte.dev/repl/b5bf5871c99742e584da244b4bfeac92?version=3.44.3) by [@Ennoriel](https://github.com/Ennoriel)
[DEMO 2](https://check-password-strength.netlify.app/)
## Installation
### Install via Package Manager
`npm i check-password-strength --save`
### Install via Browser Script Tag using [UNPKG](https://unpkg.com/)
`<script src="https://unpkg.com/check-password-strength/dist/umd.js"></script>`
## Setup & Basic Usage
```javascript
const { passwordStrength } = require('check-password-strength')
// OR
import { passwordStrength } from 'check-password-strength'
console.log(passwordStrength('asdfasdf').value)
// Too weak (It will return Too weak if the value doesn't match the RegEx conditions)
console.log(passwordStrength('asdf1234').value)
// Weak
console.log(passwordStrength('Asd1234!').value)
// Medium
console.log(passwordStrength('A@2asdF2020!!*').value)
// Strong
```
## Migration from 1.x.x to 2.0.0
```javascript
// 1.x.x
const whateEverYourFunctionNameWasBefore = require("./index");
// 'contains' attribute of the response object format was
response.contains = [{'message': 'lowercase'}, ...]
```
```javascript
// 2.0.0
const { passwordStrength : whateEverYourFunctionNameWasBefore } = require("./index");
// 'contains' attribute of the response object format is now
response.contains = ['lowercase', ...]
```
## Additional Info
### Object Result
| Property | Desc. |
| -------- | --------------------------------------------------------------- |
| id | **0** = Too weak, **1** = Weak & **2** = Medium, **3** = Strong |
| value | Too weak, Weak, Medium & Strong |
| contains | lowercase, uppercase, symbol and/or number |
| length | length of the password |
### Password Length Default Options
| Name | Mininum Diversity | Mininum Length |
| -------- | ----------------- | -------------- |
| Too weak | 0 | 0 |
| Weak | 2 | 6 |
| Medium | 4 | 8 |
| Strong | 4 | 10 |
```javascript
console.log(passwordStrength('@Sdfasd2020!@#$'))
// output
{
"id": 1,
"value": "Strong",
"contains": ['lowercase', 'uppercase', 'symbol', 'number'],
"length": 15
}
```
### Default Options
The default symbols are based from **Password Special Characters [OWASP](https://owasp.org/www-community/password-special-characters)** list (except for the space)
```
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
```
Thanks for [jlherren](https://github.com/jlherren) & [Ennoriel](https://github.com/Ennoriel) for this suggestion! 👨🏻‍💻👨🏻‍💻
The default options can be required:
```javascript
const { defaultOptions } = require("./index");
```
default options:
```javascript
[
{
id: 0,
value: "Too weak",
minDiversity: 0,
minLength: 0
},
{
id: 1,
value: "Weak",
minDiversity: 2,
minLength: 6
},
{
id: 2,
value: "Medium",
minDiversity: 4,
minLength: 8
},
{
id: 3,
value: "Strong",
minDiversity: 4,
minLength: 10
}
]
```
To override the default options, simply pass your custom array as the second argument:
- id: correspond to the return id attribute.
- value: correspond to the return value attribute.
- minDiversity: between 0 and 4, correspond to the minimum of different criterias ('lowercase', 'uppercase', 'symbol', 'number') that should be met to pass the password strength
- minLength: minimum length of the password that should be met to pass the password strength
The `minDiversity` and `minLength` parameters of the first element cannot be overriden (set to 0 at the beginning of the method). Therefore, the first element should always correspond to a "too weak" option.
```javascript
passwordStrength('myPassword', yourCustomOptions)
```
### RegEx
**Strong**
```
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*"'()+,-./:;<=>?[\]^_`{|}~])(?=.{10,})
```
**Medium Password RegEx used:**
```
^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*"'()+,-./:;<=>?[\]^_`{|}~])(?=.{8,})
```
| RegEx | Desc. |
| ----------------------------------------- | ------------------------------------------------------------------- |
| ^ | The password string will start this way |
| (?=.*[a-z]) | The string must contain at least 1 lowercase alphabetical character |
| (?=.*[A-Z]) | The string must contain at least 1 uppercase alphabetical character |
| (?=.*[0-9]) | The string must contain at least 1 numeric character |
| (?=.[!"#$%&'()*+,-./:;<=>?@[\\]^_`{\|}~])) | The string must contain at least one special character |
| (?=.{10,}) | The string must be eight characters or longer for Strong strength |
| (?=.{8,}) | The string must be eight characters or longer for Medium strength |
| (?=.{6,}) | Mininum of 6 characters for Weak strength |
## TypeScript type declarations &#9745;
Available starting version `v2.0.3` and above. (Thanks to [@Mesoptier!](https://github.com/Mesoptier))
## Other resources
##### For .NET Project
If you're working with .net core project, I've created a simple nuget package with same RegEx strings to validate a password strength.
You can easily install via Nuget Package Manager or .NET CLI ([Check.Password.Strength](https://github.com/deanilvincent/Check.Password.Strength)). This package uses Regular Expression `new Regex()` derives from `System.Text.RegularExpressions`. You can use this especially if you want to validate the passcode strength on backend services or web apis of your project.
##### Other NPM RegEx validator
I also made another NPM package ([hey-regex](https://www.npmjs.com/package/hey-regex)) that checks common inputs like numbers (whole number and decimal), alpha numeric, email and url. This package only returns `true` or `false` based from the selected function (with RegEx `.test()` inside).
Reference [blog](https://www.thepolyglotdeveloper.com/2015/05/use-regex-to-test-password-strength-in-javascript/).
### Contribute
Feel free to clone or fork this project: `https://github.com/deanilvincent/check-password-strength.git`
Contributions & pull requests are welcome!
I'll be glad if you give this project a ★ on [Github](https://github.com/deanilvincent/check-password-strength) :)
***
Kudos to [@Ennoriel](https://github.com/Ennoriel) and his efforts for making v2.x.x possible!
### License
This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/deanilvincent/check-password-strength/blob/master/LICENSE.md/) file for details.

View File

@@ -0,0 +1,76 @@
const defaultOptions = [
{
id: 0,
value: "Too weak",
minDiversity: 0,
minLength: 0
},
{
id: 1,
value: "Weak",
minDiversity: 2,
minLength: 6
},
{
id: 2,
value: "Medium",
minDiversity: 4,
minLength: 8
},
{
id: 3,
value: "Strong",
minDiversity: 4,
minLength: 10
}
]
const passwordStrength = (password, options = defaultOptions, allowedSymbols="!\"#\$%&'\(\)\*\+,-\./:;<=>\?@\[\\\\\\]\^_`\{|\}~") => {
let passwordCopy = password || ''
options[0].minDiversity = 0,
options[0].minLength = 0
const rules = [
{
regex: "[a-z]",
message: 'lowercase'
},
{
regex: '[A-Z]',
message: 'uppercase'
},
{
regex: '[0-9]',
message: 'number'
},
]
if (allowedSymbols) {
rules.push({
regex: `[${allowedSymbols}]`,
message: 'symbol'
})
}
let strength = {}
strength.contains = rules
.filter(rule => new RegExp(`${rule.regex}`).test(passwordCopy))
.map(rule => rule.message)
strength.length = passwordCopy.length;
let fulfilledOptions = options
.filter(option => strength.contains.length >= option.minDiversity)
.filter(option => strength.length >= option.minLength)
.sort((o1, o2) => o2.id - o1.id)
.map(option => ({id: option.id, value: option.value}))
Object.assign(strength, fulfilledOptions[0])
return strength;
};
module.exports = { passwordStrength, defaultOptions }

View File

@@ -0,0 +1,30 @@
export interface Option<V> {
id: number;
value: V;
minDiversity: number;
minLength: number;
}
export interface FirstOption<V> extends Option<V> {
minDiversity: 0;
minLength: 0;
}
export type Options<V> = [FirstOption<V>, ...Option<V>[]];
export const defaultOptions: Options<string>;
export type DiversityType = "lowercase" | "uppercase" | "symbol" | "number";
export interface Result<V> {
id: number;
value: V;
contains: DiversityType[];
length: number;
}
export function passwordStrength<V = string>(
password: string,
options?: Options<V>,
allowedSymbols?: string,
): Result<V>;

View File

@@ -0,0 +1,77 @@
const defaultOptions = [
{
id: 0,
value: "Too weak",
minDiversity: 0,
minLength: 0
},
{
id: 1,
value: "Weak",
minDiversity: 2,
minLength: 6
},
{
id: 2,
value: "Medium",
minDiversity: 4,
minLength: 8
},
{
id: 3,
value: "Strong",
minDiversity: 4,
minLength: 10
}
];
const passwordStrength = (password, options = defaultOptions, allowedSymbols="!\"#\$%&'\(\)\*\+,-\./:;<=>\?@\[\\\\\\]\^_`\{|\}~") => {
let passwordCopy = password || '';
options[0].minDiversity = 0,
options[0].minLength = 0;
const rules = [
{
regex: "[a-z]",
message: 'lowercase'
},
{
regex: '[A-Z]',
message: 'uppercase'
},
{
regex: '[0-9]',
message: 'number'
},
];
if (allowedSymbols) {
rules.push({
regex: `[${allowedSymbols}]`,
message: 'symbol'
});
}
let strength = {};
strength.contains = rules
.filter(rule => new RegExp(`${rule.regex}`).test(passwordCopy))
.map(rule => rule.message);
strength.length = passwordCopy.length;
let fulfilledOptions = options
.filter(option => strength.contains.length >= option.minDiversity)
.filter(option => strength.length >= option.minLength)
.sort((o1, o2) => o2.id - o1.id)
.map(option => ({id: option.id, value: option.value}));
Object.assign(strength, fulfilledOptions[0]);
return strength;
};
module.exports = { passwordStrength, defaultOptions };
//# sourceMappingURL=es.js.map

View File

@@ -0,0 +1,39 @@
{
"name": "@odit/lfk-client-js",
"description": "A lib to interact with https://git.odit.services/lfk/backend. Use this version for native JS applications.",
"version": "0.14.0",
"license": "CC-BY-NC-SA-4.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"repository": {
"type": "git",
"url": "git+https://git.odit.services/lfk/lfk-client-js"
},
"keywords": [
"odit",
"odit.services",
"lfk"
],
"author": "ODIT.Services",
"files": [
"dist",
"package.json",
"README.md"
],
"scripts": {
"build": "npm run build:prepare && npm run build:lib && npm run build:compile && npm run build:cleanup",
"build:prepare": "rimraf ./lib ./dist",
"build:lib": "openapi --input ./openapi.json --output ./lib --client fetch",
"build:compile": "tsc",
"build:cleanup": "rimraf ./lib"
},
"bugs": {
"url": "https://git.odit.services/lfk/lfk-client-js/issues"
},
"homepage": "https://git.odit.services/lfk/lfk-client-js/",
"devDependencies": {
"openapi-typescript-codegen": "0.7.0",
"rimraf": "4.1.2",
"typescript": "4.9.5"
}
}

View File

@@ -0,0 +1,387 @@
const {passwordStrength: app, defaultOptions} = require("./index");
it("Should not modify the password parameter", () => {
let pwd = "Hello!"
app(pwd)
expect(pwd).toBe("Hello!")
})
it("Should return strength id 3 if password is Strong", () => {
expect(app("A@2asdF2020!!*!").id).toBe(3);
});
//#region INTRODUCE UPDATED DEFAULT SYMBOLS AND TEST EACH SYMBOL
it("Should return strength id 3 if password is Strong with these symbols: !\"#\$%&'\(\)\*\+,-\./:;<=>\?@\[\\]\^_`\{|\}~", () => {
expect(app("A20abcdefg!\"#\$%&'\(\)\*\+,-\./:;<=>\?@\[\\]\^_`\{|\}~").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: !", () => {
expect(app("A20abcdefg!").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: @", () => {
expect(app("A20abcdefg@").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: #", () => {
expect(app("A20abcdefg#").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: ^", () => {
expect(app("A20abcdefg^").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: &", () => {
expect(app("A20abcdefg&").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: *", () => {
expect(app("A20abcdefg*").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: !", () => {
expect(app("A20abcdefg!").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: \"", () => {
expect(app("A20abcdefg\"").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: '", () => {
expect(app("A20abcdefg'").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: (", () => {
expect(app("A20abcdefg(").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: )", () => {
expect(app("A20abcdefg)").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: +", () => {
expect(app("A20abcdefg+").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: ,", () => {
expect(app("A20abcdefg,").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: -", () => {
expect(app("A20abcdefg-").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: .", () => {
expect(app("A20abcdefg.").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: /", () => {
expect(app("A20abcdefg/").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: :", () => {
expect(app("A20abcdefg:").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: ;", () => {
expect(app("A20abcdefg;").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: <", () => {
expect(app("A20abcdefg>").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: =", () => {
expect(app("A20abcdefg=").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: >", () => {
expect(app("A20abcdefg>").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: ?", () => {
expect(app("A20abcdefg?").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: [", () => {
expect(app("A20abcdefg[").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: ]", () => {
expect(app("A20abcdefg]").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: \\", () => {
expect(app("A20abcdefg\\").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: \\", () => {
expect(app("A20abcdefg\\").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: ^", () => {
expect(app("A20abcdefg^").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: _", () => {
expect(app("A20abcdefg_").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: `", () => {
expect(app("A20abcdefg`").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: {", () => {
expect(app("A20abcdefg{").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: }", () => {
expect(app("A20abcdefg}").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: |", () => {
expect(app("A20abcdefg|").id).toBe(3);
});
it("Should return strength id 3 if password is Strong with symbol: ~", () => {
expect(app("A20abcdefg~").id).toBe(3);
});
//#endregion
it("Should return strength id 2 if password is Medium", () => {
expect(app("Asd1234!").id).toBe(2);
});
it("Should return strength id 1 if password is Weak", () => {
expect(app("asdf1234").id).toBe(1);
});
it("Should return strength id 1 if password has two combination of symbol + lowercase", () => {
expect(app("asdf!@#$").id).toBe(1);
});
it("Should return strength id 1 if password has two combination of symbol + uppercase", () => {
expect(app("ASDF!@#$").id).toBe(1);
});
it("Should return strength id 1 if password has two combination of symbol + numeric", () => {
expect(app("1234!@#$").id).toBe(1);
});
it("Should return strength id 0 if password is weak", () => {
expect(app("a").id).toBe(0);
});
it("Should return strength value 'Strong' if password is Medium", () => {
expect(app("A@2asdF2020!!*").value).toBe("Strong");
});
it("Should return strength value 'Medium' if password is Medium", () => {
expect(app("Asd1234!").value).toBe("Medium");
});
it("Should return strength value 'Weak' if password is Weak", () => {
expect(app("Asdf1234").value).toBe("Weak");
});
// pass combination
it("Should return strength value 'Weak' if password has two combination of symbol + lowercase", () => {
expect(app("asdf!@#$").value).toBe("Weak");
});
it("Should return strength value 'Weak' if password has two combination of symbol + uppercase", () => {
expect(app("ASDF!@#$").value).toBe("Weak");
});
it("Should return strength value 'Weak' if password has two combination of symbol + numeric", () => {
expect(app("1234!@#$").value).toBe("Weak");
});
it("Should return strength value 'Too weak' if password is weak", () => {
expect(app("a").value).toBe("Too weak");
});
it("Should return type of number if request for id", () => {
expect(typeof app("a").id).toBe("number");
});
it("Should return type of string if request for value", () => {
expect(typeof app("a").value).toBe("string");
});
it("Should return type of object if requesting directly from the function", () => {
expect(typeof app("a")).toBe("object");
});
// contains
it("Should return true if request for contains is an array", () => {
const arrayData = Array.isArray(app("a").contains);
expect(arrayData).toEqual(true);
});
it("Should return contains of 'lowercase' if the password has lowercase", () => {
const contains = app("lower").contains;
const contain = contains.find((x) => x === "lowercase");
const condition = contain === "lowercase";
expect(condition).toEqual(true);
});
it("Should return contains of 'uppercase' if the password has uppercase", () => {
const contains = app("Uppercase").contains;
const contain = contains.find((x) => x === "uppercase");
const condition = contain === "uppercase";
expect(condition).toEqual(true);
});
it("Should return contains of 'symbol' if the password has symbol", () => {
const contains = app("!test").contains;
const contain = contains.find((x) => x === "symbol");
const condition = contain === "symbol";
expect(condition).toEqual(true);
});
it("Should return contains of 'number' if the password has number", () => {
const contains = app("1234").contains;
const contain = contains.find((x) => x === "number");
const condition = contain === "number";
expect(condition).toEqual(true);
});
it("Should return contains of all criteria (lowercase, uppercase, symbol & number)", () => {
expect(app("asdfASDF!@#$1234").contains).toStrictEqual([
"lowercase",
"uppercase",
"number",
"symbol",
]);
});
it("Should return contains of two or more message if the password has 2 or more message password criteria", () => {
expect(app("asdfASDF").contains).toStrictEqual([
"lowercase",
"uppercase",
]);
});
it("Should return contains length if contains has value", () => {
expect(app("asdfASDF").contains.length).toBe(2);
});
// length
it("Should return numeric length value if request for length", () => {
expect(app("1234").length).toBe(4);
});
it("Should return type of number if request is for length value", () => {
expect(typeof app("1234").length).toBe("number");
});
it("Should return an empty password result if password parameter is null", () => {
expect(app(null).id).toBe(0);
expect(app(null).length).toBe(0);
expect(app(null).contains).toStrictEqual([]);
});
overridenOptions = [
{
id: 0,
value: "Too weak",
minDiversity: 0,
minLength: 0
},
{
id: 1,
value: "Weak",
minDiversity: 2,
minLength: 6
},
{
id: 2,
value: "Medium",
minDiversity: 3,
minLength: 8
},
{
id: 3,
value: "Strong",
minDiversity: 4,
minLength: 10
}
]
it("[overridden options] Should return strength id 0 if password is weak", () => {
expect(app("aB1$", overridenOptions).id).toBe(0);
expect(app("aB1$", overridenOptions).value).toBe("Too weak");
});
it("[overridden options] Should return strength id 1 if password is Weak", () => {
expect(app("abcde123456", overridenOptions).id).toBe(1);
expect(app("abcde123456", overridenOptions).value).toBe("Weak");
});
it("[overridden options] Should return strength id 2 if password is Medium", () => {
expect(app("abcde123456$", overridenOptions).id).toBe(2);
expect(app("abcde123456$", overridenOptions).value).toBe("Medium");
});
it("[overridden options] Should return strength id 3 if password is Strong", () => {
expect(app("abcde123456$B", overridenOptions).id).toBe(3);
expect(app("abcde123456$B", overridenOptions).value).toBe("Strong");
});
it("[overridden options] Should return true if request for contains is an array", () => {
const arrayData = Array.isArray(app("a", overridenOptions).contains);
expect(arrayData).toEqual(true);
});
it("[overridden options] Should return contains of 'lowercase' if the password has lowercase", () => {
const contains = app("lower", overridenOptions).contains;
const contain = contains.find((x) => x === "lowercase");
const condition = contain === "lowercase";
expect(condition).toEqual(true);
});
it("[overridden options] Should return contains of 'uppercase' if the password has uppercase", () => {
const contains = app("Uppercase", overridenOptions).contains;
const contain = contains.find((x) => x === "uppercase");
const condition = contain === "uppercase";
expect(condition).toEqual(true);
});
it("[overridden options] Should return contains of 'symbol' if the password has symbol", () => {
const contains = app("!test", overridenOptions).contains;
const contain = contains.find((x) => x === "symbol");
const condition = contain === "symbol";
expect(condition).toEqual(true);
});
it("[overridden options] Should return contains of 'number' if the password has number", () => {
const contains = app("1234", overridenOptions).contains;
const contain = contains.find((x) => x === "number");
const condition = contain === "number";
expect(condition).toEqual(true);
});
it("[overridden options] Should return the same object with the default option", () => {
expect(app("abcd@")).toStrictEqual(app('abdc@', defaultOptions))
expect(app("abcd@E")).toStrictEqual(app('abdc@E', defaultOptions))
expect(app("abcd@3")).toStrictEqual(app('abdc@3', defaultOptions))
expect(app(null)).toStrictEqual(app(null, defaultOptions))
});
it("[overridden allowedSymbols] Should not contains symbols if the password does not have one", () => {
const contains = app("abcd@", undefined, '$').contains;
expect(contains).toEqual(expect.arrayContaining(['lowercase']));
expect(contains).toEqual(expect.not.arrayContaining(['uppercase']));
expect(contains).toEqual(expect.not.arrayContaining(['number']));
expect(contains).toEqual(expect.not.arrayContaining(['symbol']));
});
it("[overridden allowedSymbols] Should contains symbols if the password have one", () => {
const contains = app("abcd@Ê", undefined, 'Ê').contains;
expect(contains).toEqual(expect.arrayContaining(['lowercase']));
expect(contains).toEqual(expect.not.arrayContaining(['uppercase']));
expect(contains).toEqual(expect.not.arrayContaining(['number']));
expect(contains).toEqual(expect.arrayContaining(['symbol']));
});

View File

@@ -2,9 +2,17 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [0.17.3](https://git.odit.services/lfk/frontend/compare/0.17.2...0.17.3)
- dependency fixes [`3ea7a01`](https://git.odit.services/lfk/frontend/commit/3ea7a015a9beba3c2e4d3eb966f24ff6d4ac786e)
- set pnpm to @7 [`4432941`](https://git.odit.services/lfk/frontend/commit/44329413ed2ca23f74e86db041b2c25b2b1c2a2b)
#### [0.17.2](https://git.odit.services/lfk/frontend/compare/0.17.1...0.17.2)
> 15 March 2023
- new license file version [CI SKIP] [`00359d2`](https://git.odit.services/lfk/frontend/commit/00359d25c1bd3efdd6365bf284b3c07634049399)
- 🚀RELEASE v0.17.2 [`46db68a`](https://git.odit.services/lfk/frontend/commit/46db68ab229dc740dfff8835ef916f2c2e629b27)
- improved ThFilterGroup style [`f917018`](https://git.odit.services/lfk/frontend/commit/f917018fd92a8a5b034f735ac8b6e41995044317)
#### [0.17.1](https://git.odit.services/lfk/frontend/compare/0.17.0...0.17.1)
@@ -1321,7 +1329,7 @@ All notable changes to this project will be documented in this file. Dates are d
- init [`32357ec`](https://git.odit.services/lfk/frontend/commit/32357ece0a7195ea1135c9c3e4c6c84323f95b4d)
- tmp [`1b7173c`](https://git.odit.services/lfk/frontend/commit/1b7173cda9134ee8058a00bdc030defa80d46bfc)
- Login - move to env.js import [`8ef0b21`](https://git.odit.services/lfk/frontend/commit/8ef0b21819309752c573d0485f6514152fb684e6)
- initial commit [`4bb3bae`](https://git.odit.services/lfk/frontend/commit/4bb3bae4e6fc89c35a8a2b36b7cd6e6d47958eae)
- initial commit [`4bb3bae`](https://git.odit.services/lfk/frontend/commit/4bb3bae4e6fc89c35a8a2b36b7cd6e6d47958eae)
- Initial license export [`4c96b9a`](https://git.odit.services/lfk/frontend/commit/4c96b9a3e04dbb7c021c71aa8828a29248509fbe)
- 🚚 move to tinro svelte router [`a50ea15`](https://git.odit.services/lfk/frontend/commit/a50ea15b38023b867a9f7757e973184cbcdd2457)
- new Dashboard [`7270ce9`](https://git.odit.services/lfk/frontend/commit/7270ce9d32869abd4f6ac65ab7c2c87363633cbe)

View File

@@ -1,7 +1,7 @@
FROM registry.odit.services/hub/library/node:19.7.0-alpine3.16 as build
WORKDIR /app
COPY package.json ./
RUN npx pnpm@7.5.1 i
RUN npx pnpm@7 i
COPY package.json pnpm-lock.yaml *.config.js postcss.config.cjs tailwind.config.js vite.config.js index.html ./
COPY src ./src
COPY public ./public

View File

@@ -13,7 +13,7 @@
</head>
<body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.17.2-RELEASE_INFO</span>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.17.3-RELEASE_INFO</span>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/env.js"></script>
<script type="module" src="/src/main.js"></script>

View File

@@ -1,6 +1,6 @@
{
"name": "@odit/lfk-frontend",
"version": "0.17.2",
"version": "0.17.3",
"scripts": {
"i18n-order": "node order.js",
"dev": "vite",
@@ -10,32 +10,18 @@
},
"license": "CC-BY-NC-SA-4.0",
"devDependencies": {
"@odit/lfk-client-js": "0.13.1",
"@odit/license-exporter": "0.0.11",
"@sveltejs/vite-plugin-svelte": "1.0.0-next.6",
"@types/html-minifier": "4.0.0",
"@vincjo/datatables": "^1.1.0",
"auto-changelog": "2.2.1",
"autoprefixer": "10.2.5",
"check-password-strength": "2.0.2",
"csvtojson": "2.0.10",
"gridjs": "3.4.0",
"@odit/license-exporter": "0.0.12",
"@types/html-minifier": "4.0.2",
"auto-changelog": "2.4.0",
"autoprefixer": "10.4.14",
"html-minifier": "4.0.0",
"localforage": "1.9.0",
"marked": "2.0.3",
"postcss": "8.2.10",
"postcss": "8.4.21",
"release-it": "14.6.1",
"svelte": "3.37.0",
"svelte-focus-trap": "1.2.0",
"svelte-i18n": "3.3.9",
"svelte-preprocess": "4.7.0",
"svelte-select": "3.17.0",
"tailwindcss": "3.2.7",
"tinro": "0.6.1",
"toastify-js": "1.10.0",
"validator": "13.5.2",
"vite": "2.1.5",
"xlsx": "0.16.9"
"vite": "2.1.5"
},
"release-it": {
"git": {
@@ -55,6 +41,20 @@
}
},
"dependencies": {
"tinro": "0.6.12",
"toastify-js": "1.12.0",
"validator": "13.9.0",
"xlsx": "0.16.9",
"@odit/lfk-client-js": "0.14.0",
"@vincjo/datatables": "^1.4.0",
"check-password-strength": "2.0.7",
"csvtojson": "2.0.10",
"gridjs": "3.4.0",
"localforage": "1.10.0",
"marked": "2.0.3",
"svelte": "3.37.0",
"svelte-focus-trap": "1.2.0",
"svelte-i18n": "3.3.9",
"@paralleldrive/cuid2": "^2.2.0"
},
"volta": {

308
pnpm-lock.yaml generated
View File

@@ -1,21 +1,21 @@
lockfileVersion: 5.4
specifiers:
'@odit/lfk-client-js': 0.13.1
'@odit/license-exporter': 0.0.11
'@odit/lfk-client-js': 0.14.0
'@odit/license-exporter': 0.0.12
'@paralleldrive/cuid2': ^2.2.0
'@sveltejs/vite-plugin-svelte': 1.0.0-next.6
'@types/html-minifier': 4.0.0
'@vincjo/datatables': ^1.1.0
auto-changelog: 2.2.1
autoprefixer: 10.2.5
check-password-strength: 2.0.2
'@types/html-minifier': 4.0.2
'@vincjo/datatables': ^1.4.0
auto-changelog: 2.4.0
autoprefixer: 10.4.14
check-password-strength: 2.0.7
csvtojson: 2.0.10
gridjs: 3.4.0
html-minifier: 4.0.0
localforage: 1.9.0
localforage: 1.10.0
marked: 2.0.3
postcss: 8.2.10
postcss: 8.4.21
release-it: 14.6.1
svelte: 3.37.0
svelte-focus-trap: 1.2.0
@@ -23,43 +23,43 @@ specifiers:
svelte-preprocess: 4.7.0
svelte-select: 3.17.0
tailwindcss: 3.2.7
tinro: 0.6.1
toastify-js: 1.10.0
validator: 13.5.2
tinro: 0.6.12
toastify-js: 1.12.0
validator: 13.9.0
vite: 2.1.5
xlsx: 0.16.9
dependencies:
'@odit/lfk-client-js': 0.14.0
'@paralleldrive/cuid2': 2.2.0
devDependencies:
'@odit/lfk-client-js': 0.13.1
'@odit/license-exporter': 0.0.11
'@sveltejs/vite-plugin-svelte': 1.0.0-next.6_svelte@3.37.0+vite@2.1.5
'@types/html-minifier': 4.0.0
'@vincjo/datatables': 1.1.0
auto-changelog: 2.2.1
autoprefixer: 10.2.5_postcss@8.2.10
check-password-strength: 2.0.2
'@vincjo/datatables': 1.4.0
check-password-strength: 2.0.7
csvtojson: 2.0.10
gridjs: 3.4.0
html-minifier: 4.0.0
localforage: 1.9.0
localforage: 1.10.0
marked: 2.0.3
postcss: 8.2.10
release-it: 14.6.1
svelte: 3.37.0
svelte-focus-trap: 1.2.0
svelte-i18n: 3.3.9_svelte@3.37.0
svelte-preprocess: 4.7.0_kczdzg4a76p6bleo3ihutrynli
svelte-select: 3.17.0
tailwindcss: 3.2.7_postcss@8.2.10
tinro: 0.6.1
toastify-js: 1.10.0
validator: 13.5.2
vite: 2.1.5
tinro: 0.6.12
toastify-js: 1.12.0
validator: 13.9.0
xlsx: 0.16.9
devDependencies:
'@odit/license-exporter': 0.0.12
'@sveltejs/vite-plugin-svelte': 1.0.0-next.6_svelte@3.37.0+vite@2.1.5
'@types/html-minifier': 4.0.2
auto-changelog: 2.4.0
autoprefixer: 10.4.14_postcss@8.4.21
html-minifier: 4.0.0
postcss: 8.4.21
release-it: 14.6.1
svelte-preprocess: 4.7.0_3fnoivf624cjedq7eprmr6bhie
svelte-select: 3.17.0
tailwindcss: 3.2.7_postcss@8.4.21
vite: 2.1.5
packages:
/@babel/code-frame/7.18.6:
@@ -88,13 +88,13 @@ packages:
dependencies:
'@formatjs/intl-localematcher': 0.2.25
tslib: 2.5.0
dev: true
dev: false
/@formatjs/fast-memoize/1.2.1:
resolution: {integrity: sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==}
dependencies:
tslib: 2.5.0
dev: true
dev: false
/@formatjs/icu-messageformat-parser/2.1.0:
resolution: {integrity: sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==}
@@ -102,20 +102,20 @@ packages:
'@formatjs/ecma402-abstract': 1.11.4
'@formatjs/icu-skeleton-parser': 1.3.6
tslib: 2.5.0
dev: true
dev: false
/@formatjs/icu-skeleton-parser/1.3.6:
resolution: {integrity: sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==}
dependencies:
'@formatjs/ecma402-abstract': 1.11.4
tslib: 2.5.0
dev: true
dev: false
/@formatjs/intl-localematcher/0.2.25:
resolution: {integrity: sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==}
dependencies:
tslib: 2.5.0
dev: true
dev: false
/@iarna/toml/2.2.5:
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
@@ -253,15 +253,15 @@ packages:
'@octokit/openapi-types': 12.11.0
dev: true
/@odit/lfk-client-js/0.13.1:
resolution: {integrity: sha512-a5isLEeEVcfL3AiGyGeeC+m6aJ9+ocexJR17FM6X8vNxAW+aBz1F1SQKBibVXUOy8ihwvf6ivlXYtYNQRwVkiA==}
dev: true
/@odit/lfk-client-js/0.14.0:
resolution: {integrity: sha512-/c/1VAIWfXaczSpueAwRtkkRu59gPihtM1o2KJJOBqcbqornsPCwt2Ko/Gkca8tee38zTVupoTS+T9L5BC0a9A==}
dev: false
/@odit/license-exporter/0.0.11:
resolution: {integrity: sha512-jB5XQF913xaRSF0Hjoqaei/qcTGwBEUc2IZ68OcFShwL/fLfBhI4yhlc9nm9gHgWDEKOInI7mVE8xgpHuiGasA==}
/@odit/license-exporter/0.0.12:
resolution: {integrity: sha512-k5KxyTOk3Qz/OzId5VNXKjYOz1C4cMVfRHbq3X0VS4BM2rRuIgabrg/lbmZXDM1ExJkdBXi9sqiQ4h7N5bVbLQ==}
hasBin: true
dependencies:
yargs: 16.2.0
yargs: 17.7.1
dev: true
/@paralleldrive/cuid2/2.2.0:
@@ -339,8 +339,8 @@ packages:
source-map: 0.6.1
dev: true
/@types/html-minifier/4.0.0:
resolution: {integrity: sha512-eFnGhrKmjWBlnSGNtunetE3UU2Tc/LUl92htFslSSTmpp9EKHQVcYQadCyYfnzUEFB5G/3wLWo/USQS/mEPKrA==}
/@types/html-minifier/4.0.2:
resolution: {integrity: sha512-4IkmkXJP/25R2fZsCHDX2abztXuQRzUAZq39PfCMz2loLFj8vS9y7aF6vDl58koXSTpsF+eL4Lc5Y4Aww/GCTQ==}
dependencies:
'@types/clean-css': 4.2.6
'@types/relateurl': 0.2.29
@@ -391,9 +391,9 @@ packages:
source-map: 0.6.1
dev: true
/@vincjo/datatables/1.1.0:
resolution: {integrity: sha512-co6k/LYuhPrb9NVDc3aeHznk3rSoB0jHO9Pg2y8EZQ7oQqVEGfKE6M+7uwQV71BCXg/tdSDLjas1hJ/cu+X7IA==}
dev: true
/@vincjo/datatables/1.4.0:
resolution: {integrity: sha512-Z6s4eTFszkYtmbsr14kVig+pa4gV19tbxDD92ueuqC3k+rN9iJPcw9P+BOJrVs5kKn0WKFkwZc62JjaAVIY8Yw==}
dev: false
/acorn-node/1.8.2:
resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==}
@@ -421,12 +421,12 @@ packages:
dependencies:
exit-on-epipe: 1.0.1
printj: 1.1.2
dev: true
dev: false
/adler-32/1.3.1:
resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==}
engines: {node: '>=0.8'}
dev: true
dev: false
/ansi-align/3.0.1:
resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
@@ -487,34 +487,33 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: true
/auto-changelog/2.2.1:
resolution: {integrity: sha512-XlykJfZrXlWUAADBqGoN1elmntrRcx7oEymyYB3NRPEZxv0TfYHfivmwzejUMnwAdXKCgbQPo7GV5ULs3jwpfw==}
/auto-changelog/2.4.0:
resolution: {integrity: sha512-vh17hko1c0ItsEcw6m7qPRf3m45u+XK5QyCrrBFViElZ8jnKrPC1roSznrd1fIB/0vR/zawdECCRJtTuqIXaJw==}
engines: {node: '>=8.3'}
hasBin: true
dependencies:
commander: 5.1.0
commander: 7.2.0
handlebars: 4.7.7
lodash.uniqby: 4.7.0
node-fetch: 2.6.9
parse-github-url: 1.0.2
semver: 6.3.0
semver: 7.3.5
transitivePeerDependencies:
- encoding
dev: true
/autoprefixer/10.2.5_postcss@8.2.10:
resolution: {integrity: sha512-7H4AJZXvSsn62SqZyJCP+1AWwOuoYpUfK6ot9vm0e87XD6mT8lDywc9D9OTJPMULyGcvmIxzTAMeG2Cc+YX+fA==}
/autoprefixer/10.4.14_postcss@8.4.21:
resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
peerDependencies:
postcss: ^8.1.0
dependencies:
browserslist: 4.21.5
caniuse-lite: 1.0.30001453
colorette: 1.4.0
caniuse-lite: 1.0.30001466
fraction.js: 4.2.0
normalize-range: 0.1.2
postcss: 8.2.10
picocolors: 1.0.0
postcss: 8.4.21
postcss-value-parser: 4.2.0
dev: true
@@ -545,7 +544,7 @@ packages:
/bluebird/3.7.2:
resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==}
dev: true
dev: false
/boxen/5.1.2:
resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==}
@@ -580,7 +579,7 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001453
caniuse-lite: 1.0.30001466
electron-to-chromium: 1.4.299
node-releases: 2.0.10
update-browserslist-db: 1.0.10_browserslist@4.21.5
@@ -653,8 +652,8 @@ packages:
engines: {node: '>=10'}
dev: true
/caniuse-lite/1.0.30001453:
resolution: {integrity: sha512-R9o/uySW38VViaTrOtwfbFEiBFUh7ST3uIG4OEymIG3/uKdHDO4xk/FaqfUw0d+irSUyFPy3dZszf9VvSTPnsA==}
/caniuse-lite/1.0.30001466:
resolution: {integrity: sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w==}
dev: true
/cfb/1.2.2:
@@ -663,7 +662,7 @@ packages:
dependencies:
adler-32: 1.3.1
crc-32: 1.2.2
dev: true
dev: false
/chalk/2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
@@ -694,9 +693,9 @@ packages:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
dev: true
/check-password-strength/2.0.2:
resolution: {integrity: sha512-Dh1h1XZkRBbkKdoZip18xdFjuBU0v2SYvF1l/ZkqMTkwB4j3OiDLMTv1o63K2UI3wTnPLQPTTkGWwpLab60muA==}
dev: true
/check-password-strength/2.0.7:
resolution: {integrity: sha512-VyklBkB6dOKnCIh63zdVr7QKVMN9/npwUqNAXxWrz8HabVZH/n/d+lyNm1O/vbXFJlT/Hytb5ouYKYGkoeZirQ==}
dev: false
/chokidar/3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
@@ -751,8 +750,9 @@ packages:
engines: {node: '>= 10'}
dev: true
/cliui/7.0.4:
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
/cliui/8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
@@ -777,7 +777,7 @@ packages:
dependencies:
commander: 2.14.1
exit-on-epipe: 1.0.1
dev: true
dev: false
/color-convert/1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
@@ -800,10 +800,6 @@ packages:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
dev: true
/colorette/1.4.0:
resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==}
dev: true
/combined-stream/1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
@@ -813,19 +809,19 @@ packages:
/commander/2.14.1:
resolution: {integrity: sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==}
dev: true
dev: false
/commander/2.17.1:
resolution: {integrity: sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==}
dev: true
dev: false
/commander/2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
dev: true
/commander/5.1.0:
resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==}
engines: {node: '>= 6'}
/commander/7.2.0:
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
engines: {node: '>= 10'}
dev: true
/concat-map/0.0.1:
@@ -859,7 +855,7 @@ packages:
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
engines: {node: '>=0.8'}
hasBin: true
dev: true
dev: false
/cross-spawn/7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
@@ -889,7 +885,7 @@ packages:
bluebird: 3.7.2
lodash: 4.17.21
strip-bom: 2.0.0
dev: true
dev: false
/debug/4.3.1:
resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==}
@@ -942,7 +938,7 @@ packages:
/deepmerge/4.3.0:
resolution: {integrity: sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==}
engines: {node: '>=0.10.0'}
dev: true
dev: false
/defaults/1.0.4:
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
@@ -1064,7 +1060,6 @@ packages:
/estree-walker/2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
dev: true
/execa/4.1.0:
resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==}
@@ -1099,7 +1094,7 @@ packages:
/exit-on-epipe/1.0.1:
resolution: {integrity: sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==}
engines: {node: '>=0.8'}
dev: true
dev: false
/external-editor/3.1.0:
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
@@ -1129,7 +1124,7 @@ packages:
/fflate/0.3.11:
resolution: {integrity: sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A==}
dev: true
dev: false
/figures/3.2.0:
resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
@@ -1175,7 +1170,7 @@ packages:
/frac/1.1.2:
resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==}
engines: {node: '>=0.8'}
dev: true
dev: false
/fraction.js/4.2.0:
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
@@ -1276,7 +1271,7 @@ packages:
/globalyzer/0.1.0:
resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==}
dev: true
dev: false
/globby/11.0.3:
resolution: {integrity: sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==}
@@ -1292,7 +1287,7 @@ packages:
/globrex/0.1.2:
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
dev: true
dev: false
/got/11.8.2:
resolution: {integrity: sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==}
@@ -1339,7 +1334,7 @@ packages:
dependencies:
preact: 10.12.1
tslib: 2.5.0
dev: true
dev: false
/handlebars/4.7.7:
resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==}
@@ -1444,7 +1439,7 @@ packages:
/immediate/3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
dev: true
dev: false
/import-cwd/3.0.0:
resolution: {integrity: sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==}
@@ -1529,7 +1524,7 @@ packages:
'@formatjs/fast-memoize': 1.2.1
'@formatjs/icu-messageformat-parser': 2.1.0
tslib: 2.5.0
dev: true
dev: false
/is-arrayish/0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
@@ -1639,7 +1634,7 @@ packages:
/is-utf8/0.2.1:
resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
dev: true
dev: false
/is-yarn-global/0.3.0:
resolution: {integrity: sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==}
@@ -1688,7 +1683,7 @@ packages:
resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==}
dependencies:
immediate: 3.0.6
dev: true
dev: false
/lilconfig/2.0.6:
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
@@ -1699,11 +1694,11 @@ packages:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
/localforage/1.9.0:
resolution: {integrity: sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g==}
/localforage/1.10.0:
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
dependencies:
lie: 3.1.1
dev: true
dev: false
/locate-path/6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
@@ -1712,13 +1707,8 @@ packages:
p-locate: 5.0.0
dev: true
/lodash.uniqby/4.7.0:
resolution: {integrity: sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==}
dev: true
/lodash/4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: true
/log-symbols/4.1.0:
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
@@ -1765,7 +1755,7 @@ packages:
resolution: {integrity: sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==}
engines: {node: '>= 8.16.2'}
hasBin: true
dev: true
dev: false
/merge-stream/2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
@@ -1828,12 +1818,12 @@ packages:
/mousetrap/1.6.5:
resolution: {integrity: sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==}
dev: true
dev: false
/mri/1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'}
dev: true
dev: false
/ms/2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
@@ -2071,29 +2061,29 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/postcss-import/14.1.0_postcss@8.2.10:
/postcss-import/14.1.0_postcss@8.4.21:
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
engines: {node: '>=10.0.0'}
peerDependencies:
postcss: ^8.0.0
dependencies:
postcss: 8.2.10
postcss: 8.4.21
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.1
dev: true
/postcss-js/4.0.1_postcss@8.2.10:
/postcss-js/4.0.1_postcss@8.4.21:
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
engines: {node: ^12 || ^14 || >= 16}
peerDependencies:
postcss: ^8.4.21
dependencies:
camelcase-css: 2.0.1
postcss: 8.2.10
postcss: 8.4.21
dev: true
/postcss-load-config/3.1.4_postcss@8.2.10:
/postcss-load-config/3.1.4_postcss@8.4.21:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
peerDependencies:
@@ -2106,17 +2096,17 @@ packages:
optional: true
dependencies:
lilconfig: 2.0.6
postcss: 8.2.10
postcss: 8.4.21
yaml: 1.10.2
dev: true
/postcss-nested/6.0.0_postcss@8.2.10:
/postcss-nested/6.0.0_postcss@8.4.21:
resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.2.14
dependencies:
postcss: 8.2.10
postcss: 8.4.21
postcss-selector-parser: 6.0.11
dev: true
@@ -2132,18 +2122,18 @@ packages:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
dev: true
/postcss/8.2.10:
resolution: {integrity: sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw==}
/postcss/8.4.21:
resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
colorette: 1.4.0
nanoid: 3.3.4
source-map: 0.6.1
picocolors: 1.0.0
source-map-js: 1.0.2
dev: true
/preact/10.12.1:
resolution: {integrity: sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==}
dev: true
dev: false
/prepend-http/2.0.0:
resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==}
@@ -2154,7 +2144,7 @@ packages:
resolution: {integrity: sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==}
engines: {node: '>=0.8'}
hasBin: true
dev: true
dev: false
/protocols/1.4.8:
resolution: {integrity: sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==}
@@ -2393,7 +2383,7 @@ packages:
engines: {node: '>=6'}
dependencies:
mri: 1.2.0
dev: true
dev: false
/safe-buffer/5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
@@ -2462,6 +2452,11 @@ packages:
engines: {node: '>=8'}
dev: true
/source-map-js/1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
dev: true
/source-map/0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
@@ -2482,7 +2477,7 @@ packages:
engines: {node: '>=0.8'}
dependencies:
frac: 1.1.2
dev: true
dev: false
/strict-uri-encode/2.0.0:
resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==}
@@ -2516,7 +2511,7 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
is-utf8: 0.2.1
dev: true
dev: false
/strip-final-newline/2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
@@ -2558,7 +2553,7 @@ packages:
resolution: {integrity: sha512-/hIUHgKcFlewsQreq8v7DYNBkQe7rR0c94PNBOCsmeUwoIYAy6iXJ1pH0k3rWpjwZHKtUxeXbX1iRFlFhipbeg==}
dependencies:
mousetrap: 1.6.5
dev: true
dev: false
/svelte-hmr/0.14.12_svelte@3.37.0:
resolution: {integrity: sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==}
@@ -2582,9 +2577,9 @@ packages:
sade: 1.8.1
svelte: 3.37.0
tiny-glob: 0.2.9
dev: true
dev: false
/svelte-preprocess/4.7.0_kczdzg4a76p6bleo3ihutrynli:
/svelte-preprocess/4.7.0_3fnoivf624cjedq7eprmr6bhie:
resolution: {integrity: sha512-iNrY4YGqi0LD2e6oT9YbdSzOKntxk8gmzfqso1z/lUJOZh4o6fyIqkirmiZ8/dDJFqtIE1spVgDFWgkfhLEYlw==}
engines: {node: '>= 9.11.2'}
requiresBuild: true
@@ -2628,7 +2623,7 @@ packages:
'@types/pug': 2.0.6
'@types/sass': 1.43.1
detect-indent: 6.1.0
postcss: 8.2.10
postcss: 8.4.21
strip-indent: 3.0.0
svelte: 3.37.0
dev: true
@@ -2640,9 +2635,8 @@ packages:
/svelte/3.37.0:
resolution: {integrity: sha512-TRF30F4W4+d+Jr2KzUUL1j8Mrpns/WM/WacxYlo5MMb2E5Qy2Pk1Guj6GylxsW9OnKQl1tnF8q3hG/hQ3h6VUA==}
engines: {node: '>= 8'}
dev: true
/tailwindcss/3.2.7_postcss@8.2.10:
/tailwindcss/3.2.7_postcss@8.4.21:
resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==}
engines: {node: '>=12.13.0'}
hasBin: true
@@ -2663,11 +2657,11 @@ packages:
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.0.0
postcss: 8.2.10
postcss-import: 14.1.0_postcss@8.2.10
postcss-js: 4.0.1_postcss@8.2.10
postcss-load-config: 3.1.4_postcss@8.2.10
postcss-nested: 6.0.0_postcss@8.2.10
postcss: 8.4.21
postcss-import: 14.1.0_postcss@8.4.21
postcss-js: 4.0.1_postcss@8.4.21
postcss-load-config: 3.1.4_postcss@8.4.21
postcss-nested: 6.0.0_postcss@8.4.21
postcss-selector-parser: 6.0.11
postcss-value-parser: 4.2.0
quick-lru: 5.1.1
@@ -2680,16 +2674,16 @@ packages:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
dev: true
/tinro/0.6.1:
resolution: {integrity: sha512-fraFMuJeHfMC+xqGhCf30kn+lgrBk8aWcrWSO9aeKTgVYr8Ds3dVzV0JVTFla5GB22/jOqO74VHCvU6KGUhbZA==}
dev: true
/tinro/0.6.12:
resolution: {integrity: sha512-YYLh0a21GXXpS66ilZbywfXcPTKQQ+bv3tihoqKqSFQP6/F11N7ZmtRbFWcyZXXPFRSzNxmPJBB8ZhP0GkoS0Q==}
dev: false
/tiny-glob/0.2.9:
resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==}
dependencies:
globalyzer: 0.1.0
globrex: 0.1.2
dev: true
dev: false
/tmp/0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
@@ -2710,9 +2704,9 @@ packages:
is-number: 7.0.0
dev: true
/toastify-js/1.10.0:
resolution: {integrity: sha512-xuO499S1sw9gTdiBkZSMNE4sIoiQv/y0y534F7g2dcprVMAJZIdtOaphqiQlNJPfh0YQFDvgD4R3KcX5r94cAQ==}
dev: true
/toastify-js/1.12.0:
resolution: {integrity: sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ==}
dev: false
/tr46/0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
@@ -2724,7 +2718,7 @@ packages:
/tslib/2.5.0:
resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==}
dev: true
dev: false
/type-fest/0.20.2:
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
@@ -2814,10 +2808,10 @@ packages:
hasBin: true
dev: true
/validator/13.5.2:
resolution: {integrity: sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ==}
/validator/13.9.0:
resolution: {integrity: sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==}
engines: {node: '>= 0.10'}
dev: true
dev: false
/vite/2.1.5:
resolution: {integrity: sha512-tYU5iaYeUgQYvK/CNNz3tiJ8vYqPWfCE9IQ7K0iuzYovWw7lzty7KRYGWwV3CQPh0NKxWjOczAqiJsCL0Xb+Og==}
@@ -2825,7 +2819,7 @@ packages:
hasBin: true
dependencies:
esbuild: 0.9.7
postcss: 8.2.10
postcss: 8.4.21
resolve: 1.22.1
rollup: 2.79.1
optionalDependencies:
@@ -2874,12 +2868,12 @@ packages:
/wmf/1.0.2:
resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==}
engines: {node: '>=0.8'}
dev: true
dev: false
/word/0.3.0:
resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==}
engines: {node: '>=0.8'}
dev: true
dev: false
/wordwrap/1.0.0:
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
@@ -2927,7 +2921,7 @@ packages:
ssf: 0.11.2
wmf: 1.0.2
word: 0.3.0
dev: true
dev: false
/xtend/4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
@@ -2953,22 +2947,22 @@ packages:
engines: {node: '>=10'}
dev: true
/yargs-parser/20.2.9:
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
engines: {node: '>=10'}
/yargs-parser/21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
dev: true
/yargs/16.2.0:
resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
engines: {node: '>=10'}
/yargs/17.7.1:
resolution: {integrity: sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==}
engines: {node: '>=12'}
dependencies:
cliui: 7.0.4
cliui: 8.0.1
escalade: 3.1.1
get-caller-file: 2.0.5
require-directory: 2.1.1
string-width: 4.2.3
y18n: 5.0.8
yargs-parser: 20.2.9
yargs-parser: 21.1.1
dev: true
/yocto-queue/0.1.0:

File diff suppressed because one or more lines are too long

View File

@@ -1,125 +1,140 @@
<script>
import { getLocaleFromNavigator, _ } from "svelte-i18n";
import {
ScanService,
} from "@odit/lfk-client-js";
import { _ } from "svelte-i18n";
import { DataHandler, Datatable, Th, ThFilter } from "@vincjo/datatables";
import { ScanService } from "@odit/lfk-client-js";
import store from "../../store";
import Toastify from "toastify-js";
import ScansEmptyState from "./ScansEmptyState.svelte";
$: searchvalue = "";
import ThFilterRunner from "./ThFilterRunner.svelte";
$: active_deletes = [];
export let current_scans = [];
const handler = new DataHandler(current_scans, { rowsPerPage: 20 });
const rows = handler.getRows();
const scans_promise = ScanService.scanControllerGetAll().then((val) => {
current_scans = val;
handler.setRows(val);
});
function should_display_based_on_id(id) {
if (searchvalue.toString().slice(-1) === "*") {
return id.toString().startsWith(searchvalue.replace("*", ""));
function format_laptime(laptime) {
if (laptime == 0 || laptime == null) {
return $_("first-scan-of-the-day");
}
return id.toString() === searchvalue;
}
function format_laptime(laptime){
if(laptime == 0 || laptime == null){return $_('first-scan-of-the-day')}
if(laptime < 60){return `${laptime}s`}
if(laptime < 3600){return `${Math.floor(laptime / 60)}min ${laptime - (Math.floor(laptime / 60)*60)}s`}
return `${Math.floor(laptime / 3600)}h ${laptime - (Math.floor(laptime / 3600)*3600)}min ${laptime - (Math.floor(laptime / 3600)*3600) - (Math.floor(laptime / 60)*60)}`
if (laptime < 60) {
return `${laptime}s`;
}
if (laptime < 3600) {
return `${Math.floor(laptime / 60)}min ${
laptime - Math.floor(laptime / 60) * 60
}s`;
}
return `${Math.floor(laptime / 3600)}h ${
laptime - Math.floor(laptime / 3600) * 3600
}min ${
laptime -
Math.floor(laptime / 3600) * 3600 -
Math.floor(laptime / 60) * 60
}`;
}
</script>
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:GET')}
{#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:GET")}
{#await scans_promise}
<div
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
role="alert">
<p class="font-bold">{$_('scans-are-being-loaded')}</p>
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
role="alert"
>
<p class="font-bold">{$_("scans-are-being-loaded")}</p>
<p class="text-sm">{$_("this-might-take-a-moment")}</p>
</div>
{:then}
{#if current_scans.length === 0}
<ScansEmptyState />
{:else}
<input
type="search"
bind:value={searchvalue}
placeholder={$_('datatable.search')}
aria-label={$_('datatable.search')}
class="gridjs-input gridjs-search-input mb-4" />
<div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
<table class="divide-y divide-gray-200 w-full">
<thead class="bg-gray-50">
<tr>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('runner')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('distance-track')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('laptime')}
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{$_('status')}
</th>
<th scope="col" class="relative px-6 py-3">
<span class="sr-only">{$_('action')}</span>
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{#each current_scans as scan}
{#if scan.track?.name
.toLowerCase()
.includes(
searchvalue.toLowerCase()
) || scan.runner?.firstname
.toLowerCase()
.includes(
searchvalue.toLowerCase()
) || scan.runner?.lastname
.toLowerCase()
.includes(
searchvalue.toLowerCase()
) || should_display_based_on_id(scan.id)}
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"
>
<Datatable {handler}>
<table class="divide-y divide-gray-200 w-full">
<thead class="bg-gray-50">
<tr>
<Th {handler} orderBy="id">ID</Th>
<Th {handler}>
{$_("runner")}
</Th>
<Th {handler}>
{$_("distance")}
</Th>
<Th {handler}>
{$_("track")}
</Th>
<Th {handler}>
{$_("laptime")}
</Th>
<Th {handler}>
{$_("status")}
</Th>
<th
scope="col"
class="relative px-6 py-3"
style="border-bottom: 1px solid #ddd;"
>
{$_("action")}
</th>
</tr>
<tr>
<ThFilter {handler} filterBy="id" />
<ThFilterRunner {handler} />
<th style="border-bottom: 1px solid #ddd;" />
<th style="border-bottom: 1px solid #ddd;" />
<th style="border-bottom: 1px solid #ddd;" />
<th style="border-bottom: 1px solid #ddd;" />
<th style="border-bottom: 1px solid #ddd;" />
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{#each $rows as scan}
<tr data-rowid="scan_{scan.id}">
<td class="px-6 py-4 whitespace-nowrap text-left">
<div class="text-sm font-medium text-gray-900">
{scan.id}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<a
href="../runners/{scan.runner.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{scan.runner.firstname}
{scan.runner.middlename || ''}
{scan.runner.lastname}</a>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>{scan.runner.firstname}
{scan.runner.middlename || ""}
{scan.runner.lastname}</a
>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<td class="px-6 py-4 whitespace-nowrap text-left">
<div class="text-sm font-medium text-gray-900">
{#if scan.distance < 1000}
{scan.distance}m
{:else}{scan.distance / 1000}km{/if}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-left">
<div class="text-sm font-medium text-gray-900">
{#if scan.track}
<a
href="../tracks"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{scan.track.name}
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800"
>{scan.track.name}
</a>
{/if}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<td class="px-6 py-4 whitespace-nowrap text-left">
{#if scan.responseType === "TRACKSCAN"}
<div class="text-sm font-medium text-gray-900">
{format_laptime(scan.lapTime)}
</div>
{:else}
<div class="text-sm font-medium text-gray-900">
{$_('scan-with-fixed-distance')}
{$_("scan-with-fixed-distance")}
</div>
{/if}
</td>
@@ -127,23 +142,30 @@
<div class="flex items-center">
{#if scan.valid}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('valid')}</span>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"
>{$_("valid")}</span
>
{:else}
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('invalid')}</span>
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800"
>{$_("invalid")}</span
>
{/if}
</div>
</td>
{#if active_deletes[scan.id] === true}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
>
<button
on:click={() => {
active_deletes[scan.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer"
>{$_("cancel-delete")}</button
>
<button
on:click={() => {
ScanService.scanControllerRemove(scan.id, false).then(
@@ -152,44 +174,51 @@
(obj) => obj.id !== scan.id
);
Toastify({
text: 'Scan deleted',
text: "Scan deleted",
duration: 500,
backgroundColor:
'linear-gradient(to right, #00b09b, #96c93d)',
"linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
}
);
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
>{$_("confirm-delete")}</button
>
</td>
{:else}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"
>
<a
href="./{scan.id}"
class="text-indigo-600 hover:text-indigo-900">{$_('details')}</a>
{#if store.state.jwtinfo.userdetails.permissions.includes('SCAN:DELETE')}
class="text-indigo-600 hover:text-indigo-900"
>{$_("details")}</a
>
{#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:DELETE")}
<button
on:click={() => {
active_deletes[scan.id] = true;
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
>{$_("delete")}</button
>
{/if}
</td>
{/if}
</tr>
{/if}
{/each}
</tbody>
</table>
{/each}
</tbody>
</table>
</Datatable>
</div>
{/if}
{:catch error}
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
<span class="inline-block align-middle mr-8">
<b class="capitalize">{$_('general_promise_error')}</b>
<b class="capitalize">{$_("general_promise_error")}</b>
{error}
</span>
</div>

View File

@@ -0,0 +1,50 @@
<script>
export let handler;
let filterValue = "";
</script>
<th>
<input
on:input={() => {
setTimeout(() => {
const v = filterValue.toLowerCase();
handler.filter(v, (c) => {
if (v.startsWith("#")) {
return `#${c.runner?.id}`;
}
if (c.runner) {
let runnerName = `${c.runner.firstname} ${c.runner.lastname}`;
if (c.runner.middlename) {
runnerName = `${c.runner.firstname} ${c.runner.middlename} ${c.runner.lastname}`;
}
runnerName = runnerName.toLowerCase();
return runnerName;
}
return "";
});
}, 150);
}}
placeholder="Filter"
bind:value={filterValue}
type="text"
name="runnerfilter"
id="runnerfilter"
/>
</th>
<style>
th {
border-bottom: 1px solid #e0e0e0;
}
input {
margin: -1px 0 0 0;
padding: 0;
width: 100%;
height: 24px;
border: none;
text-align: left;
background: inherit;
outline: 0;
font-size: 14px;
}
</style>