From d8c79256c9ea93e61c48b1808e950892cd5d5321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Fri, 21 Apr 2023 12:08:35 +0200 Subject: [PATCH] feat: tests --- .c8rc.json | 5 + .mocharc.json | 5 + .pnpmfile.cjs | 33 +- backend/backend/package.json | 4 +- .../proxy/config/{default.ts => default.cjs} | 7 +- backend/proxy/package.json | 29 +- backend/proxy/src/app.ts | 14 +- backend/proxy/src/common.ts | 6 +- backend/proxy/src/main.ts | 21 +- backend/proxy/src/port-scanner.ts | 22 + backend/proxy/test/common.spec.ts | 41 +- .../test/containers/any-with-exposed-ports.ts | 44 ++ .../containers/backend-with-exposed-ports.ts | 52 ++ .../swarm-backend-with-exposed-ports.ts | 52 ++ backend/proxy/test/main.spec.ts | 405 +++--------- backend/proxy/tsconfig.json | 2 +- configuration/nyc-config/index.json | 17 +- configuration/projectmanagement/package.json | 16 +- configuration/projectmanagement/src/cli.ts | 4 +- .../projectmanagement/src/configuration.ts | 2 +- .../projectmanagement/src/tasks/remind.ts | 4 +- .../projectmanagement/src/tasks/report.ts | 4 +- .../projectmanagement/src/tasks/tidy.ts | 4 +- .../projectmanagement/src/tasks/unlabel.ts | 3 +- .../test/get-used-versions.spec.ts | 47 +- configuration/tsconfig/tsconfig.json | 5 +- examples/minimal-connector/package.json | 4 +- examples/minimal-plugin/package.json | 4 +- .../src/main/assets/capacitor.plugins.json | 136 ++-- .../AppIcon.appiconset/Contents.json | 154 ++--- .../ios/App/App/Assets.xcassets/Contents.json | 8 +- .../Splash.imageset/Contents.json | 28 +- frontend/app/package.json | 4 +- package.json | 3 +- packages/api/package.json | 9 +- packages/api/src/index.ts | 20 +- packages/api/test/bulk.spec.ts | 51 +- packages/api/test/client.spec.ts | 102 ++- packages/api/test/connector-client.spec.ts | 91 ++- packages/api/test/copy.spec.ts | 28 +- packages/api/test/e2e.spec.ts | 82 ++- packages/api/test/errors.spec.ts | 27 +- packages/api/test/http-client.spec.ts | 59 +- packages/api/test/plugin-client.spec.ts | 57 +- packages/api/test/plugin.spec.ts | 93 ++- packages/collection-utils/package.json | 13 +- packages/collection-utils/test/chunk.spec.ts | 3 +- .../collection-utils/test/difference.spec.ts | 2 +- packages/collection-utils/test/get.spec.ts | 2 +- .../collection-utils/test/group-by.spec.ts | 2 +- packages/collection-utils/test/key-by.spec.ts | 2 +- .../collection-utils/test/map-values.spec.ts | 2 +- packages/collection-utils/test/min.spec.ts | 2 +- packages/collection-utils/test/omit.spec.ts | 2 +- .../collection-utils/test/partition.spec.ts | 2 +- packages/collection-utils/test/pick.spec.ts | 2 +- .../collection-utils/test/shuffle.spec.ts | 2 +- .../collection-utils/test/string-sort.spec.ts | 2 +- packages/collection-utils/test/sum.spec.ts | 2 +- .../collection-utils/test/tree-group.spec.ts | 2 +- packages/collection-utils/test/uniq.spec.ts | 2 +- packages/collection-utils/test/zip.spec.ts | 2 +- packages/core-tools/README.md | 1 - packages/core-tools/package.json | 27 +- packages/core-tools/src/app.ts | 10 +- packages/core-tools/src/common.ts | 25 +- packages/core-tools/src/index.ts | 16 +- packages/core-tools/src/routes.ts | 6 +- packages/core-tools/src/schema.ts | 4 +- packages/core-tools/src/types/re2.ts | 6 - packages/core-tools/src/uml/create-diagram.ts | 19 +- packages/core-tools/src/util/collections.ts | 2 +- packages/core-tools/src/validate.ts | 45 +- packages/core-tools/test/common.spec.ts | 18 +- .../core-tools/test/create-diagram.spec.ts | 73 +-- packages/core-tools/test/schema.spec.ts | 19 +- packages/core-tools/test/validate.spec.ts | 66 +- packages/core/package.json | 21 +- packages/core/src/translator.ts | 2 +- packages/core/test/compat.spec.ts | 36 +- packages/core/test/dummy/building.ts | 33 + packages/core/test/dummy/bulk-response.ts | 9 + .../dish-with-translation-search-response.ts | 25 + .../core/test/dummy/dish-with-translation.ts | 17 + packages/core/test/dummy/dish.ts | 35 ++ packages/core/test/dummy/not-a-dish.ts | 13 + packages/core/test/dummy/setting.ts | 18 + packages/core/test/features.spec.ts | 98 +-- packages/core/test/guards.spec.ts | 195 +++--- packages/core/test/routes.spec.ts | 74 +-- packages/core/test/schema.spec.ts | 41 +- packages/core/test/translator.spec.ts | 425 +++++-------- packages/core/test/type.spec.ts | 59 +- packages/easy-ast/package.json | 20 +- packages/easy-ast/src/ast-internal-util.ts | 4 +- packages/easy-ast/src/easy-ast.ts | 42 +- packages/easy-ast/src/index.ts | 20 +- packages/easy-ast/src/util.ts | 41 +- packages/easy-ast/test/easy-ast-spec-type.ts | 2 +- packages/easy-ast/test/index.spec.ts | 48 ++ packages/easy-ast/test/index.ts | 35 -- .../test/{ => project}/alias-like.ast-test.ts | 6 +- .../test/{ => project}/array-like.ast-test.ts | 8 +- .../test/{ => project}/class-like.ast-test.ts | 6 +- .../test/{ => project}/comment.ast-test.ts | 7 +- .../default-generics.ast-test.ts | 5 +- .../enum-specified-value.ast-test.ts | 6 +- .../test/{ => project}/generics.ast-test.ts | 5 +- .../{ => project}/index-signature.ast-test.ts | 6 +- .../test/{ => project}/ineritance.ast-test.ts | 5 +- .../test/{ => project}/nested.ast-test.ts | 5 +- .../{ => project}/primitive-types.ast-test.ts | 5 +- .../{ => project}/stack-overflow.ast-test.ts | 5 +- packages/es-mapping-generator/package.json | 9 +- packages/es-mapping-generator/src/app.ts | 6 +- .../src/config/typemap.ts | 2 +- packages/es-mapping-generator/src/index.ts | 16 +- packages/es-mapping-generator/src/mapping.ts | 12 +- .../test/aggregations.spec.ts | 5 +- .../mappings/src/any-unknown.mapping-test.ts | 1 - .../src/tags-ignore-case.mapping-test.ts | 2 +- .../es-mapping-generator/test/mapping.spec.ts | 5 +- packages/gitlab-api/package.json | 4 +- packages/gitlab-api/src/api.ts | 2 +- .../logger/.gitlab/issue_templates/bug.md | 32 - packages/logger/package.json | 16 +- packages/logger/src/index.ts | 16 +- .../logger/src/transformations/colorize.ts | 5 +- packages/logger/test/common.spec.ts | 53 +- .../{dummyTransport.ts => dummy-transport.ts} | 2 +- packages/logger/test/logger.spec.ts | 227 +++---- packages/logger/test/smtp.spec.ts | 124 ++-- .../transformations/add-log-level.spec.ts | 13 +- .../test/transformations/colorize.spec.ts | 20 +- .../test/transformations/timestamp.spec.ts | 13 +- packages/logger/test/transport.spec.ts | 24 +- pnpm-lock.yaml | 587 +++++------------- prettier.config.cjs | 3 + sync.mjs | 15 +- turbo.json | 6 +- 140 files changed, 2100 insertions(+), 2693 deletions(-) create mode 100644 .c8rc.json create mode 100644 .mocharc.json rename backend/proxy/config/{default.ts => default.cjs} (86%) create mode 100644 backend/proxy/src/port-scanner.ts create mode 100644 backend/proxy/test/containers/any-with-exposed-ports.ts create mode 100644 backend/proxy/test/containers/backend-with-exposed-ports.ts create mode 100644 backend/proxy/test/containers/swarm-backend-with-exposed-ports.ts delete mode 100644 packages/core-tools/src/types/re2.ts create mode 100644 packages/core/test/dummy/building.ts create mode 100644 packages/core/test/dummy/bulk-response.ts create mode 100644 packages/core/test/dummy/dish-with-translation-search-response.ts create mode 100644 packages/core/test/dummy/dish-with-translation.ts create mode 100644 packages/core/test/dummy/dish.ts create mode 100644 packages/core/test/dummy/not-a-dish.ts create mode 100644 packages/core/test/dummy/setting.ts create mode 100644 packages/easy-ast/test/index.spec.ts delete mode 100644 packages/easy-ast/test/index.ts rename packages/easy-ast/test/{ => project}/alias-like.ast-test.ts (90%) rename packages/easy-ast/test/{ => project}/array-like.ast-test.ts (89%) rename packages/easy-ast/test/{ => project}/class-like.ast-test.ts (89%) rename packages/easy-ast/test/{ => project}/comment.ast-test.ts (94%) rename packages/easy-ast/test/{ => project}/default-generics.ast-test.ts (91%) rename packages/easy-ast/test/{ => project}/enum-specified-value.ast-test.ts (90%) rename packages/easy-ast/test/{ => project}/generics.ast-test.ts (92%) rename packages/easy-ast/test/{ => project}/index-signature.ast-test.ts (91%) rename packages/easy-ast/test/{ => project}/ineritance.ast-test.ts (92%) rename packages/easy-ast/test/{ => project}/nested.ast-test.ts (91%) rename packages/easy-ast/test/{ => project}/primitive-types.ast-test.ts (94%) rename packages/easy-ast/test/{ => project}/stack-overflow.ast-test.ts (90%) delete mode 100644 packages/logger/.gitlab/issue_templates/bug.md rename packages/logger/test/{dummyTransport.ts => dummy-transport.ts} (90%) create mode 100644 prettier.config.cjs diff --git a/.c8rc.json b/.c8rc.json new file mode 100644 index 00000000..00d36aa2 --- /dev/null +++ b/.c8rc.json @@ -0,0 +1,5 @@ +{ + "all": true, + "src": "./src", + "reporter": ["text", "text-summary", "cobertura", "html"] +} diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 00000000..f9f45ca2 --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,5 @@ +{ + "extension": ["ts"], + "node-option": ["loader=ts-node/esm"], + "spec": ["test/**/*.spec.ts"] +} diff --git a/.pnpmfile.cjs b/.pnpmfile.cjs index 21e7fc6b..f83d4d26 100644 --- a/.pnpmfile.cjs +++ b/.pnpmfile.cjs @@ -1,33 +1,18 @@ const path = require("path"); const merge = require("deepmerge"); +const additionalDeps = { + '@openstapps/eslint-config': require('./configuration/eslint-config/package.json'), + '@openstapps/prettier-config': require('./configuration/prettier-config/package.json'), +} + function readPackage(pkg, context) { - const eslintDeps = require('./configuration/eslint-config/package.json').peerDependencies; - const prettierDeps = require('./configuration/prettier-config/package.json').peerDependencies; - - pkg.devDependencies = { - ...eslintDeps, - ...prettierDeps, - ...(pkg.devDependencies || {}), + for (const dep in additionalDeps) { + if (dep in pkg.devDependencies) { + Object.assign(pkg.devDependencies, additionalDeps[dep].peerDependencies) + } } - // const targetConfig = defaultConfig - // .provideFields - // ?.map(it => it.split('.')) - // .reduce((acc, curr) => { - // let target = acc; - // let from = defaultConfig; - // for (const fragment of curr.slice(0, -1)) { - // target[fragment] = target[fragment] || {} - // target = target[fragment] - // from = from[fragment] - // } - // const fragment = curr[curr.length - 1] - // target[fragment] = from[fragment]; - // return acc; - // }, {}) ?? {} - // return merge(targetConfig, pkg); - return pkg } diff --git a/backend/backend/package.json b/backend/backend/package.json index a9579f7e..7e24b74f 100644 --- a/backend/backend/package.json +++ b/backend/backend/package.json @@ -20,8 +20,8 @@ "scripts": { "build": "tsup --dts", "dev": "tsup --watch", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", "start": "NODE_CONFIG_ENV=elasticsearch ALLOW_NO_TRANSPORT=true node ./lib/cli.js", diff --git a/backend/proxy/config/default.ts b/backend/proxy/config/default.cjs similarity index 86% rename from backend/proxy/config/default.ts rename to backend/proxy/config/default.cjs index 4502f0d1..0a57e657 100644 --- a/backend/proxy/config/default.ts +++ b/backend/proxy/config/default.cjs @@ -13,9 +13,10 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import {ConfigFile} from '../src/common.js'; -const config: ConfigFile = { +// ESM is not supported, and cts is not detected, so we use type-checked cjs instead. +/** @type {import('../src/common').ConfigFile} */ +const configFile = { activeVersions: ['1\\.0\\.\\d+', '2\\.0\\.\\d+'], hiddenRoutes: ['/bulk'], logFormat: 'default', @@ -31,4 +32,4 @@ const config: ConfigFile = { }, }; -export default config; +export default configFile; diff --git a/backend/proxy/package.json b/backend/proxy/package.json index 5588aa69..7f5d0e78 100644 --- a/backend/proxy/package.json +++ b/backend/proxy/package.json @@ -17,11 +17,11 @@ "bin": "app.js", "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", - "test": "nyc mocha 'test/**/*.spec.ts'" + "test": "c8 mocha" }, "dependencies": { "@openstapps/logger": "workspace:*", @@ -33,38 +33,36 @@ "dockerode": "3.3.5", "is-cidr": "4.0.2", "mustache": "4.2.0", - "node-port-scanner": "3.0.1", - "semver": "7.3.8" + "semver": "7.3.8", + "typescript": "4.8.4" }, "devDependencies": { "@openstapps/eslint-config": "workspace:*", "@openstapps/nyc-config": "workspace:*", "@openstapps/prettier-config": "workspace:*", "@openstapps/tsconfig": "workspace:*", - "@testdeck/mocha": "0.3.3", "@types/chai": "4.3.5", - "@types/chai-spies": "1.0.3", + "@types/sinon-chai": "3.2.9", "@types/config": "3.3.0", + "@types/sinon": "10.0.14", "@types/dockerode": "3.3.14", "@types/mustache": "4.2.2", + "@types/mocha": "10.0.1", "@types/node": "18.15.3", "@types/proxyquire": "1.3.28", "@types/semver": "7.3.13", "@types/sha1": "1.1.3", "chai": "4.3.7", - "chai-spies": "1.0.0", + "sinon": "15.0.4", + "sinon-chai": "3.7.0", "mocha": "10.2.0", - "nyc": "15.1.0", - "proxyquire": "2.1.3", - "rimraf": "3.0.2", + "c8": "7.13.0", "ts-node": "10.9.1", "tsup": "6.7.0", - "typedoc": "0.23.28", - "typescript": "4.8.4" + "typedoc": "0.23.28" }, "tsup": { "entry": [ - "src/app.ts", "src/app.ts" ], "sourcemap": true, @@ -77,8 +75,5 @@ "extends": [ "@openstapps" ] - }, - "nyc": { - "extends": "@openstapps/nyc-config" } } diff --git a/backend/proxy/src/app.ts b/backend/proxy/src/app.ts index e627593d..c5a44a73 100644 --- a/backend/proxy/src/app.ts +++ b/backend/proxy/src/app.ts @@ -15,10 +15,11 @@ */ import {Logger} from '@openstapps/logger'; import {execSync} from 'child_process'; -import * as Dockerode from 'dockerode'; +import type {ContainerInfo} from 'dockerode'; import mustache from 'mustache'; -import {asyncReadFile, asyncWriteFile} from './common.js'; import {getContainers, getTemplateView} from './main.js'; +import {readFile, writeFile} from 'fs/promises'; +import {configFile} from './common.js'; /* eslint-disable unicorn/prefer-module */ @@ -39,14 +40,11 @@ async function updateNginxConfig() { const containers = await getContainers(); const containerHash = containers - .map((container: Dockerode.ContainerInfo) => { + .map((container: ContainerInfo) => { return container.Id; }) .join(','); - delete require.cache[require.resolve('config')]; - // eslint-disable-next-line @typescript-eslint/no-var-requires - const configFile = require('config'); const configHash = JSON.stringify(configFile); // if containers changed -> write config file, reload nginx @@ -57,7 +55,7 @@ async function updateNginxConfig() { // render nginx config file const nginxConfig = mustache.render( - await asyncReadFile('nginx.conf.template', 'utf8'), + await readFile('nginx.conf.template', 'utf8'), await getTemplateView(containers), ); @@ -67,7 +65,7 @@ async function updateNginxConfig() { Logger.log(`Writing new config file "${configFile.output}"`); // overwrite nginx config file with our rendered one - await asyncWriteFile(configFile.output, nginxConfig, 'utf8'); + await writeFile(configFile.output, nginxConfig, 'utf8'); Logger.log('Executing "nginx -s reload" to tell nginx to reload the configuration file'); diff --git a/backend/proxy/src/common.ts b/backend/proxy/src/common.ts index b72ebb98..528b6cb6 100644 --- a/backend/proxy/src/common.ts +++ b/backend/proxy/src/common.ts @@ -15,15 +15,11 @@ */ import {Logger, SMTP} from '@openstapps/logger'; import config from 'config'; -import {existsSync, readFile, writeFile} from 'fs'; -import {promisify} from 'util'; +import {existsSync} from 'fs'; // set transport on logger Logger.setTransport(SMTP.getInstance()); -export const asyncReadFile = promisify(readFile); -export const asyncWriteFile = promisify(writeFile); - /** * A representation of the file paths of the needed ssl certificates */ diff --git a/backend/proxy/src/main.ts b/backend/proxy/src/main.ts index 5a85aaf7..73972b72 100644 --- a/backend/proxy/src/main.ts +++ b/backend/proxy/src/main.ts @@ -20,8 +20,7 @@ import mustache from 'mustache'; import path from 'path'; import * as semver from 'semver'; import { - asyncReadFile, - ConfigFile, + configFile, isFileType, protocolHardeningParameters, SSLFilePaths, @@ -29,10 +28,9 @@ import { SupportedLogFormats, TemplateView, } from './common.js'; -// @ts-expect-error missing type defs -import nodePortScanner from 'node-port-scanner'; +import {readFile} from 'fs/promises'; +import PortScanner from './port-scanner.js'; -/* eslint-disable unicorn/prefer-module */ /* eslint-disable unicorn/no-await-expression-member */ /** @@ -90,9 +88,7 @@ Please expose a port if the container should be accessible by NGINX.`); // Get a routable network connection for (const network in container.NetworkSettings.Networks) { - const scan = await nodePortScanner(container.NetworkSettings.Networks[network].IPAddress, [port]); - - if ((scan.ports.open as Array).includes(port)) { + if (await PortScanner.isPortFree(port, container.NetworkSettings.Networks[network].IPAddress)) { Logger.info( `${container.Names[0]} reachable via ${container.NetworkSettings.Networks[network].IPAddress}:${port}`, ); @@ -260,7 +256,7 @@ export async function generateMetricsServer(logFormat: string, enableMetrics?: b * @param view Data to render template with */ async function renderTemplate(path: string, view: unknown): Promise { - const content = await asyncReadFile(path, 'utf8'); + const content = await readFile(path, 'utf8'); return mustache.render(content, view); } @@ -283,12 +279,7 @@ function generateRateLimitAllowList(entries: string[]): string { * @param containers List of container info */ export async function getTemplateView(containers: Dockerode.ContainerInfo[]): Promise { - delete require.cache[require.resolve('config')]; - // eslint-disable-next-line @typescript-eslint/no-var-requires - const config = require('config'); - const configFile = config as ConfigFile; - - const cors = await asyncReadFile('./fixtures/cors.template', 'utf8'); + const cors = await readFile('./fixtures/cors.template', 'utf8'); const visibleRoutesPromises = ['/'].map(async route => { return renderTemplate(path.join('fixtures', 'visibleRoute.template'), { diff --git a/backend/proxy/src/port-scanner.ts b/backend/proxy/src/port-scanner.ts new file mode 100644 index 00000000..661fe884 --- /dev/null +++ b/backend/proxy/src/port-scanner.ts @@ -0,0 +1,22 @@ +import {createServer, Server} from 'net'; + +/** + * Checks if a port is in use + */ +async function isPortFree(port: number, hostname?: string): Promise { + return new Promise((resolve, reject) => { + const server: Server = createServer() + .once('error', error => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if ((error as any).code === 'EADDRINUSE') { + resolve(true); + } else { + reject(error); + } + }) + .once('listening', () => server.once('close', () => resolve(false)).close()) + .listen(port, hostname); + }); +} + +export default {isPortFree}; diff --git a/backend/proxy/test/common.spec.ts b/backend/proxy/test/common.spec.ts index 89d4ba2c..82085a05 100644 --- a/backend/proxy/test/common.spec.ts +++ b/backend/proxy/test/common.spec.ts @@ -13,17 +13,12 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -// tslint:disable:no-implicit-dependencies -// tslint:disable:no-magic-numbers -// tslint:disable:completed-docs -// tslint:disable:prefer-function-over-method -// tslint:disable:newline-per-chained-call -import {suite, test} from '@testdeck/mocha'; import {Logger} from '@openstapps/logger'; import {expect} from 'chai'; import {mkdirSync, writeFileSync, unlinkSync, rmdirSync} from 'fs'; -import {resolve} from 'path'; +import path from 'path'; import {isFileType} from '../src/common.js'; +import {fileURLToPath} from 'url'; process.on('unhandledRejection', async error => { await Logger.error(error); @@ -31,22 +26,20 @@ process.on('unhandledRejection', async error => { process.exit(1); }); -@suite -export class CommonSpec { - @test - async testSSLCert() { - const testCertDir = resolve(__dirname, 'certs'); - mkdirSync(testCertDir); - const notAnExptectedFileTypeFilePath = resolve(testCertDir, 'notAnExptectedFileType.txt'); - const anExptectedFileTypeFilePath = resolve(testCertDir, 'notARealCert.crt'); - writeFileSync(notAnExptectedFileTypeFilePath, 'Test'); - writeFileSync(anExptectedFileTypeFilePath, 'Test'); +describe('common', function () { + it('should use ssl certs', function () { + const testCertDirectory = path.resolve(path.dirname(fileURLToPath(import.meta.url)), 'certs'); + mkdirSync(testCertDirectory); + const notAnExpectedFileTypeFilePath = path.resolve(testCertDirectory, 'notAnExpectedFileType.txt'); + const anExpectedFileTypeFilePath = path.resolve(testCertDirectory, 'notARealCert.crt'); + writeFileSync(notAnExpectedFileTypeFilePath, 'Test'); + writeFileSync(anExpectedFileTypeFilePath, 'Test'); - expect(isFileType(notAnExptectedFileTypeFilePath, 'crt')).to.equal(false); - expect(isFileType(anExptectedFileTypeFilePath, 'crt')).to.equal(true); + expect(isFileType(notAnExpectedFileTypeFilePath, 'crt')).to.equal(false); + expect(isFileType(anExpectedFileTypeFilePath, 'crt')).to.equal(true); - unlinkSync(notAnExptectedFileTypeFilePath); - unlinkSync(anExptectedFileTypeFilePath); - rmdirSync(testCertDir); - } -} + unlinkSync(notAnExpectedFileTypeFilePath); + unlinkSync(anExpectedFileTypeFilePath); + rmdirSync(testCertDirectory); + }); +}); diff --git a/backend/proxy/test/containers/any-with-exposed-ports.ts b/backend/proxy/test/containers/any-with-exposed-ports.ts new file mode 100644 index 00000000..2b9cf70c --- /dev/null +++ b/backend/proxy/test/containers/any-with-exposed-ports.ts @@ -0,0 +1,44 @@ +/* eslint-disable unicorn/no-null */ +import type {ContainerInfo} from 'dockerode'; + +export const anyContainerWithExposedPorts: ContainerInfo = { + Command: 'sh', + Created: 1_524_669_882, + HostConfig: { + NetworkMode: 'default', + }, + Id: 'e3d3f4d18aceac2780bdb95523845d066ed25c04fc65168a5ddbd37a85671bb7', + Image: 'ubuntu:4', + ImageID: 'sha256:ef9f0c8c4b6f99dd208948c7aae1d042590aa18e05ebeae4f586e4b4beebeac9', + Labels: {}, + Mounts: [], + Names: ['/container_name_1'], + NetworkSettings: { + Networks: { + bridge: { + Aliases: null, + EndpointID: 'da17549a086ff2c9f622e80de833e6f334afda52c8f07080428640c1716dcd14', + Gateway: '172.18.0.1', + GlobalIPv6Address: '', + GlobalIPv6PrefixLen: 0, + IPAMConfig: null, + IPAddress: '172.18.0.3', + IPPrefixLen: 16, + IPv6Gateway: '', + Links: null, + MacAddress: '03:41:ac:11:00:23', + NetworkID: '947ea5247cc7429e1fdebd5404fa4d15f7c05e6765f2b93ddb3bdb6aaffd1193', + }, + }, + }, + Ports: [ + { + IP: '0.0.0.0', + PrivatePort: 80, + PublicPort: 80, + Type: 'tcp', + }, + ], + State: 'running', + Status: 'Up 3 minutes', +}; diff --git a/backend/proxy/test/containers/backend-with-exposed-ports.ts b/backend/proxy/test/containers/backend-with-exposed-ports.ts new file mode 100644 index 00000000..8889be0d --- /dev/null +++ b/backend/proxy/test/containers/backend-with-exposed-ports.ts @@ -0,0 +1,52 @@ +/* eslint-disable unicorn/no-null */ +import type {ContainerInfo} from 'dockerode'; + +export const backendContainerWithExposedPorts: ContainerInfo = { + Command: 'node ./bin/www', + Created: 1_524_669_882, + HostConfig: { + NetworkMode: 'deployment_default', + }, + Id: 'e3d3f4d18aceac2780bdb95523845d066ed25c04fc65168a5ddbd37a85671bb7', + Image: 'registry.gitlab.com/openstapps/backend/b-tu-typescript-refactor-for-new-tslint-config', + ImageID: 'sha256:ef9f0c8c4b6f99dd208948c7aae1d042590aa18e05ebeae4f586e4b4beebeac9', + Labels: { + 'com.docker.compose.config-hash': '91c6e0cebad15951824162c93392b6880b69599692f07798ae8de659c1616a03', + 'com.docker.compose.container-number': '1', + 'com.docker.compose.oneoff': 'False', + 'com.docker.compose.project': 'deployment', + 'com.docker.compose.service': 'backend', + 'com.docker.compose.version': '1.21.0', + 'stapps.version': '1.0.0', + }, + Mounts: [], + Names: ['/deployment_backend_1'], + NetworkSettings: { + Networks: { + deployment_default: { + Aliases: null, + EndpointID: 'da17549a086ff2c9f622e80de833e6f334afda52c8f07080428640c1716dcd14', + Gateway: '172.18.0.1', + GlobalIPv6Address: '', + GlobalIPv6PrefixLen: 0, + IPAMConfig: null, + IPAddress: '172.18.0.3', + IPPrefixLen: 16, + IPv6Gateway: '', + Links: null, + MacAddress: '03:41:ac:11:00:23', + NetworkID: '947ea5247cc7429e1fdebd5404fa4d15f7c05e6765f2b93ddb3bdb6aaffd1193', + }, + }, + }, + Ports: [ + { + IP: '127.0.0.1', + PrivatePort: 3000, + PublicPort: 3000, + Type: 'tcp', + }, + ], + State: 'running', + Status: 'Up 3 minutes', +}; diff --git a/backend/proxy/test/containers/swarm-backend-with-exposed-ports.ts b/backend/proxy/test/containers/swarm-backend-with-exposed-ports.ts new file mode 100644 index 00000000..2903619e --- /dev/null +++ b/backend/proxy/test/containers/swarm-backend-with-exposed-ports.ts @@ -0,0 +1,52 @@ +/* eslint-disable unicorn/no-null */ +import type {ContainerInfo} from 'dockerode'; + +export const swarmBackendContainerWithExposedPorts: ContainerInfo = { + Command: 'node ./bin/www', + Created: 1_524_669_882, + HostConfig: { + NetworkMode: 'swarm_default', + }, + Id: 'e3d3f4d18aceac2780bdb95523845d066ed25c04fc65168a5ddbd37a85671bb7', + Image: 'registry.gitlab.com/openstapps/backend/b-tu-typescript-refactor-for-new-tslint-config', + ImageID: 'sha256:ef9f0c8c4b6f99dd208948c7aae1d042590aa18e05ebeae4f586e4b4beebeac9', + Labels: { + 'com.docker.compose.config-hash': '91c6e0cebad15951824162c93392b6880b69599692f07798ae8de659c1616a03', + 'com.docker.compose.container-number': '1', + 'com.docker.compose.oneoff': 'False', + 'com.docker.stack.namespace': 'deployment', + 'com.docker.swarm.service.name': 'deployment_backend', + 'com.docker.compose.version': '1.21.0', + 'stapps.version': '1.0.0', + }, + Mounts: [], + Names: ['/deployment_backend_1'], + NetworkSettings: { + Networks: { + ingress: { + Aliases: null, + EndpointID: 'da17549a086ff2c9f622e80de833e6f334afda52c8f07080428640c1716dcd14', + Gateway: '172.18.0.1', + GlobalIPv6Address: '', + GlobalIPv6PrefixLen: 0, + IPAMConfig: null, + IPAddress: '172.18.0.3', + IPPrefixLen: 16, + IPv6Gateway: '', + Links: null, + MacAddress: '03:41:ac:11:00:23', + NetworkID: '947ea5247cc7429e1fdebd5404fa4d15f7c05e6765f2b93ddb3bdb6aaffd1193', + }, + }, + }, + Ports: [ + { + IP: 'delete me', + PrivatePort: 3000, + PublicPort: 3000, + Type: 'tcp', + }, + ], + State: 'running', + Status: 'Up 3 minutes', +}; diff --git a/backend/proxy/test/main.spec.ts b/backend/proxy/test/main.spec.ts index a194f1e0..84a22aca 100644 --- a/backend/proxy/test/main.spec.ts +++ b/backend/proxy/test/main.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ /* * Copyright (C) 2019 StApps * This program is free software: you can redistribute it and/or modify @@ -13,18 +14,16 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -// tslint:disable:no-implicit-dependencies -// tslint:disable:no-magic-numbers -// tslint:disable:completed-docs -// tslint:disable:prefer-function-over-method -// tslint:disable:newline-per-chained-call import {Logger} from '@openstapps/logger'; import chai from 'chai'; import {expect} from 'chai'; -import chaiSpies from 'chai-spies'; import {ContainerInfo} from 'dockerode'; -import {slow, suite, test, timeout} from '@testdeck/mocha'; -import {sslHardeningParameters, protocolHardeningParameters, SSLFilePaths} from './../src/common.js'; +import { + sslHardeningParameters, + protocolHardeningParameters, + SSLFilePaths, + configFile, +} from './../src/common.js'; import { containerMatchesRegex, generateUpstreamMap, @@ -34,11 +33,15 @@ import { generateMetricsServer, getContainers, } from '../src/main.js'; -import {resolve} from 'path'; +import path from 'path'; import {mkdirSync, writeFileSync, unlinkSync, rmdirSync} from 'fs'; -import proxyquire from 'proxyquire'; - -proxyquire.callThru().preserveCache(); +import {anyContainerWithExposedPorts} from './containers/any-with-exposed-ports.js'; +import {backendContainerWithExposedPorts} from './containers/backend-with-exposed-ports.js'; +import {swarmBackendContainerWithExposedPorts} from './containers/swarm-backend-with-exposed-ports.js'; +import {fileURLToPath} from 'url'; +import sinon from 'sinon'; +import sinonChai from 'sinon-chai'; +import portScannerModule from '../src/port-scanner.js'; process.on('unhandledRejection', async error => { await Logger.error(error); @@ -47,196 +50,47 @@ process.on('unhandledRejection', async error => { }); chai.should(); -chai.use(chaiSpies); +chai.use(sinonChai); -@suite(timeout(1000), slow(500)) -export class MainSpec { - static 'anyContainerWithExposedPorts': ContainerInfo = { - Command: 'sh', - Created: 1_524_669_882, - HostConfig: { - NetworkMode: 'default', - }, - Id: 'e3d3f4d18aceac2780bdb95523845d066ed25c04fc65168a5ddbd37a85671bb7', - Image: 'ubuntu:4', - ImageID: 'sha256:ef9f0c8c4b6f99dd208948c7aae1d042590aa18e05ebeae4f586e4b4beebeac9', - Labels: {}, - Mounts: [], - Names: ['/container_name_1'], - NetworkSettings: { - Networks: { - bridge: { - Aliases: null, - EndpointID: 'da17549a086ff2c9f622e80de833e6f334afda52c8f07080428640c1716dcd14', - Gateway: '172.18.0.1', - GlobalIPv6Address: '', - GlobalIPv6PrefixLen: 0, - IPAMConfig: null, - IPAddress: '172.18.0.3', - IPPrefixLen: 16, - IPv6Gateway: '', - Links: null, - MacAddress: '03:41:ac:11:00:23', - NetworkID: '947ea5247cc7429e1fdebd5404fa4d15f7c05e6765f2b93ddb3bdb6aaffd1193', - }, - }, - }, - Ports: [ - { - IP: '0.0.0.0', - PrivatePort: 80, - PublicPort: 80, - Type: 'tcp', - }, - ], - State: 'running', - Status: 'Up 3 minutes', - }; +console.log(configFile); - static 'backendContainerWithExposedPorts': ContainerInfo = { - Command: 'node ./bin/www', - Created: 1524669882, - HostConfig: { - NetworkMode: 'deployment_default', - }, - Id: 'e3d3f4d18aceac2780bdb95523845d066ed25c04fc65168a5ddbd37a85671bb7', - Image: 'registry.gitlab.com/openstapps/backend/b-tu-typescript-refactor-for-new-tslint-config', - ImageID: 'sha256:ef9f0c8c4b6f99dd208948c7aae1d042590aa18e05ebeae4f586e4b4beebeac9', - Labels: { - 'com.docker.compose.config-hash': '91c6e0cebad15951824162c93392b6880b69599692f07798ae8de659c1616a03', - 'com.docker.compose.container-number': '1', - 'com.docker.compose.oneoff': 'False', - 'com.docker.compose.project': 'deployment', - 'com.docker.compose.service': 'backend', - 'com.docker.compose.version': '1.21.0', - 'stapps.version': '1.0.0', - }, - Mounts: [], - Names: ['/deployment_backend_1'], - NetworkSettings: { - Networks: { - deployment_default: { - Aliases: null, - EndpointID: 'da17549a086ff2c9f622e80de833e6f334afda52c8f07080428640c1716dcd14', - Gateway: '172.18.0.1', - GlobalIPv6Address: '', - GlobalIPv6PrefixLen: 0, - IPAMConfig: null, - IPAddress: '172.18.0.3', - IPPrefixLen: 16, - IPv6Gateway: '', - Links: null, - MacAddress: '03:41:ac:11:00:23', - NetworkID: '947ea5247cc7429e1fdebd5404fa4d15f7c05e6765f2b93ddb3bdb6aaffd1193', - }, - }, - }, - Ports: [ - { - IP: '127.0.0.1', - PrivatePort: 3000, - PublicPort: 3000, - Type: 'tcp', - }, - ], - State: 'running', - Status: 'Up 3 minutes', - }; +describe('main', function () { + this.timeout(1000); + this.slow(500); - static 'swarmBackendContainerWithExposedPorts': ContainerInfo = { - Command: 'node ./bin/www', - Created: 1524669882, - HostConfig: { - NetworkMode: 'swarm_default', - }, - Id: 'e3d3f4d18aceac2780bdb95523845d066ed25c04fc65168a5ddbd37a85671bb7', - Image: 'registry.gitlab.com/openstapps/backend/b-tu-typescript-refactor-for-new-tslint-config', - ImageID: 'sha256:ef9f0c8c4b6f99dd208948c7aae1d042590aa18e05ebeae4f586e4b4beebeac9', - Labels: { - 'com.docker.compose.config-hash': '91c6e0cebad15951824162c93392b6880b69599692f07798ae8de659c1616a03', - 'com.docker.compose.container-number': '1', - 'com.docker.compose.oneoff': 'False', - 'com.docker.stack.namespace': 'deployment', - 'com.docker.swarm.service.name': 'deployment_backend', - 'com.docker.compose.version': '1.21.0', - 'stapps.version': '1.0.0', - }, - Mounts: [], - Names: ['/deployment_backend_1'], - NetworkSettings: { - Networks: { - ingress: { - Aliases: null, - EndpointID: 'da17549a086ff2c9f622e80de833e6f334afda52c8f07080428640c1716dcd14', - Gateway: '172.18.0.1', - GlobalIPv6Address: '', - GlobalIPv6PrefixLen: 0, - IPAMConfig: null, - IPAddress: '172.18.0.3', - IPPrefixLen: 16, - IPv6Gateway: '', - Links: null, - MacAddress: '03:41:ac:11:00:23', - NetworkID: '947ea5247cc7429e1fdebd5404fa4d15f7c05e6765f2b93ddb3bdb6aaffd1193', - }, - }, - }, - Ports: [ - { - IP: 'delete me', - PrivatePort: 3000, - PublicPort: 3000, - Type: 'tcp', - }, - ], - State: 'running', - Status: 'Up 3 minutes', - }; + const sandbox = sinon.createSandbox(); - static 'sandbox' = chai.spy.sandbox(); + beforeEach(function () { + sandbox.restore(); + }); - 'before'() { - MainSpec.sandbox.restore(); - } + it('should check if container does not match any container', function () { + expect(containerMatchesRegex('anyName', new RegExp('d+'), anyContainerWithExposedPorts)).to.be.equal( + false, + ); + }); - @test - 'check if container does not match any container'() { + it('should check if container does not match if version is incorrect', function () { expect( - containerMatchesRegex('anyName', new RegExp('d+'), MainSpec.anyContainerWithExposedPorts), + containerMatchesRegex('backend', new RegExp('1\\.4\\.\\d+'), backendContainerWithExposedPorts), ).to.be.equal(false); - } + }); - @test - 'check if container does not match if version is incorrect'() { + it('should check if container matches', function () { expect( - containerMatchesRegex('backend', new RegExp('1\\.4\\.\\d+'), MainSpec.backendContainerWithExposedPorts), - ).to.be.equal(false); - } - - @test - 'check if container matches'() { - expect( - containerMatchesRegex('backend', new RegExp('1\\.0\\.\\d+'), MainSpec.backendContainerWithExposedPorts), + containerMatchesRegex('backend', new RegExp('1\\.0\\.\\d+'), backendContainerWithExposedPorts), ).to.be.equal(true); expect( - containerMatchesRegex( - 'backend', - new RegExp('1\\.0\\.\\d+'), - MainSpec.swarmBackendContainerWithExposedPorts, - ), + containerMatchesRegex('backend', new RegExp('1\\.0\\.\\d+'), swarmBackendContainerWithExposedPorts), ).to.be.equal(true); - } + }); - @test - async 'get gateway of any container with exposed ports'() { - expect(await getGatewayOfStAppsBackend(MainSpec.anyContainerWithExposedPorts)).to.be.equal('0.0.0.0:80'); - } + it('should get gateway of any container with exposed ports', async function () { + expect(await getGatewayOfStAppsBackend(anyContainerWithExposedPorts)).to.be.equal('0.0.0.0:80'); + }); - @test - async 'get gateway of backend container'() { - const spy = MainSpec.sandbox.on(console, 'error', () => { - // noop - }); + it('should get gateway of backend container', async function () { + const spy = sandbox.stub(console, 'error'); const containerWithoutPorts: Partial = { Id: 'Foo', @@ -245,112 +99,68 @@ export class MainSpec { }; expect(await getGatewayOfStAppsBackend(containerWithoutPorts as ContainerInfo)).to.be.equal(''); - expect(spy.__spy.calls[0][0]).to.contain('Container /container_name_1 does not advertise any port.'); - } + expect(spy).to.have.been.calledWithMatch('Container /container_name_1 does not advertise any port.'); + }); - @test - async 'get gateway of backend container without ports'() { - expect(await getGatewayOfStAppsBackend(MainSpec.backendContainerWithExposedPorts)).to.be.equal( - '127.0.0.1:3000', - ); - } + it('should get gateway of backend container without ports', async function () { + expect(await getGatewayOfStAppsBackend(backendContainerWithExposedPorts)).to.be.equal('127.0.0.1:3000'); + }); - @test - async 'get gateway of backend container within docker swarm'() { - const backendContainer = MainSpec.swarmBackendContainerWithExposedPorts as any; + it('should get gateway of backend container within docker swarm', async function () { + const backendContainer = swarmBackendContainerWithExposedPorts as any; delete backendContainer.Ports[0].IP; - const main = proxyquire('../src/main', { - 'node-port-scanner': (_host: unknown, _ports: unknown) => { - return new Promise((resolve, _reject) => { - resolve({ - ports: { - open: [3000], - }, - }); - }); - }, - }); - expect(await main.getGatewayOfStAppsBackend(backendContainer)).to.be.equal('172.18.0.3:3000'); - } + const spy = sandbox.stub(portScannerModule, 'isPortFree').resolves(true); + expect(await getGatewayOfStAppsBackend(backendContainer)).to.be.equal('172.18.0.3:3000'); + expect(spy).to.have.been.called; + }); - @test - async 'fail to get gateway of backend container if unreachable'() { - const backendContainer = MainSpec.swarmBackendContainerWithExposedPorts as any; + it('should fail to get gateway of backend container if unreachable', async function () { + const backendContainer = swarmBackendContainerWithExposedPorts as any; delete backendContainer.Ports[0].IP; - const spy = MainSpec.sandbox.on(console, 'error', () => { - // noop - }); + const spy = sandbox.stub(console, 'error'); - const main = proxyquire('../src/main', { - 'node-port-scanner': (_host: unknown, _ports: unknown) => { - return new Promise((resolve, _reject) => { - resolve({ - ports: { - open: [], - }, - }); - }); - }, - }); + const scanner = sandbox.stub(portScannerModule, 'isPortFree').resolves(false); - expect(await main.getGatewayOfStAppsBackend(MainSpec.swarmBackendContainerWithExposedPorts)).to.be.equal( - '', - ); - expect(spy.__spy.calls[0][0]).to.contain( + expect(await getGatewayOfStAppsBackend(swarmBackendContainerWithExposedPorts)).to.be.equal(''); + expect(scanner.calledOnce).to.be.true; + expect(spy).to.have.been.calledWithMatch( "It's possible your current Docker network setup isn't supported yet.", ); - } + }); - @test - async 'fail to get gateway of backend container network mode is unsupported'() { - const backendContainer = MainSpec.swarmBackendContainerWithExposedPorts as any; + it('should fail to get gateway of backend container network mode is unsupported', async function () { + const backendContainer = swarmBackendContainerWithExposedPorts as any; delete backendContainer.Ports[0].IP; delete backendContainer.Ports[0].PublicPort; delete backendContainer.Ports[0].PrivatePort; - const spy = MainSpec.sandbox.on(console, 'error', () => { - // noop - }); + const spy = sandbox.stub(console, 'error'); - expect(await getGatewayOfStAppsBackend(MainSpec.swarmBackendContainerWithExposedPorts)).to.be.equal(''); - expect(spy.__spy.calls[0][0]).to.contain( + expect(await getGatewayOfStAppsBackend(swarmBackendContainerWithExposedPorts)).to.be.equal(''); + expect(spy).to.have.been.calledWithMatch( "It's possible your current Docker network setup isn't supported yet.", ); - } + }); - @test - async 'upstream map calls logger error when no matching container is found'() { - const spy = MainSpec.sandbox.on(console, 'warn', () => { - // noop - }); + it('should upstream map calls logger error when no matching container is found', async function () { + const spy = sandbox.stub(console, 'warn'); - expect( - await generateUpstreamMap( - ['0\\.8\\.\\d+'], - ['1\\.1\\.\\d+'], - [MainSpec.backendContainerWithExposedPorts], - ), - ).to.be.equal(`map $http_x_stapps_version $proxyurl { + expect(await generateUpstreamMap(['0\\.8\\.\\d+'], ['1\\.1\\.\\d+'], [backendContainerWithExposedPorts])) + .to.be.equal(`map $http_x_stapps_version $proxyurl { default unsupported; "~0\\.8\\.\\d+" unavailable; "~1\\.1\\.\\d+" outdated; } `); - expect(spy.__spy.calls[0][0]).to.contain('No backend for version'); - } + expect(spy).to.have.been.calledWithMatch('No backend for version'); + }); - @test - async 'upstream map with one active version and no outdated ones'() { - expect( - await generateUpstreamMap( - ['1\\.0\\.\\d+'], - ['0\\.8\\.\\d+'], - [MainSpec.backendContainerWithExposedPorts], - ), - ).to.be.equal(`map $http_x_stapps_version $proxyurl { + it('should upstream map with one active version and no outdated ones', async function () { + expect(await generateUpstreamMap(['1\\.0\\.\\d+'], ['0\\.8\\.\\d+'], [backendContainerWithExposedPorts])) + .to.be.equal(`map $http_x_stapps_version $proxyurl { default unsupported; "~1\\.0\\.\\d+" 1__0___d_; "~0\\.8\\.\\d+" outdated; @@ -359,17 +169,16 @@ upstream 1__0___d_ { server 127.0.0.1:3000; } `); - } + }); - @test - async 'get containers'() { + it('should get containers', async function () { try { await getContainers(); return false; - } catch (e) { - if ((e as Error).message.startsWith('No')) { + } catch (error) { + if ((error as Error).message.startsWith('No')) { // Result, if docker is installed - expect((e as Error).message).to.equal(`No running docker containers found. + expect((error as Error).message).to.equal(`No running docker containers found. Please check if docker is running and Node.js can access the docker socket (/var/run/docker.sock)`); } else { @@ -377,41 +186,34 @@ Please check if docker is running and Node.js can access the docker socket (/var expect([ new Error(`connect ENOENT /var/run/docker.sock`).message, new Error('connect EACCES /var/run/docker.sock').message, - ]).to.include((e as Error).message); + ]).to.include((error as Error).message); } } return true; - } + }); - @test - async 'get template view'() { + it('should get template view', async function () { try { - let containersWithSameVersion = [ - MainSpec.backendContainerWithExposedPorts, - MainSpec.backendContainerWithExposedPorts, - ]; + const containersWithSameVersion = [backendContainerWithExposedPorts, backendContainerWithExposedPorts]; await getTemplateView(containersWithSameVersion); return false; - } catch (e) { - expect((e as Error).message).to.equal(`Multiple backends for one version found.`); + } catch (error) { + expect((error as Error).message).to.equal(`Multiple backends for one version found.`); } return true; - } + }); - @test - async 'include metrics config'() { + it('should include metrics config', async function () { expect(await generateMetricsServer('test', true)).length.to.be.greaterThan(1); - } + }); - @test - async 'omit metrics config'() { + it('should omit metrics config', async function () { expect(await generateMetricsServer('test', false)).to.equal(''); - } + }); - @test - 'create listener faulty config'() { + it('should create listener faulty config', async function () { expect( generateListener({ certificate: 'faultyTest', @@ -423,17 +225,16 @@ Please check if docker is running and Node.js can access the docker socket (/var ${protocolHardeningParameters} `); - } + }); - @test - 'create listener correct config'() { - const testCertDir = resolve(__dirname, 'certs'); - mkdirSync(testCertDir); + it('should create listener correct config', async function () { + const testCertDirectory = path.resolve(path.dirname(fileURLToPath(import.meta.url)), 'certs'); + mkdirSync(testCertDirectory); - const certificateFile = resolve(testCertDir, 'ssl.crt'); - const certificateKeyFile = resolve(testCertDir, 'ssl.key'); - const certificateChainFile = resolve(testCertDir, 'chain.crt'); - const dhparamFile = resolve(testCertDir, 'dhparam.pem'); + const certificateFile = path.resolve(testCertDirectory, 'ssl.crt'); + const certificateKeyFile = path.resolve(testCertDirectory, 'ssl.key'); + const certificateChainFile = path.resolve(testCertDirectory, 'chain.crt'); + const dhparamFile = path.resolve(testCertDirectory, 'dhparam.pem'); writeFileSync(certificateFile, 'Test'); writeFileSync(certificateKeyFile, 'Test'); @@ -461,6 +262,6 @@ ${protocolHardeningParameters} unlinkSync(certificateKeyFile); unlinkSync(certificateChainFile); unlinkSync(dhparamFile); - rmdirSync(testCertDir); - } -} + rmdirSync(testCertDirectory); + }); +}); diff --git a/backend/proxy/tsconfig.json b/backend/proxy/tsconfig.json index 42e619ec..85e12f2d 100644 --- a/backend/proxy/tsconfig.json +++ b/backend/proxy/tsconfig.json @@ -1,4 +1,4 @@ { "extends": "@openstapps/tsconfig", - "exclude": ["./config/", "./lib/", "./test/"] + "exclude": ["./config/", "./lib/"] } diff --git a/configuration/nyc-config/index.json b/configuration/nyc-config/index.json index 1e4aba93..597efa01 100644 --- a/configuration/nyc-config/index.json +++ b/configuration/nyc-config/index.json @@ -3,18 +3,9 @@ "branches": 90, "check-coverage": true, "exclude": [], - "extension": [ - ".ts" - ], + "extension": [".ts"], "functions": 95, - "include": [ - "src/protocol/route.ts", - "src/things/abstract/thing.ts", - "src/things/abstract/thing-that-can-be-offered.ts", - "src/things/abstract/thing-with-categories.ts", - "src/translator.ts", - "src/guards.ts" - ], + "include": ["src/**/*.ts"], "lines": 95, "per-file": true, "reporter": [ @@ -22,8 +13,6 @@ "html", "text-summary" ], - "require": [ - "ts-node/register" - ], + "require": ["ts-node/register"], "statements": 95 } diff --git a/configuration/projectmanagement/package.json b/configuration/projectmanagement/package.json index ecafb40f..7bdd7081 100644 --- a/configuration/projectmanagement/package.json +++ b/configuration/projectmanagement/package.json @@ -20,11 +20,11 @@ }, "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", - "test": "nyc mocha 'test/**/*.spec.ts'" + "test": "c8 mocha" }, "dependencies": { "@openstapps/gitlab-api": "workspace:*", @@ -33,15 +33,12 @@ "commander": "10.0.0", "date-fns": "2.29.3", "glob": "10.2.1", - "mustache": "4.2.0", - "tmp": "0.2.1" + "mustache": "4.2.0" }, "devDependencies": { "@openstapps/eslint-config": "workspace:*", - "@openstapps/nyc-config": "workspace:*", "@openstapps/prettier-config": "workspace:*", "@openstapps/tsconfig": "workspace:*", - "@testdeck/mocha": "0.3.3", "@types/chai": "4.3.4", "@types/chai-as-promised": "7.1.5", "@types/glob": "8.0.1", @@ -52,7 +49,7 @@ "chai": "4.3.7", "chai-as-promised": "7.1.1", "mocha": "10.2.0", - "nyc": "15.1.0", + "c8": "7.13.0", "ts-node": "10.9.1", "tsup": "6.7.0", "typescript": "4.8.4" @@ -72,8 +69,5 @@ "extends": [ "@openstapps" ] - }, - "nyc": { - "extends": "@openstapps/nyc-config" } } diff --git a/configuration/projectmanagement/src/cli.ts b/configuration/projectmanagement/src/cli.ts index 1085fd3d..70ab9d24 100644 --- a/configuration/projectmanagement/src/cli.ts +++ b/configuration/projectmanagement/src/cli.ts @@ -13,9 +13,7 @@ * this program. If not, see . */ import {Api} from '@openstapps/gitlab-api'; -import {Logger} from '@openstapps/logger'; -import {AddLogLevel} from '@openstapps/logger/lib/transformations/add-log-level.js'; -import {Colorize} from '@openstapps/logger/lib/transformations/colorize.js'; +import {Logger, AddLogLevel, Colorize} from '@openstapps/logger'; import {Command} from 'commander'; import {existsSync, readFileSync} from 'fs'; import path from 'path'; diff --git a/configuration/projectmanagement/src/configuration.ts b/configuration/projectmanagement/src/configuration.ts index c773739c..e1491ede 100644 --- a/configuration/projectmanagement/src/configuration.ts +++ b/configuration/projectmanagement/src/configuration.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Label} from '@openstapps/gitlab-api/lib/types.js'; +import {Label} from '@openstapps/gitlab-api'; import setHours from 'date-fns/setHours'; import nextThursday from 'date-fns/nextThursday'; import previousThursday from 'date-fns/previousThursday'; diff --git a/configuration/projectmanagement/src/tasks/remind.ts b/configuration/projectmanagement/src/tasks/remind.ts index c0dcadc6..3714ac2c 100644 --- a/configuration/projectmanagement/src/tasks/remind.ts +++ b/configuration/projectmanagement/src/tasks/remind.ts @@ -12,15 +12,15 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Api} from '@openstapps/gitlab-api'; import { + Api, AccessLevel, MembershipScope, MergeRequestMergeStatus, MergeRequestState, Scope, User, -} from '@openstapps/gitlab-api/lib/types.js'; +} from '@openstapps/gitlab-api'; import {Logger} from '@openstapps/logger'; import {WebClient} from '@slack/web-api'; import {GROUPS, MAX_DEPTH_FOR_REMINDER, NOTE_PREFIX, SLACK_CHANNEL} from '../configuration.js'; diff --git a/configuration/projectmanagement/src/tasks/report.ts b/configuration/projectmanagement/src/tasks/report.ts index 181394fb..43998a7a 100644 --- a/configuration/projectmanagement/src/tasks/report.ts +++ b/configuration/projectmanagement/src/tasks/report.ts @@ -12,15 +12,15 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Api} from '@openstapps/gitlab-api'; import { + Api, Issue, IssueState, MembershipScope, MergeRequestState, Project, User, -} from '@openstapps/gitlab-api/lib/types.js'; +} from '@openstapps/gitlab-api'; import {Logger} from '@openstapps/logger'; import mustache from 'mustache'; import path from 'path'; diff --git a/configuration/projectmanagement/src/tasks/tidy.ts b/configuration/projectmanagement/src/tasks/tidy.ts index 2e1f332d..01ee2e4c 100644 --- a/configuration/projectmanagement/src/tasks/tidy.ts +++ b/configuration/projectmanagement/src/tasks/tidy.ts @@ -12,8 +12,8 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Api} from '@openstapps/gitlab-api'; import { + Api, AccessLevel, IssueState, MembershipScope, @@ -21,7 +21,7 @@ import { Milestone, Project, Scope, -} from '@openstapps/gitlab-api/lib/types.js'; +} from '@openstapps/gitlab-api'; import {Logger} from '@openstapps/logger'; import {getProjects} from '../common.js'; import { diff --git a/configuration/projectmanagement/src/tasks/unlabel.ts b/configuration/projectmanagement/src/tasks/unlabel.ts index f4c4c3e0..4f62d0ff 100644 --- a/configuration/projectmanagement/src/tasks/unlabel.ts +++ b/configuration/projectmanagement/src/tasks/unlabel.ts @@ -12,8 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Api} from '@openstapps/gitlab-api'; -import {IssueState, Scope} from '@openstapps/gitlab-api/lib/types.js'; +import {Api, IssueState, Scope} from '@openstapps/gitlab-api'; import {Logger} from '@openstapps/logger'; import {GROUPS, LAST_MEETING, NOTE_PREFIX} from '../configuration.js'; import isBefore from 'date-fns/isBefore'; diff --git a/configuration/projectmanagement/test/get-used-versions.spec.ts b/configuration/projectmanagement/test/get-used-versions.spec.ts index d8688acb..100574ea 100644 --- a/configuration/projectmanagement/test/get-used-versions.spec.ts +++ b/configuration/projectmanagement/test/get-used-versions.spec.ts @@ -1,43 +1,26 @@ import * as chai from 'chai'; import {expect} from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import {execSync} from 'child_process'; -import {suite, test} from '@testdeck/mocha'; -import {join} from 'path'; -import {dirSync} from 'tmp'; +import path from 'path'; import {getUsedVersion, getUsedVersionMajorMinor} from '../src/tasks/get-used-version.js'; chai.use(chaiAsPromised); chai.should(); -@suite() -export class GetUsedVersionsSpec { - @test - async 'does not depend on core'() { - return getUsedVersion(join(__dirname, '..'), '@openstapps/core').should.eventually.be.rejected; - } +describe('Verify Versions', function () { + it('should not depend on core', async function () { + await getUsedVersion(process.cwd(), '@openstapps/core').should.eventually.be.rejected; + }); - @test - async 'not a Node.js project'() { - return getUsedVersion(__dirname, '@openstapps/core').should.eventually.be.rejected; - } + it('should not be a Node.js project', async function () { + await getUsedVersion(path.resolve(process.cwd(), '..'), '@openstapps/core').should.eventually.be.rejected; + }); - @test - async 'has no dependencies'() { - const temporaryDirectory = dirSync(); + it('should get used version', async function () { + expect(await getUsedVersion(process.cwd(), 'mustache')).to.be.equal('4.2.0'); + }); - execSync(`cd ${temporaryDirectory.name}; npm init -y`); - - await getUsedVersion(temporaryDirectory.name, '@openstapps/core').should.eventually.be.rejected; - } - - @test - async 'get used version'() { - expect(await getUsedVersion(join(__dirname, '..'), '@krlwlfrt/async-pool')).to.be.equal('0.4.1'); - } - - @test - async 'get used version major minor'() { - expect(await getUsedVersionMajorMinor(join(__dirname, '..'), '@krlwlfrt/async-pool')).to.be.equal('0.4'); - } -} + it('should get used version major minor', async function () { + expect(await getUsedVersionMajorMinor(process.cwd(), 'mustache')).to.be.equal('4.2'); + }); +}); diff --git a/configuration/tsconfig/tsconfig.json b/configuration/tsconfig/tsconfig.json index 70d43e92..ffba3fde 100644 --- a/configuration/tsconfig/tsconfig.json +++ b/configuration/tsconfig/tsconfig.json @@ -25,5 +25,8 @@ "strict": true, "target": "ES2021" }, - "exclude": ["../../../app.js", "../../../lib/", "../../../test/"] + "ts-node": { + "transpileOnly": true + }, + "exclude": ["../../../app.js", "../../../lib/"] } diff --git a/examples/minimal-connector/package.json b/examples/minimal-connector/package.json index 2202d804..ff5d36be 100644 --- a/examples/minimal-connector/package.json +++ b/examples/minimal-connector/package.json @@ -16,8 +16,8 @@ "types": "lib/index.d.ts", "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", "test": "nyc mocha 'test/**/*.spec.ts'" diff --git a/examples/minimal-plugin/package.json b/examples/minimal-plugin/package.json index b371eedf..cd7ea3c8 100644 --- a/examples/minimal-plugin/package.json +++ b/examples/minimal-plugin/package.json @@ -12,8 +12,8 @@ "bin": "app.js", "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", "start": "node lib/cli.js" diff --git a/frontend/app/android/app/src/main/assets/capacitor.plugins.json b/frontend/app/android/app/src/main/assets/capacitor.plugins.json index 91bf9943..15c7ce3a 100644 --- a/frontend/app/android/app/src/main/assets/capacitor.plugins.json +++ b/frontend/app/android/app/src/main/assets/capacitor.plugins.json @@ -1,70 +1,70 @@ [ - { - "pkg": "@capacitor/app", - "classpath": "com.capacitorjs.plugins.app.AppPlugin" - }, - { - "pkg": "@capacitor/browser", - "classpath": "com.capacitorjs.plugins.browser.BrowserPlugin" - }, - { - "pkg": "@capacitor/device", - "classpath": "com.capacitorjs.plugins.device.DevicePlugin" - }, - { - "pkg": "@capacitor/dialog", - "classpath": "com.capacitorjs.plugins.dialog.DialogPlugin" - }, - { - "pkg": "@capacitor/filesystem", - "classpath": "com.capacitorjs.plugins.filesystem.FilesystemPlugin" - }, - { - "pkg": "@capacitor/geolocation", - "classpath": "com.capacitorjs.plugins.geolocation.GeolocationPlugin" - }, - { - "pkg": "@capacitor/haptics", - "classpath": "com.capacitorjs.plugins.haptics.HapticsPlugin" - }, - { - "pkg": "@capacitor/keyboard", - "classpath": "com.capacitorjs.plugins.keyboard.KeyboardPlugin" - }, - { - "pkg": "@capacitor/local-notifications", - "classpath": "com.capacitorjs.plugins.localnotifications.LocalNotificationsPlugin" - }, - { - "pkg": "@capacitor/network", - "classpath": "com.capacitorjs.plugins.network.NetworkPlugin" - }, - { - "pkg": "@capacitor/preferences", - "classpath": "com.capacitorjs.plugins.preferences.PreferencesPlugin" - }, - { - "pkg": "@capacitor/share", - "classpath": "com.capacitorjs.plugins.share.SharePlugin" - }, - { - "pkg": "@capacitor/splash-screen", - "classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin" - }, - { - "pkg": "@capacitor/status-bar", - "classpath": "com.capacitorjs.plugins.statusbar.StatusBarPlugin" - }, - { - "pkg": "@hugotomazi/capacitor-navigation-bar", - "classpath": "br.com.tombus.capacitor.plugin.navigationbar.NavigationBarPlugin" - }, - { - "pkg": "@transistorsoft/capacitor-background-fetch", - "classpath": "com.transistorsoft.bgfetch.capacitor.BackgroundFetchPlugin" - }, - { - "pkg": "capacitor-secure-storage-plugin", - "classpath": "com.whitestein.securestorage.SecureStoragePluginPlugin" - } + { + "pkg": "@capacitor/app", + "classpath": "com.capacitorjs.plugins.app.AppPlugin" + }, + { + "pkg": "@capacitor/browser", + "classpath": "com.capacitorjs.plugins.browser.BrowserPlugin" + }, + { + "pkg": "@capacitor/device", + "classpath": "com.capacitorjs.plugins.device.DevicePlugin" + }, + { + "pkg": "@capacitor/dialog", + "classpath": "com.capacitorjs.plugins.dialog.DialogPlugin" + }, + { + "pkg": "@capacitor/filesystem", + "classpath": "com.capacitorjs.plugins.filesystem.FilesystemPlugin" + }, + { + "pkg": "@capacitor/geolocation", + "classpath": "com.capacitorjs.plugins.geolocation.GeolocationPlugin" + }, + { + "pkg": "@capacitor/haptics", + "classpath": "com.capacitorjs.plugins.haptics.HapticsPlugin" + }, + { + "pkg": "@capacitor/keyboard", + "classpath": "com.capacitorjs.plugins.keyboard.KeyboardPlugin" + }, + { + "pkg": "@capacitor/local-notifications", + "classpath": "com.capacitorjs.plugins.localnotifications.LocalNotificationsPlugin" + }, + { + "pkg": "@capacitor/network", + "classpath": "com.capacitorjs.plugins.network.NetworkPlugin" + }, + { + "pkg": "@capacitor/preferences", + "classpath": "com.capacitorjs.plugins.preferences.PreferencesPlugin" + }, + { + "pkg": "@capacitor/share", + "classpath": "com.capacitorjs.plugins.share.SharePlugin" + }, + { + "pkg": "@capacitor/splash-screen", + "classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin" + }, + { + "pkg": "@capacitor/status-bar", + "classpath": "com.capacitorjs.plugins.statusbar.StatusBarPlugin" + }, + { + "pkg": "@hugotomazi/capacitor-navigation-bar", + "classpath": "br.com.tombus.capacitor.plugin.navigationbar.NavigationBarPlugin" + }, + { + "pkg": "@transistorsoft/capacitor-background-fetch", + "classpath": "com.transistorsoft.bgfetch.capacitor.BackgroundFetchPlugin" + }, + { + "pkg": "capacitor-secure-storage-plugin", + "classpath": "com.whitestein.securestorage.SecureStoragePluginPlugin" + } ] diff --git a/frontend/app/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json b/frontend/app/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json index 90eea7ec..dd3b8bcc 100644 --- a/frontend/app/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/frontend/app/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,116 +1,116 @@ { - "images" : [ + "images": [ { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "AppIcon-20x20@2x.png", - "scale" : "2x" + "size": "20x20", + "idiom": "iphone", + "filename": "AppIcon-20x20@2x.png", + "scale": "2x" }, { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "AppIcon-20x20@3x.png", - "scale" : "3x" + "size": "20x20", + "idiom": "iphone", + "filename": "AppIcon-20x20@3x.png", + "scale": "3x" }, { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "AppIcon-29x29@2x-1.png", - "scale" : "2x" + "size": "29x29", + "idiom": "iphone", + "filename": "AppIcon-29x29@2x-1.png", + "scale": "2x" }, { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "AppIcon-29x29@3x.png", - "scale" : "3x" + "size": "29x29", + "idiom": "iphone", + "filename": "AppIcon-29x29@3x.png", + "scale": "3x" }, { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "AppIcon-40x40@2x.png", - "scale" : "2x" + "size": "40x40", + "idiom": "iphone", + "filename": "AppIcon-40x40@2x.png", + "scale": "2x" }, { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "AppIcon-40x40@3x.png", - "scale" : "3x" + "size": "40x40", + "idiom": "iphone", + "filename": "AppIcon-40x40@3x.png", + "scale": "3x" }, { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "AppIcon-60x60@2x.png", - "scale" : "2x" + "size": "60x60", + "idiom": "iphone", + "filename": "AppIcon-60x60@2x.png", + "scale": "2x" }, { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "AppIcon-60x60@3x.png", - "scale" : "3x" + "size": "60x60", + "idiom": "iphone", + "filename": "AppIcon-60x60@3x.png", + "scale": "3x" }, { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "AppIcon-20x20@1x.png", - "scale" : "1x" + "size": "20x20", + "idiom": "ipad", + "filename": "AppIcon-20x20@1x.png", + "scale": "1x" }, { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "AppIcon-20x20@2x-1.png", - "scale" : "2x" + "size": "20x20", + "idiom": "ipad", + "filename": "AppIcon-20x20@2x-1.png", + "scale": "2x" }, { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "AppIcon-29x29@1x.png", - "scale" : "1x" + "size": "29x29", + "idiom": "ipad", + "filename": "AppIcon-29x29@1x.png", + "scale": "1x" }, { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "AppIcon-29x29@2x.png", - "scale" : "2x" + "size": "29x29", + "idiom": "ipad", + "filename": "AppIcon-29x29@2x.png", + "scale": "2x" }, { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "AppIcon-40x40@1x.png", - "scale" : "1x" + "size": "40x40", + "idiom": "ipad", + "filename": "AppIcon-40x40@1x.png", + "scale": "1x" }, { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "AppIcon-40x40@2x-1.png", - "scale" : "2x" + "size": "40x40", + "idiom": "ipad", + "filename": "AppIcon-40x40@2x-1.png", + "scale": "2x" }, { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "AppIcon-76x76@1x.png", - "scale" : "1x" + "size": "76x76", + "idiom": "ipad", + "filename": "AppIcon-76x76@1x.png", + "scale": "1x" }, { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "AppIcon-76x76@2x.png", - "scale" : "2x" + "size": "76x76", + "idiom": "ipad", + "filename": "AppIcon-76x76@2x.png", + "scale": "2x" }, { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "AppIcon-83.5x83.5@2x.png", - "scale" : "2x" + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "AppIcon-83.5x83.5@2x.png", + "scale": "2x" }, { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "AppIcon-512@2x.png", - "scale" : "1x" + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "AppIcon-512@2x.png", + "scale": "1x" } ], - "info" : { - "version" : 1, - "author" : "xcode" + "info": { + "version": 1, + "author": "xcode" } -} \ No newline at end of file +} diff --git a/frontend/app/ios/App/App/Assets.xcassets/Contents.json b/frontend/app/ios/App/App/Assets.xcassets/Contents.json index da4a164c..97a8662e 100644 --- a/frontend/app/ios/App/App/Assets.xcassets/Contents.json +++ b/frontend/app/ios/App/App/Assets.xcassets/Contents.json @@ -1,6 +1,6 @@ { - "info" : { - "version" : 1, - "author" : "xcode" + "info": { + "version": 1, + "author": "xcode" } -} \ No newline at end of file +} diff --git a/frontend/app/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json b/frontend/app/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json index d7d96a67..b7814927 100644 --- a/frontend/app/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json +++ b/frontend/app/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json @@ -1,23 +1,23 @@ { - "images" : [ + "images": [ { - "idiom" : "universal", - "filename" : "splash-2732x2732-2.png", - "scale" : "1x" + "idiom": "universal", + "filename": "splash-2732x2732-2.png", + "scale": "1x" }, { - "idiom" : "universal", - "filename" : "splash-2732x2732-1.png", - "scale" : "2x" + "idiom": "universal", + "filename": "splash-2732x2732-1.png", + "scale": "2x" }, { - "idiom" : "universal", - "filename" : "splash-2732x2732.png", - "scale" : "3x" + "idiom": "universal", + "filename": "splash-2732x2732.png", + "scale": "3x" } ], - "info" : { - "version" : 1, - "author" : "xcode" + "info": { + "version": 1, + "author": "xcode" } -} \ No newline at end of file +} diff --git a/frontend/app/package.json b/frontend/app/package.json index a62c6dad..6b97cdf2 100644 --- a/frontend/app/package.json +++ b/frontend/app/package.json @@ -31,8 +31,8 @@ "docker:run:android": "sudo docker run -v $PWD:/app --privileged -v /dev/bus/usb:/dev/bus/usb --net=host -it registry.gitlab.com/openstapps/app bash -c \"npm run run:android\"", "docker:serve": "sudo docker run -p 8100:8100 -p 35729:35729 -p 53703:53703 -v $PWD:/app -it registry.gitlab.com/openstapps/app bash -c \"npm run start:external\"", "e2e": "ng e2e", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "licenses": "license-checker --json > src/assets/about/licenses.json && ts-node ./scripts/accumulate-licenses.ts && git add src/assets/about/licenses.json", "lint": "ng lint", "lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts,.html src/", diff --git a/package.json b/package.json index 6472e5e0..ad6701a8 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "lint:fix": "dotenv -c -- turbo run lint:fix", "publish-packages": "dotenv -c -- turbo run build format lint test && changeset version && changeset publish", "syncpack": "syncpack list-mismatches && syncpack lint-semver-ranges", - "syncpack:fix": "node sync.mjs && syncpack format && syncpack fix-mismatches" + "syncpack:fix": "node sync.mjs && syncpack format && syncpack fix-mismatches", + "test": "dotenv -c -- turbo run test" }, "devDependencies": { "@changesets/cli": "2.26.0", diff --git a/packages/api/package.json b/packages/api/package.json index c6809503..c0c42b97 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -22,11 +22,11 @@ }, "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", - "test": "nyc mocha 'test/**/*.spec.ts'" + "test": "c8 mocha" }, "dependencies": { "@krlwlfrt/async-pool": "0.7.0", @@ -58,7 +58,6 @@ "@openstapps/nyc-config": "workspace:*", "@openstapps/prettier-config": "workspace:*", "@openstapps/tsconfig": "workspace:*", - "@testdeck/mocha": "0.3.3", "@types/body-parser": "1.19.2", "@types/chai": "4.3.5", "@types/chai-as-promised": "7.1.5", @@ -75,7 +74,7 @@ "fs-extra": "10.1.0", "mocha": "10.2.0", "nock": "13.3.1", - "nyc": "15.1.0", + "c8": "7.13.0", "ts-node": "10.9.1", "tsup": "6.7.0", "typedoc": "0.23.28", diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index dd53a743..f70f1dc9 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,10 +1,10 @@ -export * from './bulk.js' -export * from './client.js' -export * from './connector-client.js' -export * from './copy.js' -export * from './e2e.js' -export * from './errors.js' -export * from './http-client.js' -export * from './http-client-interface.js' -export * from './plugin.js' -export * from './plugin-client.js' +export * from './bulk.js'; +export * from './client.js'; +export * from './connector-client.js'; +export * from './copy.js'; +export * from './e2e.js'; +export * from './errors.js'; +export * from './http-client.js'; +export * from './http-client-interface.js'; +export * from './plugin.js'; +export * from './plugin-client.js'; diff --git a/packages/api/test/bulk.spec.ts b/packages/api/test/bulk.spec.ts index ee797928..574d9ea1 100644 --- a/packages/api/test/bulk.spec.ts +++ b/packages/api/test/bulk.spec.ts @@ -24,29 +24,27 @@ import {expect} from 'chai'; import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import chaiSpies from 'chai-spies'; -import {suite, test} from '@testdeck/mocha'; import moment from 'moment'; -import {Bulk} from '../src/bulk.js'; -import {Client} from '../src/client.js'; -import {BulkWithMultipleTypesError} from '../src/errors.js'; -import {HttpClient} from '../src/http-client.js'; +import {HttpClient, Bulk, Client, BulkWithMultipleTypesError} from '../src/index.js'; chai.should(); chai.use(chaiSpies); chai.use(chaiAsPromised); -const sandbox = chai.spy.sandbox(); +describe('Bulk', function () { + const sandbox = chai.spy.sandbox(); -const bulkAddRoute = new SCBulkAddRoute(); -const bulkDoneRoute = new SCBulkDoneRoute(); + const bulkAddRoute = new SCBulkAddRoute(); + const bulkDoneRoute = new SCBulkDoneRoute(); -const httpClient = new HttpClient(); -const client = new Client(httpClient, 'http://localhost'); + const httpClient = new HttpClient(); + const client = new Client(httpClient, 'http://localhost'); -@suite() -export class BulkSpec { - @test - async add() { + afterEach(function () { + sandbox.restore(); + }) + + it('should add', async function () { sandbox.on(client, 'invokeRoute', () => { return {}; }); @@ -82,10 +80,9 @@ export class BulkSpec { }, dish, ); - } + }); - @test - async addFails() { + it('should fail add', async function () { const bulk = new Bulk(SCThingType.Dish, client, { expiration: moment().add(3600, 'seconds').format(), source: 'foo', @@ -108,15 +105,10 @@ export class BulkSpec { uid: 'foo', }; - return bulk.add(message).should.be.rejectedWith(BulkWithMultipleTypesError); - } + await bulk.add(message).should.be.rejectedWith(BulkWithMultipleTypesError); + }); - async after() { - sandbox.restore(); - } - - @test - async construct() { + it('should construct', function () { expect(() => { return new Bulk(SCThingType.Dish, client, { expiration: moment().add(3600, 'seconds').format(), @@ -126,10 +118,9 @@ export class BulkSpec { uid: 'bar', }); }).not.to.throw(); - } + }); - @test - async done() { + it('should done', async function () { sandbox.on(client, 'invokeRoute', () => { return {}; }); @@ -149,5 +140,5 @@ export class BulkSpec { expect(client.invokeRoute).to.have.been.first.called.with(bulkDoneRoute, { UID: 'bar', }); - } -} + }); +}); diff --git a/packages/api/test/client.spec.ts b/packages/api/test/client.spec.ts index 14f7c64b..fe265f0e 100644 --- a/packages/api/test/client.spec.ts +++ b/packages/api/test/client.spec.ts @@ -28,11 +28,7 @@ import {expect} from 'chai'; import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import chaiSpies from 'chai-spies'; -import {suite, test} from '@testdeck/mocha'; -import {Client} from '../src/client.js'; -import {ApiError, OutOfRangeError} from '../src/errors.js'; -import {HttpClient} from '../src/http-client.js'; -import {HttpClientResponse} from '../src/http-client-interface.js'; +import {ApiError, OutOfRangeError, Client, HttpClient, HttpClientResponse} from '../src/index.js'; chai.should(); chai.use(chaiSpies); @@ -84,21 +80,18 @@ async function invokeIndexRouteFails(): Promise { return new Client(httpClient, 'http://localhost'); }).not.to.throw(); - } + }); - @test - async constructWithHeaders() { + it('should construct with headers', async function () { sandbox.on(httpClient, 'request', invokeIndexRoute); expect(httpClient.request).not.to.have.been.first.called(); @@ -115,10 +108,9 @@ export class ClientSpec { method: indexRoute.method, url: new URL('http://localhost' + indexRoute.getUrlPath()), }); - } + }); - @test - async getThing() { + it('should get thing', async function () { const message: SCMessage = { audiences: ['employees'], categories: ['news'], @@ -174,10 +166,9 @@ export class ClientSpec { method: searchRoute.method, url: new URL('http://localhost' + searchRoute.getUrlPath()), }); - } + }); - @test - async getThingFailsByEmptyResponse() { + it('should fail getThing by empty response', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -202,10 +193,9 @@ export class ClientSpec { const client = new Client(httpClient, 'http://localhost'); return client.getThing('bar').should.be.rejected; - } + }); - @test - async getThingFailsByUid() { + it('should fail getThing by uid', async function () { const message: SCMessage = { audiences: ['employees'], categories: ['news'], @@ -244,10 +234,9 @@ export class ClientSpec { const client = new Client(httpClient, 'http://localhost'); return client.getThing('bar').should.be.rejected; - } + }); - @test - async handshake() { + it('should handshake', async function () { sandbox.on(httpClient, 'request', invokeIndexRoute); expect(httpClient.request).not.to.have.been.first.called(); @@ -263,10 +252,9 @@ export class ClientSpec { method: indexRoute.method, url: new URL('http://localhost' + indexRoute.getUrlPath()), }); - } + }); - @test - async handshakeFails() { + it('should fail handshake', async function () { sandbox.on(httpClient, 'request', invokeIndexRoute); expect(httpClient.request).not.to.have.been.first.called(); @@ -274,10 +262,9 @@ export class ClientSpec { const client = new Client(httpClient, 'http://localhost'); return client.handshake('bar.bar.dummy').should.be.rejectedWith(ApiError); - } + }); - @test - async invokePlugin() { + it('should invoke plugin', async function () { sandbox.on( httpClient, 'request', @@ -303,13 +290,12 @@ export class ClientSpec { await client.invokePlugin('unsupportedPlugin').should.be.rejectedWith(ApiError, /.*supportedPlugin.*/gim); // again with cached feature definitions - return client + await client .invokePlugin('supportedPlugin') .should.not.be.rejectedWith(ApiError, /.*supportedPlugin.*/gim); - } + }); - @test - async invokePluginUnavailable() { + it('should invoke unavailable plugin', async function () { sandbox.on( httpClient, 'request', @@ -350,10 +336,9 @@ export class ClientSpec { ); // again with cached feature definitions return client.invokePlugin('supportedPlugin').should.be.rejectedWith(ApiError, /.*supportedPlugin.*/gim); - } + }); - @test - async invokeRoute() { + it('should invoke route', async function () { sandbox.on(httpClient, 'request', invokeIndexRoute); expect(httpClient.request).not.to.have.been.first.called(); @@ -369,10 +354,9 @@ export class ClientSpec { method: indexRoute.method, url: new URL('http://localhost' + indexRoute.getUrlPath()), }); - } + }); - @test - async invokeRouteFails() { + it('should fail to invoke route', async function () { sandbox.on(httpClient, 'request', invokeIndexRouteFails); expect(httpClient.request).not.to.have.been.first.called(); @@ -380,10 +364,9 @@ export class ClientSpec { const client = new Client(httpClient, 'http://localhost'); return client.invokeRoute(indexRoute).should.be.rejectedWith(ApiError); - } + }); - @test - async multiSearch() { + it('should multi search', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -430,10 +413,9 @@ export class ClientSpec { method: multiSearchRoute.method, url: new URL('http://localhost' + multiSearchRoute.getUrlPath()), }); - } + }); - @test - async multiSearchWithPreflight() { + it('should multi search with preflight', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -488,10 +470,9 @@ export class ClientSpec { method: multiSearchRoute.method, url: new URL('http://localhost' + multiSearchRoute.getUrlPath()), }); - } + }); - @test - nextWindow() { + it('should next window', async function () { let searchRequest: SCSearchRequest = {size: 30}; const searchResponse: SCSearchResponse = { data: [], @@ -515,10 +496,9 @@ export class ClientSpec { expect(() => { Client.nextWindow(searchRequest, searchResponse); }).to.throw(OutOfRangeError); - } + }); - @test - async search() { + it('should search', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -551,10 +531,9 @@ export class ClientSpec { method: searchRoute.method, url: new URL('http://localhost' + searchRoute.getUrlPath()), }); - } + }); - @test - async searchNext() { + it('should search next', async function () { const searchResponse: SCSearchResponse = { data: [], facets: [], @@ -589,10 +568,9 @@ export class ClientSpec { method: searchRoute.method, url: new URL('http://localhost' + searchRoute.getUrlPath()), }); - } + }); - @test - async searchWithPreflight() { + it('should search with preflight', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -633,5 +611,5 @@ export class ClientSpec { method: searchRoute.method, url: new URL('http://localhost' + searchRoute.getUrlPath()), }); - } -} + }); +}); diff --git a/packages/api/test/connector-client.spec.ts b/packages/api/test/connector-client.spec.ts index 253b01a1..00c952f9 100644 --- a/packages/api/test/connector-client.spec.ts +++ b/packages/api/test/connector-client.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/no-null */ /* * Copyright (C) 2018 StApps * This program is free software: you can redistribute it and/or modify it @@ -12,7 +13,6 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {asyncPool} from '@krlwlfrt/async-pool/lib/async-pool'; import { isThing, SCBulkAddResponse, @@ -33,16 +33,12 @@ import {expect} from 'chai'; import chaiAsPromised from 'chai-as-promised'; import chaiSpies from 'chai-spies'; import clone = require('rfdc'); -import {readdir, readFile} from 'fs'; -import {suite, test} from '@testdeck/mocha'; import moment from 'moment'; -import {join, resolve} from 'path'; import traverse from 'traverse'; -import {promisify} from 'util'; -import {ConnectorClient} from '../src/connector-client.js'; -import {EmptyBulkError, NamespaceNotDefinedError} from '../src/errors.js'; -import {HttpClient} from '../src/http-client.js'; -import {HttpClientRequest, HttpClientResponse} from '../src/http-client-interface.js'; +import {ConnectorClient, EmptyBulkError, NamespaceNotDefinedError, HttpClient, HttpClientRequest, HttpClientResponse} from '../src/index.js'; +import path from "path"; +import {fileURLToPath} from "url"; +import {readdir, readFile} from "fs/promises"; chai.should(); chai.use(chaiSpies); @@ -55,9 +51,6 @@ const bulkDoneRoute = new SCBulkDoneRoute(); const bulkRoute = new SCBulkRoute(); const thingUpdateRoute = new SCThingUpdateRoute(); -const readdirPromisified = promisify(readdir); -const readFilePromisified = promisify(readFile); - const httpClient = new HttpClient(); /** @@ -76,14 +69,12 @@ function doesContainThings(thing: T): boolea }, false); } -@suite() -export class ConnectorClientSpec { - async after() { +describe('ConnectorClient', function () { + afterEach(function () { sandbox.restore(); - } + }); - @test - async bulk() { + it('should bulk', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -115,10 +106,9 @@ export class ConnectorClientSpec { method: bulkRoute.method, url: new URL('http://localhost' + bulkRoute.getUrlPath()), }); - } + }); - @test - async bulkWithoutTimeout() { + it('should bulk without timeout', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -150,10 +140,9 @@ export class ConnectorClientSpec { method: bulkRoute.method, url: new URL('http://localhost' + bulkRoute.getUrlPath()), }); - } + }); - @test - async index() { + it('should index', async function () { const messages: SCMessage[] = [ { audiences: ['employees'], @@ -240,16 +229,14 @@ export class ConnectorClientSpec { method: bulkRoute.method, url: new URL('http://localhost' + bulkRoute.getUrlPath()), }); - } + }); - @test - async indexFails() { + it('should fail to index', async function () { const connectorClient = new ConnectorClient(httpClient, 'http://localhost'); - return connectorClient.index([]).should.be.rejectedWith(EmptyBulkError); - } + await connectorClient.index([]).should.be.rejectedWith(EmptyBulkError); + }); - @test - async indexWithoutSource() { + it('should index without source', async function () { const messages: SCMessage[] = [ { audiences: ['employees'], @@ -336,28 +323,25 @@ export class ConnectorClientSpec { method: bulkRoute.method, url: new URL('http://localhost' + bulkRoute.getUrlPath()), }); - } + }); - @test - makeUuid() { + it('should make uuid', async function () { const uuid = ConnectorClient.makeUUID('foo', 'b-tu'); expect(uuid).to.be.equal('abad271e-d9e9-5802-b7bc-96d8a647b451'); expect(ConnectorClient.makeUUID('bar', 'b-tu')).not.to.be.equal(uuid); expect(ConnectorClient.makeUUID('foo', 'f-u')).not.to.be.equal(uuid); - } + }); - @test - makeUuidFails() { + it('should fail making a uuid', async function (){ expect(() => { ConnectorClient.makeUUID('foo', 'b-u'); }).to.throw(NamespaceNotDefinedError); - } + }); - @test - async removeReferences() { - const pathToTestFiles = resolve( - __dirname, + it('should remove references', async function () { + const pathToTestFiles = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), '..', 'node_modules', '@openstapps', @@ -367,14 +351,14 @@ export class ConnectorClientSpec { 'indexable', ); - const testFiles = await readdirPromisified(pathToTestFiles); + const testFiles = await readdir(pathToTestFiles); - const testInstances = await asyncPool(5, testFiles, async testFile => { - const buffer = await readFilePromisified(join(pathToTestFiles, testFile)); + const testInstances = await Promise.all(testFiles.map(async testFile => { + const buffer = await readFile(path.join(pathToTestFiles, testFile)); const content = JSON.parse(buffer.toString()); return content.instance; - }); + })); for (const testInstance of testInstances) { const checkInstance = clone()(testInstance); @@ -384,6 +368,7 @@ export class ConnectorClientSpec { false, JSON.stringify([testInstance, testInstanceWithoutReferences], null, 2), ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any expect((testInstanceWithoutReferences as any).origin).to.be.equal( undefined, JSON.stringify([testInstance, testInstanceWithoutReferences], null, 2), @@ -393,10 +378,9 @@ export class ConnectorClientSpec { 'Removing the references of a thing could have side effects because no deep copy is used', ); } - } + }); - @test - async removeUndefinedProperties() { + it('should remove undefined properties', async function () { const objectWithUndefinedProperties = { value: 'foo', novalue: undefined, @@ -417,10 +401,9 @@ export class ConnectorClientSpec { objectWithoutUndefinedProperties, JSON.stringify([objectWithUndefinedProperties, objectWithoutUndefinedProperties], null, 2), ); - } + }); - @test - async update() { + it('should update', async function () { const message: SCMessage = { audiences: ['employees'], categories: ['news'], @@ -462,5 +445,5 @@ export class ConnectorClientSpec { }), ), }); - } -} + }); +}); diff --git a/packages/api/test/copy.spec.ts b/packages/api/test/copy.spec.ts index 862f6aab..47efd8d5 100644 --- a/packages/api/test/copy.spec.ts +++ b/packages/api/test/copy.spec.ts @@ -27,12 +27,9 @@ import { import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import chaiSpies from 'chai-spies'; -import {suite, test} from '@testdeck/mocha'; import moment from 'moment'; -import {copy} from '../src/copy.js'; -import {ApiError} from '../src/errors.js'; -import {HttpClient, RequestOptions, Response} from '../src/http-client.js'; -import {RecursivePartial} from './client.spec'; +import {copy, ApiError, HttpClient, RequestOptions, Response} from '../src/index.js'; +import {RecursivePartial} from './client.spec.js'; chai.should(); chai.use(chaiSpies); @@ -47,14 +44,12 @@ const searchRoute = new SCSearchRoute(); const httpClient = new HttpClient(); -@suite() -export class CopySpec { - async after() { +describe('Copy', function () { + afterEach(function () { sandbox.restore(); - } + }); - @test - async copy() { + it('should copy', async function () { type responses = Response; sandbox.on( @@ -133,10 +128,9 @@ export class CopySpec { type: SCThingType.Dish, version: 'foo.bar.foobar', }); - } + }); - @test - async copyShouldFail() { + it('should fail to copy', async function () { type responses = Response; sandbox.on( @@ -206,7 +200,7 @@ export class CopySpec { }, ); - return copy(httpClient, { + await copy(httpClient, { batchSize: 5, from: 'http://foo.bar', source: 'stapps-copy', @@ -214,5 +208,5 @@ export class CopySpec { type: SCThingType.Dish, version: 'foo.bar.foobar', }).should.be.rejectedWith(ApiError); - } -} + }); +}); diff --git a/packages/api/test/e2e.spec.ts b/packages/api/test/e2e.spec.ts index ff8dd09e..59a3e929 100644 --- a/packages/api/test/e2e.spec.ts +++ b/packages/api/test/e2e.spec.ts @@ -12,9 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ - -// tslint:disable-next-line: max-line-length -// tslint:disable: completed-docs no-implicit-dependencies prefer-function-over-method newline-per-chained-call member-ordering +// eslint-disable-next-line unicorn/prevent-abbreviations import { SCBulkAddResponse, SCBulkAddRoute, @@ -32,12 +30,12 @@ import chaiSpies from 'chai-spies'; import clone = require('rfdc'); import {existsSync, mkdirSync, rmdirSync, unlinkSync} from 'fs'; import {createFileSync} from 'fs-extra'; -import {suite, test} from '@testdeck/mocha'; -import {join} from 'path'; -import {e2eRun, getItemsFromSamples} from '../src/e2e.js'; -import {ApiError} from '../src/errors.js'; -import {HttpClient, RequestOptions, Response} from '../src/http-client.js'; -import {RecursivePartial} from './client.spec'; +// eslint-disable-next-line unicorn/prevent-abbreviations +import {e2eRun, getItemsFromSamples, ApiError, HttpClient, RequestOptions, Response} from '../src/index.js'; +import {RecursivePartial} from './client.spec.js'; +import {expect} from "chai"; +import path from "path"; +import {fileURLToPath} from "url"; chai.should(); chai.use(chaiSpies); @@ -55,26 +53,21 @@ const httpClient = new HttpClient(); const storedThings: Map = new Map(); -@suite -export class E2EConnectorSpec { - async after() { +describe('e2e Connector', function () { + afterEach(function () { sandbox.restore(); - } + }); - @test - async getCoreTestSamples() { + it('should get core test samples', async function () { const items = await getItemsFromSamples('./node_modules/@openstapps/core/test/resources'); - // tslint:disable-next-line: no-unused-expression - chai.expect(items).to.not.be.empty; - } + expect(items).to.not.be.empty; + }); - @test - async getCoreTestSamplesShouldFail() { - await chai.expect(getItemsFromSamples('./nonexistantdirectory')).to.be.rejectedWith(Error); - } + it('should fail to get core test samples', async function () { + await chai.expect(getItemsFromSamples('./non-existent-directory')).to.be.rejectedWith(Error); + }); - @test - async e2eRunSimulation() { + it('should run e2e simulation', async function () { type responses = Response; let failOnCompare = false; @@ -167,10 +160,9 @@ export class E2EConnectorSpec { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', }).should.be.rejectedWith('Unexpected difference'); - } + }); - @test - async indexShouldFail() { + it('should fail to index', async function () { type responses = Response; sandbox.on(httpClient, 'request', async (): Promise> => { @@ -185,33 +177,31 @@ export class E2EConnectorSpec { to: 'http://localhost', samplesLocation: './node_modules/@openstapps/core/test/resources', }).should.be.rejectedWith(ApiError); - } + }); - @test - async indexShouldFailDirectoryWithoutData() { - const emptyDirPath = join(__dirname, 'emptyDir'); - if (!existsSync(emptyDirPath)) { - mkdirSync(emptyDirPath); + it('should fail to index directory without data', async function () { + const emptyDirectoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'emptyDir'); + if (!existsSync(emptyDirectoryPath)) { + mkdirSync(emptyDirectoryPath); } - await e2eRun(httpClient, {to: 'http://localhost', samplesLocation: emptyDirPath}).should.be.rejectedWith( + await e2eRun(httpClient, {to: 'http://localhost', samplesLocation: emptyDirectoryPath}).should.be.rejectedWith( 'Could not index samples. None were retrieved from the file system.', ); - rmdirSync(emptyDirPath); - } + rmdirSync(emptyDirectoryPath); + }); - @test - async indexShouldFailDirectoryWithoutJsonData() { - const somewhatFilledDirPath = join(__dirname, 'somewhatFilledDir'); - if (!existsSync(somewhatFilledDirPath)) { - mkdirSync(somewhatFilledDirPath); + it('should fail to index directory without json data', async function () { + const somewhatFilledDirectoryPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'somewhatFilledDir'); + if (!existsSync(somewhatFilledDirectoryPath)) { + mkdirSync(somewhatFilledDirectoryPath); } - const nonJsonFile = join(somewhatFilledDirPath, 'nonjson.txt'); + const nonJsonFile = path.join(somewhatFilledDirectoryPath, 'nonjson.txt'); createFileSync(nonJsonFile); await e2eRun(httpClient, { to: 'http://localhost', - samplesLocation: somewhatFilledDirPath, + samplesLocation: somewhatFilledDirectoryPath, }).should.be.rejectedWith('Could not index samples. None were retrieved from the file system.'); unlinkSync(nonJsonFile); - rmdirSync(somewhatFilledDirPath); - } -} + rmdirSync(somewhatFilledDirectoryPath); + }); +}); diff --git a/packages/api/test/errors.spec.ts b/packages/api/test/errors.spec.ts index f13164c6..6b89f2e8 100644 --- a/packages/api/test/errors.spec.ts +++ b/packages/api/test/errors.spec.ts @@ -16,8 +16,7 @@ import chai from 'chai'; import {expect} from 'chai'; import chaiAsPromised from 'chai-as-promised'; import chaiSpies from 'chai-spies'; -import {suite, test} from '@testdeck/mocha'; -import {ApiError} from '../src/errors.js'; +import {ApiError} from '../src/index.js'; chai.should(); chai.use(chaiSpies); @@ -25,36 +24,32 @@ chai.use(chaiAsPromised); const sandbox = chai.spy.sandbox(); -@suite() -export class ErrorsSpec { - async after() { +describe('Errors', function () { + afterEach(function () { sandbox.restore(); - } + }); - @test - async shouldAddAdditionalData() { + it('should add additional data', function () { const error = new ApiError({ additionalData: 'Lorem ipsum', }); expect(error.toString()).to.contain('Lorem ipsum'); - } + }); - @test - async shouldAddRemoteStackTrace() { + it('should add remote stack-trace', async function () { const error = new ApiError({ stack: 'Lorem ipsum', }); expect(error.toString()).to.contain('Lorem ipsum'); - } + }); - @test - async shouldSetName() { + it('should set name', async function () { const error = new ApiError({ name: 'Foo', }); expect(error.name).to.be.equal('Foo'); - } -} + }); +}); diff --git a/packages/api/test/http-client.spec.ts b/packages/api/test/http-client.spec.ts index f991935a..0e00aa0e 100644 --- a/packages/api/test/http-client.spec.ts +++ b/packages/api/test/http-client.spec.ts @@ -13,27 +13,23 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {suite, test} from '@testdeck/mocha'; import nock from 'nock'; -import {HttpClient} from '../src/http-client.js'; +import {HttpClient} from '../src/index.js'; // TODO: use after each to clean up the nock (then there is no need for numerated resource links) -@suite() -export class HttpClientSpec { - @test - async construct() { +describe('HttpClient', function () { + afterEach(function () { + nock.cleanAll(); + }) + + it('should construct', function () { expect(() => { return new HttpClient(); }).not.to.throw(); - } + }); - async after() { - nock.cleanAll(); - } - - @test - async request() { + it('should request', async function () { const client = new HttpClient(); nock('http://www.example.com').get('/resource').reply(200, 'foo'); @@ -43,10 +39,9 @@ export class HttpClientSpec { }); expect(response.body).to.be.equal('foo'); - } + }); - @test - async requestWithBody() { + it('should request with body', async function () { const client = new HttpClient(); nock('http://www.example.com').get('/resource').reply(200, 'foo'); @@ -56,12 +51,11 @@ export class HttpClientSpec { }); expect(response.body).to.be.equal('foo'); - } + }); - @test - async requestWithError() { + it('should request with error', async function () { const client = new HttpClient(); - let caughtErr; + let caughtError; nock('http://www.example.com').get('/resource').replyWithError('foo'); @@ -72,15 +66,14 @@ export class HttpClientSpec { }, url: new URL('http://www.example.com/resource'), }); - } catch (err) { - caughtErr = err; + } catch (error) { + caughtError = error; } - expect(caughtErr).not.to.be.undefined; - } + expect(caughtError).not.to.be.undefined; + }); - @test - async requestWithHeaders() { + it('should request with headers', async function () { const client = new HttpClient(); nock('http://www.example.com').get('/resource').reply(200, 'foo'); @@ -93,10 +86,9 @@ export class HttpClientSpec { }); expect(response.body).to.be.equal('foo'); - } + }); - @test - async requestWithMethodGet() { + it('should request with method GET', async function () { const client = new HttpClient(); nock('http://www.example.com').get('/resource').reply(200, 'foo'); @@ -107,10 +99,9 @@ export class HttpClientSpec { }); expect(response.body).to.be.equal('foo'); - } + }); - @test - async requestWithMethodPost() { + it('should request with method POST', async function () { const client = new HttpClient(); nock('http://www.example.com').post('/resource').reply(200, 'foo'); @@ -121,5 +112,5 @@ export class HttpClientSpec { }); expect(response.body).to.be.equal('foo'); - } -} + }); +}); diff --git a/packages/api/test/plugin-client.spec.ts b/packages/api/test/plugin-client.spec.ts index 1599b503..b3739ccc 100644 --- a/packages/api/test/plugin-client.spec.ts +++ b/packages/api/test/plugin-client.spec.ts @@ -16,10 +16,7 @@ import {SCPluginRegisterRequest, SCPluginRegisterResponse, SCPluginRegisterRoute import chai from 'chai'; import {expect} from 'chai'; import chaiSpies from 'chai-spies'; -import {suite, test, timeout} from '@testdeck/mocha'; -import {HttpClient} from '../src/http-client.js'; -import {HttpClientResponse} from '../src/http-client-interface.js'; -import {PluginClient} from '../src/plugin-client.js'; +import {HttpClient, HttpClientResponse, PluginClient} from '../src/index.js'; import {TestPlugin} from './plugin-resources/test-plugin.js'; chai.use(chaiSpies); @@ -27,21 +24,16 @@ chai.use(chaiSpies); const sandbox = chai.spy.sandbox(); const httpClient = new HttpClient(); - const pluginRegisterRoute = new SCPluginRegisterRoute(); - const pluginClient = new PluginClient(httpClient, 'http://localhost'); -@suite(timeout(10000)) -export class PluginClientSpec { - static plugin: TestPlugin; +describe('PluginClient', function () { + this.timeout(10_000); - static async after() { - await this.plugin.close(); - } + let plugin: TestPlugin; - static async before() { - this.plugin = new TestPlugin( + beforeEach(async function () { + plugin = new TestPlugin( 4000, '', '', @@ -51,19 +43,19 @@ export class PluginClientSpec { getSchema: () => { /***/ }, - } as any, + } as never, '', '', '', ); - } + }); - async after() { + afterEach(async function () { + await plugin.close(); sandbox.restore(); - } + }); - @test - async registerPlugin() { + it('should register the plugin', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -76,16 +68,16 @@ export class PluginClientSpec { expect(httpClient.request).not.to.have.been.called(); - await pluginClient.registerPlugin(PluginClientSpec.plugin); + await pluginClient.registerPlugin(plugin); const request: SCPluginRegisterRequest = { action: 'add', plugin: { - address: PluginClientSpec.plugin.fullUrl, - name: PluginClientSpec.plugin.name, - requestSchema: PluginClientSpec.plugin.requestSchema, - responseSchema: PluginClientSpec.plugin.responseSchema, - route: PluginClientSpec.plugin.route, + address: plugin.fullUrl, + name: plugin.name, + requestSchema: plugin.requestSchema, + responseSchema: plugin.responseSchema, + route: plugin.route, }, }; @@ -97,10 +89,9 @@ export class PluginClientSpec { method: pluginRegisterRoute.method, url: new URL(`http://localhost${pluginRegisterRoute.getUrlPath()}`), }); - } + }); - @test - async unregisterPlugin() { + it('should unregister the plugin', async function () { sandbox.on(httpClient, 'request', async (): Promise> => { return { body: { @@ -113,11 +104,11 @@ export class PluginClientSpec { expect(httpClient.request).not.to.have.been.called(); - await pluginClient.unregisterPlugin(PluginClientSpec.plugin); + await pluginClient.unregisterPlugin(plugin); const request: SCPluginRegisterRequest = { action: 'remove', - route: PluginClientSpec.plugin.route, + route: plugin.route, }; expect(httpClient.request).to.have.been.first.called.with({ @@ -128,5 +119,5 @@ export class PluginClientSpec { method: pluginRegisterRoute.method, url: new URL(`http://localhost${pluginRegisterRoute.getUrlPath()}`), }); - } -} + }); +}); diff --git a/packages/api/test/plugin.spec.ts b/packages/api/test/plugin.spec.ts index 83ac9f1e..73317ccb 100644 --- a/packages/api/test/plugin.spec.ts +++ b/packages/api/test/plugin.spec.ts @@ -13,36 +13,35 @@ * this program. If not, see . */ -import {Converter} from '@openstapps/core-tools/lib/schema'; +import {Converter} from '@openstapps/core-tools'; import chai from 'chai'; import {expect} from 'chai'; import chaiSpies from 'chai-spies'; -import {readFileSync} from 'fs'; -import {suite, test, timeout} from '@testdeck/mocha'; -import {resolve} from 'path'; -import {HttpClient} from '../src/http-client.js'; +import {HttpClient} from '../src/index.js'; import {TestPlugin} from './plugin-resources/test-plugin.js'; +import path from "path"; +import {readFile} from "fs/promises"; +import {fileURLToPath} from "url"; chai.use(chaiSpies); -process.on('unhandledRejection', err => { - throw err; +process.on('unhandledRejection', error => { + throw error; }); const sandbox = chai.spy.sandbox(); const httpClient = new HttpClient(); -@suite(timeout(20000)) -export class PluginSpec { - static testPlugin: TestPlugin; +const dirname = path.dirname(fileURLToPath(import.meta.url)); - static async after() { - PluginSpec.testPlugin.close(); - } +describe('Plugin', function () { + this.timeout(20_000); - static async before() { - PluginSpec.testPlugin = new TestPlugin( + let testPlugin: TestPlugin; + + beforeEach(function () { + testPlugin = new TestPlugin( 4000, '', '', @@ -52,22 +51,22 @@ export class PluginSpec { getSchema: () => { /***/ }, - } as any, + } as never, '', '', '', ); - } + }) - async after() { + afterEach(async function () { + await testPlugin.close(); sandbox.restore(); - } + }) - @test - async construct() { + it('should construct', async function () { const converter = new Converter( - __dirname, - resolve(__dirname, 'plugin-resources', 'test-plugin-response.ts'), + dirname, + path.resolve(dirname, 'plugin-resources', 'test-plugin-response.ts'), ); sandbox.on(converter, 'getSchema', schemaName => { @@ -80,20 +79,19 @@ export class PluginSpec { 'http://B', '/C', // this doesn't matter for our tests, it's only something that affects the backend 'http://D', - // @ts-ignore fake converter is not a converter converter, 'PluginTestRequest', 'PluginTestResponse', - JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json')).toString()).version, + JSON.parse(await readFile(path.resolve(dirname, '..', 'package.json'), 'utf8')).version, ); expect(constructTestPlugin.port).to.be.equal(4001); expect(constructTestPlugin.name).to.be.equal('A'); expect(constructTestPlugin.url).to.be.equal('http://B'); expect(constructTestPlugin.route).to.be.equal('/C'); - // @ts-ignore backendUrl is protected + // @ts-expect-error private property expect(constructTestPlugin.backendUrl).to.be.equal('http://D'); // schemas are already covered, together with the directory and version - // @ts-ignore active is private + // @ts-expect-error private property expect(constructTestPlugin.active).to.be.equal(false); expect(constructTestPlugin.requestSchema.$id).to.be.equal('PluginTestRequest'); expect(constructTestPlugin.responseSchema.$id).to.be.equal('PluginTestResponse'); @@ -103,15 +101,14 @@ export class PluginSpec { url: new URL('http://localhost:4001'), }); // onRouteInvoke is a protected method, but we need to access it from the outside to test it - // @ts-ignore + // @ts-expect-error protected method expect(constructTestPlugin.onRouteInvoke).not.to.have.been.called(); await constructTestPlugin.close(); sandbox.restore(constructTestPlugin, 'onRouteInvoke'); - } + }); - @test - async fullUrl() { + it('should have full url', async function () { const constructTestPlugin = new TestPlugin( 4001, '', @@ -122,37 +119,35 @@ export class PluginSpec { getSchema: () => { /***/ }, - } as any, + } as never, '', '', '', ); expect(constructTestPlugin.fullUrl).to.be.equal('http://B:4001'); await constructTestPlugin.close(); - } + }); - @test - async start() { - PluginSpec.testPlugin.start(); + it('should start', async function () { + testPlugin.start(); - sandbox.on(PluginSpec.testPlugin, 'onRouteInvoke'); + sandbox.on(testPlugin, 'onRouteInvoke'); await httpClient.request({ url: new URL('http://localhost:4000'), }); // onRouteInvoke is a protected method, but we need to access it from the outside to test it - // @ts-ignore - expect(PluginSpec.testPlugin.onRouteInvoke).to.have.been.called(); - } + // @ts-expect-error protected method + expect(testPlugin.onRouteInvoke).to.have.been.called(); + }); - @test - async stop() { + it('should stop', async function () { // simulate a normal use case by first starting the plugin and then stopping it - PluginSpec.testPlugin.start(); - PluginSpec.testPlugin.stop(); + testPlugin.start(); + testPlugin.stop(); - sandbox.on(PluginSpec.testPlugin, 'onRouteInvoke'); + sandbox.on(testPlugin, 'onRouteInvoke'); const response = await httpClient.request({ url: new URL('http://localhost:4000'), @@ -160,7 +155,7 @@ export class PluginSpec { await expect(response.statusCode).to.be.equal(404); // onRouteInvoke is a protected method, but we need to access it from the outside to test it - // @ts-ignore - expect(PluginSpec.testPlugin.onRouteInvoke).not.to.have.been.called(); - } -} + // @ts-expect-error protected method + expect(testPlugin.onRouteInvoke).not.to.have.been.called(); + }); +}); diff --git a/packages/collection-utils/package.json b/packages/collection-utils/package.json index 74ed2fbf..ac17dc1f 100644 --- a/packages/collection-utils/package.json +++ b/packages/collection-utils/package.json @@ -6,20 +6,20 @@ "main": "lib/index.js", "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", - "test": "nyc mocha 'test/**/*.spec.ts'" + "test": "c8 mocha" }, "devDependencies": { "@openstapps/eslint-config": "workspace:*", - "@openstapps/nyc-config": "workspace:*", "@openstapps/prettier-config": "workspace:*", "@openstapps/tsconfig": "workspace:*", + "@types/node": "18.15.3", "@types/chai": "4.3.4", "@types/mocha": "10.0.1", - "@types/node": "18.15.3", + "c8": "7.13.0", "chai": "4.3.7", "mocha": "10.2.0", "ts-node": "10.9.1", @@ -41,8 +41,5 @@ "@openstapps" ] }, - "nyc": { - "extends": "@openstapps/nyc-config" - }, "exports": "./lib/index.js" } diff --git a/packages/collection-utils/test/chunk.spec.ts b/packages/collection-utils/test/chunk.spec.ts index f1cf480a..c07a865d 100644 --- a/packages/collection-utils/test/chunk.spec.ts +++ b/packages/collection-utils/test/chunk.spec.ts @@ -12,8 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ - -import {chunk} from '../src/chunk.js'; +import {chunk} from '../src/index.js'; import {expect} from 'chai'; describe('chunk', function () { diff --git a/packages/collection-utils/test/difference.spec.ts b/packages/collection-utils/test/difference.spec.ts index 4295cff2..e1c451c6 100644 --- a/packages/collection-utils/test/difference.spec.ts +++ b/packages/collection-utils/test/difference.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {differenceBy} from '../src/difference.js'; +import {differenceBy} from '../src/index.js'; import {expect} from 'chai'; describe('differenceBy', function () { diff --git a/packages/collection-utils/test/get.spec.ts b/packages/collection-utils/test/get.spec.ts index 59a372e8..042396b4 100644 --- a/packages/collection-utils/test/get.spec.ts +++ b/packages/collection-utils/test/get.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {get} from '../src/get.js'; +import {get} from '../src/index.js'; import {expect} from 'chai'; describe('get', function () { diff --git a/packages/collection-utils/test/group-by.spec.ts b/packages/collection-utils/test/group-by.spec.ts index aff27d8b..990bc383 100644 --- a/packages/collection-utils/test/group-by.spec.ts +++ b/packages/collection-utils/test/group-by.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {groupBy, groupByStable, groupByProperty} from '../src/group-by.js'; +import {groupBy, groupByStable, groupByProperty} from '../src/index.js'; import {expect} from 'chai'; describe('groupBy', () => { diff --git a/packages/collection-utils/test/key-by.spec.ts b/packages/collection-utils/test/key-by.spec.ts index 77ea068e..878c49a4 100644 --- a/packages/collection-utils/test/key-by.spec.ts +++ b/packages/collection-utils/test/key-by.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {keyBy} from '../src/key-by.js'; +import {keyBy} from '../src/index.js'; import {expect} from 'chai'; describe('keyBy', function () { diff --git a/packages/collection-utils/test/map-values.spec.ts b/packages/collection-utils/test/map-values.spec.ts index 4e968f2d..67b49d34 100644 --- a/packages/collection-utils/test/map-values.spec.ts +++ b/packages/collection-utils/test/map-values.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {mapValues} from '../src/map-values.js'; +import {mapValues} from '../src/index.js'; import {expect} from 'chai'; describe('map-values', () => { diff --git a/packages/collection-utils/test/min.spec.ts b/packages/collection-utils/test/min.spec.ts index 2d9e4c62..df7b6cc7 100644 --- a/packages/collection-utils/test/min.spec.ts +++ b/packages/collection-utils/test/min.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {minBy} from '../src/min.js'; +import {minBy} from '../src/index.js'; import {expect} from 'chai'; describe('minBy', function () { diff --git a/packages/collection-utils/test/omit.spec.ts b/packages/collection-utils/test/omit.spec.ts index 0055edc6..bd6e5ac5 100644 --- a/packages/collection-utils/test/omit.spec.ts +++ b/packages/collection-utils/test/omit.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {omit} from '../src/omit.js'; +import {omit} from '../src/index.js'; import {expect} from 'chai'; describe('omit', function () { diff --git a/packages/collection-utils/test/partition.spec.ts b/packages/collection-utils/test/partition.spec.ts index c379dd72..b01998e5 100644 --- a/packages/collection-utils/test/partition.spec.ts +++ b/packages/collection-utils/test/partition.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {partition} from '../src/partition.js'; +import {partition} from '../src/index.js'; import {expect} from 'chai'; describe('partition', function () { diff --git a/packages/collection-utils/test/pick.spec.ts b/packages/collection-utils/test/pick.spec.ts index 85fd3e9d..68e48bf8 100644 --- a/packages/collection-utils/test/pick.spec.ts +++ b/packages/collection-utils/test/pick.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {pick} from '../src/pick.js'; +import {pick} from '../src/index.js'; import {expect} from 'chai'; describe('pick', function () { diff --git a/packages/collection-utils/test/shuffle.spec.ts b/packages/collection-utils/test/shuffle.spec.ts index 0dbf9465..79732396 100644 --- a/packages/collection-utils/test/shuffle.spec.ts +++ b/packages/collection-utils/test/shuffle.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {shuffle} from '../src/shuffle.js'; +import {shuffle} from '../src/index.js'; import {expect} from 'chai'; describe('shuffle', function () { diff --git a/packages/collection-utils/test/string-sort.spec.ts b/packages/collection-utils/test/string-sort.spec.ts index 053b8167..d554a0e4 100644 --- a/packages/collection-utils/test/string-sort.spec.ts +++ b/packages/collection-utils/test/string-sort.spec.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {stringSort, stringSortBy} from '../src/string-sort.js'; +import {stringSort, stringSortBy} from '../src/index.js'; import {expect} from 'chai'; describe('stringSort', () => { diff --git a/packages/collection-utils/test/sum.spec.ts b/packages/collection-utils/test/sum.spec.ts index 19fdea97..76b8ba47 100644 --- a/packages/collection-utils/test/sum.spec.ts +++ b/packages/collection-utils/test/sum.spec.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {sum, sumBy} from '../src/sum.js'; +import {sum, sumBy} from '../src/index.js'; describe('sum', () => { it('should return the sum of all elements in the collection', () => { diff --git a/packages/collection-utils/test/tree-group.spec.ts b/packages/collection-utils/test/tree-group.spec.ts index de759a30..d2f71f65 100644 --- a/packages/collection-utils/test/tree-group.spec.ts +++ b/packages/collection-utils/test/tree-group.spec.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {Tree, treeGroupBy} from '../src/tree-group.js'; +import {Tree, treeGroupBy} from '../src/index.js'; interface TestItem { id: number; diff --git a/packages/collection-utils/test/uniq.spec.ts b/packages/collection-utils/test/uniq.spec.ts index a6cce2f8..95e9192b 100644 --- a/packages/collection-utils/test/uniq.spec.ts +++ b/packages/collection-utils/test/uniq.spec.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {uniqBy} from '../src/uniq.js'; +import {uniqBy} from '../src/index.js'; describe('uniq', function () { it('should return an array with unique values', function () { diff --git a/packages/collection-utils/test/zip.spec.ts b/packages/collection-utils/test/zip.spec.ts index 246c83f7..ad8855f3 100644 --- a/packages/collection-utils/test/zip.spec.ts +++ b/packages/collection-utils/test/zip.spec.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {zip} from '../src/zip.js'; +import {zip} from '../src/index.js'; describe('zip', function () { it('should zip arrays together', function () { diff --git a/packages/core-tools/README.md b/packages/core-tools/README.md index bac5c9bd..7c7a456b 100644 --- a/packages/core-tools/README.md +++ b/packages/core-tools/README.md @@ -46,7 +46,6 @@ Inside of a script in `package.json` or if the npm package is installed globally openstapps-core-tools schema src/core lib/schema ``` - ## How to use the validator? ### Using the validator programatically diff --git a/packages/core-tools/package.json b/packages/core-tools/package.json index a478e6a7..24733acb 100644 --- a/packages/core-tools/package.json +++ b/packages/core-tools/package.json @@ -27,26 +27,25 @@ }, "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", "plantuml-restart": "docker restart plantuml-server", "plantuml-start": "docker run --name plantuml-server -d -p 8080:8080 registry.gitlab.com/openstapps/core-tools:latest", "plantuml-stop": "docker stop plantuml-server", - "test": "nyc mocha 'test/**/*.spec.ts'" + "test": "c8 mocha" }, "dependencies": { "@openstapps/collection-utils": "workspace:*", - "@openstapps/logger": "workspace:*", "@openstapps/easy-ast": "workspace:*", + "@openstapps/logger": "workspace:*", "ajv": "8.12.0", + "re2": "1.18.0", "better-ajv-errors": "1.2.0", - "chai": "4.3.7", "commander": "10.0.0", "deepmerge": "4.3.1", "del": "6.1.1", - "eslint": "8.33.0", "flatted": "3.2.7", "fs-extra": "10.1.0", "glob": "10.2.1", @@ -56,18 +55,14 @@ "mustache": "4.2.0", "openapi-types": "12.1.0", "plantuml-encoder": "1.4.0", - "re2": "1.18.0", "toposort": "2.0.2", - "ts-json-schema-generator": "1.2.0", - "ts-node": "10.9.1", - "typescript": "4.8.4" + "ts-json-schema-generator": "1.2.0" }, "devDependencies": { "@openstapps/eslint-config": "workspace:*", "@openstapps/nyc-config": "workspace:*", "@openstapps/prettier-config": "workspace:*", "@openstapps/tsconfig": "workspace:*", - "@testdeck/mocha": "0.3.3", "@types/chai": "4.3.4", "@types/fs-extra": "9.0.13", "@types/glob": "8.0.1", @@ -75,10 +70,13 @@ "@types/mocha": "10.0.1", "@types/mustache": "4.2.2", "@types/node": "18.15.3", + "chai": "4.3.7", "mocha": "10.2.0", + "c8": "7.13.0", "nock": "13.3.0", "tsup": "6.7.0", - "typedoc": "0.23.28" + "ts-node": "10.9.1", + "typescript": "4.8.4" }, "tsup": { "entry": [ @@ -99,8 +97,5 @@ "eslintIgnore": [ "resources", "openapi" - ], - "nyc": { - "extends": "@openstapps/nyc-config" - } + ] } diff --git a/packages/core-tools/src/app.ts b/packages/core-tools/src/app.ts index df8ff3cf..b64bddb3 100644 --- a/packages/core-tools/src/app.ts +++ b/packages/core-tools/src/app.ts @@ -17,7 +17,6 @@ import {Command} from 'commander'; import {existsSync, readFileSync, writeFileSync} from 'fs'; import {copy} from 'fs-extra'; import path from 'path'; -import {mkdirPromisified, readFilePromisified} from './common.js'; import {lightweightDefinitionsFromPath, lightweightProjectFromPath} from '@openstapps/easy-ast'; import {openapi3Template} from './resources/openapi-303-template.js'; import {gatherRouteInformation, generateOpenAPIForRoute} from './routes.js'; @@ -27,6 +26,7 @@ import {UMLConfig} from './uml/uml-config.js'; import {capitalize} from './util/string.js'; import {validateFiles, writeReport} from './validate.js'; import {fileURLToPath} from 'url'; +import {mkdir, readFile} from 'fs/promises'; // handle unhandled promise rejections process.on('unhandledRejection', async (reason: unknown) => { @@ -42,7 +42,7 @@ const commander = new Command('openstapps-core-tools'); // eslint-disable-next-line unicorn/prefer-module commander.version( JSON.parse( - readFileSync(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json')).toString(), + readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json')).toString(), ).version, ); @@ -100,7 +100,7 @@ commander // copy schema json schema files try { if (!existsSync(outDirectorySchemasPath)) { - await mkdirPromisified(outDirectorySchemasPath, { + await mkdir(outDirectorySchemasPath, { recursive: true, }); } @@ -134,7 +134,7 @@ commander.command('schema ').action(async (relativeSourceP Logger.info(`Found ${validatableTypes.length} type(s) to generate schemas for.`); - await mkdirPromisified(schemaPath, { + await mkdir(schemaPath, { recursive: true, }); @@ -150,7 +150,7 @@ commander.command('schema ').action(async (relativeSourceP Logger.info(`Using ${corePackageJsonPath} to determine version for schemas.`); - const buffer = await readFilePromisified(corePackageJsonPath); + const buffer = await readFile(corePackageJsonPath); const corePackageJson = JSON.parse(buffer.toString()); const coreVersion = corePackageJson.version; diff --git a/packages/core-tools/src/common.ts b/packages/core-tools/src/common.ts index dac4708a..3ea2fa0c 100644 --- a/packages/core-tools/src/common.ts +++ b/packages/core-tools/src/common.ts @@ -13,17 +13,8 @@ * this program. If not, see . */ import {Logger} from '@openstapps/logger'; -import {existsSync, mkdir, readFile, unlink, writeFile} from 'fs'; -import glob from 'glob'; -import {platform} from 'os'; -import {promisify} from 'util'; import path from 'path'; - -export const globPromisified = promisify(glob.Glob); -export const mkdirPromisified = promisify(mkdir); -export const readFilePromisified = promisify(readFile); -export const writeFilePromisified = promisify(writeFile); -export const unlinkPromisified = promisify(unlink); +import {existsSync} from 'fs'; /** * Get path that contains a tsconfig.json @@ -33,21 +24,15 @@ export const unlinkPromisified = promisify(unlink); export function getTsconfigPath(startPath: string): string { let tsconfigPath = startPath; - // see https://stackoverflow.com/questions/9652043/identifying-the-file-system-root-with-node-js - const root = platform() === 'win32' ? process.cwd().split(path.sep)[0] : '/'; - - // repeat until a tsconfig.json is found while (!existsSync(path.join(tsconfigPath, 'tsconfig.json'))) { - if (tsconfigPath === root) { + const parent = path.resolve(tsconfigPath, '..'); + if (tsconfigPath === parent) { throw new Error( - `Reached file system root ${root} while searching for 'tsconfig.json' in ${startPath}!`, + `Reached file system root ${parent} while searching for 'tsconfig.json' in ${startPath}!`, ); } - // pop last directory - const tsconfigPathParts = tsconfigPath.split(path.sep); - tsconfigPathParts.pop(); - tsconfigPath = tsconfigPathParts.join(path.sep); + tsconfigPath = parent; } Logger.info(`Using 'tsconfig.json' from ${tsconfigPath}.`); diff --git a/packages/core-tools/src/index.ts b/packages/core-tools/src/index.ts index 9695025f..dfd380fd 100644 --- a/packages/core-tools/src/index.ts +++ b/packages/core-tools/src/index.ts @@ -1,11 +1,11 @@ -export * from './validate.js' -export * from './types/validator.js' +export * from './validate.js'; +export * from './types/validator.js'; -export * from './uml/uml-config.js' -export * from './uml/create-diagram.js' +export * from './uml/uml-config.js'; +export * from './uml/create-diagram.js'; -export * from './routes.js' -export * from './types/routes.js' +export * from './routes.js'; +export * from './types/routes.js'; -export * from './schema.js' -export * from './types/schema.js' +export * from './schema.js'; +export * from './types/schema.js'; diff --git a/packages/core-tools/src/routes.ts b/packages/core-tools/src/routes.ts index c8c31f4d..d1a6922a 100644 --- a/packages/core-tools/src/routes.ts +++ b/packages/core-tools/src/routes.ts @@ -13,7 +13,11 @@ * this program. If not, see . */ import {OpenAPIV3} from 'openapi-types'; -import {isLightweightClass, lightweightProjectFromPath, LightweightProjectWithIndex} from '@openstapps/easy-ast'; +import { + isLightweightClass, + lightweightProjectFromPath, + LightweightProjectWithIndex, +} from '@openstapps/easy-ast'; import {RouteInstanceWithMeta, RouteWithMetaInformation} from './types/routes.js'; import {rejectNil} from './util/collections.js'; import {capitalize} from './util/string.js'; diff --git a/packages/core-tools/src/schema.ts b/packages/core-tools/src/schema.ts index c526163b..b4307211 100644 --- a/packages/core-tools/src/schema.ts +++ b/packages/core-tools/src/schema.ts @@ -22,7 +22,7 @@ import {getTsconfigPath} from './common.js'; import {definitionsOf, lightweightProjectFromPath} from '@openstapps/easy-ast'; import {isSchemaWithDefinitions} from './util/guards.js'; import path from 'path'; -import re2 from './types/re2.js'; +import re2 from 're2'; /** * StAppsCore converter @@ -64,7 +64,7 @@ export class Converter { this.generator = new SchemaGenerator(program, createParser(program, config), createFormatter(config)); // create Ajv instance - this.schemaValidator = new Ajv.default({code: {regExp: re2}}); + this.schemaValidator = new Ajv.default({code: {regExp: re2 as never}}); } /** diff --git a/packages/core-tools/src/types/re2.ts b/packages/core-tools/src/types/re2.ts deleted file mode 100644 index 53a1d6e7..00000000 --- a/packages/core-tools/src/types/re2.ts +++ /dev/null @@ -1,6 +0,0 @@ -import re2 from 're2'; - -type Re2 = typeof re2 & {code: string}; -(re2 as Re2).code = 'require("lib/types/re2").default'; - -export default re2 as Re2; diff --git a/packages/core-tools/src/uml/create-diagram.ts b/packages/core-tools/src/uml/create-diagram.ts index 61cab545..de660d21 100644 --- a/packages/core-tools/src/uml/create-diagram.ts +++ b/packages/core-tools/src/uml/create-diagram.ts @@ -13,7 +13,6 @@ * this program. If not, see . */ import {Logger} from '@openstapps/logger'; -import {createWriteStream} from 'fs'; import * as request from 'got'; import { expandTypeValue, @@ -22,9 +21,10 @@ import { LightweightClassDefinition, LightweightDefinition, LightweightProperty, - LightweightType + LightweightType, } from '@openstapps/easy-ast'; import {UMLConfig} from './uml-config.js'; +import {writeFile} from 'fs/promises'; /** * Converts the lightweight class/enum definitions according to the configuration, @@ -81,8 +81,8 @@ export async function createDiagramFromString( plantUmlBaseURL: string, outputFile = `Diagram-${new Date().toISOString()}`, ) { - // eslint-disable-next-line @typescript-eslint/no-var-requires,unicorn/prefer-module - const plantumlEncoder = require('plantuml-encoder'); + // @ts-expect-error no declarations + const plantumlEncoder = await import('plantuml-encoder'); const plantUMLCode = plantumlEncoder.encode(`@startuml\n${modelPlantUMLCode}\n@enduml`); const url = `${plantUmlBaseURL}/svg/${plantUMLCode}`; let response; @@ -100,13 +100,10 @@ export async function createDiagramFromString( throw error; } // attach file extension - const fileName = `${outputFile}.svg`; - try { - createWriteStream(fileName).write(response.body); - Logger.log(`Writen data to file: ${fileName}`); - } catch { - throw new Error('Could not write file. Are you missing permissions?'); - } + const fileName = `${outputFile.replace(/[^\w-]/g, '_')}.svg`; + + await writeFile(fileName, response.body); + Logger.log(`Writen data to file: ${fileName}`); return fileName; } diff --git a/packages/core-tools/src/util/collections.ts b/packages/core-tools/src/util/collections.ts index ee0fdf84..e1e07a53 100644 --- a/packages/core-tools/src/util/collections.ts +++ b/packages/core-tools/src/util/collections.ts @@ -17,7 +17,7 @@ */ export function rejectNil(array: Array): T[] { // eslint-disable-next-line unicorn/no-null - return array.filter(it => it == null) as T[]; + return array.filter(it => it != null) as T[]; } /** diff --git a/packages/core-tools/src/validate.ts b/packages/core-tools/src/validate.ts index e6c64abf..c6bed361 100644 --- a/packages/core-tools/src/validate.ts +++ b/packages/core-tools/src/validate.ts @@ -15,16 +15,17 @@ import {Logger} from '@openstapps/logger'; import Ajv from 'ajv'; import betterAjvErrors, {IOutputError} from 'better-ajv-errors'; -import {PathLike} from 'fs'; +import type {PathLike} from 'fs'; +import {readFile, writeFile} from 'fs/promises'; import {JSONSchema7} from 'json-schema'; import mustache from 'mustache'; import {Schema} from 'ts-json-schema-generator'; -import {globPromisified, readFilePromisified, writeFilePromisified} from './common.js'; import {ExpectedValidationErrors, ValidationError, ValidationResult} from './types/validator.js'; import {isThingWithType} from './util/guards.js'; import path from 'path'; -import re2 from './types/re2.js'; -import {toPosixPath} from './util/posix-path.js'; +import re2 from 're2'; +import {glob} from 'glob'; +import {fileURLToPath} from 'url'; /** * StAppsCore validator @@ -35,13 +36,13 @@ export class Validator { */ private readonly ajv = new Ajv.default({ verbose: true, - code: {regExp: re2}, + code: {regExp: re2 as never}, }); /** * Map of schema names to schemas */ - private readonly schemas: {[type: string]: Schema} = {}; + private readonly schemas: { [type: string]: Schema } = {}; /** * A wrapper function for Ajv that transforms the error into the compatible old error @@ -58,8 +59,9 @@ export class Validator { * * @param schemaDirectory Path to directory that contains schema files */ - public async addSchemas(schemaDirectory: PathLike): Promise { - const schemaFiles = await globPromisified(path.posix.join(toPosixPath(schemaDirectory), '*.json')); + public async addSchemas(schemaDirectory: string): Promise { + const searchGlob = path.posix.join(schemaDirectory.replaceAll(path.sep, path.posix.sep), '*.json'); + const schemaFiles = await glob(searchGlob); if (schemaFiles.length === 0) { throw new Error(`No schema files in ${schemaDirectory.toString()}!`); @@ -70,7 +72,7 @@ export class Validator { await Promise.all( schemaFiles.map(async (file: string) => { // read schema file - const buffer = await readFilePromisified(file); + const buffer = await readFile(file); // add schema to map this.schemas[path.basename(file, '.json')] = JSON.parse(buffer.toString()); @@ -92,7 +94,7 @@ export class Validator { if (schema === undefined) { if (isThingWithType(instance)) { // schema name can be inferred from type string - const schemaSuffix = (instance as {type: string}).type + const schemaSuffix = (instance as { type: string }).type .split(' ') .map((part: string) => { return part.slice(0, 1).toUpperCase() + part.slice(1); @@ -175,8 +177,8 @@ export async function validateFiles( const v = new Validator(); await v.addSchemas(schemaDirectory); - // get list of files to test - const testFiles = await globPromisified(path.join(resourcesDirectory, '*.json')); + // get a list of files to test + const testFiles = await glob(path.posix.join(resourcesDirectory.replaceAll(path.sep, path.posix.sep), '*.json'), {absolute: true}); if (testFiles.length === 0) { throw new Error(`No test files in ${resourcesDirectory}!`); @@ -191,7 +193,7 @@ export async function validateFiles( testFiles.map(async (testFile: string) => { const testFileName = path.basename(testFile); - const buffer = await readFilePromisified(path.join(resourcesDirectory, testFileName)); + const buffer = await readFile(testFile); // read test description from file const testDescription = JSON.parse(buffer.toString()); @@ -260,12 +262,14 @@ export async function validateFiles( * @param errors Errors that occurred in validation */ export async function writeReport(reportPath: PathLike, errors: ExpectedValidationErrors): Promise { - // eslint-disable-next-line unicorn/prefer-module - let buffer = await readFilePromisified(path.resolve(__dirname, '..', 'resources', 'file.html.mustache')); + let buffer = await readFile( + path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'resources', 'file.html.mustache'), + ); const fileTemplate = buffer.toString(); - // eslint-disable-next-line unicorn/prefer-module - buffer = await readFilePromisified(path.resolve(__dirname, '..', 'resources', 'error.html.mustache')); + buffer = await readFile( + path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'resources', 'error.html.mustache'), + ); const errorTemplate = buffer.toString(); let output = ''; @@ -295,11 +299,12 @@ export async function writeReport(reportPath: PathLike, errors: ExpectedValidati }); } - // eslint-disable-next-line unicorn/prefer-module - buffer = await readFilePromisified(path.resolve(__dirname, '..', 'resources', 'report.html.mustache')); + buffer = await readFile( + path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'resources', 'report.html.mustache'), + ); const reportTemplate = buffer.toString(); - await writeFilePromisified( + await writeFile( reportPath, mustache.render(reportTemplate, { report: output, diff --git a/packages/core-tools/test/common.spec.ts b/packages/core-tools/test/common.spec.ts index a60b79fb..a7014034 100644 --- a/packages/core-tools/test/common.spec.ts +++ b/packages/core-tools/test/common.spec.ts @@ -15,9 +15,9 @@ */ import {Logger} from '@openstapps/logger'; import {expect} from 'chai'; -import {slow, suite, test, timeout} from '@testdeck/mocha'; -import {cwd} from 'process'; import {getTsconfigPath} from '../src/common.js'; +import path from 'path'; +import {fileURLToPath} from 'url'; process.on('unhandledRejection', (reason: unknown): void => { if (reason instanceof Error) { @@ -26,10 +26,10 @@ process.on('unhandledRejection', (reason: unknown): void => { process.exit(1); }); -@suite(timeout(20_000), slow(10_000)) -export class CommonSpec { - @test - async getTsconfigPath() { - expect(getTsconfigPath(__dirname)).to.be.equal(cwd()); - } -} +describe('common', function () { + describe('getTsconfigPath', function () { + it('should get tsconfig path', function () { + expect(getTsconfigPath(path.dirname(fileURLToPath(import.meta.url)))).to.be.equal(process.cwd()); + }); + }); +}); diff --git a/packages/core-tools/test/create-diagram.spec.ts b/packages/core-tools/test/create-diagram.spec.ts index 745322c4..173ce1f2 100644 --- a/packages/core-tools/test/create-diagram.spec.ts +++ b/packages/core-tools/test/create-diagram.spec.ts @@ -14,36 +14,32 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {existsSync, unlinkSync} from 'fs'; -import {slow, suite, test, timeout} from '@testdeck/mocha'; -import {createDiagram, createDiagramFromString} from '../src/uml/create-diagram.js'; -import {UMLConfig} from '../src/uml/uml-config.js'; -import {LightweightDefinition, lightweightDefinitionsFromPath} from '@openstapps/easy-ast'; +import {unlink} from 'fs/promises'; +import {createDiagram, createDiagramFromString} from '../src/index.js'; +import {UMLConfig} from '../src/index.js'; +import {lightweightDefinitionsFromPath} from '@openstapps/easy-ast'; import nock = require('nock'); import path from 'path'; +import {existsSync} from 'fs'; +import {fileURLToPath} from 'url'; -@suite(timeout(15_000), slow(5000)) -export class CreateDiagramSpec { - plantUmlConfig: UMLConfig; +describe('CreateDiagram', function () { + this.timeout(15_000); + this.slow(5000); - definitions: LightweightDefinition[]; + const plantUmlConfig: UMLConfig = { + definitions: [], + showAssociations: true, + showEnumValues: true, + showInheritance: true, + showInheritedProperties: true, + showOptionalProperties: true, + showProperties: true, + }; - constructor() { - this.plantUmlConfig = { - definitions: [], - showAssociations: true, - showEnumValues: true, - showInheritance: true, - showInheritedProperties: true, - showOptionalProperties: true, - showProperties: true, - }; + const definitions = lightweightDefinitionsFromPath('./test/model'); - this.definitions = lightweightDefinitionsFromPath('./test/model'); - } - - @test - async shouldRefuseRequest() { + it('should refuse request', async function () { const testPlantUmlCode = 'class Test{\n}'; try { await createDiagramFromString(testPlantUmlCode, 'http://plantuml:8080'); @@ -54,7 +50,7 @@ export class CreateDiagramSpec { new Error('getaddrinfo ENOTFOUND plantuml').message, ]).to.include((error as NodeJS.ErrnoException).message); } - } + }); /** * This test will only test the functionality of the method @@ -63,26 +59,25 @@ export class CreateDiagramSpec { * - Writing the response to a file * This test will not check the file content */ - @test - async shouldCreateDiagrams() { + it('should create diagrams', async function () { nock('http://plantuml:8080') .persist() .get(() => true) .reply(200, 'This will be the file content'); - let fileName = await createDiagram(this.definitions, this.plantUmlConfig, 'http://plantuml:8080'); - let filePath = path.resolve(__dirname, '..', fileName); - expect(await existsSync(filePath)).to.equal(true); + let fileName = await createDiagram(definitions, plantUmlConfig, 'http://plantuml:8080'); + let filePath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', fileName); + expect(existsSync(filePath)).to.be.true; - await unlinkSync(fileName); - this.plantUmlConfig.showAssociations = false; + await unlink(fileName); + plantUmlConfig.showAssociations = false; - this.plantUmlConfig.showInheritance = false; - fileName = await createDiagram(this.definitions, this.plantUmlConfig, 'http://plantuml:8080'); - filePath = path.resolve(__dirname, '..', fileName); - expect(await existsSync(filePath)).to.equal(true); - await unlinkSync(fileName); + plantUmlConfig.showInheritance = false; + fileName = await createDiagram(definitions, plantUmlConfig, 'http://plantuml:8080'); + filePath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', fileName); + expect(existsSync(filePath)).to.be.true; + await unlink(fileName); nock.cleanAll(); - } -} + }); +}); diff --git a/packages/core-tools/test/schema.spec.ts b/packages/core-tools/test/schema.spec.ts index 99218ab6..8f3db365 100644 --- a/packages/core-tools/test/schema.spec.ts +++ b/packages/core-tools/test/schema.spec.ts @@ -15,9 +15,9 @@ */ import {Logger} from '@openstapps/logger'; import {expect} from 'chai'; -import {slow, suite, test, timeout} from '@testdeck/mocha'; import {Converter} from '../src/schema.js'; import path from 'path'; +import {fileURLToPath} from 'url'; process.on('unhandledRejection', (error: unknown) => { if (error instanceof Error) { @@ -26,11 +26,14 @@ process.on('unhandledRejection', (error: unknown) => { process.exit(1); }); -@suite(timeout(40_000), slow(10_000)) -export class SchemaSpec { - @test - async getSchema() { - const converter = new Converter(path.join(__dirname, '..', 'src', 'resources')); +describe('Schema', function () { + this.timeout(40_000); + this.slow(10_000); + + it('should create schema', function () { + const converter = new Converter( + path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'src', 'resources'), + ); const schema = converter.getSchema('Foo', '0.0.1'); expect(schema).to.be.deep.equal({ @@ -77,5 +80,5 @@ export class SchemaSpec { required: ['lorem', 'type'], type: 'object', }); - } -} + }); +}); diff --git a/packages/core-tools/test/validate.spec.ts b/packages/core-tools/test/validate.spec.ts index 28b11ba0..81b4d086 100644 --- a/packages/core-tools/test/validate.spec.ts +++ b/packages/core-tools/test/validate.spec.ts @@ -15,14 +15,14 @@ */ import {Logger} from '@openstapps/logger'; import {expect} from 'chai'; -import {existsSync, mkdirSync, writeFileSync} from 'fs'; +import {existsSync} from 'fs'; import {JSONSchema7 as Schema} from 'json-schema'; -import {slow, suite, test, timeout} from '@testdeck/mocha'; -import rimraf from 'rimraf'; import {Foo} from '../src/resources/foo.js'; -import {Converter} from '../src/schema.js'; import {Validator} from '../src/validate.js'; import path from 'path'; +import {fileURLToPath} from 'url'; +import {rm, mkdir, writeFile} from 'fs/promises'; +import {Converter} from '../src/index.js'; process.on('unhandledRejection', (error: unknown) => { if (error instanceof Error) { @@ -31,57 +31,55 @@ process.on('unhandledRejection', (error: unknown) => { process.exit(1); }); -const tmpdir = path.join(__dirname, 'tmp'); +const tmpdir = path.join(path.dirname(fileURLToPath(import.meta.url)), 'tmp'); const fooInstance: Foo = { lorem: 'ipsum', type: 'Foo', }; -@suite(timeout(40_000), slow(5000)) -export class ValidateSpec { - static converter: Converter; +describe('Validator', function () { + this.timeout(40_000); + this.slow(5000); - static schema: Schema; + let schema: Schema; + let converter: Converter; - static before() { - this.converter = new Converter(path.join(__dirname, '..', 'src', 'resources')); - this.schema = this.converter.getSchema('Foo', '0.0.1'); + beforeEach(async function () { + converter = new Converter( + path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'src', 'resources'), + ); + schema = converter.getSchema('Foo', '0.0.1'); if (!existsSync(tmpdir)) { - mkdirSync(tmpdir); + await mkdir(tmpdir); } - writeFileSync(path.join(tmpdir, 'SCFoo.json'), JSON.stringify(this.schema, undefined, 2)); - } + await writeFile(path.join(tmpdir, 'SCFoo.json'), JSON.stringify(schema, undefined, 2)); + }); - static after() { - rimraf(tmpdir, error => { - // tslint:disable-next-line: no-unused-expression + afterEach(async function () { + try { + await rm(tmpdir, {recursive: true}); + } catch (error) { expect(error, `Unable to remove temporary directory for tests at: ${tmpdir}`).to.be.null; - }); - } + } + }); - @test - async validateBySchemaIdentifyingString() { + it('should validate by schema identifying string', async function () { const validator = new Validator(); await validator.addSchemas(tmpdir); const validationResult = validator.validate(fooInstance, 'SCFoo'); - // tslint:disable-next-line: no-unused-expression expect(validationResult.errors, JSON.stringify(validationResult.errors, undefined, 2)).to.be.empty; - } + }); - @test - async validateBySchemaInstance() { + it('should validate by schema instance', async function () { const validator = new Validator(); - const validationResult = validator.validate(fooInstance, ValidateSpec.schema); - // tslint:disable-next-line: no-unused-expression + const validationResult = validator.validate(fooInstance, schema); expect(validationResult.errors, JSON.stringify(validationResult.errors, undefined, 2)).to.be.empty; - } + }); - @test - async validateIntrinsic() { + it('should validate intrinsic', async function () { const validator = new Validator(); await validator.addSchemas(tmpdir); const validationResult = validator.validate(fooInstance); - // tslint:disable-next-line: no-unused-expression expect(validationResult.errors, JSON.stringify(validationResult.errors, undefined, 2)).to.be.empty; - } -} + }); +}); diff --git a/packages/core/package.json b/packages/core/package.json index ac53f046..44ae78b8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -26,15 +26,15 @@ "main": "./lib/index.js", "types": "./lib/index.d.ts", "scripts": { - "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "build": "tsup --dts && pnpm run mappings && pnpm run schema", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", "mappings": "openstapps-es-mapping-generator mapping ../core/src -i minlength,pattern,see,tjs-format -m lib/mappings/mappings.json -a lib/mappings/aggregations.json", "mappings-integration": "openstapps-es-mapping-generator put-es-templates lib/mappings/mappings.json http://elasticsearch:9200/", - "schema": "node --max-old-space-size=8192 --stack-size=10240 ./node_modules/@openstapps/core-tools/lib/cli.js schema src lib/schema", - "test": "nyc mocha --recursive 'test/*.spec.ts'" + "schema": "node --max-old-space-size=8192 --stack-size=10240 ./node_modules/@openstapps/core-tools/lib/app.js schema src lib/schema", + "test": "c8 mocha" }, "dependencies": { "@openstapps/core-tools": "workspace:*", @@ -51,7 +51,7 @@ "@openstapps/logger": "workspace:*", "@openstapps/prettier-config": "workspace:*", "@openstapps/tsconfig": "workspace:*", - "@testdeck/mocha": "0.3.3", + "@openstapps/easy-ast": "workspace:*", "@types/chai": "4.3.4", "@types/json-patch": "0.0.30", "@types/json-schema": "7.0.11", @@ -62,8 +62,7 @@ "chai": "4.3.7", "conditional-type-checks": "1.0.6", "mocha": "10.2.0", - "nyc": "15.1.0", - "rimraf": "4.4.0", + "c8": "7.13.0", "source-map-support": "0.5.21", "surge": "0.23.1", "ts-node": "10.9.1", @@ -115,12 +114,10 @@ "resources", "openapi" ], - "nyc": { - "extends": "@openstapps/nyc-config" - }, "openstapps-configuration": { "overrides": [ - "lint" + "lint", + "build" ] } } diff --git a/packages/core/src/translator.ts b/packages/core/src/translator.ts index 29e043e5..a9d7a7e2 100644 --- a/packages/core/src/translator.ts +++ b/packages/core/src/translator.ts @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import equal from 'fast-deep-equal/es6'; +import equal from 'fast-deep-equal/es6/index.js'; import clone from 'rfdc'; import {SCLanguageCode} from './general/i18n.js'; import {isThing} from './guards.js'; diff --git a/packages/core/test/compat.spec.ts b/packages/core/test/compat.spec.ts index f2b203d5..1b8230f3 100644 --- a/packages/core/test/compat.spec.ts +++ b/packages/core/test/compat.spec.ts @@ -13,41 +13,31 @@ * this program. If not, see . */ -import {lightweightProjectFromPath} from '@openstapps/core-tools/lib/easy-ast/easy-ast'; -import {LightweightProject} from '@openstapps/core-tools/lib/easy-ast/types/lightweight-project'; +import {lightweightProjectFromPath, LightweightProject} from '@openstapps/easy-ast'; import {expect} from 'chai'; -import {reduce} from 'lodash'; -process.on('unhandledRejection', err => { - throw err; +process.on('unhandledRejection', error => { + throw error; }); describe('Mapping Compatibility', () => { let project: LightweightProject; before(function () { - this.timeout(15000); - this.slow(10000); + this.timeout(15_000); + this.slow(10_000); project = lightweightProjectFromPath('src'); }); it('non-exported definitions should not have duplicate names across files', () => { - reduce( - project, - (result, file) => - reduce( - file, - (result2, _, key) => { - expect(result2[key]).to.be.undefined; - return { - [key]: true, - ...result2, - }; - }, - result, - ), - {} as Record, - ); + const names = new Set(); + + for (const file in project) { + for (const definition in project[file]) { + expect(names).not.to.include(definition); + names.add(definition); + } + } }); }); diff --git a/packages/core/test/dummy/building.ts b/packages/core/test/dummy/building.ts new file mode 100644 index 00000000..3c8af0a1 --- /dev/null +++ b/packages/core/test/dummy/building.ts @@ -0,0 +1,33 @@ +import {SCBuildingWithoutReferences, SCThingType} from '../../src/index.js'; + +export const building: SCBuildingWithoutReferences = { + address: { + addressCountry: 'base-address.addressCountry', + addressLocality: 'base-address.addressLocality', + postalCode: 'base-address.postalCode', + streetAddress: 'base-address.streetAddress', + }, + categories: ['office', 'education'], + floors: ['base-floor0', 'base-floor1'], + geo: { + point: { + coordinates: [12, 13], + type: 'Point', + }, + }, + name: 'base-space-name', + translations: { + de: { + address: { + addressCountry: 'de-address.addressCountry', + addressLocality: 'de-address.addressLocality', + postalCode: 'de-address.postalCode', + streetAddress: 'de-address.streetAddress', + }, + floors: ['de-floor0', 'de-floor1'], + name: 'de-space-name', + }, + }, + type: SCThingType.Building, + uid: '540862f3-ea30-5b8f-8678-56b4dc217140', +}; diff --git a/packages/core/test/dummy/bulk-response.ts b/packages/core/test/dummy/bulk-response.ts new file mode 100644 index 00000000..c4496783 --- /dev/null +++ b/packages/core/test/dummy/bulk-response.ts @@ -0,0 +1,9 @@ +import {SCBulkResponse, SCThingType} from '../../src/index.js'; + +export const bulkResponse: SCBulkResponse = { + expiration: '2009-06-30T18:30:00+02:00 ', + source: 'bar', + state: 'done', + type: SCThingType.Dish, + uid: 'foo', +}; diff --git a/packages/core/test/dummy/dish-with-translation-search-response.ts b/packages/core/test/dummy/dish-with-translation-search-response.ts new file mode 100644 index 00000000..a7a40b4d --- /dev/null +++ b/packages/core/test/dummy/dish-with-translation-search-response.ts @@ -0,0 +1,25 @@ +import {SCSearchResponse} from '../../src/index.js'; +import {dishWithTranslation} from './dish-with-translation.js'; + +export const dishWithTranslationSearchResponse: SCSearchResponse = { + data: [dishWithTranslation], + facets: [ + { + buckets: [ + { + count: 1, + key: 'key', + }, + ], + field: 'field', + }, + ], + pagination: { + count: 1, + offset: 0, + total: 1, + }, + stats: { + time: 1, + }, +}; diff --git a/packages/core/test/dummy/dish-with-translation.ts b/packages/core/test/dummy/dish-with-translation.ts new file mode 100644 index 00000000..9aa55072 --- /dev/null +++ b/packages/core/test/dummy/dish-with-translation.ts @@ -0,0 +1,17 @@ +import {SCDish, SCThingOriginType, SCThingType} from '../../src/index.js'; + +export const dishWithTranslation: SCDish = { + categories: ['appetizer'], + name: 'foo', + origin: { + created: '', + type: SCThingOriginType.User, + }, + translations: { + de: { + name: 'Foo', + }, + }, + type: SCThingType.Dish, + uid: 'bar', +}; diff --git a/packages/core/test/dummy/dish.ts b/packages/core/test/dummy/dish.ts new file mode 100644 index 00000000..3c59e99b --- /dev/null +++ b/packages/core/test/dummy/dish.ts @@ -0,0 +1,35 @@ +import {SCDish, SCThingOriginType, SCThingType} from '../../src/index.js'; +import {building} from './building.js'; + +export const dish: SCDish = { + categories: ['main dish', 'dessert'], + characteristics: [{name: 'base-characteristic0'}, {name: 'base-characteristic1'}], + name: 'base-dish-name', + offers: [ + { + availability: 'in stock', + inPlace: building, + prices: { + default: 23.42, + }, + provider: { + name: 'base-provider', + type: SCThingType.Organization, + uid: '540862f3-ea30-5b8f-8678-56b4dc217141', + }, + }, + ], + origin: { + indexed: '1970-01-01T00:00:00.000Z', + name: 'dish-connector', + type: SCThingOriginType.Remote, + }, + translations: { + de: { + characteristics: [{name: 'de-characteristic0'}, {name: 'de-characteristic1'}], + name: 'de-dish-name', + }, + }, + type: SCThingType.Dish, + uid: '540862f3-ea30-5b8f-8678-56b4dc217140', +}; diff --git a/packages/core/test/dummy/not-a-dish.ts b/packages/core/test/dummy/not-a-dish.ts new file mode 100644 index 00000000..6fa76ebc --- /dev/null +++ b/packages/core/test/dummy/not-a-dish.ts @@ -0,0 +1,13 @@ +import {SCThingOriginType} from '../../src/index.js'; +import {SCDish} from '../../lib/index.js'; + +export const notADish: Omit & {type: 'foobar'} = { + categories: ['appetizer'], + name: 'foo', + origin: { + created: '', + type: SCThingOriginType.User, + }, + type: 'foobar', + uid: 'bar', +}; diff --git a/packages/core/test/dummy/setting.ts b/packages/core/test/dummy/setting.ts new file mode 100644 index 00000000..8c9a3da9 --- /dev/null +++ b/packages/core/test/dummy/setting.ts @@ -0,0 +1,18 @@ +import {SCSetting, SCSettingInputType, SCThingOriginType, SCThingType} from '../../src/index.js'; + +export const setting: SCSetting = { + categories: ['profile'], + defaultValue: 'student', + description: 'base-description', + inputType: SCSettingInputType.SingleChoice, + name: 'group', + order: 1, + origin: { + indexed: '2018-11-11T14:30:00Z', + name: 'Dummy', + type: SCThingOriginType.Remote, + }, + type: SCThingType.Setting, + uid: '2c97aa36-4aa2-43de-bc5d-a2b2cb3a530e', + values: ['student', 'employee', true, 42], +}; diff --git a/packages/core/test/features.spec.ts b/packages/core/test/features.spec.ts index a6cd7321..d4b2063f 100644 --- a/packages/core/test/features.spec.ts +++ b/packages/core/test/features.spec.ts @@ -16,18 +16,17 @@ import { isLightweightClass, isLightweightEnum, isUnionType, -} from '@openstapps/core-tools/lib/easy-ast/ast-util'; -import {LightweightAliasDefinition} from '@openstapps/core-tools/lib/easy-ast/types/lightweight-alias-definition'; -import {LightweightProjectWithIndex} from '@openstapps/core-tools/lib/easy-ast/types/lightweight-project'; -import {LightweightType} from '@openstapps/core-tools/lib/easy-ast/types/lightweight-type'; -import {LightweightClassDefinition} from '@openstapps/core-tools/src/easy-ast/types/lightweight-class-definition'; -import {LightweightDefinition} from '@openstapps/core-tools/src/easy-ast/types/lightweight-definition'; -import {LightweightProperty} from '@openstapps/core-tools/src/easy-ast/types/lightweight-property'; + LightweightAliasDefinition, + LightweightProjectWithIndex, + LightweightType, + LightweightClassDefinition, + LightweightDefinition, + LightweightProperty, +} from '@openstapps/easy-ast'; import {expect} from 'chai'; -import {assign, chain, clone, flatMap, isNil, reduce, reject, some} from 'lodash'; -process.on('unhandledRejection', err => { - throw err; +process.on('unhandledRejection', error => { + throw error; }); describe('Features', () => { @@ -37,8 +36,8 @@ describe('Features', () => { let thingsWithoutReferences: LightweightClassDefinition[]; before(function () { - this.timeout(15000); - this.slow(10000); + this.timeout(15_000); + this.slow(10_000); project = new LightweightProjectWithIndex('src'); @@ -51,9 +50,7 @@ describe('Features', () => { referenceName: 'SCDiff', }); - expect( - thingsReflection.type?.specificationTypes?.every(it => typeof it.referenceName !== 'undefined'), - ).to.be.true; + expect(thingsReflection.type?.specificationTypes?.map(it => it.referenceName)).not.to.include(undefined); thingNames = thingsReflection.type?.specificationTypes?.map(type => type.referenceName!) ?? []; things = thingNames.map(it => project.definitions[it]).filter(isLightweightClass); thingsWithoutReferences = thingNames @@ -64,15 +61,22 @@ describe('Features', () => { const inheritedProperties = function ( classLike: LightweightClassDefinition, ): Record | undefined { - return reduce( - [...(classLike.implementedDefinitions ?? []), ...(classLike.extendedDefinitions ?? [])], - (obj, extension) => { - const object = project.definitions[extension.referenceName ?? '']; + const extendClause = [ + ...(classLike.implementedDefinitions ?? []), + ...(classLike.extendedDefinitions ?? []), + ]; + const properties = {...classLike.properties}; - return assign(obj, isLightweightClass(object) ? inheritedProperties(object) : obj); - }, - clone(classLike.properties), - ); + for (const definition of extendClause) { + const object = project.definitions[definition.referenceName!]; + if (isLightweightClass(object)) { + Object.assign(properties, inheritedProperties(object)); + } else { + Object.assign(properties, object); + } + } + + return properties; }; it('should have an origin', () => { @@ -82,42 +86,36 @@ describe('Features', () => { }); it('should not have duplicate names', () => { - reduce( - project.files, - (fileResult, file) => - reduce( - file, - (definitionResult, definition: LightweightDefinition) => { - expect(definitionResult[definition.name]).to.be.undefined; - definitionResult[definition.name] = true; // something that's not undefined + const names = new Set(); - return definitionResult; - }, - fileResult, - ), - {} as Record, - ); + for (const fileName in project.files) { + const file = project.files[fileName]; + for (const definition in file) { + const definitionName = file[definition].name; + expect(names).not.to.include(definitionName); + names.add(definitionName); + } + } }); it('should not have properties referencing SCThing', () => { const allPropertyReferenceNames: (property: LightweightProperty) => string[] = property => - reject( - [property.type.referenceName!, ...flatMap(property.properties, allPropertyReferenceNames)], - isNil, - ); + [ + property.type.referenceName!, + ...Object.values(property.properties ?? []).flatMap(allPropertyReferenceNames), + ].filter(it => !!it); const typeHasSCThingReferences: (type?: LightweightType) => boolean = type => type?.referenceName ? hasSCThingReferences(project.definitions[type.referenceName]) - : some(type?.specificationTypes, typeHasSCThingReferences); + : type?.specificationTypes?.some(typeHasSCThingReferences) === true; const hasSCThingReferences: (definition?: LightweightDefinition) => boolean = definition => isLightweightClass(definition) - ? chain(inheritedProperties(definition)) - .flatMap(it => flatMap(it.properties, allPropertyReferenceNames)) + ? Object.values(inheritedProperties(definition) ?? []) + .flatMap(it => Object.values(it.properties ?? []).flatMap(allPropertyReferenceNames)) .map(it => project.definitions[it] as LightweightDefinition) .some(it => it.name === 'SCThing' || hasSCThingReferences(it)) - .value() : definition ? typeHasSCThingReferences(definition.type) : false; @@ -127,16 +125,18 @@ describe('Features', () => { } }); + /** + * Checks if a definition is an SCThing + */ function extendsSCThing(definition?: LightweightDefinition): boolean { return isLightweightClass(definition) - ? chain([ + ? [ ...((definition as LightweightClassDefinition).extendedDefinitions ?? []), ...((definition as LightweightClassDefinition).implementedDefinitions ?? []), - ]) + ] .map(it => it.referenceName) - .reject(isNil) + .filter(it => !!it) .some(it => it === 'SCThing' || extendsSCThing(project.definitions[it!])) - .value() : false; } diff --git a/packages/core/test/guards.spec.ts b/packages/core/test/guards.spec.ts index 1eddbb8d..b1e02e33 100644 --- a/packages/core/test/guards.spec.ts +++ b/packages/core/test/guards.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/no-null */ /* * Copyright (C) 2018, 2019 StApps * This program is free software: you can redistribute it and/or modify it @@ -12,12 +13,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {slow, suite, test, timeout} from '@testdeck/mocha'; -import {SCBulkResponse} from '../src/protocol/routes/bulk-request.js'; -import {SCMultiSearchResponse} from '../src/protocol/routes/search-multi.js'; -import {SCSearchResponse} from '../src/protocol/routes/search.js'; -import {SCThingOriginType, SCThingType} from '../src/things/abstract/thing.js'; -import {SCDish} from '../src/things/dish.js'; +import {SCMultiSearchResponse} from '../src/index.js'; import {expect} from 'chai'; import { isBulkResponse, @@ -26,117 +22,104 @@ import { isThing, isThingWithTranslations, } from '../src/guards.js'; +import {bulkResponse} from './dummy/bulk-response.js'; +import {dishWithTranslation} from './dummy/dish-with-translation.js'; +import {dishWithTranslationSearchResponse} from './dummy/dish-with-translation-search-response.js'; +import {notADish} from './dummy/not-a-dish.js'; import {SCBulkResponse} from '../src/protocol/routes/bulk-request.js'; import {SCSearchResponse} from '../src/protocol/routes/search.js'; import {SCMultiSearchResponse} from '../src/protocol/routes/search-multi.js'; import {SCThingOriginType, SCThingType} from '../src/things/abstract/thing.js'; -import {SCDish} from '../src/things/dish'; +import {SCDish} from '../src/things/dish.js'; -@suite(timeout(10000), slow(5000)) -export class GuardsSpec { - static bulkResponse: SCBulkResponse = { - expiration: '2009-06-30T18:30:00+02:00 ', - source: 'bar', - state: 'done', - type: SCThingType.Dish, - uid: 'foo', - }; +describe('Guards', function () { + this.timeout(10_000); + this.slow(5000); - static dishWithTranslation: SCDish = { - categories: ['appetizer'], - name: 'foo', - origin: { - created: '', - type: SCThingOriginType.User, - }, - translations: { - de: { - name: 'Foo', - }, - }, - type: SCThingType.Dish, - uid: 'bar', - }; + describe('isBulkResponse', function () { + it(`should not accept nullish values`, function () { + expect(isBulkResponse(null)).to.be.false; + }); - static notADish = { - categories: ['appetizer'], - name: 'foo', - origin: { - created: '', - type: SCThingOriginType.User, - }, - type: 'foobar', - uid: 'bar', - }; + it('should not accept a dish', function () { + expect(isBulkResponse(dishWithTranslation)).to.be.false; + }); - static searchResponse: SCSearchResponse = { - data: [GuardsSpec.dishWithTranslation], - facets: [ - { - buckets: [ - { - count: 1, - key: 'key', - }, - ], - field: 'field', - }, - ], - pagination: { - count: 1, - offset: 0, - total: 1, - }, - stats: { - time: 1, - }, - }; + it('should accept a bulk', function () { + expect(isBulkResponse(bulkResponse)).to.be.true; + }); + }); - @test - public isBulkResponse() { - expect(isBulkResponse(null)).to.be.equal(false); - expect(isBulkResponse(GuardsSpec.dishWithTranslation)).to.be.equal(false); - expect(isBulkResponse(GuardsSpec.bulkResponse)).to.be.equal(true); - } - - @test - public isMultiSearchResponse() { + describe('isMultiSearchResponse', function () { const multiSearchResponse: SCMultiSearchResponse = { - foo: GuardsSpec.searchResponse, + foo: dishWithTranslationSearchResponse, }; - expect(isMultiSearchResponse(multiSearchResponse)).to.be.equal(true); - const notAMultiSearchResponse = {...multiSearchResponse, ...{bar: 'baz'}}; - expect(isMultiSearchResponse(notAMultiSearchResponse)).to.be.equal(false); - delete multiSearchResponse.foo; - expect(isMultiSearchResponse(multiSearchResponse)).to.be.equal(false); - } - @test - public isSearchResponse() { - const notASearchResponse = {...GuardsSpec.searchResponse}; - // @ts-ignore - delete notASearchResponse.pagination; - expect(isSearchResponse(notASearchResponse)).to.be.equal(false); - // @ts-ignore - delete notASearchResponse.data; - expect(isSearchResponse(notASearchResponse)).to.be.equal(false); - expect(isSearchResponse(null)).to.be.equal(false); - expect(isSearchResponse(GuardsSpec.searchResponse)).to.be.equal(true); - } + it('should accept a multi search response', function () { + expect(isMultiSearchResponse(multiSearchResponse)).to.be.true; + }); - @test - public isThing() { - expect(isThing('foo')).to.be.equal(false); - expect(isThing({type: 'foo'})).to.be.equal(false); - expect(isThing(GuardsSpec.notADish)).to.be.equal(false); - expect(isThing(GuardsSpec.dishWithTranslation)).to.be.equal(true); - } + it('should not accept a multi search response with invalid search requests', function () { + const notAMultiSearchResponse = {...multiSearchResponse, bar: 'baz'}; + expect(isMultiSearchResponse(notAMultiSearchResponse)).to.be.false; + }); - @test - public isThingWithTranslations() { - const dishWithoutTranslation = {...GuardsSpec.dishWithTranslation}; - delete dishWithoutTranslation.translations; - expect(isThingWithTranslations(dishWithoutTranslation)).to.be.equal(false); - expect(isThingWithTranslations(GuardsSpec.dishWithTranslation)).to.be.equal(true); - } -} + it('should not accept empty responses', function () { + expect(isMultiSearchResponse({})).to.be.false; + }); + }); + + describe('isSearchResponse', function () { + it('should accept a search response', function () { + expect(isSearchResponse(dishWithTranslationSearchResponse)).to.be.true; + }); + + it('should not accept nullish values', function () { + expect(isSearchResponse(null)).to.be.false; + }); + + it('should not accept a response without pagination', function () { + const response = {...dishWithTranslationSearchResponse}; + // @ts-expect-error this is on purpose of course + delete response.pagination; + expect(isSearchResponse(response)).to.be.false; + }); + + it('should not accept a response without data', function () { + const response = {...dishWithTranslationSearchResponse}; + // @ts-expect-error this is on purpose of course + delete response.data; + expect(isSearchResponse(response)).to.be.false; + }); + }); + + describe('isThing', function () { + it('should not accept strings', function () { + expect(isThing('foo')).to.be.false; + }); + + it('should not accept objects with arbitrary type values', function () { + expect(isThing({type: 'foo'})).to.be.false; + }); + + it('should not accept things with missing props', function () { + expect(isThing(notADish)).to.be.false; + }); + + it('should accept valid things', function () { + expect(isThing(dishWithTranslation)).to.be.true; + }); + }); + + describe('isThingWithTranslations', function () { + it('should not accept things without translations', function () { + const dishWithoutTranslation = {...dishWithTranslation}; + delete dishWithoutTranslation.translations; + expect(isThingWithTranslations(dishWithoutTranslation)).to.be.false; + }); + + it('should accept things with translations', function () { + expect(isThingWithTranslations(dishWithTranslation)).to.be.true; + }); + }); +}); diff --git a/packages/core/test/routes.spec.ts b/packages/core/test/routes.spec.ts index 12d9c9e3..0787b7d6 100644 --- a/packages/core/test/routes.spec.ts +++ b/packages/core/test/routes.spec.ts @@ -14,69 +14,51 @@ */ import {slow, suite, test, timeout} from '@testdeck/mocha'; import {expect} from 'chai'; -import {slow, suite, test, timeout} from '@testdeck/mocha'; -import {SCBulkRoute} from '../src/protocol/routes/bulk-request.js'; -import {SCBulkAddRoute} from '../src/protocol/routes/bulk-add.js'; -import {SCThingUpdateRoute} from '../src/protocol/routes/thing-update.js'; +import {SCBulkRoute} from '../src/index.js'; +import {SCBulkAddRoute} from '../src/index.js'; +import {SCThingUpdateRoute} from '../src/index.js'; -@suite(timeout(10000), slow(5000)) -export class RoutesSpec { - @test - public bulkAddRouteUrlPath() { - const bulkAddRoute = new SCBulkAddRoute(); +describe('Routes', function () { + this.timeout(10_000); + this.slow(5000); + it('should produce correct BulkAddRoute url path', function () { expect( - bulkAddRoute.getUrlPath({ + new SCBulkAddRoute().getUrlPath({ UID: '540862f3-ea30-5b8f-8678-56b4dc217140', }), ).to.equal('/bulk/540862f3-ea30-5b8f-8678-56b4dc217140'); - } + }); - @test - public bulkRouteUrlPath() { - const bulkRoute = new SCBulkRoute(); - - expect(bulkRoute.getUrlPath()).to.equal('/bulk'); - } - - @test - public thingUpdateRouteUrlPath() { - const thingUpdateRoute = new SCThingUpdateRoute(); + it('should produce correct BlukRoute url path', function () { + expect(new SCBulkRoute().getUrlPath()).to.equal('/bulk'); + }); + it('should produce correct ThingUpdateRoute url path', function () { expect( - thingUpdateRoute.getUrlPath({ + new SCThingUpdateRoute().getUrlPath({ TYPE: 'dish', UID: '540862f3-ea30-5b8f-8678-56b4dc217140', }), ).to.equal('/dish/540862f3-ea30-5b8f-8678-56b4dc217140'); - } + }); - @test - public tooManyParameters() { - const thingUpdateRoute = new SCThingUpdateRoute(); - - const fn = () => { - thingUpdateRoute.getUrlPath({ + it('should throw an error if too many parameters are provided', function () { + expect(() => + new SCThingUpdateRoute().getUrlPath({ FOO: 'bar', TYPE: 'dish', UID: '540862f3-ea30-5b8f-8678-56b4dc217140', - }); - }; + }), + ).to.throw('Extraneous parameters provided.'); + }); - expect(fn).to.throw('Extraneous parameters provided.'); - } - - @test - public wrongParameters() { - const thingUpdateRoute = new SCThingUpdateRoute(); - - const fn = () => { - thingUpdateRoute.getUrlPath({ + it('should throw an error if wrong parameters are provided', function () { + expect(() => + new SCThingUpdateRoute().getUrlPath({ TYPO: 'dish', UID: '540862f3-ea30-5b8f-8678-56b4dc217140', - }); - }; - - expect(fn).to.throw("Parameter 'TYPE' not provided."); - } -} + }), + ).to.throw("Parameter 'TYPE' not provided."); + }); +}); diff --git a/packages/core/test/schema.spec.ts b/packages/core/test/schema.spec.ts index 65ada8ef..4ddfe23d 100644 --- a/packages/core/test/schema.spec.ts +++ b/packages/core/test/schema.spec.ts @@ -1,29 +1,22 @@ -import {validateFiles, writeReport} from '@openstapps/core-tools/lib/validate'; -import {slow, suite, test, timeout} from '@testdeck/mocha'; +import {validateFiles, writeReport} from '@openstapps/core-tools'; import {expect} from 'chai'; -import {mkdirSync} from 'fs'; -import {join, resolve} from 'path'; +import {mkdir} from 'fs/promises'; +import path from 'path'; -@suite(timeout(15000), slow(10000)) -export class SchemaSpec { - @test - async 'validate against test files'() { - const errorsPerFile = { - ...(await validateFiles(resolve('lib', 'schema'), resolve('test', 'resources'))), - ...(await validateFiles(resolve('lib', 'schema'), resolve('test', 'resources', 'indexable'))), - }; +describe('Schema', function () { + this.timeout(15_000); + this.slow(10_000); - let unexpected = false; - Object.keys(errorsPerFile).forEach(file => { - unexpected = unexpected || errorsPerFile[file].some(error => !error.expected); - }); + it('should validate against test files', async function () { + const errorsPerFile = await validateFiles(path.resolve('lib', 'schema'), path.resolve('test', 'resources')); - mkdirSync('report', { - recursive: true, - }); + await mkdir('report', {recursive: true}); + await writeReport(path.join('report', 'index.html'), errorsPerFile); - await writeReport(join('report', 'index.html'), errorsPerFile); - - expect(unexpected).to.be.equal(false); - } -} + for (const file of Object.keys(errorsPerFile)) { + for (const error of errorsPerFile[file]) { + expect(error.expected).to.be.true; + } + } + }); +}); diff --git a/packages/core/test/translator.spec.ts b/packages/core/test/translator.spec.ts index 9c28a353..b57c3770 100644 --- a/packages/core/test/translator.spec.ts +++ b/packages/core/test/translator.spec.ts @@ -15,93 +15,11 @@ import {slow, suite, test, timeout} from '@testdeck/mocha'; import {expect} from 'chai'; import clone from 'rfdc'; -import {SCThingOriginType, SCThingRemoteOrigin, SCThingType} from '../src/things/abstract/thing.js'; -import {SCBuildingWithoutReferences} from '../src/things/building.js'; -import {SCDish, SCDishMeta} from '../src/things/dish.js'; -import {SCSetting, SCSettingInputType} from '../src/things/setting.js'; -import {SCThingTranslator} from '../src/translator.js'; - -const building: SCBuildingWithoutReferences = { - address: { - addressCountry: 'base-address.addressCountry', - addressLocality: 'base-address.addressLocality', - postalCode: 'base-address.postalCode', - streetAddress: 'base-address.streetAddress', - }, - categories: ['office', 'education'], - floors: ['base-floor0', 'base-floor1'], - geo: { - point: { - coordinates: [12.0, 13.0], - type: 'Point', - }, - }, - name: 'base-space-name', - translations: { - de: { - address: { - addressCountry: 'de-address.addressCountry', - addressLocality: 'de-address.addressLocality', - postalCode: 'de-address.postalCode', - streetAddress: 'de-address.streetAddress', - }, - floors: ['de-floor0', 'de-floor1'], - name: 'de-space-name', - }, - }, - type: SCThingType.Building, - uid: '540862f3-ea30-5b8f-8678-56b4dc217140', -}; - -const dish: SCDish = { - categories: ['main dish', 'dessert'], - characteristics: [{name: 'base-characteristic0'}, {name: 'base-characteristic1'}], - name: 'base-dish-name', - offers: [ - { - availability: 'in stock', - inPlace: building, - prices: { - default: 23.42, - }, - provider: { - name: 'base-provider', - type: SCThingType.Organization, - uid: '540862f3-ea30-5b8f-8678-56b4dc217141', - }, - }, - ], - origin: { - indexed: '1970-01-01T00:00:00.000Z', - name: 'dish-connector', - type: SCThingOriginType.Remote, - }, - translations: { - de: { - characteristics: [{name: 'de-characteristic0'}, {name: 'de-characteristic1'}], - name: 'de-dish-name', - }, - }, - type: SCThingType.Dish, - uid: '540862f3-ea30-5b8f-8678-56b4dc217140', -}; - -const setting: SCSetting = { - categories: ['profile'], - defaultValue: 'student', - description: 'base-description', - inputType: SCSettingInputType.SingleChoice, - name: 'group', - order: 1, - origin: { - indexed: '2018-11-11T14:30:00Z', - name: 'Dummy', - type: SCThingOriginType.Remote, - }, - type: SCThingType.Setting, - uid: '2c97aa36-4aa2-43de-bc5d-a2b2cb3a530e', - values: ['student', 'employee', true, 42], -}; +import {SCThingRemoteOrigin} from '../src/index.js'; +import {SCDishMeta} from '../src/index.js'; +import {SCThingTranslator} from '../src/index.js'; +import {dish} from './dummy/dish.js'; +import {setting} from './dummy/setting.js'; const translator = new SCThingTranslator('de'); const translatorEN = new SCThingTranslator('en'); @@ -111,242 +29,207 @@ const translatorWithFallback = new SCThingTranslator('tt'); const translatedThingDE = translator.translate(dish); const translatedThingFallback = translatorWithFallback.translate(dish); -@suite(timeout(10000), slow(5000)) -export class TranslationSpecInplace { - @test - public directEnumSingleValue() { - expect(translator.translatedAccess(setting).inputType()).to.equal('einfache Auswahl'); - } +describe('Translator', function () { + this.timeout(10_000); + this.slow(5000); - @test - public directStringLiteralType() { - expect(translator.translatedAccess(dish).type()).to.equal('Essen'); - expect(translatedThingDE.type).to.equal('Essen'); - } - - @test - public directStringProperty() { - expect(translator.translatedAccess(dish).name()).to.equal('de-dish-name'); - expect(translatedThingDE.name).to.equal('de-dish-name'); - } - - @test - public directArrayOfString() { - expect(translator.translatedAccess(dish).characteristics()).to.deep.equal([ - {name: 'de-characteristic0'}, - {name: 'de-characteristic1'}, - ]); - expect(translatedThingDE.characteristics).to.deep.equal([ - {name: 'de-characteristic0'}, - {name: 'de-characteristic1'}, - ]); - } - - @test - public directArrayOfStringSubscript() { - expect(translator.translatedAccess(dish).characteristics[1]()).to.deep.equal({ - name: 'de-characteristic1', + describe('direct', function () { + it('should translate enum single value', function () { + expect(translator.translatedAccess(setting).inputType).to.equal('einfache Auswahl'); }); - expect(translatedThingDE.characteristics![1]).to.deep.equal({name: 'de-characteristic1'}); - } - @test - public directMetaArrayOfString() { - expect(translator.translatedAccess(dish).categories()).to.deep.equal(['Hauptgericht', 'Nachtisch']); - expect(translatedThingDE.categories).to.deep.equal(['Hauptgericht', 'Nachtisch']); - } - - @test - public directMetaArrayOfStringSubscript() { - expect(translator.translatedAccess(dish).categories[1]()).to.equal('Nachtisch'); - expect(translatedThingDE.categories[1]).to.equal('Nachtisch'); - } - - @test - public nestedStringLiteralType() { - expect(translator.translatedAccess(dish).offers[0].inPlace.type()).to.equal('Gebäude'); - expect(translatedThingDE.offers![0].inPlace!.type).to.equal('Gebäude'); - } - - @test - public nestedStringProperty() { - expect(translator.translatedAccess(dish).offers[0].inPlace.name()).to.equal('de-space-name'); - expect(translatedThingDE.offers![0].inPlace!.name).to.equal('de-space-name'); - } - - @test - public nestedMetaArrayOfString() { - expect(translator.translatedAccess(dish).offers[0].inPlace.categories()).to.deep.equal([ - 'Büro', - 'Bildung', - ]); - expect(translatedThingDE.offers![0].inPlace!.categories).to.deep.equal(['Büro', 'Bildung']); - } - - @test - public nestedMetaArrayOfStringSubscript() { - expect(translator.translatedAccess(dish).offers[0].inPlace.categories[1]()).to.equal('Bildung'); - expect(translatedThingDE.offers![0].inPlace!.categories[1]).to.equal('Bildung'); - } - - @test - public directStringLiteralTypeFallback() { - expect(translatorWithFallback.translatedAccess(dish).type()).to.equal('dish'); - expect(translatedThingFallback.type).to.equal('dish'); - } - - @test - public directStringPropertyFallback() { - expect(translatorWithFallback.translatedAccess(dish).name()).to.equal('base-dish-name'); - expect(translatedThingFallback.name).to.equal('base-dish-name'); - } - - @test - public directArrayOfStringSubscriptFallback() { - expect(translatorWithFallback.translatedAccess(dish).characteristics[1]()).to.deep.equal({ - name: 'base-characteristic1', + it('should translate string literal type', function () { + expect(translator.translatedAccess(dish).type).to.equal('Essen'); + expect(translatedThingDE.type).to.equal('Essen'); }); - expect(translatedThingFallback.characteristics![1]).to.deep.equal({name: 'base-characteristic1'}); - } - @test - public directMetaArrayOfStringFallback() { - expect(translatorWithFallback.translatedAccess(dish).categories()).to.deep.equal([ - 'main dish', - 'dessert', - ]); - expect(translatedThingFallback.categories).to.deep.equal(['main dish', 'dessert']); - } + it('should translate string property', function () { + expect(translator.translatedAccess(dish).name).to.equal('de-dish-name'); + expect(translatedThingDE.name).to.equal('de-dish-name'); + }); - @test - public directMetaArrayOfStringSubscriptFallback() { - expect(translatorWithFallback.translatedAccess(dish).categories[1]()).to.equal('dessert'); - expect(translatedThingFallback.categories[1]).to.equal('dessert'); - } + it('should translate array of strings', function () { + expect(translator.translatedAccess(dish).characteristics).to.deep.equal([ + {name: 'de-characteristic0'}, + {name: 'de-characteristic1'}, + ]); + expect(translatedThingDE.characteristics).to.deep.equal([ + {name: 'de-characteristic0'}, + {name: 'de-characteristic1'}, + ]); + }); - @test - public nestedStringLiteralTypeFallback() { - expect(translatorWithFallback.translatedAccess(dish).offers[0].inPlace.type()).to.equal('building'); - expect(translatedThingFallback.offers![0].inPlace!.type).to.equal('building'); - } + it('should translate array of strings subscript', function () { + expect(translator.translatedAccess(dish).characteristics?.[1]).to.deep.equal({ + name: 'de-characteristic1', + }); + expect(translatedThingDE.characteristics![1]).to.deep.equal({name: 'de-characteristic1'}); + }); - @test - public nestedStringPropertyFallback() { - expect(translatorWithFallback.translatedAccess(dish).offers[0].inPlace.name()).to.equal( - 'base-space-name', - ); - expect(translatedThingFallback.offers![0].inPlace!.name).to.equal('base-space-name'); - } + it('should translate meta array of string', function () { + expect(translator.translatedAccess(dish).categories).to.deep.equal(['Hauptgericht', 'Nachtisch']); + expect(translatedThingDE.categories).to.deep.equal(['Hauptgericht', 'Nachtisch']); + }); - @test - public nestedMetaArrayOfStringFallback() { - expect(translatorWithFallback.translatedAccess(dish).offers[0].inPlace.categories()).to.deep.equal([ - 'office', - 'education', - ]); - expect(translatedThingFallback.offers![0].inPlace!.categories).to.deep.equal(['office', 'education']); - } + it('should translate meta array of strings subscript', function () { + expect(translator.translatedAccess(dish).categories[1]).to.equal('Nachtisch'); + expect(translatedThingDE.categories[1]).to.equal('Nachtisch'); + }); + }); - @test - public nestedMetaArrayOfStringSubscriptFallback() { - expect(translatorWithFallback.translatedAccess(dish).offers[0].inPlace.categories[1]()).to.equal( - 'education', - ); - expect(translatedThingFallback.offers![0].inPlace!.categories[1]).to.equal('education'); - } + describe('nested', function () { + it('should translate string literal type', function () { + expect(translator.translatedAccess(dish).offers?.[0].inPlace?.type).to.equal('Gebäude'); + expect(translatedThingDE.offers![0].inPlace!.type).to.equal('Gebäude'); + }); - @test - public directStringLiteralTypeUndefined() { - const undefinedThing = eval('(x) => undefined;'); - expect(translator.translatedAccess(undefinedThing())('defaultValue')).to.equal('defaultValue'); - expect(translator.translatedAccess(dish).name('defaultValue')).to.not.equal('defaultValue'); - } + it('should translate nested string property', function () { + expect(translator.translatedAccess(dish).offers?.[0].inPlace?.name).to.equal('de-space-name'); + expect(translatedThingDE.offers![0].inPlace!.name).to.equal('de-space-name'); + }); - @test - public nestedMetaArrayOfStringSubscriptUndefined() { - const workingTranslation = eval( - "translator.translatedAccess(dish).offers[0].inPlace.categories[1]('printer');", - ); - const defaultValueTranslation = eval( - "translator.translatedAccess(dish).offers[0].inPlace.categories[1234]('printer');", - ); + it('should translate meta array of strings', function () { + expect(translator.translatedAccess(dish).offers?.[0].inPlace?.categories).to.deep.equal([ + 'Büro', + 'Bildung', + ]); + expect(translatedThingDE.offers![0].inPlace!.categories).to.deep.equal(['Büro', 'Bildung']); + }); - expect(defaultValueTranslation).to.equal('printer'); - expect(workingTranslation).to.not.equal('printer'); - } + it('should translate meta array of strings subscript', function () { + expect(translator.translatedAccess(dish).offers?.[0].inPlace?.categories[1]).to.equal('Bildung'); + expect(translatedThingDE.offers![0].inPlace!.categories[1]).to.equal('Bildung'); + }); + }); - @test - public reaccessWithChangedSourceOmitsLRUCache() { + describe('direct (fallback)', function () { + it('should translate string literal types', function () { + expect(translatorWithFallback.translatedAccess(dish).type).to.equal('dish'); + expect(translatedThingFallback.type).to.equal('dish'); + }); + + it('should translate string property', function () { + expect(translatorWithFallback.translatedAccess(dish).name).to.equal('base-dish-name'); + expect(translatedThingFallback.name).to.equal('base-dish-name'); + }); + + it('should translate array of strings subscript', function () { + expect(translatorWithFallback.translatedAccess(dish).characteristics?.[1]).to.deep.equal({ + name: 'base-characteristic1', + }); + expect(translatedThingFallback.characteristics![1]).to.deep.equal({name: 'base-characteristic1'}); + }); + + it('should translate meta array of strings', function () { + expect(translatorWithFallback.translatedAccess(dish).categories).to.deep.equal([ + 'main dish', + 'dessert', + ]); + expect(translatedThingFallback.categories).to.deep.equal(['main dish', 'dessert']); + }); + + it('should translate meta array of string subscript', function () { + expect(translatorWithFallback.translatedAccess(dish).categories[1]).to.equal('dessert'); + expect(translatedThingFallback.categories[1]).to.equal('dessert'); + }); + }); + + describe('nested (fallback)', function () { + it('should translate string literal type', function () { + expect(translatorWithFallback.translatedAccess(dish).offers?.[0].inPlace?.type).to.equal('building'); + expect(translatedThingFallback.offers![0].inPlace!.type).to.equal('building'); + }); + + it('should translate string property', function () { + expect(translatorWithFallback.translatedAccess(dish).offers?.[0].inPlace?.name).to.equal( + 'base-space-name', + ); + expect(translatedThingFallback.offers![0].inPlace!.name).to.equal('base-space-name'); + }); + + it('should translate meta array of string', function () { + expect(translatorWithFallback.translatedAccess(dish).offers?.[0].inPlace?.categories).to.deep.equal([ + 'office', + 'education', + ]); + expect(translatedThingFallback.offers![0].inPlace!.categories).to.deep.equal(['office', 'education']); + }); + + it('should translate meta array of strings subscript', function () { + expect(translatorWithFallback.translatedAccess(dish).offers?.[0].inPlace?.categories[1]).to.equal( + 'education', + ); + expect(translatedThingFallback.offers![0].inPlace!.categories[1]).to.equal('education'); + }); + }); + + it('should omit LRU cache with changed source', function () { const translatorDE = new SCThingTranslator('de'); const dishCopy = clone()(dish); const translatedDish = translatorDE.translatedAccess(dish); - const distructivelyTranslatedDish = translatorDE.translate(dish); + const destructivelyTranslatedDish = translatorDE.translate(dish); - (dishCopy.origin as SCThingRemoteOrigin).name = 'tranlator.spec'; + (dishCopy.origin as SCThingRemoteOrigin).name = 'translator.spec'; expect(translatorDE.translatedAccess(dishCopy)).not.to.deep.equal(translatedDish); - expect(translatorDE.translate(dishCopy)).not.to.equal(distructivelyTranslatedDish); - } + expect(translatorDE.translate(dishCopy)).not.to.equal(destructivelyTranslatedDish); + }); - @test - public changingTranslatorLanguageFlushesItsLRUCache() { + it('should flush its LRU cache with changed translator language', function () { const translatorDE = new SCThingTranslator('de'); - expect(translatorDE.translatedAccess(dish).name()).to.equal('de-dish-name'); + expect(translatorDE.translatedAccess(dish).name).to.equal('de-dish-name'); expect(translatorDE.translate(dish).name).to.equal('de-dish-name'); translatorDE.language = 'en'; - expect(translatorDE.translatedAccess(dish).name()).to.equal('base-dish-name'); + expect(translatorDE.translatedAccess(dish).name).to.equal('base-dish-name'); expect(translatorDE.translate(dish).name).to.equal('base-dish-name'); - } + }); - @test - public forceTranslatorLRUCacheToOverflow() { + it('should force translator LRU cache to overflow', function () { const translatorDE = new SCThingTranslator('de'); // Make sure to add more elements to the translator cache than the maximum cache capacity. See Translator.ts for (let i = 0; i < 201; i++) { const anotherDish = Object.assign({}, dish); anotherDish.uid = String(i); - expect(translatorDE.translatedAccess(anotherDish).name()).to.equal('de-dish-name'); + expect(translatorDE.translatedAccess(anotherDish).name).to.equal('de-dish-name'); } - } -} + }); +}); -@suite(timeout(10000), slow(5000)) -export class MetaTranslationSpec { - @test - public consistencyWithMetaClass() { +describe('MetaTranslator', function () { + this.timeout(10_000); + this.slow(5000); + + it('should have consistency with meta class', function () { const dishMetaTranslationsDE = translator.translatedPropertyNames(dish.type); const dishMetaTranslationsEN = translatorEN.translatedPropertyNames(dish.type); expect(dishMetaTranslationsEN).to.not.deep.equal(dishMetaTranslationsDE); expect(dishMetaTranslationsDE).to.deep.equal(new SCDishMeta().fieldTranslations.de); expect(dishMetaTranslationsEN).to.deep.equal(new SCDishMeta().fieldTranslations.en); - } + }); - @test - public retrieveTranslatedPropertyValueType() { + it('should retrieve translated property value type', function () { const dishTypeDE = translator.translatedPropertyValue(dish.type, 'type'); const dishTypeEN = translatorEN.translatedPropertyValue(dish.type, 'type', undefined); const dishTypeBASE = translatorWithFallback.translatedPropertyValue(dish.type, 'type'); expect(dishTypeDE).to.deep.equal(new SCDishMeta().fieldValueTranslations.de.type); expect(dishTypeEN).to.deep.equal(new SCDishMeta().fieldValueTranslations.en.type); expect(dishTypeBASE).to.deep.equal(new SCDishMeta().fieldValueTranslations.en.type); - } + }); - @test - public retrieveTranslatedPropertyValueNested() { + it('should retrieve translated property value nested', function () { const dishTypeDE = translator.translatedPropertyValue(dish.type, 'categories', 'main dish'); const dishTypeEN = translatorEN.translatedPropertyValue(dish.type, 'categories', 'main dish'); const dishTypeBASE = translatorWithFallback.translatedPropertyValue(dish.type, 'categories', 'main dish'); expect(dishTypeDE).to.deep.equal(new SCDishMeta().fieldValueTranslations.de.categories['main dish']); expect(dishTypeEN).to.deep.equal(dish.categories[0]); expect(dishTypeBASE).to.deep.equal(dish.categories[0]); - } + }); - @test - public thingWithoutMetaClass() { + it('should translate thing without meta class', function () { const dishCopy = clone()(dish); - const typeNonExistant = eval("(x) => x + 'typeNonExistant';"); - // this will assign a non existant SCThingType to dishCopy - dishCopy.type = typeNonExistant(); + const typeNonExistent = eval("(x) => x + 'typeNonExistent';"); + // this will assign a non-existent SCThingType to dishCopy + dishCopy.type = typeNonExistent(); const dishMetaTranslationsDE = translator.translatedPropertyNames(dishCopy.type); expect(dishMetaTranslationsDE).to.be.undefined; - } -} + }); +}); diff --git a/packages/core/test/type.spec.ts b/packages/core/test/type.spec.ts index ca61fc47..a5fa5ca2 100644 --- a/packages/core/test/type.spec.ts +++ b/packages/core/test/type.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ /* * Copyright (C) 2019 StApps * This program is free software: you can redistribute it and/or modify it @@ -13,35 +14,35 @@ * this program. If not, see . */ import {assert, Has, IsAny, IsNever, NotHas} from 'conditional-type-checks'; -import {SCThing, SCThingWithoutReferences} from '../src/things/abstract/thing.js'; -import {SCAcademicEvent, SCAcademicEventWithoutReferences} from '../src/things/academic-event.js'; -import {SCArticle, SCArticleWithoutReferences} from '../src/things/article.js'; -import {SCAssessment, SCAssessmentWithoutReferences} from '../src/things/assessment.js'; -import {SCBook, SCBookWithoutReferences} from '../src/things/book.js'; -import {SCBuilding, SCBuildingWithoutReferences} from '../src/things/building.js'; -import {SCCatalog, SCCatalogWithoutReferences} from '../src/things/catalog.js'; -import {SCContactPoint, SCContactPointWithoutReferences} from '../src/things/contact-point.js'; -import {SCCourseOfStudy, SCCourseOfStudyWithoutReferences} from '../src/things/course-of-study.js'; -import {SCDateSeries, SCDateSeriesWithoutReferences} from '../src/things/date-series.js'; -import {SCDiff, SCDiffWithoutReferences} from '../src/things/diff.js'; -import {SCDish, SCDishWithoutReferences} from '../src/things/dish.js'; -import {SCFavorite, SCFavoriteWithoutReferences} from '../src/things/favorite.js'; -import {SCFloor, SCFloorWithoutReferences} from '../src/things/floor.js'; -import {SCMessage, SCMessageWithoutReferences} from '../src/things/message.js'; -import {SCOrganization, SCOrganizationWithoutReferences} from '../src/things/organization.js'; -import {SCPerson, SCPersonWithoutReferences} from '../src/things/person.js'; -import {SCPointOfInterest, SCPointOfInterestWithoutReferences} from '../src/things/point-of-interest.js'; -import {SCRoom, SCRoomWithoutReferences} from '../src/things/room.js'; -import {SCSemester, SCSemesterWithoutReferences} from '../src/things/semester.js'; -import {SCSetting, SCSettingWithoutReferences} from '../src/things/setting.js'; -import {SCSportCourse, SCSportCourseWithoutReferences} from '../src/things/sport-course.js'; -import {SCStudyModule, SCStudyModuleWithoutReferences} from '../src/things/study-module.js'; -import {SCTicket, SCTicketWithoutReferences} from '../src/things/ticket.js'; -import {SCToDo, SCToDoWithoutReferences} from '../src/things/todo.js'; -import {SCTour, SCTourWithoutReferences} from '../src/things/tour.js'; -import {SCVideo, SCVideoWithoutReferences} from '../src/things/video.js'; -import {SCPeriodical, SCPeriodicalWithoutReferences} from '../src/things/periodical.js'; -import {SCPublicationEvent, SCPublicationEventWithoutReferences} from '../src/things/publication-event.js'; +import {SCThing, SCThingWithoutReferences} from '../src/index.js'; +import {SCAcademicEvent, SCAcademicEventWithoutReferences} from '../src/index.js'; +import {SCArticle, SCArticleWithoutReferences} from '../src/index.js'; +import {SCAssessment, SCAssessmentWithoutReferences} from '../src/index.js'; +import {SCBook, SCBookWithoutReferences} from '../src/index.js'; +import {SCBuilding, SCBuildingWithoutReferences} from '../src/index.js'; +import {SCCatalog, SCCatalogWithoutReferences} from '../src/index.js'; +import {SCContactPoint, SCContactPointWithoutReferences} from '../src/index.js'; +import {SCCourseOfStudy, SCCourseOfStudyWithoutReferences} from '../src/index.js'; +import {SCDateSeries, SCDateSeriesWithoutReferences} from '../src/index.js'; +import {SCDiff, SCDiffWithoutReferences} from '../src/index.js'; +import {SCDish, SCDishWithoutReferences} from '../src/index.js'; +import {SCFavorite, SCFavoriteWithoutReferences} from '../src/index.js'; +import {SCFloor, SCFloorWithoutReferences} from '../src/index.js'; +import {SCMessage, SCMessageWithoutReferences} from '../src/index.js'; +import {SCOrganization, SCOrganizationWithoutReferences} from '../src/index.js'; +import {SCPerson, SCPersonWithoutReferences} from '../src/index.js'; +import {SCPointOfInterest, SCPointOfInterestWithoutReferences} from '../src/index.js'; +import {SCRoom, SCRoomWithoutReferences} from '../src/index.js'; +import {SCSemester, SCSemesterWithoutReferences} from '../src/index.js'; +import {SCSetting, SCSettingWithoutReferences} from '../src/index.js'; +import {SCSportCourse, SCSportCourseWithoutReferences} from '../src/index.js'; +import {SCStudyModule, SCStudyModuleWithoutReferences} from '../src/index.js'; +import {SCTicket, SCTicketWithoutReferences} from '../src/index.js'; +import {SCToDo, SCToDoWithoutReferences} from '../src/index.js'; +import {SCTour, SCTourWithoutReferences} from '../src/index.js'; +import {SCVideo, SCVideoWithoutReferences} from '../src/index.js'; +import {SCPeriodical, SCPeriodicalWithoutReferences} from '../src/index.js'; +import {SCPublicationEvent, SCPublicationEventWithoutReferences} from '../src/index.js'; /** * Check if E extends T diff --git a/packages/easy-ast/package.json b/packages/easy-ast/package.json index 051e6169..e08aea17 100644 --- a/packages/easy-ast/package.json +++ b/packages/easy-ast/package.json @@ -10,34 +10,33 @@ "types": "./lib/index.d.ts", "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", - "test": "nyc mocha 'test/**/*.spec.ts'" + "test": "c8 mocha" }, "dependencies": { "@openstapps/collection-utils": "workspace:*", "@openstapps/logger": "workspace:*", + "glob": "10.2.1", "typescript": "4.8.4" }, "devDependencies": { "@openstapps/eslint-config": "workspace:*", - "@openstapps/nyc-config": "workspace:*", "@openstapps/prettier-config": "workspace:*", "@openstapps/tsconfig": "workspace:*", - "@testdeck/mocha": "0.3.3", "@types/chai": "4.3.4", - "@types/fs-extra": "9.0.13", "@types/mocha": "10.0.1", "@types/node": "18.15.3", + "c8": "7.13.0", + "chai": "4.3.7", "mocha": "10.2.0", - "nock": "13.3.0", + "ts-node": "10.9.1", "tsup": "6.7.0" }, "tsup": { "entry": [ - "src/app.ts", "src/index.ts" ], "sourcemap": true, @@ -54,8 +53,5 @@ "eslintIgnore": [ "resources", "openapi" - ], - "nyc": { - "extends": "@openstapps/nyc-config" - } + ] } diff --git a/packages/easy-ast/src/ast-internal-util.ts b/packages/easy-ast/src/ast-internal-util.ts index bccbbc3c..9a9f0108 100644 --- a/packages/easy-ast/src/ast-internal-util.ts +++ b/packages/easy-ast/src/ast-internal-util.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import * as ts from 'typescript'; +import ts from 'typescript'; import {cleanupEmpty} from './util.js'; import {LightweightComment} from './types/lightweight-comment.js'; @@ -33,7 +33,7 @@ export function extractComment(node: ts.Node): LightweightComment | undefined { ? undefined : cleanupEmpty({ shortSummary: comment?.[0], - description: comment?.[comment.length - 1], + description: comment?.slice(1).join('\n\n'), tags: jsDocument?.tags?.map(tag => cleanupEmpty({ name: tag.tagName?.escapedText ?? 'UNRESOLVED_NAME', diff --git a/packages/easy-ast/src/easy-ast.ts b/packages/easy-ast/src/easy-ast.ts index bb72b1f1..e8bb41d9 100644 --- a/packages/easy-ast/src/easy-ast.ts +++ b/packages/easy-ast/src/easy-ast.ts @@ -14,7 +14,7 @@ * this program. If not, see . */ import ts from 'typescript'; -import {cleanupEmpty, mapNotNil, rejectNil, expandPathToFilesSync} from './util.js'; +import {cleanupEmpty, expandPathToFilesSync, mapNotNil, rejectNil} from './util.js'; import { extractComment, filterChildrenTo, @@ -77,7 +77,7 @@ class LightweightDefinitionBuilder { constructor(sourcePath: string | string[], readonly includeComments: boolean) { const rootNames = Array.isArray(sourcePath) ? sourcePath - : expandPathToFilesSync(path.resolve(sourcePath), file => file.endsWith('ts')); + : expandPathToFilesSync(path.resolve(sourcePath), it => it.endsWith('.ts')); this.program = ts.createProgram({ rootNames: rootNames, @@ -121,7 +121,7 @@ class LightweightDefinitionBuilder { classLike: ts.ClassDeclaration | ts.InterfaceDeclaration, ): LightweightClassDefinition { const heritages = mapValues( - groupBy([...classLike.heritageClauses!], it => it.token.toString()), + groupBy([...(classLike.heritageClauses || [])], it => it.token.toString()), heritages => heritages.flatMap(it => it.types), ); @@ -162,23 +162,25 @@ class LightweightDefinitionBuilder { collectProperties( members: ts.NodeArray, - ): Record { - return keyBy( - filterNodeTo(members as ts.NodeArray, isProperty).map(property => - cleanupEmpty({ - comment: this.includeComments ? extractComment(property) : undefined, - name: resolvePropertyName(property.name) ?? property.getText(), - type: this.lightweightTypeAtNode(property), - properties: this.collectProperties((property.type as ts.TypeLiteralNode)?.members), - optional: ts.isPropertyDeclaration(property) - ? property.questionToken === undefined - ? undefined - : true - : undefined, - }), - ), - it => it.name, - ); + ): Record | undefined { + return members + ? keyBy( + filterNodeTo(members as ts.NodeArray, isProperty).map(property => + cleanupEmpty({ + comment: this.includeComments ? extractComment(property) : undefined, + name: resolvePropertyName(property.name) ?? property.getText(), + type: this.lightweightTypeAtNode(property), + properties: this.collectProperties((property.type as ts.TypeLiteralNode)?.members), + optional: ts.isPropertyDeclaration(property) + ? property.questionToken === undefined + ? undefined + : true + : undefined, + }), + ), + it => it.name, + ) + : undefined; } private lightweightTypeAtNode(node: ts.Node): LightweightType { diff --git a/packages/easy-ast/src/index.ts b/packages/easy-ast/src/index.ts index e09a4865..ac31cf2e 100644 --- a/packages/easy-ast/src/index.ts +++ b/packages/easy-ast/src/index.ts @@ -12,14 +12,14 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -export * from './easy-ast.js' -export * from './ast-util.js' +export * from './easy-ast.js'; +export * from './ast-util.js'; -export * from './types/lightweight-alias-definition.js' -export * from './types/lightweight-class-definition.js' -export * from './types/lightweight-comment.js' -export * from './types/lightweight-definition.js' -export * from './types/lightweight-definition-kind.js' -export * from './types/lightweight-project.js' -export * from './types/lightweight-property.js' -export * from './types/lightweight-type.js' +export * from './types/lightweight-alias-definition.js'; +export * from './types/lightweight-class-definition.js'; +export * from './types/lightweight-comment.js'; +export * from './types/lightweight-definition.js'; +export * from './types/lightweight-definition-kind.js'; +export * from './types/lightweight-project.js'; +export * from './types/lightweight-property.js'; +export * from './types/lightweight-type.js'; diff --git a/packages/easy-ast/src/util.ts b/packages/easy-ast/src/util.ts index ed51bcbf..1400b6e6 100644 --- a/packages/easy-ast/src/util.ts +++ b/packages/easy-ast/src/util.ts @@ -12,15 +12,36 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import path from "path"; -import {readdirSync, statSync} from "fs"; +import {readdirSync, statSync} from 'fs'; +import path from 'path'; + +/** + * Expand a path to a list of all files deeply contained in it + */ +export function expandPathToFilesSync(sourcePath: string, accept: (fileName: string) => boolean): string[] { + const fullPath = path.resolve(sourcePath); + const directory = statSync(fullPath); + + return directory.isDirectory() + ? readdirSync(fullPath).flatMap(fragment => + expandPathToFilesSync(path.resolve(sourcePath, fragment), accept), + ) + : [fullPath].filter(accept); +} + +/** + * Take a Windows path and make a Unix path out of it + */ +export function toUnixPath(pathString: string): string { + return pathString.replaceAll(path.sep, path.posix.sep); +} /** * Filters only defined elements */ export function rejectNil(array: Array): T[] { // eslint-disable-next-line unicorn/no-null - return array.filter(it => it == null) as T[]; + return array.filter(it => it != null) as T[]; } /** @@ -45,17 +66,3 @@ export function cleanupEmpty(object: T): T { } return out; } - -/** - * Expand a path to a list of all files deeply contained in it - */ -export function expandPathToFilesSync(sourcePath: string, accept: (fileName: string) => boolean): string[] { - const fullPath = path.resolve(sourcePath); - const directory = statSync(fullPath); - - return directory.isDirectory() - ? readdirSync(fullPath).flatMap(fragment => - expandPathToFilesSync(path.resolve(sourcePath, fragment), accept), - ) - : [fullPath].filter(accept); -} diff --git a/packages/easy-ast/test/easy-ast-spec-type.ts b/packages/easy-ast/test/easy-ast-spec-type.ts index 683b73ea..96f8c49e 100644 --- a/packages/easy-ast/test/easy-ast-spec-type.ts +++ b/packages/easy-ast/test/easy-ast-spec-type.ts @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {LightweightFile} from '../../src/easy-ast/types/lightweight-project.js'; +import {LightweightFile} from '../src/index.js'; export interface EasyAstSpecType { testName: string; diff --git a/packages/easy-ast/test/index.spec.ts b/packages/easy-ast/test/index.spec.ts new file mode 100644 index 00000000..cc580f0b --- /dev/null +++ b/packages/easy-ast/test/index.spec.ts @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +import {lightweightProjectFromPath} from '../src/index.js'; +import {expect} from 'chai'; +import {expandPathToFilesSync, toUnixPath} from '../src/util.js'; +import type {EasyAstSpecType} from './easy-ast-spec-type.js'; + +const projectPath = './test/project'; + +const tests = await Promise.all( + expandPathToFilesSync(projectPath, file => file.endsWith('ast-test.ts')).map(async it => ({ + path: toUnixPath(it), + config: await import(`file://${it}`).then(it => it.testConfig as EasyAstSpecType), + })), +); + +describe('Easy AST', async function () { + it('should build the project', function () { + const project = lightweightProjectFromPath(projectPath, true); + expect(Object.keys(project).length).to.equal(tests.length); + }); + + const project = lightweightProjectFromPath(projectPath, true); + + for (const {path, config} of tests) { + it(config.testName, function () { + const projectAtPath = project[path]; + expect(projectAtPath).not.to.be.undefined; + for (const key in projectAtPath) { + if (key.startsWith('$')) delete projectAtPath[key]; + } + + expect(projectAtPath).to.be.deep.equal(config.expected); + }); + } +}); diff --git a/packages/easy-ast/test/index.ts b/packages/easy-ast/test/index.ts deleted file mode 100644 index 85ffebe3..00000000 --- a/packages/easy-ast/test/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2021 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -import {expandPathToFilesSync, toUnixPath} from '../src/util.js'; -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {lightweightProjectFromPath} from '../src/easy-ast.js'; -import {expect} from 'chai'; - -describe('Easy AST', async () => { - const project = lightweightProjectFromPath('./test/easy-ast', true); - for (const file of expandPathToFilesSync('./test/easy-ast', file => file.endsWith('ast-test.ts'))) { - try { - const test = (await import(file))['testConfig'] as EasyAstSpecType; - - it(test.testName, () => { - expect(omitBy(project[toUnixPath(file)], (_value, key) => key.startsWith('$'))).to.be.deep.equal( - test.expected, - ); - }); - } catch (error) { - console.error(error); - } - } -}); diff --git a/packages/easy-ast/test/alias-like.ast-test.ts b/packages/easy-ast/test/project/alias-like.ast-test.ts similarity index 90% rename from packages/easy-ast/test/alias-like.ast-test.ts rename to packages/easy-ast/test/project/alias-like.ast-test.ts index f7097e42..18c9cdfc 100644 --- a/packages/easy-ast/test/alias-like.ast-test.ts +++ b/packages/easy-ast/test/project/alias-like.ast-test.ts @@ -13,11 +13,13 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; +// @ts-expect-error unused type type TestTypeAlias = number | string; +// @ts-expect-error unused type enum TestEnum { Foo, Bar, diff --git a/packages/easy-ast/test/array-like.ast-test.ts b/packages/easy-ast/test/project/array-like.ast-test.ts similarity index 89% rename from packages/easy-ast/test/array-like.ast-test.ts rename to packages/easy-ast/test/project/array-like.ast-test.ts index c33724b0..45dd05a7 100644 --- a/packages/easy-ast/test/array-like.ast-test.ts +++ b/packages/easy-ast/test/project/array-like.ast-test.ts @@ -13,14 +13,18 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; interface Random {} +// @ts-expect-error unused type type TestArrayGeneric = Array; +// @ts-expect-error unused type type TestArrayLiteral = number[]; +// @ts-expect-error unused type type TestArrayReferenceGeneric = Array; +// @ts-expect-error unused type type TestArrayReferenceLiteral = Random[]; export const testConfig: EasyAstSpecType = { diff --git a/packages/easy-ast/test/class-like.ast-test.ts b/packages/easy-ast/test/project/class-like.ast-test.ts similarity index 89% rename from packages/easy-ast/test/class-like.ast-test.ts rename to packages/easy-ast/test/project/class-like.ast-test.ts index 9ba26e7c..5df79e98 100644 --- a/packages/easy-ast/test/class-like.ast-test.ts +++ b/packages/easy-ast/test/project/class-like.ast-test.ts @@ -13,13 +13,15 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; +// @ts-expect-error unused type interface TestInterface { foo: number; } +// @ts-expect-error unused type class TestClass { bar: string = 'test'; } diff --git a/packages/easy-ast/test/comment.ast-test.ts b/packages/easy-ast/test/project/comment.ast-test.ts similarity index 94% rename from packages/easy-ast/test/comment.ast-test.ts rename to packages/easy-ast/test/project/comment.ast-test.ts index 4db61a5f..cb28a281 100644 --- a/packages/easy-ast/test/comment.ast-test.ts +++ b/packages/easy-ast/test/project/comment.ast-test.ts @@ -13,8 +13,8 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; /** * Class comment @@ -25,6 +25,7 @@ import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-de * * @classTag classParameter1 classParameter2 */ +// @ts-expect-error unused type interface TestInterface { /** * Property comment @@ -47,6 +48,7 @@ interface TestInterface { * * @classTag classParameter1 classParameter2 */ +// @ts-expect-error unused type class TestClass { /** * Property comment @@ -69,6 +71,7 @@ class TestClass { * * @enumTag enumParameter1 */ +// @ts-expect-error unused type enum TestAlias {} export const testConfig: EasyAstSpecType = { diff --git a/packages/easy-ast/test/default-generics.ast-test.ts b/packages/easy-ast/test/project/default-generics.ast-test.ts similarity index 91% rename from packages/easy-ast/test/default-generics.ast-test.ts rename to packages/easy-ast/test/project/default-generics.ast-test.ts index 20392a31..eaffac2f 100644 --- a/packages/easy-ast/test/default-generics.ast-test.ts +++ b/packages/easy-ast/test/project/default-generics.ast-test.ts @@ -13,13 +13,14 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; interface Test1 { foo: T; } +// @ts-expect-error unused type interface Test2 { bar: Test1; } diff --git a/packages/easy-ast/test/enum-specified-value.ast-test.ts b/packages/easy-ast/test/project/enum-specified-value.ast-test.ts similarity index 90% rename from packages/easy-ast/test/enum-specified-value.ast-test.ts rename to packages/easy-ast/test/project/enum-specified-value.ast-test.ts index 6b41af7b..4acf28ad 100644 --- a/packages/easy-ast/test/enum-specified-value.ast-test.ts +++ b/packages/easy-ast/test/project/enum-specified-value.ast-test.ts @@ -13,14 +13,16 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; +// @ts-expect-error unused type enum TestAuto { Foo, Bar, } +// @ts-expect-error unused type enum TestSpecified { YES = 'yes', NO = 'no', diff --git a/packages/easy-ast/test/generics.ast-test.ts b/packages/easy-ast/test/project/generics.ast-test.ts similarity index 92% rename from packages/easy-ast/test/generics.ast-test.ts rename to packages/easy-ast/test/project/generics.ast-test.ts index 78d6c305..dd8a20a5 100644 --- a/packages/easy-ast/test/generics.ast-test.ts +++ b/packages/easy-ast/test/project/generics.ast-test.ts @@ -13,11 +13,12 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; interface $Random {} +// @ts-expect-error unused type interface Generics { baz: Foo; } diff --git a/packages/easy-ast/test/index-signature.ast-test.ts b/packages/easy-ast/test/project/index-signature.ast-test.ts similarity index 91% rename from packages/easy-ast/test/index-signature.ast-test.ts rename to packages/easy-ast/test/project/index-signature.ast-test.ts index 2d038187..201660ca 100644 --- a/packages/easy-ast/test/index-signature.ast-test.ts +++ b/packages/easy-ast/test/project/index-signature.ast-test.ts @@ -13,15 +13,17 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; interface $Random {} +// @ts-expect-error unused interface IndexSignatureObject { [key: string]: $Random; } +// @ts-expect-error unused interface IndexSignaturePrimitive { [key: string]: number; } diff --git a/packages/easy-ast/test/ineritance.ast-test.ts b/packages/easy-ast/test/project/ineritance.ast-test.ts similarity index 92% rename from packages/easy-ast/test/ineritance.ast-test.ts rename to packages/easy-ast/test/project/ineritance.ast-test.ts index 42728f3f..76ce7ec3 100644 --- a/packages/easy-ast/test/ineritance.ast-test.ts +++ b/packages/easy-ast/test/project/ineritance.ast-test.ts @@ -13,8 +13,8 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; interface $BaseInterface { foo: T; @@ -26,6 +26,7 @@ interface $BaseInterface2 { class $BaseClass {} +// @ts-expect-error unused class InheritingClass extends $BaseClass implements $BaseInterface, $BaseInterface2 { bar: string = ''; diff --git a/packages/easy-ast/test/nested.ast-test.ts b/packages/easy-ast/test/project/nested.ast-test.ts similarity index 91% rename from packages/easy-ast/test/nested.ast-test.ts rename to packages/easy-ast/test/project/nested.ast-test.ts index 257f5e52..a85c740a 100644 --- a/packages/easy-ast/test/nested.ast-test.ts +++ b/packages/easy-ast/test/project/nested.ast-test.ts @@ -13,9 +13,10 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; +// @ts-expect-error unused interface NestedObject { nested: { deeplyNested: { diff --git a/packages/easy-ast/test/primitive-types.ast-test.ts b/packages/easy-ast/test/project/primitive-types.ast-test.ts similarity index 94% rename from packages/easy-ast/test/primitive-types.ast-test.ts rename to packages/easy-ast/test/project/primitive-types.ast-test.ts index 16edae06..a975a286 100644 --- a/packages/easy-ast/test/primitive-types.ast-test.ts +++ b/packages/easy-ast/test/project/primitive-types.ast-test.ts @@ -13,9 +13,10 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; +// @ts-expect-error unused interface Test { number_type: number; string_type: string; diff --git a/packages/easy-ast/test/stack-overflow.ast-test.ts b/packages/easy-ast/test/project/stack-overflow.ast-test.ts similarity index 90% rename from packages/easy-ast/test/stack-overflow.ast-test.ts rename to packages/easy-ast/test/project/stack-overflow.ast-test.ts index c2a4432f..60a532a2 100644 --- a/packages/easy-ast/test/stack-overflow.ast-test.ts +++ b/packages/easy-ast/test/project/stack-overflow.ast-test.ts @@ -13,9 +13,10 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {EasyAstSpecType} from './easy-ast-spec-type.js'; -import {LightweightDefinitionKind} from '../../src/easy-ast/types/lightweight-definition-kind.js'; +import {EasyAstSpecType} from '../easy-ast-spec-type.js'; +import {LightweightDefinitionKind} from '../../src/index.js'; +// @ts-expect-error unused interface Foo> { bar: T; } diff --git a/packages/es-mapping-generator/package.json b/packages/es-mapping-generator/package.json index aa579d60..37fbdc46 100644 --- a/packages/es-mapping-generator/package.json +++ b/packages/es-mapping-generator/package.json @@ -13,11 +13,11 @@ "author": "Thea Schöbl ", "scripts": { "build": "rimraf lib && tsc", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint -c .eslintrc --ignore-path .eslintignore --ext .ts src/ test/", "lint:fix": "eslint --fix -c .eslintrc --ignore-path .eslintignore --ext .ts src/ test/", - "test": "mocha --require ts-node/register test/*.spec.ts" + "test": "c8 mocha" }, "dependencies": { "@elastic/elasticsearch": "8.4.0", @@ -38,9 +38,10 @@ "@types/rimraf": "3.0.2", "chai": "4.3.7", "mocha": "10.2.0", + "c8": "7.13.0", "nock": "13.3.0", + "rimraf": "5.0.0", "ts-node": "10.9.1", - "rimraf": "5.0.0" }, "prettier": "@openstapps/prettier-config" } diff --git a/packages/es-mapping-generator/src/app.ts b/packages/es-mapping-generator/src/app.ts index 2b703d73..bbb97b7c 100644 --- a/packages/es-mapping-generator/src/app.ts +++ b/packages/es-mapping-generator/src/app.ts @@ -17,9 +17,9 @@ import {mkdirSync, readFileSync, writeFileSync} from 'fs'; import got from 'got'; import path from 'path'; import {exit} from 'process'; -import {generateTemplate} from './mapping.js'; -import {getProjectReflection} from './project-reflection.js'; -import {ElasticsearchTemplateCollection} from './types/mapping.js'; +import {generateTemplate} from './mapping'; +import {getProjectReflection} from './project-reflection'; +import {ElasticsearchTemplateCollection} from './types/mapping'; // handle unhandled promise rejections process.on('unhandledRejection', async (reason: unknown) => { diff --git a/packages/es-mapping-generator/src/config/typemap.ts b/packages/es-mapping-generator/src/config/typemap.ts index a95634c3..37dfbd9d 100644 --- a/packages/es-mapping-generator/src/config/typemap.ts +++ b/packages/es-mapping-generator/src/config/typemap.ts @@ -13,7 +13,7 @@ * this program. If not, see . */ import {MappingFloatNumberProperty} from '@elastic/elasticsearch/lib/api/types'; -import {ElasticsearchTypemap} from '../types/mapping.js'; +import {ElasticsearchTypemap} from '../types/mapping'; export const PARSE_ERROR = 'PARSE_ERROR' as MappingFloatNumberProperty['type']; export const MISSING_PREMAP = 'MISSING_PREMAP' as MappingFloatNumberProperty['type']; diff --git a/packages/es-mapping-generator/src/index.ts b/packages/es-mapping-generator/src/index.ts index bfa6b52b..8ceff37f 100644 --- a/packages/es-mapping-generator/src/index.ts +++ b/packages/es-mapping-generator/src/index.ts @@ -1,6 +1,10 @@ -export * from './mapping' -export * from './project-reflection' -export * from './config/premap' -export * from './config/fieldmap' -export * from './config/settings' -export * from './config/typemap' +export * from './mapping'; +export * from './project-reflection'; + +export * from './config/premap'; +export * from './config/fieldmap'; +export * from './config/settings'; +export * from './config/typemap'; + +export * from './types/mapping'; +export * from './types/aggregation'; diff --git a/packages/es-mapping-generator/src/mapping.ts b/packages/es-mapping-generator/src/mapping.ts index 8af2bbbb..913ef0ed 100644 --- a/packages/es-mapping-generator/src/mapping.ts +++ b/packages/es-mapping-generator/src/mapping.ts @@ -33,13 +33,13 @@ import { TypeParameterType, UnionType, } from 'typedoc/dist/lib/models'; -import {fieldmap, filterableMap, filterableTagName} from './config/fieldmap.js'; -import {premaps} from './config/premap.js'; -import {settings} from './config/settings.js'; -import {dynamicTypes, isTagType, MISSING_PREMAP, PARSE_ERROR, TYPE_CONFLICT, typemap} from './config/typemap.js'; -import {AggregationSchema, ESNestedAggregation} from './types/aggregation.js'; +import {fieldmap, filterableMap, filterableTagName} from './config/fieldmap'; +import {premaps} from './config/premap'; +import {settings} from './config/settings'; +import {dynamicTypes, isTagType, MISSING_PREMAP, PARSE_ERROR, TYPE_CONFLICT, typemap} from './config/typemap'; +import {AggregationSchema, ESNestedAggregation} from './types/aggregation'; import {ElasticsearchTemplateCollection, - MappingGenTemplate} from './types/mapping.js'; + MappingGenTemplate} from './types/mapping'; import * as console from 'console'; let dynamicTemplates: Record[] = []; diff --git a/packages/es-mapping-generator/test/aggregations.spec.ts b/packages/es-mapping-generator/test/aggregations.spec.ts index 8cec52aa..7a284334 100644 --- a/packages/es-mapping-generator/test/aggregations.spec.ts +++ b/packages/es-mapping-generator/test/aggregations.spec.ts @@ -12,7 +12,6 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Logger} from '@openstapps/logger'; import {readdirSync, statSync} from 'fs'; import path from 'path'; import {MapAggTest} from './mapping-model/map-agg-test.js'; @@ -48,8 +47,8 @@ describe('ES Aggregation Gen', async () => { it(test.testName, function () { magAppInstance.testInterfaceAgainstPath(test); }); - } catch (error: any) { - await Logger.error('UNHANDLED REJECTION', error.stack); + } catch (error) { + console.error('UNHANDLED REJECTION', (error as any).stack); process.exit(1); } } diff --git a/packages/es-mapping-generator/test/mapping-model/mappings/src/any-unknown.mapping-test.ts b/packages/es-mapping-generator/test/mapping-model/mappings/src/any-unknown.mapping-test.ts index 03486435..2e3ccee5 100644 --- a/packages/es-mapping-generator/test/mapping-model/mappings/src/any-unknown.mapping-test.ts +++ b/packages/es-mapping-generator/test/mapping-model/mappings/src/any-unknown.mapping-test.ts @@ -12,7 +12,6 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ - import {ThingType} from './types.js'; import {MapAggTestOptions} from '../../map-agg-test-options.js'; diff --git a/packages/es-mapping-generator/test/mapping-model/mappings/src/tags-ignore-case.mapping-test.ts b/packages/es-mapping-generator/test/mapping-model/mappings/src/tags-ignore-case.mapping-test.ts index ff8e7c14..37cc3e98 100644 --- a/packages/es-mapping-generator/test/mapping-model/mappings/src/tags-ignore-case.mapping-test.ts +++ b/packages/es-mapping-generator/test/mapping-model/mappings/src/tags-ignore-case.mapping-test.ts @@ -54,7 +54,7 @@ export const testConfig: MapAggTestOptions = { dynamic: 'strict', properties: { baz: { - type: 'float', + type: ElasticsearchDataType.float, }, }, }, diff --git a/packages/es-mapping-generator/test/mapping.spec.ts b/packages/es-mapping-generator/test/mapping.spec.ts index 073dd2d4..d98bde15 100644 --- a/packages/es-mapping-generator/test/mapping.spec.ts +++ b/packages/es-mapping-generator/test/mapping.spec.ts @@ -12,7 +12,6 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Logger} from '@openstapps/logger'; import {readdirSync, statSync} from 'fs'; import path from 'path'; import {MapAggTest} from './mapping-model/map-agg-test.js'; @@ -49,8 +48,8 @@ describe('ES Mapping Gen', async () => { it(test.testName, function () { magAppInstance.testInterfaceAgainstPath(test); }); - } catch (error: any) { - await Logger.error('UNHANDLED REJECTION', error.stack); + } catch (error) { + console.error('UNHANDLED REJECTION', (error as any).stack); process.exit(1); } } diff --git a/packages/gitlab-api/package.json b/packages/gitlab-api/package.json index 186a38b6..0c5bbc46 100644 --- a/packages/gitlab-api/package.json +++ b/packages/gitlab-api/package.json @@ -16,8 +16,8 @@ }, "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/" }, diff --git a/packages/gitlab-api/src/api.ts b/packages/gitlab-api/src/api.ts index 6dcf06dd..13de6048 100644 --- a/packages/gitlab-api/src/api.ts +++ b/packages/gitlab-api/src/api.ts @@ -35,7 +35,7 @@ import { } from './types.js'; import got from 'got'; -export * from './types.js' +export * from './types.js'; /** * Sleep for a number of milliseconds diff --git a/packages/logger/.gitlab/issue_templates/bug.md b/packages/logger/.gitlab/issue_templates/bug.md deleted file mode 100644 index 4ef365a8..00000000 --- a/packages/logger/.gitlab/issue_templates/bug.md +++ /dev/null @@ -1,32 +0,0 @@ -## Summary - -(Summarize the bug encountered concisely) - -## Steps to reproduce - -(How one can reproduce the issue - this is very important) - -## Example Project - -(If possible, please create an example project here on GitLab.com that exhibits the problematic behaviour, and link to it here in the bug report) - -(If you are using an older version of GitLab, this will also determine whether the bug has been fixed in a more recent version) - -## What is the current bug behavior? - -(What actually happens) - -## What is the expected correct behavior? - -(What you should see instead) - -## Relevant logs and/or screenshots - -(Paste any relevant logs - please use code blocks (```) to format console output, -logs, and code as it's very hard to read otherwise.) - -## Possible fixes - -(If you can, link to the line of code that might be responsible for the problem) - -/label ~meeting diff --git a/packages/logger/package.json b/packages/logger/package.json index a1c07fb4..413e8c68 100644 --- a/packages/logger/package.json +++ b/packages/logger/package.json @@ -15,25 +15,22 @@ "types": "./lib/index.d.ts", "scripts": { "build": "tsup --dts", - "format": "prettier .", - "format:fix": "prettier --write .", + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore", "lint": "eslint --ext .ts src/", "lint:fix": "eslint --fix --ext .ts src/", - "test": "nyc mocha 'test/**/*.spec.ts'" + "test": "c8 mocha" }, "dependencies": { "@types/nodemailer": "6.4.7", - "chalk": "4.1.2", + "chalk": "5.2.0", "flatted": "3.2.7", - "moment": "2.29.4", "nodemailer": "6.9.1" }, "devDependencies": { "@openstapps/eslint-config": "workspace:*", - "@openstapps/nyc-config": "workspace:*", "@openstapps/prettier-config": "workspace:*", "@openstapps/tsconfig": "workspace:*", - "@testdeck/mocha": "0.3.3", "@types/chai": "4.3.4", "@types/chai-as-promised": "7.1.5", "@types/chai-spies": "1.0.3", @@ -43,7 +40,7 @@ "chai-as-promised": "7.1.1", "chai-spies": "1.0.0", "mocha": "10.2.0", - "nyc": "15.1.0", + "c8": "7.13.0", "ts-node": "10.9.1", "tsup": "6.7.0", "typedoc": "0.23.28", @@ -63,8 +60,5 @@ "extends": [ "@openstapps" ] - }, - "nyc": { - "extends": "@openstapps/nyc-config" } } diff --git a/packages/logger/src/index.ts b/packages/logger/src/index.ts index c4b3922e..6d5ffe0c 100644 --- a/packages/logger/src/index.ts +++ b/packages/logger/src/index.ts @@ -1,9 +1,9 @@ -export * from './logger.js' -export * from './common.js' -export * from './smtp.js' -export * from './transformation.js' -export * from './transport.js' +export * from './logger.js'; +export * from './common.js'; +export * from './smtp.js'; +export * from './transformation.js'; +export * from './transport.js'; -export * from './transformations/add-log-level.js' -export * from './transformations/colorize.js' -export * from './transformations/timestamp.js' +export * from './transformations/add-log-level.js'; +export * from './transformations/colorize.js'; +export * from './transformations/timestamp.js'; diff --git a/packages/logger/src/transformations/colorize.ts b/packages/logger/src/transformations/colorize.ts index cabacb0a..699a5b3e 100644 --- a/packages/logger/src/transformations/colorize.ts +++ b/packages/logger/src/transformations/colorize.ts @@ -13,6 +13,8 @@ * this program. If not, see . */ import chalk from 'chalk'; +// eslint-disable-next-line unicorn/import-style +import type {ChalkInstance} from 'chalk'; import {LogLevel} from '../logger.js'; import {Transformation} from '../transformation.js'; @@ -31,7 +33,8 @@ export class Colorize implements Transformation { * @param logLevelToColor Map from log level to color transformation to apply */ constructor( - private readonly logLevelToColor: {[k in LogLevel]: chalk.Chalk} = { + // not entirely sure why we can't just use the functions directly here + private readonly logLevelToColor: {[k in LogLevel]: ChalkInstance} = { ERROR: chalk.bold.red, INFO: chalk.cyan, LOG: chalk.white, diff --git a/packages/logger/test/common.spec.ts b/packages/logger/test/common.spec.ts index 14e2dc8c..02880861 100644 --- a/packages/logger/test/common.spec.ts +++ b/packages/logger/test/common.spec.ts @@ -13,18 +13,15 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {suite, test} from '@testdeck/mocha'; import { deleteUndefinedProperties, isNodeEnvironment, isProductiveEnvironment, isProductiveNodeEnvironment, -} from '../src/common.js'; +} from '../src/index.js'; -@suite() -export class CommonSpec { - @test - deleteUndefinedProperties1() { +describe('common', function () { + it('should should delete undefined properties (1)', function () { expect( deleteUndefinedProperties({ a: 2, @@ -39,20 +36,18 @@ export class CommonSpec { c: 3, }, }); - } + }); - @test - deleteUndefinedProperties2() { + it('should delete undefined properties (2)', function () { expect( deleteUndefinedProperties({ a: undefined, b: undefined, }), ).to.deep.equal({}); - } + }); - @test - deleteUndefinedProperties3() { + it('should delete undefined properties (3)', function () { expect( deleteUndefinedProperties({ a: 2, @@ -64,49 +59,41 @@ export class CommonSpec { b: 'foo', c: 'bar', }); - } + }); - @test - isNodeEnvironment() { + it('should detect node environment', function () { expect(isNodeEnvironment()).to.be.equal(true); const savedProcess = process; - // @ts-ignore + // @ts-expect-error override this process = undefined; - expect(isNodeEnvironment()).to.be.equal(false); process = savedProcess; - } + }); - @test - isProductiveEnvironment() { - const nodeEnv = process.env.NODE_ENV; + it('should detect production environment', function () { + const nodeEnvironment = process.env.NODE_ENV; process.env.NODE_ENV = ''; - expect(isProductiveEnvironment()).to.be.equal(false); process.env.NODE_ENV = 'production'; - expect(isProductiveEnvironment()).to.be.equal(true); - process.env.NODE_ENV = nodeEnv; - } + process.env.NODE_ENV = nodeEnvironment; + }); - @test - isProductiveNodeEnvironment() { - const nodeEnv = process.env.NODE_ENV; + it('should detect node production environment', function () { + const nodeEnvironment = process.env.NODE_ENV; process.env.NODE_ENV = ''; - expect(isProductiveNodeEnvironment()).to.be.equal(false); process.env.NODE_ENV = 'production'; - expect(isProductiveNodeEnvironment()).to.be.equal(true); - process.env.NODE_ENV = nodeEnv; - } -} + process.env.NODE_ENV = nodeEnvironment; + }); +}); diff --git a/packages/logger/test/dummyTransport.ts b/packages/logger/test/dummy-transport.ts similarity index 90% rename from packages/logger/test/dummyTransport.ts rename to packages/logger/test/dummy-transport.ts index 41a9b1f0..61184577 100644 --- a/packages/logger/test/dummyTransport.ts +++ b/packages/logger/test/dummy-transport.ts @@ -1,4 +1,4 @@ -import {Transport, VerifiableTransport} from '../src/transport.js'; +import {Transport, VerifiableTransport} from '../src/index.js'; export class DummyTransport extends Transport { send(subject: string, message: string): Promise { diff --git a/packages/logger/test/logger.spec.ts b/packages/logger/test/logger.spec.ts index b33e5b2f..23a0af71 100644 --- a/packages/logger/test/logger.spec.ts +++ b/packages/logger/test/logger.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ /* * Copyright (C) 2018, 2020 StApps * This program is free software: you can redistribute it and/or modify it @@ -16,41 +17,35 @@ import chai from 'chai'; import {expect} from 'chai'; import chaiAsPromised from 'chai-as-promised'; import chaiSpies from 'chai-spies'; -import {suite, test} from '@testdeck/mocha'; -import {Logger} from '../src/logger.js'; -import {AddLogLevel} from '../src/transformations/add-log-level.js'; -import {Colorize} from '../src/transformations/colorize.js'; -import {DummyTransport} from './dummyTransport.js'; +import {Logger, AddLogLevel, Colorize} from '../src/index.js'; +import {DummyTransport} from './dummy-transport.js'; +import path from 'node:path'; +import chalk from 'chalk'; chai.should(); chai.use(chaiSpies); chai.use(chaiAsPromised); -@suite() -export class LoggerSpec { - static 'sandbox': ChaiSpies.Sandbox; +chalk.level = 2; - static 'before'() { - LoggerSpec.sandbox = chai.spy.sandbox(); - } +describe('Logger', function () { + const sandbox = chai.spy.sandbox(); - 'before'() { + beforeEach(function () { Logger.setTransformations([new AddLogLevel()]); - } + }); - 'after'() { - LoggerSpec.sandbox.restore(); - } + afterEach(function () { + sandbox.restore(); + }); - @test - async 'default log level'() { + it('should read default log level', async function () { expect((Logger as any).getLevel('LOG')).to.be.equal(31); expect((Logger as any).getLevel('EXIT')).to.be.equal(0); - } + }); - @test - async 'error'() { - const spy = LoggerSpec.sandbox.on(console, 'error', () => { + it('should error', async function () { + const spy = sandbox.on(console, 'error', () => { // noop }); @@ -59,15 +54,14 @@ export class LoggerSpec { expect(spy).to.have.been.called(); expect(spy.__spy.calls[0][0]).to.contain('[ERROR]'); expect(spy.__spy.calls[0][0]).to.contain('Foobar'); - } + }); - @test - async 'error in productive environment'() { - const spy = LoggerSpec.sandbox.on(console, 'error', () => { + it('should error in productive environment', async function () { + const spy = sandbox.on(console, 'error', () => { // noop }); - const nodeEnv = process.env.NODE_ENV; + const nodeEnvironment = process.env.NODE_ENV; process.env.NODE_ENV = 'production'; await Logger.error('Foobar').should.be.rejectedWith(Error); @@ -87,12 +81,11 @@ export class LoggerSpec { Logger.setTransport(); - process.env.NODE_ENV = nodeEnv; - } + process.env.NODE_ENV = nodeEnvironment; + }); - @test - async 'error without output'() { - const spy = LoggerSpec.sandbox.on(console, 'error', () => { + it('should error without output', async function () { + const spy = sandbox.on(console, 'error', () => { // noop }); @@ -103,24 +96,24 @@ export class LoggerSpec { delete process.env.STAPPS_LOG_LEVEL; expect(spy).not.to.have.been.called(); - } + }); - @test - async 'error with Error'() { - const spy = LoggerSpec.sandbox.on(console, 'error', () => { + it('should error with Error', async function () { + const spy = sandbox.on(console, 'error', () => { // noop }); + // eslint-disable-next-line unicorn/error-message await Logger.error(new Error()); expect(spy).to.have.been.called(); expect(spy.__spy.calls[0][0]).to.contain('Error'); - expect(spy.__spy.calls[0][0]).to.contain(process.cwd()); - } + const directory = process.cwd().replaceAll(path.sep, path.posix.sep); + expect(spy.__spy.calls[0][0]).to.contain(directory); + }); - @test - 'info'() { - const spy = LoggerSpec.sandbox.on(console, 'info', () => { + it('should info', function () { + const spy = sandbox.on(console, 'info', () => { // noop }); @@ -129,23 +122,22 @@ export class LoggerSpec { expect(spy).to.have.been.called(); expect(spy.__spy.calls[0][0]).to.contain('[INFO]'); expect(spy.__spy.calls[0][0]).to.contain('Foobar'); - } + }); - @test - async 'exits'() { - const infoSpy = LoggerSpec.sandbox.on(console, 'info', () => { + it('should exit', async function () { + const infoSpy = sandbox.on(console, 'info', () => { // noop }); - const logSpy = LoggerSpec.sandbox.on(console, 'log', () => { + const logSpy = sandbox.on(console, 'log', () => { // noop }); - const warnSpy = LoggerSpec.sandbox.on(console, 'warn', () => { + const warnSpy = sandbox.on(console, 'warn', () => { // noop }); - const errorSpy = LoggerSpec.sandbox.on(console, 'error', () => { + const errorSpy = sandbox.on(console, 'error', () => { // noop }); - const processSpy = LoggerSpec.sandbox.on(process, 'exit', () => { + const processSpy = sandbox.on(process, 'exit', () => { // noop }); @@ -173,11 +165,10 @@ export class LoggerSpec { expect(processSpy).to.have.been.called.exactly(5); process.env.STAPPS_EXIT_LEVEL = exitLevel; - } + }); - @test - 'info without output'() { - const spy = LoggerSpec.sandbox.on(console, 'info', () => { + it('should info without output', function () { + const spy = sandbox.on(console, 'info', () => { // noop }); @@ -188,10 +179,9 @@ export class LoggerSpec { delete process.env.STAPPS_LOG_LEVEL; expect(spy).not.to.have.been.called; - } + }); - @test - 'initialized'() { + it('should be initialized', function () { Logger.setTransport(new DummyTransport()); expect(() => { @@ -199,11 +189,10 @@ export class LoggerSpec { }).not.to.throw(); Logger.setTransport(); - } + }); - @test - 'initialized in productive environment'() { - const nodeEnv = process.env.NODE_ENV; + it('should be initialized in productive environment', function () { + const nodeEnvironment = process.env.NODE_ENV; process.env.NODE_ENV = 'production'; Logger.setTransport(new DummyTransport()); @@ -218,7 +207,7 @@ export class LoggerSpec { Logger.initialized(); }).to.throw(); - const spy = LoggerSpec.sandbox.on(console, 'warn', () => { + const spy = sandbox.on(console, 'warn', () => { // noop }); @@ -232,14 +221,13 @@ export class LoggerSpec { expect(spy).to.have.been.called(); - process.env.NODE_ENV = nodeEnv; - } + process.env.NODE_ENV = nodeEnvironment; + }); - @test - 'is compatible with log aggregation in productive environment'() { + it('should be compatible with log aggregation in productive environment', function () { Logger.setTransformations([new AddLogLevel(), new Colorize()]); - let spy = LoggerSpec.sandbox.on(console, 'log', () => { + const spy = sandbox.on(console, 'log', () => { // noop }); @@ -248,7 +236,7 @@ export class LoggerSpec { expect(spy).to.have.been.called.once; expect(spy.__spy.calls[0][0]).to.equal('\u001B[37m[LOG] Foo\u001B[39m\n\u001B[37mbar\u001B[39m'); - const nodeEnv = process.env.NODE_ENV; + const nodeEnvironment = process.env.NODE_ENV; process.env.NODE_ENV = 'production'; process.env.ALLOW_NO_TRANSPORT = 'true'; @@ -259,13 +247,12 @@ export class LoggerSpec { expect(spy).to.have.been.called.twice; expect(spy.__spy.calls[1][0]).to.equal('[LOG] Foo bar'); - process.env.NODE_ENV = nodeEnv; + process.env.NODE_ENV = nodeEnvironment; delete process.env.ALLOW_NO_TRANSPORT; - } + }); - @test - 'log'() { - const spy = LoggerSpec.sandbox.on(console, 'log', () => { + it('should log', function () { + const spy = sandbox.on(console, 'log', () => { // noop }); @@ -274,11 +261,10 @@ export class LoggerSpec { expect(spy).to.have.been.called(); expect(spy.__spy.calls[0][0]).to.contain('[LOG]'); expect(spy.__spy.calls[0][0]).to.contain('Foobar'); - } + }); - @test - 'log without output'() { - const spy = LoggerSpec.sandbox.on(console, 'log', () => { + it('should log without output', function () { + const spy = sandbox.on(console, 'log', () => { // noop }); @@ -289,11 +275,10 @@ export class LoggerSpec { delete process.env.STAPPS_LOG_LEVEL; expect(spy).to.not.have.been.called(); - } + }); - @test - 'ok'() { - const spy = LoggerSpec.sandbox.on(console, 'log', () => { + it('should ok', function () { + const spy = sandbox.on(console, 'log', () => { // noop }); @@ -302,11 +287,10 @@ export class LoggerSpec { expect(spy).to.have.been.called(); expect(spy.__spy.calls[0][0]).to.contain('[OK]'); expect(spy.__spy.calls[0][0]).to.contain('Foobar'); - } + }); - @test - 'ok without output'() { - const spy = LoggerSpec.sandbox.on(console, 'log', () => { + it('should ok without output', function () { + const spy = sandbox.on(console, 'log', () => { // noop }); @@ -317,19 +301,17 @@ export class LoggerSpec { delete process.env.STAPPS_LOG_LEVEL; expect(spy).not.to.have.been.called(); - } + }); - @test - 'setTransport'() { + it('should set transport', function () { expect(() => { Logger.setTransport(new DummyTransport()); Logger.setTransport(); }).not.to.throw(); - } + }); - @test - 'stringify'() { - const spy = LoggerSpec.sandbox.on(console, 'log', () => { + it('should stringify', function () { + const spy = sandbox.on(console, 'log', () => { // noop }); @@ -338,11 +320,10 @@ export class LoggerSpec { expect(spy).to.have.been.called(); expect(spy.__spy.calls[0][0]).to.contain('foo'); expect(spy.__spy.calls[0][0]).to.contain('bar'); - } + }); - @test - 'stringify object'() { - const spy = LoggerSpec.sandbox.on(console, 'log', () => { + it('should stringify object', function () { + const spy = sandbox.on(console, 'log', () => { // noop }); @@ -353,11 +334,10 @@ export class LoggerSpec { expect(spy).to.have.been.called(); expect(spy.__spy.calls[0][0]).to.contain('foo'); expect(spy.__spy.calls[0][0]).to.contain('bar'); - } + }); - @test - 'warn'() { - const spy = LoggerSpec.sandbox.on(console, 'warn', () => { + it('should warn', function () { + const spy = sandbox.on(console, 'warn', () => { // noop }); @@ -366,11 +346,10 @@ export class LoggerSpec { expect(spy).to.have.been.called(); expect(spy.__spy.calls[0][0]).to.contain('[WARN]'); expect(spy.__spy.calls[0][0]).to.contain('Foobar'); - } + }); - @test - 'warn without output'() { - const spy = LoggerSpec.sandbox.on(console, 'warn', () => { + it('should warn without output', function () { + const spy = sandbox.on(console, 'warn', () => { // noop }); @@ -381,17 +360,16 @@ export class LoggerSpec { delete process.env.STAPPS_LOG_LEVEL; expect(spy).not.to.have.been.called(); - } + }); - @test - 'log level exclusiveness'() { - const warnSpy = LoggerSpec.sandbox.on(console, 'warn', () => { + it('should log level exclusiveness', function () { + const warnSpy = sandbox.on(console, 'warn', () => { // noop WARN }); - const infoSpy = LoggerSpec.sandbox.on(console, 'info', () => { + const infoSpy = sandbox.on(console, 'info', () => { // noop INFO }); - const okSpy = LoggerSpec.sandbox.on(console, 'log', () => { + const okSpy = sandbox.on(console, 'log', () => { // noop OK }); @@ -413,20 +391,19 @@ export class LoggerSpec { expect(okSpy).to.not.have.been.called(); delete process.env.STAPPS_LOG_LEVEL; - } + }); - @test - 'getExitLevel'() { + it('should getExitLevel', function () { const savedProcess = process; - // @ts-ignore + // @ts-expect-error ignore process = undefined; (global as any).window = { STAPPS_EXIT_LEVEL: 0, }; - const stub = LoggerSpec.sandbox.on(console, 'info', () => { + const stub = sandbox.on(console, 'info', () => { // noop }); @@ -437,20 +414,19 @@ export class LoggerSpec { delete (global as any).window; expect(stub).not.to.have.been.called(); - } + }); - @test - 'getLogLevel'() { + it('should getLogLevel', function () { const savedProcess = process; - // @ts-ignore + // @ts-expect-error ignore process = undefined; (global as any).window = { STAPPS_LOG_LEVEL: 0, }; - const stub = LoggerSpec.sandbox.on(console, 'info', () => { + const stub = sandbox.on(console, 'info', () => { // noop }); @@ -461,20 +437,19 @@ export class LoggerSpec { delete (global as any).window; expect(stub).not.to.have.been.called(); - } + }); - @test - 'output without transformations'() { + it('should output without transformations', function () { Logger.setTransformations([]); - const stub = LoggerSpec.sandbox.on(console, 'log', () => { + const stub = sandbox.on(console, 'log', () => { // noop }); - const applyTransformationsSpy = LoggerSpec.sandbox.on(new Logger(), 'applyTransformations'); + const applyTransformationsSpy = sandbox.on(new Logger(), 'applyTransformations'); Logger.log('Foobar'); expect(stub).to.have.been.called.with('Foobar'); expect(applyTransformationsSpy).not.to.have.been.called; - } -} + }); +}); diff --git a/packages/logger/test/smtp.spec.ts b/packages/logger/test/smtp.spec.ts index f106aecd..50a69146 100644 --- a/packages/logger/test/smtp.spec.ts +++ b/packages/logger/test/smtp.spec.ts @@ -13,96 +13,42 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {suite, test} from '@testdeck/mocha'; -import {SMTP} from '../src/smtp.js'; +import {SMTP} from '../src/index.js'; -@suite() -export class SMTPSpec { - /* tslint:disable:member-ordering */ - @test - mailValidation1() { - expect(SMTP.isValidEmailAddress('stordeur@campus.tu-berlin.de')).to.be.true; - } +const validEmails = [ + 'stordeur@campus.tu-berlin.de', + 'foo@bar.com', + 'test@test.cz', + 'info@beispiel.to', + 'stördeur@campus.tu-berlin.de', + 'stordeur@campus.tu-berlin.de+a', +]; - @test - mailValidation2() { - expect(SMTP.isValidEmailAddress('foo@bar.com')).to.be.true; - } +const invalidEmails = [ + 'stordeurcampus.tu-berlin.de', + '@campus.tu-berlin.de', + '', + '@', + ' stordeur@campus.tu-berlin.de', + 'stord+eur@campus.tu-berlin.de ', + 'stordeur@campus..tu-berlin.de', + 'stordeur@campus', +]; - @test - mailValidation3() { - expect(SMTP.isValidEmailAddress('test@test.cz')).to.be.true; - } +describe('isValidEmailAddress', function () { + describe('valid emails', function () { + for (const email of validEmails) { + it(`should detect "${email}" as valid`, function () { + expect(SMTP.isValidEmailAddress(email)).to.be.true; + }); + } + }); - @test - mailValidation4() { - expect(SMTP.isValidEmailAddress('info@beispiel.to')).to.be.true; - } - - @test - mailValidation5() { - expect(SMTP.isValidEmailAddress('stördeur@campus.tu-berlin.de')).to.be.true; - } - - @test - mailValidation6() { - expect(SMTP.isValidEmailAddress('stordeur@campus.tu-berlin.de+a')).to.be.true; - } - - @test - mailValidation7() { - expect(SMTP.isValidEmailAddress('stordeurcampus.tu-berlin.de')).to.be.false; - } - - @test - mailValidation8() { - expect(SMTP.isValidEmailAddress('@campus.tu-berlin.de')).to.be.false; - } - - @test - mailValidation9() { - expect(SMTP.isValidEmailAddress('')).to.be.false; - } - - @test - mailValidation10() { - expect(SMTP.isValidEmailAddress('@')).to.be.false; - } - - @test - mailValidation11() { - expect(SMTP.isValidEmailAddress('@')).to.be.false; - } - - @test - mailValidation12() { - expect(SMTP.isValidEmailAddress(' stordeur@campus.tu-berlin.de')).to.be.false; - } - - @test - mailValidation13() { - expect(SMTP.isValidEmailAddress('stordeur@campus.tu-berlin.de ')).to.be.false; - } - - @test - mailValidation14() { - expect(SMTP.isValidEmailAddress('stord+eur@campus.tu-berlin.de ')).to.be.false; - } - - @test - mailValidation15() { - expect(SMTP.isValidEmailAddress('anselm..stordeur@campus.tu-berlin.de')).to.be.false; - } - - @test - mailValidation16() { - expect(SMTP.isValidEmailAddress('stordeur@campus..tu-berlin.de')).to.be.false; - } - - @test - mailValidation17() { - expect(SMTP.isValidEmailAddress('stordeur@campus')).to.be.false; - } - - /* tslint:enable:member-ordering */ -} + describe('invalid emails', function () { + for (const email of invalidEmails) { + it(`should detect "${email}" as invalid`, function () { + expect(SMTP.isValidEmailAddress(email)).to.be.false; + }); + } + }); +}); diff --git a/packages/logger/test/transformations/add-log-level.spec.ts b/packages/logger/test/transformations/add-log-level.spec.ts index 18c900a2..0e37460d 100644 --- a/packages/logger/test/transformations/add-log-level.spec.ts +++ b/packages/logger/test/transformations/add-log-level.spec.ts @@ -13,15 +13,12 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {suite, test} from '@testdeck/mocha'; -import {AddLogLevel} from '../../src/transformations/add-log-level.js'; +import {AddLogLevel} from '../../src/index.js'; -@suite() -export class AddLogLevelSpec { - @test - transform() { +describe('add log level', function () { + it('should transform', function () { const transformation = new AddLogLevel(); expect(transformation.transform('ERROR', 'Foobar')).to.be.equal('[ERROR] Foobar'); - } -} + }); +}); diff --git a/packages/logger/test/transformations/colorize.spec.ts b/packages/logger/test/transformations/colorize.spec.ts index 88e67a4f..450791b9 100644 --- a/packages/logger/test/transformations/colorize.spec.ts +++ b/packages/logger/test/transformations/colorize.spec.ts @@ -13,18 +13,18 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {suite, test} from '@testdeck/mocha'; -import {Colorize} from '../../src/transformations/colorize.js'; +import {Colorize} from '../../src/index.js'; +import chalk from 'chalk'; -@suite() -export class ColorizeSpec { - @test - transform() { +chalk.level = 2; + +describe('colorize', function () { + it('should transform', function () { const transformation = new Colorize(); expect(transformation.transform('ERROR', 'Foobar')).to.be.equal( - '\u001b[1m\u001b[31mFoobar\u001b[39m\u001b[22m', + '\u001B[1m\u001B[31mFoobar\u001B[39m\u001B[22m', ); - expect(transformation.transform('LOG', 'Foobar')).to.be.equal('\u001b[37mFoobar\u001b[39m'); - } -} + expect(transformation.transform('LOG', 'Foobar')).to.be.equal('\u001B[37mFoobar\u001B[39m'); + }); +}); diff --git a/packages/logger/test/transformations/timestamp.spec.ts b/packages/logger/test/transformations/timestamp.spec.ts index c48b6de7..b7079387 100644 --- a/packages/logger/test/transformations/timestamp.spec.ts +++ b/packages/logger/test/transformations/timestamp.spec.ts @@ -13,15 +13,12 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {suite, test} from '@testdeck/mocha'; -import {Timestamp} from '../../src/transformations/timestamp.js'; +import {Timestamp} from '../../src/index.js'; -@suite() -export class TimeStampSpec { - @test - default() { +describe('timestamp', function () { + it('should contain Z', function () { const transformation = new Timestamp(); expect(transformation.transform('ERROR', 'Foobar')).to.be.contain(`Z`); - } -} + }); +}); diff --git a/packages/logger/test/transport.spec.ts b/packages/logger/test/transport.spec.ts index 6e8dbbab..18842b3b 100644 --- a/packages/logger/test/transport.spec.ts +++ b/packages/logger/test/transport.spec.ts @@ -13,19 +13,15 @@ * this program. If not, see . */ import {expect} from 'chai'; -import {suite, test} from '@testdeck/mocha'; -import {isTransportWithVerification} from '../src/common.js'; -import {DummyTransport, VerifiableDummyTransport} from './dummyTransport.js'; +import {isTransportWithVerification} from '../src/index.js'; +import {DummyTransport, VerifiableDummyTransport} from './dummy-transport.js'; -@suite() -export class TransportSpec { - @test - isNotTransportWithVerification() { - return expect(isTransportWithVerification(new DummyTransport())).to.be.false; - } +describe('transport', function () { + it('should not have transport with verification', function () { + expect(isTransportWithVerification(new DummyTransport())).to.be.false; + }); - @test - isTransportWithVerification() { - return expect(isTransportWithVerification(new VerifiableDummyTransport())).to.be.true; - } -} + it('should have transport with verification', function () { + expect(isTransportWithVerification(new VerifiableDummyTransport())).to.be.true; + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 68fb32b7..60039c42 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,35 +5,19 @@ importers: .: specifiers: '@changesets/cli': 2.26.0 - '@typescript-eslint/eslint-plugin': 5.49.0 - '@typescript-eslint/parser': 5.49.0 deepmerge: 4.3.1 dotenv-cli: 7.1.0 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0 - eslint-plugin-jsdoc: 39.7.4 - eslint-plugin-prettier: 4.2.1 - eslint-plugin-unicorn: 45.0.2 glob: 10.2.1 package-sync-cli: 1.3.2 - prettier: 2.8.6 syncpack: 9.8.4 turbo: 1.8.3 typedoc: 0.23.28 devDependencies: '@changesets/cli': 2.26.0 - '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe - '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 deepmerge: 4.3.1 dotenv-cli: 7.1.0 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0_eslint@8.33.0 - eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 - eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe - eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 glob: 10.2.1 package-sync-cli: 1.3.2 - prettier: 2.8.6 syncpack: 9.8.4 turbo: 1.8.3 typedoc: 0.23.28_typescript@4.8.4 @@ -178,20 +162,21 @@ importers: '@openstapps/nyc-config': workspace:* '@openstapps/prettier-config': workspace:* '@openstapps/tsconfig': workspace:* - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 - '@types/chai-spies': 1.0.3 '@types/config': 3.3.0 '@types/dockerode': 3.3.14 + '@types/mocha': 10.0.1 '@types/mustache': 4.2.2 '@types/node': 18.15.3 '@types/proxyquire': 1.3.28 '@types/semver': 7.3.13 '@types/sha1': 1.1.3 + '@types/sinon': 10.0.14 + '@types/sinon-chai': 3.2.9 '@typescript-eslint/eslint-plugin': 5.49.0 '@typescript-eslint/parser': 5.49.0 + c8: 7.13.0 chai: 4.3.7 - chai-spies: 1.0.0 config: 3.3.9 dockerode: 3.3.4 eslint: 8.33.0 @@ -202,11 +187,10 @@ importers: is-cidr: 4.0.2 mocha: 10.2.0 mustache: 4.2.0 - node-port-scanner: 3.0.1 - nyc: 15.1.0 prettier: 2.8.6 - proxyquire: 2.1.3 semver: 7.3.8 + sinon: 15.0.4 + sinon-chai: 3.7.0 ts-node: 10.9.1 tsup: 6.7.0 typedoc: 0.23.28 @@ -217,40 +201,40 @@ importers: dockerode: 3.3.4 is-cidr: 4.0.2 mustache: 4.2.0 - node-port-scanner: 3.0.1 semver: 7.3.8 + typescript: 4.8.4 devDependencies: '@openstapps/eslint-config': link:../../configuration/eslint-config '@openstapps/nyc-config': link:../../configuration/nyc-config '@openstapps/prettier-config': link:../../configuration/prettier-config '@openstapps/tsconfig': link:../../configuration/tsconfig - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 - '@types/chai-spies': 1.0.3 '@types/config': 3.3.0 '@types/dockerode': 3.3.14 + '@types/mocha': 10.0.1 '@types/mustache': 4.2.2 '@types/node': 18.15.3 '@types/proxyquire': 1.3.28 '@types/semver': 7.3.13 '@types/sha1': 1.1.3 + '@types/sinon': 10.0.14 + '@types/sinon-chai': 3.2.9 '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 + c8: 7.13.0 chai: 4.3.7 - chai-spies: 1.0.0_chai@4.3.7 eslint: 8.33.0 eslint-config-prettier: 8.6.0_eslint@8.33.0 eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 mocha: 10.2.0 - nyc: 15.1.0 prettier: 2.8.6 - proxyquire: 2.1.3 + sinon: 15.0.4 + sinon-chai: 3.7.0_chai@4.3.7+sinon@15.0.4 ts-node: 10.9.1_x7wmykdye3n75c4332b67wrzwm tsup: 6.7.0_mwhvu7sfp6vq5ryuwb6hlbjfka typedoc: 0.23.28_typescript@4.8.4 - typescript: 4.8.4 configuration/eslint-config: specifiers: @@ -261,8 +245,7 @@ importers: eslint-plugin-jsdoc: 39.7.4 eslint-plugin-prettier: 4.2.1 eslint-plugin-unicorn: 45.0.2 - prettier: 2.8.6 - devDependencies: + dependencies: '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 eslint: 8.33.0 @@ -270,46 +253,14 @@ importers: eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 - prettier: 2.8.6 configuration/nyc-config: - specifiers: - '@typescript-eslint/eslint-plugin': 5.49.0 - '@typescript-eslint/parser': 5.49.0 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0 - eslint-plugin-jsdoc: 39.7.4 - eslint-plugin-prettier: 4.2.1 - eslint-plugin-unicorn: 45.0.2 - prettier: 2.8.6 - devDependencies: - '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe - '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0_eslint@8.33.0 - eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 - eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe - eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 - prettier: 2.8.6 + specifiers: {} configuration/prettier-config: specifiers: - '@typescript-eslint/eslint-plugin': 5.49.0 - '@typescript-eslint/parser': 5.49.0 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0 - eslint-plugin-jsdoc: 39.7.4 - eslint-plugin-prettier: 4.2.1 - eslint-plugin-unicorn: 45.0.2 prettier: 2.8.6 - devDependencies: - '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe - '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0_eslint@8.33.0 - eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 - eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe - eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 + dependencies: prettier: 2.8.6 configuration/projectmanagement: @@ -317,11 +268,9 @@ importers: '@openstapps/eslint-config': workspace:* '@openstapps/gitlab-api': workspace:* '@openstapps/logger': workspace:* - '@openstapps/nyc-config': workspace:* '@openstapps/prettier-config': workspace:* '@openstapps/tsconfig': workspace:* '@slack/web-api': 6.8.1 - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 '@types/chai-as-promised': 7.1.5 '@types/glob': 8.0.1 @@ -331,6 +280,7 @@ importers: '@types/tmp': 0.2.3 '@typescript-eslint/eslint-plugin': 5.49.0 '@typescript-eslint/parser': 5.49.0 + c8: 7.13.0 chai: 4.3.7 chai-as-promised: 7.1.1 commander: 10.0.0 @@ -343,9 +293,7 @@ importers: glob: 10.2.1 mocha: 10.2.0 mustache: 4.2.0 - nyc: 15.1.0 prettier: 2.8.6 - tmp: 0.2.1 ts-node: 10.9.1 tsup: 6.7.0 typescript: 4.8.4 @@ -357,13 +305,10 @@ importers: date-fns: 2.29.3 glob: 10.2.1 mustache: 4.2.0 - tmp: 0.2.1 devDependencies: '@openstapps/eslint-config': link:../eslint-config - '@openstapps/nyc-config': link:../nyc-config '@openstapps/prettier-config': link:../prettier-config '@openstapps/tsconfig': link:../tsconfig - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 '@types/chai-as-promised': 7.1.5 '@types/glob': 8.0.1 @@ -373,6 +318,7 @@ importers: '@types/tmp': 0.2.3 '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 + c8: 7.13.0 chai: 4.3.7 chai-as-promised: 7.1.1_chai@4.3.7 eslint: 8.33.0 @@ -381,31 +327,13 @@ importers: eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 mocha: 10.2.0 - nyc: 15.1.0 prettier: 2.8.6 ts-node: 10.9.1_x7wmykdye3n75c4332b67wrzwm tsup: 6.7.0_mwhvu7sfp6vq5ryuwb6hlbjfka typescript: 4.8.4 configuration/tsconfig: - specifiers: - '@typescript-eslint/eslint-plugin': 5.49.0 - '@typescript-eslint/parser': 5.49.0 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0 - eslint-plugin-jsdoc: 39.7.4 - eslint-plugin-prettier: 4.2.1 - eslint-plugin-unicorn: 45.0.2 - prettier: 2.8.6 - devDependencies: - '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe - '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0_eslint@8.33.0 - eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 - eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe - eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 - prettier: 2.8.6 + specifiers: {} examples/minimal-connector: specifiers: @@ -604,7 +532,6 @@ importers: cypress: 12.0.1 deepmerge: 4.3.1 eslint: 8.33.0 - eslint-config-prettier: 8.6.0 eslint-plugin-jsdoc: 39.7.4 eslint-plugin-prettier: 4.2.1 eslint-plugin-unicorn: 45.0.2 @@ -738,9 +665,8 @@ importers: cordova-res: 0.15.4 cypress: 12.0.1 eslint: 8.33.0 - eslint-config-prettier: 8.6.0_eslint@8.33.0 eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 - eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe + eslint-plugin-prettier: 4.2.1_fg7zrowtkfjq3bdfm2dwtoazsu eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 fontkit: 2.0.2 glob: 10.2.1 @@ -772,7 +698,6 @@ importers: '@openstapps/nyc-config': workspace:* '@openstapps/prettier-config': workspace:* '@openstapps/tsconfig': workspace:* - '@testdeck/mocha': 0.3.3 '@types/body-parser': 1.19.2 '@types/chai': 4.3.4 '@types/chai-as-promised': 7.1.5 @@ -790,6 +715,7 @@ importers: '@typescript-eslint/eslint-plugin': 5.49.0 '@typescript-eslint/parser': 5.49.0 body-parser: 1.20.1 + c8: 7.13.0 chai: 4.3.7 chai-as-promised: 7.1.1 chai-spies: 1.0.0 @@ -809,7 +735,6 @@ importers: moment: 2.29.4 morgan: 1.10.0 nock: 13.3.0 - nyc: 15.1.0 prettier: 2.8.6 rfdc: 1.3.0 traverse: 0.6.7 @@ -841,7 +766,6 @@ importers: '@openstapps/nyc-config': link:../../configuration/nyc-config '@openstapps/prettier-config': link:../../configuration/prettier-config '@openstapps/tsconfig': link:../../configuration/tsconfig - '@testdeck/mocha': 0.3.3 '@types/body-parser': 1.19.2 '@types/chai': 4.3.4 '@types/chai-as-promised': 7.1.5 @@ -858,6 +782,7 @@ importers: '@types/wait-on': 5.3.1 '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 + c8: 7.13.0 chai: 4.3.7 chai-as-promised: 7.1.1_chai@4.3.7 chai-spies: 1.0.0_chai@4.3.7 @@ -870,7 +795,6 @@ importers: fs-extra: 10.1.0 mocha: 10.2.0 nock: 13.3.0 - nyc: 15.1.0 prettier: 2.8.6 ts-node: 10.9.1_x7wmykdye3n75c4332b67wrzwm tsup: 6.7.0_mwhvu7sfp6vq5ryuwb6hlbjfka @@ -880,7 +804,6 @@ importers: packages/collection-utils: specifiers: '@openstapps/eslint-config': workspace:* - '@openstapps/nyc-config': workspace:* '@openstapps/prettier-config': workspace:* '@openstapps/tsconfig': workspace:* '@types/chai': 4.3.4 @@ -888,6 +811,7 @@ importers: '@types/node': 18.15.3 '@typescript-eslint/eslint-plugin': 5.49.0 '@typescript-eslint/parser': 5.49.0 + c8: 7.13.0 chai: 4.3.7 eslint: 8.33.0 eslint-config-prettier: 8.6.0 @@ -901,7 +825,6 @@ importers: typescript: 4.8.4 devDependencies: '@openstapps/eslint-config': link:../../configuration/eslint-config - '@openstapps/nyc-config': link:../../configuration/nyc-config '@openstapps/prettier-config': link:../../configuration/prettier-config '@openstapps/tsconfig': link:../../configuration/tsconfig '@types/chai': 4.3.4 @@ -909,6 +832,7 @@ importers: '@types/node': 18.15.3 '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 + c8: 7.13.0 chai: 4.3.7 eslint: 8.33.0 eslint-config-prettier: 8.6.0_eslint@8.33.0 @@ -924,12 +848,12 @@ importers: packages/core: specifiers: '@openstapps/core-tools': workspace:* + '@openstapps/easy-ast': workspace:* '@openstapps/es-mapping-generator': workspace:* '@openstapps/eslint-config': workspace:* '@openstapps/logger': workspace:* '@openstapps/prettier-config': workspace:* '@openstapps/tsconfig': workspace:* - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 '@types/geojson': 1.0.6 '@types/json-patch': 0.0.30 @@ -938,6 +862,7 @@ importers: '@types/node': 18.15.3 '@typescript-eslint/eslint-plugin': 5.49.0 '@typescript-eslint/parser': 5.49.0 + c8: 7.13.0 chai: 4.3.7 conditional-type-checks: 1.0.6 eslint: 8.33.0 @@ -950,10 +875,8 @@ importers: json-patch: 0.7.0 json-schema: 0.4.0 mocha: 10.2.0 - nyc: 15.1.0 prettier: 2.8.6 rfdc: 1.3.0 - rimraf: 4.4.0 source-map-support: 0.5.21 surge: 0.23.1 ts-node: 10.9.1 @@ -968,12 +891,12 @@ importers: json-schema: 0.4.0 rfdc: 1.3.0 devDependencies: + '@openstapps/easy-ast': link:../easy-ast '@openstapps/es-mapping-generator': link:../es-mapping-generator '@openstapps/eslint-config': link:../../configuration/eslint-config '@openstapps/logger': link:../logger '@openstapps/prettier-config': link:../../configuration/prettier-config '@openstapps/tsconfig': link:../../configuration/tsconfig - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 '@types/json-patch': 0.0.30 '@types/json-schema': 7.0.11 @@ -981,6 +904,7 @@ importers: '@types/node': 18.15.3 '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 + c8: 7.13.0 chai: 4.3.7 conditional-type-checks: 1.0.6 eslint: 8.33.0 @@ -989,9 +913,7 @@ importers: eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 mocha: 10.2.0 - nyc: 15.1.0 prettier: 2.8.6 - rimraf: 4.4.0 source-map-support: 0.5.21 surge: 0.23.1 ts-node: 10.9.1_x7wmykdye3n75c4332b67wrzwm @@ -1007,7 +929,6 @@ importers: '@openstapps/nyc-config': workspace:* '@openstapps/prettier-config': workspace:* '@openstapps/tsconfig': workspace:* - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 '@types/fs-extra': 9.0.13 '@types/glob': 8.0.1 @@ -1019,6 +940,7 @@ importers: '@typescript-eslint/parser': 5.49.0 ajv: 8.12.0 better-ajv-errors: 1.2.0 + c8: 7.13.0 chai: 4.3.7 commander: 10.0.0 deepmerge: 4.3.1 @@ -1045,7 +967,6 @@ importers: ts-json-schema-generator: 1.2.0 ts-node: 10.9.1 tsup: 6.7.0 - typedoc: 0.23.28 typescript: 4.8.4 dependencies: '@openstapps/collection-utils': link:../collection-utils @@ -1053,11 +974,9 @@ importers: '@openstapps/logger': link:../logger ajv: 8.12.0 better-ajv-errors: 1.2.0_ajv@8.12.0 - chai: 4.3.7 commander: 10.0.0 deepmerge: 4.3.1 del: 6.1.1 - eslint: 8.33.0 flatted: 3.2.7 fs-extra: 10.1.0 glob: 10.2.1 @@ -1070,14 +989,11 @@ importers: re2: 1.18.0 toposort: 2.0.2 ts-json-schema-generator: 1.2.0 - ts-node: 10.9.1_x7wmykdye3n75c4332b67wrzwm - typescript: 4.8.4 devDependencies: '@openstapps/eslint-config': link:../../configuration/eslint-config '@openstapps/nyc-config': link:../../configuration/nyc-config '@openstapps/prettier-config': link:../../configuration/prettier-config '@openstapps/tsconfig': link:../../configuration/tsconfig - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 '@types/fs-extra': 9.0.13 '@types/glob': 8.0.1 @@ -1087,6 +1003,9 @@ importers: '@types/node': 18.15.3 '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 + c8: 7.13.0 + chai: 4.3.7 + eslint: 8.33.0 eslint-config-prettier: 8.6.0_eslint@8.33.0 eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe @@ -1094,59 +1013,60 @@ importers: mocha: 10.2.0 nock: 13.3.0 prettier: 2.8.6 + ts-node: 10.9.1_x7wmykdye3n75c4332b67wrzwm tsup: 6.7.0_mwhvu7sfp6vq5ryuwb6hlbjfka - typedoc: 0.23.28_typescript@4.8.4 + typescript: 4.8.4 packages/easy-ast: specifiers: '@openstapps/collection-utils': workspace:* '@openstapps/eslint-config': workspace:* '@openstapps/logger': workspace:* - '@openstapps/nyc-config': workspace:* '@openstapps/prettier-config': workspace:* '@openstapps/tsconfig': workspace:* - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 - '@types/fs-extra': 9.0.13 '@types/mocha': 10.0.1 '@types/node': 18.15.3 '@typescript-eslint/eslint-plugin': 5.49.0 '@typescript-eslint/parser': 5.49.0 + c8: 7.13.0 + chai: 4.3.7 eslint: 8.33.0 eslint-config-prettier: 8.6.0 eslint-plugin-jsdoc: 39.7.4 eslint-plugin-prettier: 4.2.1 eslint-plugin-unicorn: 45.0.2 + glob: 10.2.1 mocha: 10.2.0 - nock: 13.3.0 prettier: 2.8.6 + ts-node: 10.9.1 tsup: 6.7.0 typescript: 4.8.4 dependencies: '@openstapps/collection-utils': link:../collection-utils '@openstapps/logger': link:../logger + glob: 10.2.1 typescript: 4.8.4 devDependencies: '@openstapps/eslint-config': link:../../configuration/eslint-config - '@openstapps/nyc-config': link:../../configuration/nyc-config '@openstapps/prettier-config': link:../../configuration/prettier-config '@openstapps/tsconfig': link:../../configuration/tsconfig - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 - '@types/fs-extra': 9.0.13 '@types/mocha': 10.0.1 '@types/node': 18.15.3 '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 + c8: 7.13.0 + chai: 4.3.7 eslint: 8.33.0 eslint-config-prettier: 8.6.0_eslint@8.33.0 eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 mocha: 10.2.0 - nock: 13.3.0 prettier: 2.8.6 - tsup: 6.7.0_typescript@4.8.4 + ts-node: 10.9.1_x7wmykdye3n75c4332b67wrzwm + tsup: 6.7.0_mwhvu7sfp6vq5ryuwb6hlbjfka packages/es-mapping-generator: specifiers: @@ -1156,16 +1076,10 @@ importers: '@types/mocha': 10.0.1 '@types/node': 14.18.38 '@types/rimraf': 3.0.2 - '@typescript-eslint/eslint-plugin': 5.49.0 - '@typescript-eslint/parser': 5.49.0 + c8: 7.13.0 chai: 4.3.7 commander: 10.0.0 deepmerge: 4.3.1 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0 - eslint-plugin-jsdoc: 39.7.4 - eslint-plugin-prettier: 4.2.1 - eslint-plugin-unicorn: 45.0.2 flatted: 3.2.7 got: 11.8.6 mocha: 10.2.0 @@ -1190,14 +1104,8 @@ importers: '@types/mocha': 10.0.1 '@types/node': 14.18.38 '@types/rimraf': 3.0.2 - '@typescript-eslint/eslint-plugin': 5.49.0_kfd4zpckoia5uuabb7zlmzbqou - '@typescript-eslint/parser': 5.49.0_ymn73yqtyin7iqj6whnaesgwei + c8: 7.13.0 chai: 4.3.7 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0_eslint@8.33.0 - eslint-plugin-jsdoc: 39.7.4_eslint@8.33.0 - eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe - eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 mocha: 10.2.0 nock: 13.3.0 prettier: 2.8.6 @@ -1251,10 +1159,8 @@ importers: packages/logger: specifiers: '@openstapps/eslint-config': workspace:* - '@openstapps/nyc-config': workspace:* '@openstapps/prettier-config': workspace:* '@openstapps/tsconfig': workspace:* - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 '@types/chai-as-promised': 7.1.5 '@types/chai-spies': 1.0.3 @@ -1263,10 +1169,11 @@ importers: '@types/nodemailer': 6.4.7 '@typescript-eslint/eslint-plugin': 5.49.0 '@typescript-eslint/parser': 5.49.0 + c8: 7.13.0 chai: 4.3.7 chai-as-promised: 7.1.1 chai-spies: 1.0.0 - chalk: 4.1.2 + chalk: 5.2.0 eslint: 8.33.0 eslint-config-prettier: 8.6.0 eslint-plugin-jsdoc: 39.7.4 @@ -1274,9 +1181,7 @@ importers: eslint-plugin-unicorn: 45.0.2 flatted: 3.2.7 mocha: 10.2.0 - moment: 2.29.4 nodemailer: 6.9.1 - nyc: 15.1.0 prettier: 2.8.6 ts-node: 10.9.1 tsup: 6.7.0 @@ -1284,16 +1189,13 @@ importers: typescript: 4.8.4 dependencies: '@types/nodemailer': 6.4.7 - chalk: 4.1.2 + chalk: 5.2.0 flatted: 3.2.7 - moment: 2.29.4 nodemailer: 6.9.1 devDependencies: '@openstapps/eslint-config': link:../../configuration/eslint-config - '@openstapps/nyc-config': link:../../configuration/nyc-config '@openstapps/prettier-config': link:../../configuration/prettier-config '@openstapps/tsconfig': link:../../configuration/tsconfig - '@testdeck/mocha': 0.3.3 '@types/chai': 4.3.4 '@types/chai-as-promised': 7.1.5 '@types/chai-spies': 1.0.3 @@ -1301,6 +1203,7 @@ importers: '@types/node': 18.15.3 '@typescript-eslint/eslint-plugin': 5.49.0_bhfhikta3fu7tua7ac2hrytgwe '@typescript-eslint/parser': 5.49.0_o2s6jvgtr2hafiobaqfgu6k2l4 + c8: 7.13.0 chai: 4.3.7 chai-as-promised: 7.1.1_chai@4.3.7 chai-spies: 1.0.0_chai@4.3.7 @@ -1310,7 +1213,6 @@ importers: eslint-plugin-prettier: 4.2.1_2blprs6rvzrjlgi3xqpegp3hoe eslint-plugin-unicorn: 45.0.2_eslint@8.33.0 mocha: 10.2.0 - nyc: 15.1.0 prettier: 2.8.6 ts-node: 10.9.1_x7wmykdye3n75c4332b67wrzwm tsup: 6.7.0_mwhvu7sfp6vq5ryuwb6hlbjfka @@ -1929,12 +1831,12 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/generator': 7.16.8 + '@babel/generator': 7.21.3 '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.16.12 '@babel/helper-module-transforms': 7.21.2 '@babel/helpers': 7.21.0 '@babel/parser': 7.21.3 - '@babel/template': 7.16.7 + '@babel/template': 7.20.7 '@babel/traverse': 7.21.3 '@babel/types': 7.21.3 convert-source-map: 1.9.0 @@ -4025,6 +3927,10 @@ packages: resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} dev: false + /@bcoe/v8-coverage/0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + /@capacitor/android/4.6.1_@capacitor+core@4.6.1: resolution: {integrity: sha512-Hnh1tmUr1SP67U6D6ry5I5BEBSN/1nkBAIjQIqf5tF82WNxKbpbC6GfkHE4hMJZinRTrCf36LkrdP8srh7SxoA==} peerDependencies: @@ -4582,7 +4488,6 @@ packages: comment-parser: 1.3.1 esquery: 1.5.0 jsdoc-type-pratt-parser: 3.1.0 - dev: true /@esbuild/android-arm/0.17.12: resolution: {integrity: sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==} @@ -4790,7 +4695,6 @@ packages: dependencies: eslint: 8.33.0 eslint-visitor-keys: 3.3.0 - dev: true /@eslint/eslintrc/1.4.1: resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==} @@ -5696,6 +5600,12 @@ packages: type-detect: 4.0.8 dev: true + /@sinonjs/commons/3.0.0: + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + dependencies: + type-detect: 4.0.8 + dev: true + /@sinonjs/fake-timers/10.0.2: resolution: {integrity: sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==} dependencies: @@ -5716,6 +5626,14 @@ packages: type-detect: 4.0.8 dev: true + /@sinonjs/samsam/8.0.0: + resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==} + dependencies: + '@sinonjs/commons': 2.0.0 + lodash.get: 4.4.2 + type-detect: 4.0.8 + dev: true + /@sinonjs/text-encoding/0.7.2: resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} dev: true @@ -6019,6 +5937,10 @@ packages: '@types/node': 18.15.3 dev: false + /@types/istanbul-lib-coverage/2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + /@types/jasmine/4.3.1: resolution: {integrity: sha512-Vu8l+UGcshYmV1VWwULgnV/2RDbBaO6i2Ptx7nd//oJPIZGhoI1YLST4VKagD2Pq/Bc2/7zvtvhM7F3p4SN7kQ==} dev: true @@ -6117,7 +6039,6 @@ packages: /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} - dev: true /@types/parse-json/4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} @@ -6166,7 +6087,6 @@ packages: /@types/semver/7.3.13: resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} - dev: true /@types/serve-index/1.9.1: resolution: {integrity: sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==} @@ -6186,6 +6106,13 @@ packages: '@types/node': 18.15.3 dev: true + /@types/sinon-chai/3.2.9: + resolution: {integrity: sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==} + dependencies: + '@types/chai': 4.3.4 + '@types/sinon': 10.0.14 + dev: true + /@types/sinon-express-mock/1.3.9: resolution: {integrity: sha512-wHtSYqZ/c1FytL4qEMVb3tp8UZk1EnUq6Qc4jQv5eJ9N2QtFdS4WU3Wijqzeu5r3/DfZqpvzkxbbZLa0+9F9sA==} dependencies: @@ -6199,6 +6126,12 @@ packages: '@types/sinonjs__fake-timers': 8.1.2 dev: true + /@types/sinon/10.0.14: + resolution: {integrity: sha512-mn72up6cjaMyMuaPaa/AwKf6WtsSRysQC7wxFkCm1XcOKXPM1z+5Y4H5wjIVBz4gdAkjvZxVVfjA6ba1nHr5WQ==} + dependencies: + '@types/sinonjs__fake-timers': 8.1.2 + dev: true + /@types/sinonjs__fake-timers/8.1.1: resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==} dev: true @@ -6323,34 +6256,6 @@ packages: typescript: 4.8.4 transitivePeerDependencies: - supports-color - dev: true - - /@typescript-eslint/eslint-plugin/5.49.0_kfd4zpckoia5uuabb7zlmzbqou: - resolution: {integrity: sha512-IhxabIpcf++TBaBa1h7jtOWyon80SXPRLDq0dVz5SLFC/eW6tofkw/O7Ar3lkx5z5U6wzbKDrl2larprp5kk5Q==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/parser': 5.49.0_ymn73yqtyin7iqj6whnaesgwei - '@typescript-eslint/scope-manager': 5.49.0 - '@typescript-eslint/type-utils': 5.49.0_ymn73yqtyin7iqj6whnaesgwei - '@typescript-eslint/utils': 5.49.0_ymn73yqtyin7iqj6whnaesgwei - debug: 4.3.4 - eslint: 8.33.0 - ignore: 5.2.4 - natural-compare-lite: 1.4.0 - regexpp: 3.2.0 - semver: 7.3.8 - tsutils: 3.21.0_typescript@3.8.3 - typescript: 3.8.3 - transitivePeerDependencies: - - supports-color - dev: true /@typescript-eslint/experimental-utils/5.27.1_glr7kvvu63i7xo5xtsf5x2uhzq: resolution: {integrity: sha512-Vd8uewIixGP93sEnmTRIH6jHZYRQRkGPDPpapACMvitJKX8335VHNyqKTE+mZ+m3E2c5VznTZfSsSsS5IF7vUA==} @@ -6403,27 +6308,6 @@ packages: typescript: 4.8.4 transitivePeerDependencies: - supports-color - dev: true - - /@typescript-eslint/parser/5.49.0_ymn73yqtyin7iqj6whnaesgwei: - resolution: {integrity: sha512-veDlZN9mUhGqU31Qiv2qEp+XrJj5fgZpJ8PW30sHU+j/8/e5ruAhLaVDAeznS7A7i4ucb/s8IozpDtt9NqCkZg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.49.0 - '@typescript-eslint/types': 5.49.0 - '@typescript-eslint/typescript-estree': 5.49.0_typescript@3.8.3 - debug: 4.3.4 - eslint: 8.33.0 - typescript: 3.8.3 - transitivePeerDependencies: - - supports-color - dev: true /@typescript-eslint/scope-manager/5.27.1: resolution: {integrity: sha512-fQEOSa/QroWE6fAEg+bJxtRZJTH8NTskggybogHt4H9Da8zd4cJji76gA5SBlR0MgtwF7rebxTbDKB49YUCpAg==} @@ -6439,7 +6323,6 @@ packages: dependencies: '@typescript-eslint/types': 5.49.0 '@typescript-eslint/visitor-keys': 5.49.0 - dev: true /@typescript-eslint/type-utils/5.49.0_glr7kvvu63i7xo5xtsf5x2uhzq: resolution: {integrity: sha512-eUgLTYq0tR0FGU5g1YHm4rt5H/+V2IPVkP0cBmbhRyEmyGe4XvJ2YJ6sYTmONfjmdMqyMLad7SB8GvblbeESZA==} @@ -6479,27 +6362,6 @@ packages: typescript: 4.8.4 transitivePeerDependencies: - supports-color - dev: true - - /@typescript-eslint/type-utils/5.49.0_ymn73yqtyin7iqj6whnaesgwei: - resolution: {integrity: sha512-eUgLTYq0tR0FGU5g1YHm4rt5H/+V2IPVkP0cBmbhRyEmyGe4XvJ2YJ6sYTmONfjmdMqyMLad7SB8GvblbeESZA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.49.0_typescript@3.8.3 - '@typescript-eslint/utils': 5.49.0_ymn73yqtyin7iqj6whnaesgwei - debug: 4.3.4 - eslint: 8.33.0 - tsutils: 3.21.0_typescript@3.8.3 - typescript: 3.8.3 - transitivePeerDependencies: - - supports-color - dev: true /@typescript-eslint/types/5.27.1: resolution: {integrity: sha512-LgogNVkBhCTZU/m8XgEYIWICD6m4dmEDbKXESCbqOXfKZxRKeqpiJXQIErv66sdopRKZPo5l32ymNqibYEH/xg==} @@ -6509,7 +6371,6 @@ packages: /@typescript-eslint/types/5.49.0: resolution: {integrity: sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true /@typescript-eslint/typescript-estree/5.27.1_typescript@4.6.4: resolution: {integrity: sha512-DnZvvq3TAJ5ke+hk0LklvxwYsnXpRdqUY5gaVS0D4raKtbznPz71UJGnPTHEFo0GDxqLOLdMkkmVZjSpET1hFw==} @@ -6532,27 +6393,6 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree/5.49.0_typescript@3.8.3: - resolution: {integrity: sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.49.0 - '@typescript-eslint/visitor-keys': 5.49.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.8 - tsutils: 3.21.0_typescript@3.8.3 - typescript: 3.8.3 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree/5.49.0_typescript@4.6.4: resolution: {integrity: sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6593,7 +6433,6 @@ packages: typescript: 4.8.4 transitivePeerDependencies: - supports-color - dev: true /@typescript-eslint/utils/5.27.1_glr7kvvu63i7xo5xtsf5x2uhzq: resolution: {integrity: sha512-mZ9WEn1ZLDaVrhRaYgzbkXBkTPghPFsup8zDbbsYTxC5OmqrFE7skkKS/sraVsLP3TcT3Ki5CSyEFBRkLH/H/w==} @@ -6651,27 +6490,6 @@ packages: transitivePeerDependencies: - supports-color - typescript - dev: true - - /@typescript-eslint/utils/5.49.0_ymn73yqtyin7iqj6whnaesgwei: - resolution: {integrity: sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.49.0 - '@typescript-eslint/types': 5.49.0 - '@typescript-eslint/typescript-estree': 5.49.0_typescript@3.8.3 - eslint: 8.33.0 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.33.0 - semver: 7.3.8 - transitivePeerDependencies: - - supports-color - - typescript - dev: true /@typescript-eslint/visitor-keys/5.27.1: resolution: {integrity: sha512-xYs6ffo01nhdJgPieyk7HAOpjhTsx7r/oB9LWEhwAXgwn33tkr+W8DI2ChboqhZlC4q3TC6geDYPoiX8ROqyOQ==} @@ -6687,7 +6505,6 @@ packages: dependencies: '@typescript-eslint/types': 5.49.0 eslint-visitor-keys: 3.3.0 - dev: true /@webassemblyjs/ast/1.11.1: resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} @@ -7281,6 +7098,7 @@ packages: /assertion-error/1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true /ast-transform/0.0.0: resolution: {integrity: sha512-e/JfLiSoakfmL4wmTGPjv0HpTICVmxwXgYOB8x+mzozHL8v+dSfCbrJ8J8hJ0YBP0XcYu1aLZ6b/3TnxNK3P2A==} @@ -7857,7 +7675,6 @@ packages: /builtin-modules/3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - dev: true /builtin-status-codes/3.0.0: resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} @@ -7886,6 +7703,25 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + /c8/7.13.0: + resolution: {integrity: sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==} + engines: {node: '>=10.12.0'} + hasBin: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@istanbuljs/schema': 0.1.3 + find-up: 5.0.0 + foreground-child: 2.0.0 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-report: 3.0.0 + istanbul-reports: 3.1.5 + rimraf: 3.0.2 + test-exclude: 6.0.0 + v8-to-istanbul: 9.1.0 + yargs: 16.2.0 + yargs-parser: 20.2.9 + dev: true + /cac/6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -8092,6 +7928,7 @@ packages: loupe: 2.3.6 pathval: 1.1.1 type-detect: 4.0.8 + dev: true /chalk/1.1.3: resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} @@ -8127,12 +7964,18 @@ packages: ansi-styles: 4.3.0 supports-color: 7.2.0 + /chalk/5.2.0: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + /chardet/0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true /check-error/1.0.2: resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + dev: true /check-more-types/2.24.0: resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==} @@ -8197,7 +8040,6 @@ packages: /ci-info/3.8.0: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} engines: {node: '>=8'} - dev: true /cidr-regex/3.1.1: resolution: {integrity: sha512-RBqYd32aDwbCMFJRL6wHOlDNYJsPNTt8vC82ErHF5vKt8QQzxm1FrkW8s/R5pVrXMf17sba09Uoy91PKiddAsw==} @@ -8231,7 +8073,6 @@ packages: engines: {node: '>=4'} dependencies: escape-string-regexp: 1.0.5 - dev: true /clean-stack/2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} @@ -8455,7 +8296,6 @@ packages: /comment-parser/1.3.1: resolution: {integrity: sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==} engines: {node: '>= 12.0.0'} - dev: true /common-tags/1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} @@ -9325,6 +9165,7 @@ packages: engines: {node: '>=6'} dependencies: type-detect: 4.0.8 + dev: true /deep-equal/1.1.1: resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} @@ -9849,7 +9690,6 @@ packages: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: is-arrayish: 0.2.1 - dev: true /es-abstract/1.21.2: resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==} @@ -10273,7 +10113,6 @@ packages: eslint: '>=7.0.0' dependencies: eslint: 8.33.0 - dev: true /eslint-plugin-jsdoc/39.7.4_eslint@8.33.0: resolution: {integrity: sha512-2eJcWGKRyNQFa37UIpGcAdOp3wtES8vV3mlnFmEmJCuBNyFhK6cMhbZgMkLoLjKnipoxsN9GbfZZ+8nPY8ETZQ==} @@ -10291,7 +10130,6 @@ packages: spdx-expression-parse: 3.0.1 transitivePeerDependencies: - supports-color - dev: true /eslint-plugin-prettier/4.2.1_2blprs6rvzrjlgi3xqpegp3hoe: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} @@ -10308,6 +10146,21 @@ packages: eslint-config-prettier: 8.6.0_eslint@8.33.0 prettier: 2.8.6 prettier-linter-helpers: 1.0.0 + + /eslint-plugin-prettier/4.2.1_fg7zrowtkfjq3bdfm2dwtoazsu: + resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + eslint: '>=7.28.0' + eslint-config-prettier: '*' + prettier: '>=2.0.0' + peerDependenciesMeta: + eslint-config-prettier: + optional: true + dependencies: + eslint: 8.33.0 + prettier: 2.8.6 + prettier-linter-helpers: 1.0.0 dev: true /eslint-plugin-unicorn/45.0.2_eslint@8.33.0: @@ -10333,7 +10186,6 @@ packages: safe-regex: 2.1.1 semver: 7.3.8 strip-indent: 3.0.0 - dev: true /eslint-scope/5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} @@ -10341,7 +10193,6 @@ packages: dependencies: esrecurse: 4.3.0 estraverse: 4.3.0 - dev: true /eslint-scope/7.1.1: resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} @@ -10454,7 +10305,6 @@ packages: /estraverse/4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} - dev: true /estraverse/5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} @@ -10709,7 +10559,6 @@ packages: /fast-diff/1.2.0: resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} - dev: true /fast-glob/3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} @@ -10791,14 +10640,6 @@ packages: minimatch: 5.1.6 dev: true - /fill-keys/1.0.2: - resolution: {integrity: sha512-tcgI872xXjwFF4xgQmLxi76GnwJG3g/3isB1l4/G5Z4zrbddGpBjqZCO9oEAcB5wX0Hj/5iQB3toxfO7in1hHA==} - engines: {node: '>=0.10.0'} - dependencies: - is-object: 1.0.2 - merge-descriptors: 1.0.1 - dev: true - /fill-range/7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -10856,7 +10697,6 @@ packages: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - dev: true /find-up/5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} @@ -11162,6 +11002,7 @@ packages: /get-func-name/2.0.0: resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + dev: true /get-intrinsic/1.2.0: resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} @@ -11351,16 +11192,6 @@ packages: minimatch: 5.1.6 once: 1.4.0 - /glob/9.3.0: - resolution: {integrity: sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - fs.realpath: 1.0.0 - minimatch: 7.4.2 - minipass: 4.2.5 - path-scurry: 1.6.1 - dev: true - /global-dirs/3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} engines: {node: '>=10'} @@ -11653,7 +11484,6 @@ packages: /hosted-git-info/2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: true /hosted-git-info/4.1.0: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} @@ -12163,7 +11993,6 @@ packages: /is-arrayish/0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true /is-arrayish/0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} @@ -12195,7 +12024,6 @@ packages: engines: {node: '>=6'} dependencies: builtin-modules: 3.3.0 - dev: true /is-callable/1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} @@ -12310,10 +12138,6 @@ packages: engines: {node: '>=8'} dev: true - /is-object/1.0.2: - resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} - dev: true - /is-path-cwd/1.0.0: resolution: {integrity: sha512-cnS56eR9SPAscL77ik76ATVqoPARTqPIVkMDVxRaWH06zT+6+CzIroYRJ0VVvm0Z1zfAvxvz9i/D3Ppjaqt5Nw==} engines: {node: '>=0.10.0'} @@ -12526,7 +12350,7 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.16.12 + '@babel/core': 7.21.3 '@babel/parser': 7.21.3 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 @@ -12696,12 +12520,10 @@ packages: /jsdoc-type-pratt-parser/3.1.0: resolution: {integrity: sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==} engines: {node: '>=12.0.0'} - dev: true /jsesc/0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true - dev: true /jsesc/2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} @@ -12713,7 +12535,6 @@ packages: resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} engines: {node: '>=6'} hasBin: true - dev: true /json-buffer/3.0.0: resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} @@ -12729,7 +12550,6 @@ packages: /json-parse-even-better-errors/2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true /json-patch/0.7.0: resolution: {integrity: sha512-9zaGTzsV6Hal5HVMC8kb4niXYQOOcq3tUp0P/GTw6HHZFPVwtCU2+mXE9q59MelL9uknALWnoKrUxnDpUX728g==} @@ -13098,7 +12918,6 @@ packages: /lines-and-columns/1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true /lines-and-columns/2.0.3: resolution: {integrity: sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==} @@ -13188,7 +13007,6 @@ packages: engines: {node: '>=8'} dependencies: p-locate: 4.1.0 - dev: true /locate-path/6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} @@ -13350,6 +13168,7 @@ packages: resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} dependencies: get-func-name: 2.0.0 + dev: true /lowercase-keys/1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} @@ -13660,7 +13479,6 @@ packages: /min-indent/1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - dev: true /mini-css-extract-plugin/2.5.3_webpack@5.70.0: resolution: {integrity: sha512-YseMB8cs8U/KCaAGQoqYmfUuhhGW0a9p9XvWXrxVOkE3/IiISTLw4ALNt7JR5B2eYauFM+PQGSbXMDmVbR7Tfw==} @@ -13919,10 +13737,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /module-not-found-error/1.0.1: - resolution: {integrity: sha512-pEk4ECWQXV6z2zjhRZUongnLJNUeGQJ3w6OQ5ctGwD+i5o93qjRQUk2Rt6VdNeu3sEP0AB4LcfvdebpxBRVr4g==} - dev: true - /moment/2.29.4: resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} dev: false @@ -14032,7 +13846,6 @@ packages: /natural-compare-lite/1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true /natural-compare/1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -14273,10 +14086,6 @@ packages: vm-browserify: 1.1.2 dev: true - /node-port-scanner/3.0.1: - resolution: {integrity: sha512-TuFGEWfye+1atB74v0Vm6myEjpq0L5Jo3UaOG9xgtYHxnFZN0fF9CnwCxp7ENWDerGbI1UXAgdRMIPz8TM73Hg==} - dev: false - /node-preload/0.2.1: resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} engines: {node: '>=8'} @@ -14330,7 +14139,6 @@ packages: resolve: 1.22.1 semver: 5.7.1 validate-npm-package-license: 3.0.4 - dev: true /normalize-package-data/3.0.3: resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} @@ -14847,7 +14655,6 @@ packages: engines: {node: '>=6'} dependencies: p-try: 2.2.0 - dev: true /p-limit/3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} @@ -14867,7 +14674,6 @@ packages: engines: {node: '>=8'} dependencies: p-limit: 2.3.0 - dev: true /p-locate/5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} @@ -14923,7 +14729,6 @@ packages: /p-try/2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - dev: true /pac-proxy-agent/5.0.0: resolution: {integrity: sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==} @@ -15054,7 +14859,6 @@ packages: error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - dev: true /parse-node-version/1.0.1: resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} @@ -15139,14 +14943,6 @@ packages: /path-parse/1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - /path-scurry/1.6.1: - resolution: {integrity: sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==} - engines: {node: '>=14'} - dependencies: - lru-cache: 7.18.3 - minipass: 4.2.5 - dev: true - /path-scurry/1.7.0: resolution: {integrity: sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==} engines: {node: '>=16 || 14 >=14.17'} @@ -15176,6 +14972,7 @@ packages: /pathval/1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true /pause-stream/0.0.11: resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} @@ -15300,7 +15097,6 @@ packages: /pluralize/8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} - dev: true /png-js/1.0.0: resolution: {integrity: sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==} @@ -15503,22 +15299,6 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-load-config/3.1.4: - resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} - engines: {node: '>= 10'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - dependencies: - lilconfig: 2.1.0 - yaml: 1.10.2 - dev: true - /postcss-load-config/3.1.4_ts-node@10.9.1: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -15786,13 +15566,11 @@ packages: engines: {node: '>=6.0.0'} dependencies: fast-diff: 1.2.0 - dev: true /prettier/2.8.6: resolution: {integrity: sha512-mtuzdiBbHwPEgl7NxWlqOkithPyp4VN93V7VeHVWBF+ad3I5avc0RVDT4oImXQy9H/AqxA2NSQH8pSxHW6FYbQ==} engines: {node: '>=10.13.0'} hasBin: true - dev: true /pretty-bytes/5.6.0: resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} @@ -15936,14 +15714,6 @@ packages: engines: {node: '>=0.8.0'} dev: true - /proxyquire/2.1.3: - resolution: {integrity: sha512-BQWfCqYM+QINd+yawJz23tbBM40VIGXOdDw3X344KcclI/gtBbdWF6SlQ4nK/bYhF9d27KYug9WzljHC6B9Ysg==} - dependencies: - fill-keys: 1.0.2 - module-not-found-error: 1.0.1 - resolve: 1.22.1 - dev: true - /prr/1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} dev: true @@ -16212,7 +15982,6 @@ packages: find-up: 4.1.0 read-pkg: 5.2.0 type-fest: 0.8.1 - dev: true /read-pkg/3.0.0: resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} @@ -16231,7 +16000,6 @@ packages: normalize-package-data: 2.5.0 parse-json: 5.2.0 type-fest: 0.6.0 - dev: true /read-yaml-file/1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} @@ -16425,7 +16193,6 @@ packages: /regexp-tree/0.1.24: resolution: {integrity: sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==} hasBin: true - dev: true /regexp.prototype.flags/1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} @@ -16471,7 +16238,6 @@ packages: hasBin: true dependencies: jsesc: 0.5.0 - dev: true /release-zalgo/1.0.0: resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} @@ -16642,14 +16408,6 @@ packages: dependencies: glob: 7.2.0 - /rimraf/4.4.0: - resolution: {integrity: sha512-X36S+qpCUR0HjXlkDe4NAOhS//aHH0Z+h8Ckf2auGJk3PTnx5rLmrHkwNdbVQuCSUhOyFrlRvFEllZOYE+yZGQ==} - engines: {node: '>=14'} - hasBin: true - dependencies: - glob: 9.3.0 - dev: true - /rimraf/5.0.0: resolution: {integrity: sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==} engines: {node: '>=14'} @@ -16726,7 +16484,6 @@ packages: resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} dependencies: regexp-tree: 0.1.24 - dev: true /safe-stable-stringify/2.4.2: resolution: {integrity: sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==} @@ -16866,7 +16623,6 @@ packages: /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true - dev: true /semver/6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} @@ -17117,6 +16873,16 @@ packages: is-arrayish: 0.3.2 dev: true + /sinon-chai/3.7.0_chai@4.3.7+sinon@15.0.4: + resolution: {integrity: sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==} + peerDependencies: + chai: ^4.0.0 + sinon: '>=4.0.0' + dependencies: + chai: 4.3.7 + sinon: 15.0.4 + dev: true + /sinon-express-mock/2.2.1_sinon@14.0.2: resolution: {integrity: sha512-z1wqaPMwEnfn0SpigFhVYVS/ObX1tkqyRzRdccX99FgQaLkxGSo4684unr3NCqWeYZ1zchxPw7oFIDfzg1cAjg==} peerDependencies: @@ -17136,6 +16902,17 @@ packages: supports-color: 7.2.0 dev: true + /sinon/15.0.4: + resolution: {integrity: sha512-uzmfN6zx3GQaria1kwgWGeKiXSSbShBbue6Dcj0SI8fiCNFbiUDqKl57WFlY5lyhxZVUKmXvzgG2pilRQCBwWg==} + dependencies: + '@sinonjs/commons': 3.0.0 + '@sinonjs/fake-timers': 10.0.2 + '@sinonjs/samsam': 8.0.0 + diff: 5.1.0 + nise: 5.1.4 + supports-color: 7.2.0 + dev: true + /sirv/1.0.19: resolution: {integrity: sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==} engines: {node: '>= 10'} @@ -17394,22 +17171,18 @@ packages: dependencies: spdx-expression-parse: 3.0.1 spdx-license-ids: 3.0.13 - dev: true /spdx-exceptions/2.3.0: resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: true /spdx-expression-parse/3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} dependencies: spdx-exceptions: 2.3.0 spdx-license-ids: 3.0.13 - dev: true /spdx-license-ids/3.0.13: resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} - dev: true /spdx-ranges/2.1.1: resolution: {integrity: sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==} @@ -17728,7 +17501,6 @@ packages: engines: {node: '>=8'} dependencies: min-indent: 1.0.1 - dev: true /strip-json-comments/2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} @@ -18236,6 +18008,7 @@ packages: engines: {node: '>=8.17.0'} dependencies: rimraf: 3.0.2 + dev: true /to-arraybuffer/1.0.1: resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} @@ -18518,42 +18291,6 @@ packages: - ts-node dev: true - /tsup/6.7.0_typescript@4.8.4: - resolution: {integrity: sha512-L3o8hGkaHnu5TdJns+mCqFsDBo83bJ44rlK7e6VdanIvpea4ArPcU3swWGsLVbXak1PqQx/V+SSmFPujBK+zEQ==} - engines: {node: '>=14.18'} - hasBin: true - peerDependencies: - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.1.0' - peerDependenciesMeta: - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - dependencies: - bundle-require: 4.0.1_esbuild@0.17.12 - cac: 6.7.14 - chokidar: 3.5.3 - debug: 4.3.4 - esbuild: 0.17.12 - execa: 5.1.1 - globby: 11.1.0 - joycon: 3.1.1 - postcss-load-config: 3.1.4 - resolve-from: 5.0.0 - rollup: 3.20.0 - source-map: 0.8.0-beta.0 - sucrase: 3.30.0 - tree-kill: 1.2.2 - typescript: 4.8.4 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - /tsutils/2.29.0_typescript@3.8.3: resolution: {integrity: sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==} peerDependencies: @@ -18591,7 +18328,6 @@ packages: dependencies: tslib: 1.14.1 typescript: 4.8.4 - dev: true /tty-browserify/0.0.0: resolution: {integrity: sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==} @@ -18697,6 +18433,7 @@ packages: /type-detect/4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + dev: true /type-fest/0.13.1: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} @@ -18720,12 +18457,10 @@ packages: /type-fest/0.6.0: resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} engines: {node: '>=8'} - dev: true /type-fest/0.8.1: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - dev: true /type-is/1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} @@ -19040,12 +18775,20 @@ packages: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true + /v8-to-istanbul/9.1.0: + resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.9.0 + dev: true + /validate-npm-package-license/3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - dev: true /validate-npm-package-name/3.0.0: resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} diff --git a/prettier.config.cjs b/prettier.config.cjs new file mode 100644 index 00000000..c060491a --- /dev/null +++ b/prettier.config.cjs @@ -0,0 +1,3 @@ +module.exports = { + ...require('./configuration/prettier-config/index.json'), +} diff --git a/sync.mjs b/sync.mjs index fb46e104..38221ac7 100644 --- a/sync.mjs +++ b/sync.mjs @@ -7,8 +7,8 @@ const options = { format: { override: { scripts: { - "format": "prettier .", - "format:fix": "prettier --write ." + "format": "prettier . --ignore-path ../../.gitignore", + "format:fix": "prettier --write . --ignore-path ../../.gitignore" }, prettier: "@openstapps/prettier-config" }, @@ -40,17 +40,6 @@ const options = { }, }, if: "tsup" - }, - test: { - override: { - scripts: { - "test": "nyc mocha 'test/**/*.spec.ts'" - }, - nyc: { - extends: "@openstapps/nyc-config" - } - }, - if: "@openstapps/nyc-config" } } diff --git a/turbo.json b/turbo.json index 6962ae07..c2430dda 100644 --- a/turbo.json +++ b/turbo.json @@ -16,6 +16,10 @@ "lint:fix": { "dependsOn": ["^lint:fix"] }, + "test": { + "dependsOn": ["^test"], + "outputs": [".coverage"] + }, "check-configuration": { "dependsOn": ["^check-configuration"] }, @@ -23,4 +27,4 @@ } } -} \ No newline at end of file +}