mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into setup-tests-for-resolvers
This commit is contained in:
commit
c20e17d11a
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@ -72,7 +72,7 @@ jobs:
|
||||
##########################################################################
|
||||
- name: Backend | Build `production` image
|
||||
run: |
|
||||
docker build --target production -t "gradido/backend:latest" -t "gradido/backend:production" -t "gradido/backend:${VERSION}" -t "gradido/backend:${BUILD_VERSION}" backend/
|
||||
docker build -f ./backend/Dockerfile --target production -t "gradido/backend:latest" -t "gradido/backend:production" -t "gradido/backend:${VERSION}" -t "gradido/backend:${BUILD_VERSION}" .
|
||||
docker save "gradido/backend" > /tmp/backend.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
|
||||
25
.github/workflows/test.yml
vendored
25
.github/workflows/test.yml
vendored
@ -47,7 +47,7 @@ jobs:
|
||||
##########################################################################
|
||||
- name: Backend | Build `test` image
|
||||
run: |
|
||||
docker build --target test -t "gradido/backend:test" backend/
|
||||
docker build -f ./backend/Dockerfile --target test -t "gradido/backend:test" backend/
|
||||
docker save "gradido/backend:test" > /tmp/backend.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
@ -147,7 +147,7 @@ jobs:
|
||||
##########################################################################
|
||||
- name: mariadb | Build `test` image
|
||||
run: |
|
||||
docker build --target mariadb_server_test -t "gradido/mariadb:test" -f ./mariadb/Dockerfile ./
|
||||
docker build --target mariadb_server -t "gradido/mariadb:test" -f ./mariadb/Dockerfile ./
|
||||
docker save "gradido/mariadb:test" > /tmp/mariadb.tar
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
@ -344,7 +344,7 @@ jobs:
|
||||
report_name: Coverage Frontend
|
||||
type: lcov
|
||||
result_path: ./coverage/lcov.info
|
||||
min_coverage: 82
|
||||
min_coverage: 83
|
||||
token: ${{ github.token }}
|
||||
|
||||
##############################################################################
|
||||
@ -416,10 +416,16 @@ jobs:
|
||||
--health-timeout=3s
|
||||
--health-retries=4
|
||||
steps:
|
||||
- name: Debug service
|
||||
run: echo "$(docker ps)"
|
||||
- name: Debug container choosing script
|
||||
run: echo "$(docker container ls | grep mariadb | awk '{ print $1 }')"
|
||||
# - name: Debug service
|
||||
# run: echo "$(docker ps)"
|
||||
#- name: Debug container choosing script
|
||||
# run: echo "$(docker container ls | grep mariadb | awk '{ print $1 }')"
|
||||
- name: get mariadb container id
|
||||
run: echo "::set-output name=id::$(docker container ls | grep mariadb | awk '{ print $1 }')"
|
||||
id: mariadb_container
|
||||
- name: get automatic created network
|
||||
run: echo "::set-output name=id::$(docker network ls | grep github_network | awk '{ print $1 }')"
|
||||
id: network
|
||||
##########################################################################
|
||||
# CHECKOUT CODE ##########################################################
|
||||
##########################################################################
|
||||
@ -427,6 +433,11 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
# Database migration
|
||||
- name: Start database migration
|
||||
run: |
|
||||
docker build --target production_up -t "gradido/database:production_up" database/
|
||||
docker run --network ${{ steps.network.outputs.id }} --name=database --env NODE_ENV=production --env DB_HOST=mariadb --env DB_DATABASE=gradido_community_test -d gradido/database:production_up
|
||||
##########################################################################
|
||||
# Build Login-Server Test Docker image ###################################
|
||||
##########################################################################
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,7 +2,6 @@
|
||||
/node_modules/*
|
||||
.vscode
|
||||
messages.pot
|
||||
.skeema
|
||||
nbproject
|
||||
.metadata
|
||||
/.env
|
||||
|
||||
7
.vscode/extensions.json
vendored
Normal file
7
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
||||
@ -42,6 +42,8 @@ EXPOSE ${PORT}
|
||||
RUN mkdir -p ${DOCKER_WORKDIR}
|
||||
WORKDIR ${DOCKER_WORKDIR}
|
||||
|
||||
RUN mkdir -p /database
|
||||
|
||||
##################################################################################
|
||||
# DEVELOPMENT (Connected to the local environment, to reload on demand) ##########
|
||||
##################################################################################
|
||||
@ -51,22 +53,32 @@ FROM base as development
|
||||
# local filesystem which will need a rebuild anyway
|
||||
|
||||
# Run command
|
||||
# (for development we need to execute npm install since the
|
||||
# (for development we need to execute yarn install since the
|
||||
# node_modules are on another volume and need updating)
|
||||
CMD /bin/sh -c "yarn install && yarn run dev"
|
||||
CMD /bin/sh -c "cd /database && yarn install && yarn build && cd /app && yarn install && yarn run dev"
|
||||
|
||||
##################################################################################
|
||||
# BUILD (Does contain all files and is therefore bloated) ########################
|
||||
##################################################################################
|
||||
FROM base as build
|
||||
|
||||
# Copy everything
|
||||
COPY . .
|
||||
# npm install
|
||||
# Copy everything from backend
|
||||
COPY ./backend/ ./
|
||||
# Copy everything from database
|
||||
COPY ./database/ ../database/
|
||||
|
||||
# yarn install backend
|
||||
RUN yarn install --production=false --frozen-lockfile --non-interactive
|
||||
# npm build
|
||||
|
||||
# yarn install database
|
||||
RUN cd ../database && yarn install --production=false --frozen-lockfile --non-interactive
|
||||
|
||||
# yarn build
|
||||
RUN yarn run build
|
||||
|
||||
# yarn build database
|
||||
RUN cd ../database && yarn run build
|
||||
|
||||
##################################################################################
|
||||
# TEST ###########################################################################
|
||||
##################################################################################
|
||||
@ -82,8 +94,10 @@ FROM base as production
|
||||
|
||||
# Copy "binary"-files from build image
|
||||
COPY --from=build ${DOCKER_WORKDIR}/build ./build
|
||||
COPY --from=build ${DOCKER_WORKDIR}/../database/build ../database/build
|
||||
# We also copy the node_modules express and serve-static for the run script
|
||||
# COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
||||
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
||||
COPY --from=build ${DOCKER_WORKDIR}/../database/node_modules ../database/node_modules
|
||||
# Copy static files
|
||||
# COPY --from=build ${DOCKER_WORKDIR}/public ./public
|
||||
# Copy package.json for script definitions (lock file should not be needed)
|
||||
|
||||
@ -4,4 +4,7 @@ module.exports = {
|
||||
preset: 'ts-jest',
|
||||
collectCoverage: true,
|
||||
collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**'],
|
||||
moduleNameMapper: {
|
||||
'@entity/(.*)': '<rootDir>/../database/entity/$1',
|
||||
},
|
||||
}
|
||||
|
||||
@ -28,11 +28,12 @@
|
||||
"jest": "^27.2.4",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"libsodium-wrappers": "^0.7.9",
|
||||
"module-alias": "^2.2.2",
|
||||
"mysql2": "^2.3.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"ts-jest": "^27.0.5",
|
||||
"type-graphql": "^1.1.1",
|
||||
"typeorm": "^0.2.37"
|
||||
"typeorm": "^0.2.38"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.12",
|
||||
@ -51,5 +52,8 @@
|
||||
"prettier": "^2.3.1",
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "^4.3.4"
|
||||
},
|
||||
"_moduleAliases": {
|
||||
"@entity" : "../database/build/entity"
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,12 +19,12 @@ import { UserRepository } from '../../typeorm/repository/User'
|
||||
import { UserTransactionRepository } from '../../typeorm/repository/UserTransaction'
|
||||
import { TransactionRepository } from '../../typeorm/repository/Transaction'
|
||||
|
||||
import { User as dbUser } from '../../typeorm/entity/User'
|
||||
import { UserTransaction as dbUserTransaction } from '../../typeorm/entity/UserTransaction'
|
||||
import { Transaction as dbTransaction } from '../../typeorm/entity/Transaction'
|
||||
import { User as dbUser } from '@entity/User'
|
||||
import { UserTransaction as dbUserTransaction } from '@entity/UserTransaction'
|
||||
import { Transaction as dbTransaction } from '@entity/Transaction'
|
||||
|
||||
import { apiPost } from '../../apis/HttpRequest'
|
||||
import { roundFloorFrom4 } from '../../util/round'
|
||||
import { roundFloorFrom4, roundCeilFrom4 } from '../../util/round'
|
||||
import { calculateDecay, calculateDecayWithInterval } from '../../util/decay'
|
||||
import { TransactionTypeId } from '../enum/TransactionTypeId'
|
||||
import { TransactionType } from '../enum/TransactionType'
|
||||
@ -150,7 +150,7 @@ async function calculateAndAddDecayTransactions(
|
||||
|
||||
const decayTransaction = new Transaction()
|
||||
decayTransaction.type = 'decay'
|
||||
decayTransaction.balance = roundFloorFrom4(balance)
|
||||
decayTransaction.balance = roundCeilFrom4(balance)
|
||||
decayTransaction.decayDuration = decay.decayDuration
|
||||
decayTransaction.decayStart = decay.decayStart
|
||||
decayTransaction.decayEnd = decay.decayEnd
|
||||
|
||||
@ -9,7 +9,7 @@ import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode'
|
||||
import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse'
|
||||
import { UpdateUserInfosResponse } from '../model/UpdateUserInfosResponse'
|
||||
import { User } from '../model/User'
|
||||
import { User as DbUser } from '../../typeorm/entity/User'
|
||||
import { User as DbUser } from '@entity/User'
|
||||
import encode from '../../jwt/encode'
|
||||
import ChangePasswordArgs from '../arg/ChangePasswordArgs'
|
||||
import CheckUsernameArgs from '../arg/CheckUsernameArgs'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { createConnection, Connection } from 'typeorm'
|
||||
import CONFIG from '../config'
|
||||
import path from 'path'
|
||||
import { entities } from '@entity/index'
|
||||
|
||||
const connection = async (): Promise<Connection | null> => {
|
||||
let con = null
|
||||
@ -13,7 +13,7 @@ const connection = async (): Promise<Connection | null> => {
|
||||
username: CONFIG.DB_USER,
|
||||
password: CONFIG.DB_PASSWORD,
|
||||
database: CONFIG.DB_DATABASE,
|
||||
entities: [path.join(__dirname, 'entity', '*.{ts,js}')],
|
||||
entities,
|
||||
synchronize: false,
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import { Migration } from './entity/Migration'
|
||||
import { getRepository } from 'typeorm'
|
||||
import { Migration } from '@entity/Migration'
|
||||
|
||||
const getDBVersion = async (): Promise<string | null> => {
|
||||
try {
|
||||
const dbVersion = await Migration.findOne({ order: { version: 'DESC' } })
|
||||
const dbVersion = await getRepository(Migration).findOne({ order: { version: 'DESC' } })
|
||||
return dbVersion ? dbVersion.fileName : null
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { Balance } from '../entity/Balance'
|
||||
import { Balance } from '@entity/Balance'
|
||||
|
||||
@EntityRepository(Balance)
|
||||
export class BalanceRepository extends Repository<Balance> {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { Transaction } from '../entity/Transaction'
|
||||
import { Transaction } from '@entity/Transaction'
|
||||
|
||||
@EntityRepository(Transaction)
|
||||
export class TransactionRepository extends Repository<Transaction> {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { User } from '../entity/User'
|
||||
import { User } from '@entity/User'
|
||||
|
||||
@EntityRepository(User)
|
||||
export class UserRepository extends Repository<User> {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { UserSetting } from '../entity/UserSetting'
|
||||
import { UserSetting } from '@entity/UserSetting'
|
||||
import { Setting } from '../../graphql/enum/Setting'
|
||||
import { isStringBoolean } from '../../util/validate'
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { EntityRepository, Repository } from 'typeorm'
|
||||
import { Order } from '../../graphql/enum/Order'
|
||||
import { UserTransaction } from '../entity/UserTransaction'
|
||||
import { UserTransaction } from '@entity/UserTransaction'
|
||||
|
||||
@EntityRepository(UserTransaction)
|
||||
export class UserTransactionRepository extends Repository<UserTransaction> {
|
||||
|
||||
@ -46,7 +46,9 @@
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
"paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
"@entity/*": ["../database/entity/*"]
|
||||
},
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
@ -68,5 +70,12 @@
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
}
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "../database/tsconfig.json",
|
||||
// add 'prepend' if you want to include the referenced project in your output file
|
||||
// "prepend": true,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -4123,6 +4123,11 @@ mkdirp@^1.0.4:
|
||||
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
module-alias@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0"
|
||||
integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
|
||||
@ -5374,10 +5379,10 @@ typedarray-to-buffer@^3.1.5:
|
||||
dependencies:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
typeorm@^0.2.37:
|
||||
version "0.2.37"
|
||||
resolved "https://registry.npmjs.org/typeorm/-/typeorm-0.2.37.tgz"
|
||||
integrity sha512-7rkW0yCgFC24I5T0f3S/twmLSuccPh1SQmxET/oDWn2sSDVzbyWdnItSdKy27CdJGTlKHYtUVeOcMYw5LRsXVw==
|
||||
typeorm@^0.2.38:
|
||||
version "0.2.38"
|
||||
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.38.tgz#2af08079919f6ab04cd17017f9faa2c8d5cd566f"
|
||||
integrity sha512-M6Y3KQcAREQcphOVJciywf4mv6+A0I/SeR+lWNjKsjnQ+a3XcMwGYMGL0Jonsx3H0Cqlf/3yYqVki1jIXSK/xg==
|
||||
dependencies:
|
||||
"@sqltools/formatter" "^1.2.2"
|
||||
app-root-path "^3.0.0"
|
||||
|
||||
@ -15,7 +15,8 @@ class ServerUsersController extends AppController
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$this->Auth->allow(['add', 'edit']);
|
||||
// uncomment in devmode to add new community server admin user, but don't!!! commit it
|
||||
//$this->Auth->allow(['add', 'edit']);
|
||||
$this->Auth->deny('index');
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ phpServer.host = nginx
|
||||
loginServer.path = http://localhost/account
|
||||
loginServer.default_locale = de
|
||||
loginServer.db.host = mariadb
|
||||
loginServer.db.name = gradido_login
|
||||
loginServer.db.name = gradido_community
|
||||
loginServer.db.user = root
|
||||
loginServer.db.password =
|
||||
loginServer.db.port = 3306
|
||||
|
||||
@ -17,7 +17,7 @@ phpServer.host = nginx
|
||||
loginServer.path = http://localhost/account
|
||||
loginServer.default_locale = de
|
||||
loginServer.db.host = mariadb
|
||||
loginServer.db.name = gradido_login_test
|
||||
loginServer.db.name = gradido_community_test
|
||||
loginServer.db.user = root
|
||||
loginServer.db.password =
|
||||
loginServer.db.port = 3306
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `host`, `home`, `description`) VALUES
|
||||
(1, 'docker', 'docker gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2 with blockchain db');
|
||||
|
||||
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@ RUN yarn run build
|
||||
FROM build as test_up
|
||||
|
||||
# Run command
|
||||
CMD /bin/sh -c "yarn run dev_up"
|
||||
CMD /bin/sh -c "yarn install && yarn run dev_up"
|
||||
|
||||
##################################################################################
|
||||
# TEST RESET #####################################################################
|
||||
@ -81,7 +81,7 @@ CMD /bin/sh -c "yarn run dev_up"
|
||||
FROM build as test_reset
|
||||
|
||||
# Run command
|
||||
CMD /bin/sh -c "yarn run dev_reset"
|
||||
CMD /bin/sh -c "yarn install && yarn run dev_reset"
|
||||
|
||||
##################################################################################
|
||||
# TEST DOWN ######################################################################
|
||||
@ -89,7 +89,7 @@ CMD /bin/sh -c "yarn run dev_reset"
|
||||
FROM build as test_down
|
||||
|
||||
# Run command
|
||||
CMD /bin/sh -c "yarn run dev_down"
|
||||
CMD /bin/sh -c "yarn install && yarn run dev_down"
|
||||
|
||||
##################################################################################
|
||||
# PRODUCTION (Does contain only "binary"- and static-files to reduce image size) #
|
||||
|
||||
26
database/entity/0001-init_db/User.ts
Normal file
26
database/entity/0001-init_db/User.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
|
||||
|
||||
// Moriz: I do not like the idea of having two user tables
|
||||
@Entity('state_users')
|
||||
export class User extends BaseEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number
|
||||
|
||||
@Column({ type: 'binary', length: 32, name: 'public_key' })
|
||||
pubkey: Buffer
|
||||
|
||||
@Column()
|
||||
email: string
|
||||
|
||||
@Column({ name: 'first_name' })
|
||||
firstName: string
|
||||
|
||||
@Column({ name: 'last_name' })
|
||||
lastName: string
|
||||
|
||||
@Column()
|
||||
username: string
|
||||
|
||||
@Column()
|
||||
disabled: boolean
|
||||
}
|
||||
@ -7,9 +7,6 @@ export class User extends BaseEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number
|
||||
|
||||
// @ManyToOne(type => Group, group => group.users)
|
||||
// group: Group;
|
||||
|
||||
@Column({ type: 'binary', length: 32, name: 'public_key' })
|
||||
pubkey: Buffer
|
||||
|
||||
1
database/entity/Balance.ts
Normal file
1
database/entity/Balance.ts
Normal file
@ -0,0 +1 @@
|
||||
export { Balance } from './0001-init_db/Balance'
|
||||
1
database/entity/Migration.ts
Normal file
1
database/entity/Migration.ts
Normal file
@ -0,0 +1 @@
|
||||
export { Migration } from './0001-init_db/Migration'
|
||||
1
database/entity/Transaction.ts
Normal file
1
database/entity/Transaction.ts
Normal file
@ -0,0 +1 @@
|
||||
export { Transaction } from './0001-init_db/Transaction'
|
||||
1
database/entity/TransactionCreation.ts
Normal file
1
database/entity/TransactionCreation.ts
Normal file
@ -0,0 +1 @@
|
||||
export { TransactionCreation } from './0001-init_db/TransactionCreation'
|
||||
1
database/entity/TransactionSendCoin.ts
Normal file
1
database/entity/TransactionSendCoin.ts
Normal file
@ -0,0 +1 @@
|
||||
export { TransactionSendCoin } from './0001-init_db/TransactionSendCoin'
|
||||
1
database/entity/User.ts
Normal file
1
database/entity/User.ts
Normal file
@ -0,0 +1 @@
|
||||
export { User } from './0002-add_settings/User'
|
||||
1
database/entity/UserSetting.ts
Normal file
1
database/entity/UserSetting.ts
Normal file
@ -0,0 +1 @@
|
||||
export { UserSetting } from './0002-add_settings/UserSetting'
|
||||
1
database/entity/UserTransaction.ts
Normal file
1
database/entity/UserTransaction.ts
Normal file
@ -0,0 +1 @@
|
||||
export { UserTransaction } from './0001-init_db/UserTransaction'
|
||||
19
database/entity/index.ts
Normal file
19
database/entity/index.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Balance } from './Balance'
|
||||
import { Migration } from './Migration'
|
||||
import { Transaction } from './Transaction'
|
||||
import { TransactionCreation } from './TransactionCreation'
|
||||
import { TransactionSendCoin } from './TransactionSendCoin'
|
||||
import { User } from './User'
|
||||
import { UserSetting } from './UserSetting'
|
||||
import { UserTransaction } from './UserTransaction'
|
||||
|
||||
export const entities = [
|
||||
Balance,
|
||||
Migration,
|
||||
Transaction,
|
||||
TransactionCreation,
|
||||
TransactionSendCoin,
|
||||
User,
|
||||
UserSetting,
|
||||
UserTransaction,
|
||||
]
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(`
|
||||
CREATE TABLE IF NOT EXISTS \`user_setting\` (
|
||||
CREATE TABLE \`user_setting\` (
|
||||
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`userId\` int(11) NOT NULL,
|
||||
\`key\` varchar(255) NOT NULL,
|
||||
@ -22,5 +22,5 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
// write downgrade logic as parameter of queryFn
|
||||
await queryFn(`DROP TABLE IF EXISTS \`user_setting\`;`)
|
||||
await queryFn(`DROP TABLE \`user_setting\`;`)
|
||||
}
|
||||
|
||||
153
database/migrations/0003-login_server_tables.ts
Normal file
153
database/migrations/0003-login_server_tables.ts
Normal file
@ -0,0 +1,153 @@
|
||||
/* FIRST MIGRATION
|
||||
*
|
||||
* This migration is special since it takes into account that
|
||||
* the database can be setup already but also may not be.
|
||||
* Therefore you will find all `CREATE TABLE` statements with
|
||||
* a `IF NOT EXISTS`, all `INSERT` with an `IGNORE` and in the
|
||||
* downgrade function all `DROP TABLE` with a `IF EXISTS`.
|
||||
* This ensures compatibility for existing or non-existing
|
||||
* databases.
|
||||
*/
|
||||
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_app_access_tokens\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`user_id\` int NOT NULL,
|
||||
\`access_code\` bigint unsigned NOT NULL,
|
||||
\`created\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`updated\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (\`id\`),
|
||||
UNIQUE KEY \`access_code\` (\`access_code\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_elopage_buys\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`elopage_user_id\` int DEFAULT NULL,
|
||||
\`affiliate_program_id\` int NOT NULL,
|
||||
\`publisher_id\` int NOT NULL,
|
||||
\`order_id\` int NOT NULL,
|
||||
\`product_id\` int NOT NULL,
|
||||
\`product_price\` int NOT NULL,
|
||||
\`payer_email\` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
\`publisher_email\` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
\`payed\` tinyint NOT NULL,
|
||||
\`success_date\` datetime NOT NULL,
|
||||
\`event\` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_email_opt_in_types\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`name\` varchar(255) NOT NULL,
|
||||
\`description\` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_email_opt_in\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`user_id\` int NOT NULL,
|
||||
\`verification_code\` bigint unsigned NOT NULL,
|
||||
\`email_opt_in_type_id\` int NOT NULL,
|
||||
\`created\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`resend_count\` int DEFAULT '0',
|
||||
\`updated\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (\`id\`),
|
||||
UNIQUE KEY \`verification_code\` (\`verification_code\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_groups\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`alias\` varchar(190) NOT NULL,
|
||||
\`name\` varchar(255) NOT NULL,
|
||||
\`url\` varchar(255) NOT NULL,
|
||||
\`host\` varchar(255) DEFAULT "/",
|
||||
\`home\` varchar(255) DEFAULT "/",
|
||||
\`description\` text,
|
||||
PRIMARY KEY (\`id\`),
|
||||
UNIQUE KEY \`alias\` (\`alias\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_pending_tasks\` (
|
||||
\`id\` int UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
\`user_id\` int UNSIGNED DEFAULT 0,
|
||||
\`request\` varbinary(2048) NOT NULL,
|
||||
\`created\` datetime NOT NULL,
|
||||
\`finished\` datetime DEFAULT '2000-01-01 000000',
|
||||
\`result_json\` text DEFAULT NULL,
|
||||
\`param_json\` text DEFAULT NULL,
|
||||
\`task_type_id\` int UNSIGNED NOT NULL,
|
||||
\`child_pending_task_id\` int UNSIGNED DEFAULT 0,
|
||||
\`parent_pending_task_id\` int UNSIGNED DEFAULT 0,
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_roles\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`name\` varchar(255) NOT NULL,
|
||||
\`description\` varchar(255) NOT NULL,
|
||||
\`flags\` bigint NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_user_backups\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`user_id\` int NOT NULL,
|
||||
\`passphrase\` text NOT NULL,
|
||||
\`mnemonic_type\` int DEFAULT '-1',
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_user_roles\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`user_id\` int NOT NULL,
|
||||
\`role_id\` int NOT NULL,
|
||||
PRIMARY KEY (\`id\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
await queryFn(`
|
||||
CREATE TABLE \`login_users\` (
|
||||
\`id\` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
\`email\` varchar(191) NOT NULL,
|
||||
\`first_name\` varchar(150) NOT NULL,
|
||||
\`last_name\` varchar(255) DEFAULT '',
|
||||
\`username\` varchar(255) DEFAULT '',
|
||||
\`description\` text DEFAULT '',
|
||||
\`password\` bigint unsigned DEFAULT '0',
|
||||
\`pubkey\` binary(32) DEFAULT NULL,
|
||||
\`privkey\` binary(80) DEFAULT NULL,
|
||||
\`email_hash\` binary(32) DEFAULT NULL,
|
||||
\`created\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
\`email_checked\` tinyint NOT NULL DEFAULT '0',
|
||||
\`passphrase_shown\` tinyint NOT NULL DEFAULT '0',
|
||||
\`language\` varchar(4) NOT NULL DEFAULT 'de',
|
||||
\`disabled\` tinyint DEFAULT '0',
|
||||
\`group_id\` int unsigned DEFAULT 0,
|
||||
\`publisher_id\` int DEFAULT 0,
|
||||
PRIMARY KEY (\`id\`),
|
||||
UNIQUE KEY \`email\` (\`email\`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
`)
|
||||
}
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
// write downgrade logic as parameter of queryFn
|
||||
await queryFn(`DROP TABLE \`login_app_access_tokens\`;`)
|
||||
await queryFn(`DROP TABLE \`login_elopage_buys\`;`)
|
||||
await queryFn(`DROP TABLE \`login_email_opt_in_types\`;`)
|
||||
await queryFn(`DROP TABLE \`login_email_opt_in\`;`)
|
||||
await queryFn(`DROP TABLE \`login_groups\`;`)
|
||||
await queryFn(`DROP TABLE \`login_pending_tasks\`;`)
|
||||
await queryFn(`DROP TABLE \`login_roles\`;`)
|
||||
await queryFn(`DROP TABLE \`login_user_backups\`;`)
|
||||
await queryFn(`DROP TABLE \`login_user_roles\`;`)
|
||||
await queryFn(`DROP TABLE \`login_users\`;`)
|
||||
}
|
||||
74
database/migrations/0004-login_server_data.ts
Normal file
74
database/migrations/0004-login_server_data.ts
Normal file
@ -0,0 +1,74 @@
|
||||
/* FIRST MIGRATION
|
||||
*
|
||||
* This migration is special since it takes into account that
|
||||
* the database can be setup already but also may not be.
|
||||
* Therefore you will find all `CREATE TABLE` statements with
|
||||
* a `IF NOT EXISTS`, all `INSERT` with an `IGNORE` and in the
|
||||
* downgrade function all `DROP TABLE` with a `IF EXISTS`.
|
||||
* This ensures compatibility for existing or non-existing
|
||||
* databases.
|
||||
*/
|
||||
|
||||
const LOGIN_SERVER_DB = 'gradido_login'
|
||||
|
||||
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
const loginDatabaseExists = await queryFn(`
|
||||
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${LOGIN_SERVER_DB}'
|
||||
`)
|
||||
if (loginDatabaseExists.length === 0) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Skipping Login Server Database migration - Database ${LOGIN_SERVER_DB} not found`)
|
||||
return
|
||||
}
|
||||
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_app_access_tokens\` SELECT * FROM ${LOGIN_SERVER_DB}.\`app_access_tokens\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_elopage_buys\` SELECT * FROM ${LOGIN_SERVER_DB}.\`elopage_buys\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_email_opt_in_types\` SELECT * FROM ${LOGIN_SERVER_DB}.\`email_opt_in_types\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_email_opt_in\` SELECT * FROM ${LOGIN_SERVER_DB}.\`email_opt_in\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_groups\` SELECT * FROM ${LOGIN_SERVER_DB}.\`groups\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_pending_tasks\` SELECT * FROM ${LOGIN_SERVER_DB}.\`pending_tasks\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_roles\` SELECT * FROM ${LOGIN_SERVER_DB}.\`roles\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_user_backups\` SELECT * FROM ${LOGIN_SERVER_DB}.\`user_backups\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_user_roles\` SELECT * FROM ${LOGIN_SERVER_DB}.\`user_roles\`;
|
||||
`)
|
||||
await queryFn(`
|
||||
INSERT INTO \`login_users\` SELECT * FROM ${LOGIN_SERVER_DB}.\`users\`;
|
||||
`)
|
||||
|
||||
// TODO clarify if we need this on non docker environment?
|
||||
await queryFn(`
|
||||
INSERT IGNORE INTO \`login_groups\` (\`id\`, \`alias\`, \`name\`, \`url\`, \`host\`, \`home\`, \`description\`) VALUES
|
||||
(1, 'docker', 'docker gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2 with blockchain db');
|
||||
`)
|
||||
}
|
||||
|
||||
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
|
||||
// write downgrade logic as parameter of queryFn
|
||||
await queryFn(`DELETE FROM \`login_app_access_tokens\`;`)
|
||||
await queryFn(`DELETE FROM \`login_elopage_buys\`;`)
|
||||
await queryFn(`DELETE FROM \`login_email_opt_in_types\`;`)
|
||||
await queryFn(`DELETE FROM \`login_email_opt_in\`;`)
|
||||
await queryFn(`DELETE FROM \`login_groups\`;`)
|
||||
await queryFn(`DELETE FROM \`login_pending_tasks\`;`)
|
||||
await queryFn(`DELETE FROM \`login_roles\`;`)
|
||||
await queryFn(`DELETE FROM \`login_user_backups\`;`)
|
||||
await queryFn(`DELETE FROM \`login_user_roles\`;`)
|
||||
await queryFn(`DELETE FROM \`login_users\`;`)
|
||||
}
|
||||
@ -19,7 +19,7 @@
|
||||
"lint": "eslint . --ext .js,.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.7.1",
|
||||
"@types/node": "^16.10.3",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.2",
|
||||
"@typescript-eslint/parser": "^4.29.2",
|
||||
"eslint": "^7.32.0",
|
||||
@ -37,6 +37,8 @@
|
||||
"dependencies": {
|
||||
"dotenv": "^10.0.0",
|
||||
"mysql2": "^2.3.0",
|
||||
"ts-mysql-migrate": "^1.0.2"
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"ts-mysql-migrate": "^1.0.2",
|
||||
"typeorm": "^0.2.38"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
import 'reflect-metadata'
|
||||
import { createPool, PoolConfig } from 'mysql'
|
||||
import { Migration } from 'ts-mysql-migrate'
|
||||
import CONFIG from './config'
|
||||
import prepare from './prepare'
|
||||
import connection from './typeorm/connection'
|
||||
|
||||
const run = async (command: string) => {
|
||||
// Database actions not supported by our migration library
|
||||
await prepare()
|
||||
|
||||
// Database connection
|
||||
// Database connection for Migrations
|
||||
const poolConfig: PoolConfig = {
|
||||
host: CONFIG.DB_HOST,
|
||||
port: CONFIG.DB_PORT,
|
||||
@ -26,6 +28,12 @@ const run = async (command: string) => {
|
||||
dir: CONFIG.MIGRATIONS_DIRECTORY,
|
||||
})
|
||||
|
||||
// Database connection for TypeORM
|
||||
const con = await connection()
|
||||
if (!con || !con.isConnected) {
|
||||
throw new Error(`Couldn't open connection to database`)
|
||||
}
|
||||
|
||||
await migration.initialize()
|
||||
|
||||
// Execute command
|
||||
@ -42,6 +50,10 @@ const run = async (command: string) => {
|
||||
default:
|
||||
throw new Error(`Unsupported command ${command}`)
|
||||
}
|
||||
|
||||
// Terminate connections gracefully
|
||||
await con.close()
|
||||
pool.end()
|
||||
}
|
||||
|
||||
run(process.argv[2])
|
||||
|
||||
27
database/src/typeorm/connection.ts
Normal file
27
database/src/typeorm/connection.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { createConnection, Connection } from 'typeorm'
|
||||
import CONFIG from '../config'
|
||||
import { entities } from '../../entity/index'
|
||||
|
||||
const connection = async (): Promise<Connection | null> => {
|
||||
let con = null
|
||||
try {
|
||||
con = await createConnection({
|
||||
name: 'default',
|
||||
type: 'mysql',
|
||||
host: CONFIG.DB_HOST,
|
||||
port: CONFIG.DB_PORT,
|
||||
username: CONFIG.DB_USER,
|
||||
password: CONFIG.DB_PASSWORD,
|
||||
database: CONFIG.DB_DATABASE,
|
||||
entities,
|
||||
synchronize: false,
|
||||
})
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
return con
|
||||
}
|
||||
|
||||
export default connection
|
||||
@ -4,19 +4,19 @@
|
||||
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
|
||||
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
"declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
// "outFile": "./build/outfile.js", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./build", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
"composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
@ -47,7 +47,7 @@
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
@ -68,5 +68,6 @@
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
}
|
||||
},
|
||||
"references": [] /* Any project that is referenced must itself have a `references` array (which may be empty). */
|
||||
}
|
||||
|
||||
@ -90,6 +90,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
|
||||
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
|
||||
|
||||
"@sqltools/formatter@^1.2.2":
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.3.tgz#1185726610acc37317ddab11c3c7f9066966bd20"
|
||||
integrity sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg==
|
||||
|
||||
"@szmarczak/http-timer@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
|
||||
@ -129,11 +134,21 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*", "@types/node@^16.7.1":
|
||||
"@types/node@*":
|
||||
version "16.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.1.tgz#c6b9198178da504dfca1fd0be9b2e1002f1586f0"
|
||||
integrity sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==
|
||||
|
||||
"@types/node@^16.10.3":
|
||||
version "16.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5"
|
||||
integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==
|
||||
|
||||
"@types/zen-observable@0.8.3":
|
||||
version "0.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3"
|
||||
integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^4.29.2":
|
||||
version "4.29.2"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz#f54dc0a32b8f61c6024ab8755da05363b733838d"
|
||||
@ -260,6 +275,11 @@ ansi-colors@^4.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
|
||||
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
|
||||
|
||||
ansi-regex@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
|
||||
|
||||
ansi-regex@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
|
||||
@ -270,6 +290,11 @@ ansi-regex@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||
|
||||
ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
@ -284,6 +309,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
any-promise@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
|
||||
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
|
||||
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||
@ -292,6 +322,11 @@ anymatch@~3.1.2:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
app-root-path@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad"
|
||||
integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==
|
||||
|
||||
arg@^4.1.0:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||
@ -304,6 +339,11 @@ argparse@^1.0.7:
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
array-includes@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a"
|
||||
@ -339,6 +379,11 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
bignumber.js@9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075"
|
||||
@ -378,6 +423,14 @@ braces@^3.0.1, braces@~3.0.2:
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
buffer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
cacheable-request@^6.0.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
|
||||
@ -409,6 +462,17 @@ camelcase@^5.3.1:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
|
||||
chalk@^1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
|
||||
integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
|
||||
dependencies:
|
||||
ansi-styles "^2.2.1"
|
||||
escape-string-regexp "^1.0.2"
|
||||
has-ansi "^2.0.0"
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.0.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
@ -426,7 +490,7 @@ chalk@^3.0.0:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
chalk@^4.0.0:
|
||||
chalk@^4.0.0, chalk@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
@ -459,6 +523,27 @@ cli-boxes@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
|
||||
integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
|
||||
|
||||
cli-highlight@^2.1.11:
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf"
|
||||
integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==
|
||||
dependencies:
|
||||
chalk "^4.0.0"
|
||||
highlight.js "^10.7.1"
|
||||
mz "^2.4.0"
|
||||
parse5 "^5.1.1"
|
||||
parse5-htmlparser2-tree-adapter "^6.0.0"
|
||||
yargs "^16.0.0"
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
clone-response@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
|
||||
@ -624,6 +709,11 @@ dotenv@^10.0.0:
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
|
||||
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
|
||||
|
||||
dotenv@^8.2.0:
|
||||
version "8.6.0"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
|
||||
integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==
|
||||
|
||||
duplexer3@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
|
||||
@ -692,12 +782,17 @@ es-to-primitive@^1.2.1:
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||
|
||||
escape-goat@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
|
||||
integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
@ -945,6 +1040,11 @@ fastq@^1.6.0:
|
||||
dependencies:
|
||||
reusify "^1.0.4"
|
||||
|
||||
figlet@^1.1.1:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.5.2.tgz#dda34ff233c9a48e36fcff6741aeb5bafe49b634"
|
||||
integrity sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ==
|
||||
|
||||
file-entry-cache@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
|
||||
@ -1006,6 +1106,11 @@ generate-function@^2.3.1:
|
||||
dependencies:
|
||||
is-property "^1.0.2"
|
||||
|
||||
get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
|
||||
@ -1048,6 +1153,18 @@ glob@^7.1.3:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.1.6:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
|
||||
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global-dirs@^2.0.1:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d"
|
||||
@ -1096,6 +1213,13 @@ graceful-fs@^4.1.2:
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
|
||||
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
has-bigints@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
|
||||
@ -1135,6 +1259,11 @@ has@^1.0.3:
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
highlight.js@^10.7.1:
|
||||
version "10.7.3"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
|
||||
integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.9"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
|
||||
@ -1152,6 +1281,11 @@ iconv-lite@^0.6.2:
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3.0.0"
|
||||
|
||||
ieee754@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
ignore-by-default@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
|
||||
@ -1193,7 +1327,7 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@~2.0.3:
|
||||
inherits@2, inherits@^2.0.1, inherits@~2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
@ -1392,6 +1526,13 @@ js-yaml@^3.13.1:
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
js-yaml@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
json-buffer@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
|
||||
@ -1551,6 +1692,11 @@ minimist@^1.2.0, minimist@^1.2.5:
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
mkdirp@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
@ -1590,6 +1736,15 @@ mysql@^2.18.1:
|
||||
safe-buffer "5.1.2"
|
||||
sqlstring "2.3.1"
|
||||
|
||||
mz@^2.4.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
|
||||
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
object-assign "^4.0.1"
|
||||
thenify-all "^1.0.0"
|
||||
|
||||
named-placeholders@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.2.tgz#ceb1fbff50b6b33492b5cf214ccf5e39cef3d0e8"
|
||||
@ -1645,6 +1800,11 @@ normalize-url@^4.1.0:
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
|
||||
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
|
||||
object-inspect@^1.11.0, object-inspect@^1.9.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1"
|
||||
@ -1734,6 +1894,11 @@ parent-module@^1.0.0:
|
||||
dependencies:
|
||||
callsites "^3.0.0"
|
||||
|
||||
parent-require@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parent-require/-/parent-require-1.0.0.tgz#746a167638083a860b0eef6732cb27ed46c32977"
|
||||
integrity sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=
|
||||
|
||||
parse-json@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
|
||||
@ -1742,6 +1907,23 @@ parse-json@^4.0.0:
|
||||
error-ex "^1.3.1"
|
||||
json-parse-better-errors "^1.0.1"
|
||||
|
||||
parse5-htmlparser2-tree-adapter@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
|
||||
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
|
||||
dependencies:
|
||||
parse5 "^6.0.1"
|
||||
|
||||
parse5@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
|
||||
integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
|
||||
|
||||
parse5@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
|
||||
|
||||
path-exists@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
|
||||
@ -1912,6 +2094,11 @@ readdirp@~3.6.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
reflect-metadata@^0.1.13:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
|
||||
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
|
||||
|
||||
regexpp@^3.0.0, regexpp@^3.1.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
|
||||
@ -1931,6 +2118,11 @@ registry-url@^5.0.0:
|
||||
dependencies:
|
||||
rc "^1.2.8"
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
require-from-string@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||
@ -1980,11 +2172,21 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
safe-buffer@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3.0.0":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
sax@>=0.6.0:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||
|
||||
semver-diff@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
|
||||
@ -2014,6 +2216,14 @@ seq-queue@^0.0.5:
|
||||
resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e"
|
||||
integrity sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=
|
||||
|
||||
sha.js@^2.4.11:
|
||||
version "2.4.11"
|
||||
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
|
||||
integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
|
||||
dependencies:
|
||||
inherits "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
@ -2136,6 +2346,13 @@ string_decoder@~1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
strip-ansi@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||
integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
|
||||
dependencies:
|
||||
ansi-regex "^2.0.0"
|
||||
|
||||
strip-ansi@^5.1.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
|
||||
@ -2165,6 +2382,11 @@ strip-json-comments@~2.0.1:
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
|
||||
|
||||
supports-color@^5.3.0, supports-color@^5.5.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
@ -2201,6 +2423,20 @@ text-table@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
thenify-all@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
|
||||
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
|
||||
dependencies:
|
||||
thenify ">= 3.1.0 < 4"
|
||||
|
||||
"thenify@>= 3.1.0 < 4":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
|
||||
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
|
||||
to-readable-stream@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
|
||||
@ -2260,6 +2496,11 @@ tslib@^1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.1.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||
|
||||
tsutils@^3.21.0:
|
||||
version "3.21.0"
|
||||
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
|
||||
@ -2291,6 +2532,29 @@ typedarray-to-buffer@^3.1.5:
|
||||
dependencies:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
typeorm@^0.2.38:
|
||||
version "0.2.38"
|
||||
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.38.tgz#2af08079919f6ab04cd17017f9faa2c8d5cd566f"
|
||||
integrity sha512-M6Y3KQcAREQcphOVJciywf4mv6+A0I/SeR+lWNjKsjnQ+a3XcMwGYMGL0Jonsx3H0Cqlf/3yYqVki1jIXSK/xg==
|
||||
dependencies:
|
||||
"@sqltools/formatter" "^1.2.2"
|
||||
app-root-path "^3.0.0"
|
||||
buffer "^6.0.3"
|
||||
chalk "^4.1.0"
|
||||
cli-highlight "^2.1.11"
|
||||
debug "^4.3.1"
|
||||
dotenv "^8.2.0"
|
||||
glob "^7.1.6"
|
||||
js-yaml "^4.0.0"
|
||||
mkdirp "^1.0.4"
|
||||
reflect-metadata "^0.1.13"
|
||||
sha.js "^2.4.11"
|
||||
tslib "^2.1.0"
|
||||
xml2js "^0.4.23"
|
||||
yargonaut "^1.1.4"
|
||||
yargs "^17.0.1"
|
||||
zen-observable-ts "^1.0.0"
|
||||
|
||||
typescript@^4.3.5:
|
||||
version "4.3.5"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
|
||||
@ -2401,6 +2665,15 @@ word-wrap@^1.2.3:
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
|
||||
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
@ -2421,6 +2694,24 @@ xdg-basedir@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
|
||||
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
|
||||
|
||||
xml2js@^0.4.23:
|
||||
version "0.4.23"
|
||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66"
|
||||
integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==
|
||||
dependencies:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "~11.0.0"
|
||||
|
||||
xmlbuilder@~11.0.0:
|
||||
version "11.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
|
||||
integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
|
||||
|
||||
yallist@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
|
||||
@ -2431,7 +2722,60 @@ yallist@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||
|
||||
yargonaut@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/yargonaut/-/yargonaut-1.1.4.tgz#c64f56432c7465271221f53f5cc517890c3d6e0c"
|
||||
integrity sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==
|
||||
dependencies:
|
||||
chalk "^1.1.1"
|
||||
figlet "^1.1.1"
|
||||
parent-require "^1.0.0"
|
||||
|
||||
yargs-parser@^20.2.2:
|
||||
version "20.2.9"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
|
||||
yargs@^16.0.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yargs@^17.0.1:
|
||||
version "17.2.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea"
|
||||
integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yn@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
||||
|
||||
zen-observable-ts@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz#2d1aa9d79b87058e9b75698b92791c1838551f83"
|
||||
integrity sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==
|
||||
dependencies:
|
||||
"@types/zen-observable" "0.8.3"
|
||||
zen-observable "0.8.15"
|
||||
|
||||
zen-observable@0.8.15:
|
||||
version "0.8.15"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15"
|
||||
integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
|
||||
|
||||
@ -36,8 +36,6 @@ cd $PROJECT_PATH
|
||||
# git checkout -f master
|
||||
git pull
|
||||
cd deployment/bare_metal
|
||||
echo 'update schemas' >> $UPDATE_HTML
|
||||
./update_db_schemas.sh
|
||||
echo 'starting with rebuilding login-server<br>' >> $UPDATE_HTML
|
||||
./build_and_start_login_server.sh
|
||||
echo 'starting with rebuilding frontend<br>' >> $UPDATE_HTML
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#!/bin/bash
|
||||
# For that to work skeema needed to be installed on system
|
||||
# in login_server/skeema skeema configuration files need to be there also in the subfolders
|
||||
# Update DB Schemas (only the schemas, not the data)
|
||||
|
||||
cd ../../login_server/skeema
|
||||
skeema push --allow-unsafe
|
||||
@ -36,8 +36,11 @@ services:
|
||||
# This makes sure the docker container has its own node modules.
|
||||
# Therefore it is possible to have a different node version on the host machine
|
||||
- backend_node_modules:/app/node_modules
|
||||
- backend_database_node_modules:/database/node_modules
|
||||
- backend_database_build:/database/build
|
||||
# bind the local folder to the docker to allow live reload
|
||||
- ./backend:/app
|
||||
- ./database:/database
|
||||
|
||||
########################################################
|
||||
# DATABASE ##############################################
|
||||
@ -133,25 +136,12 @@ services:
|
||||
- external-net
|
||||
volumes:
|
||||
- /sessions
|
||||
|
||||
#########################################################
|
||||
## skeema for updating dbs if changes happend ###########
|
||||
#########################################################
|
||||
skeema:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./skeema/Dockerfile
|
||||
target: skeema_dev_run
|
||||
depends_on:
|
||||
- mariadb
|
||||
networks:
|
||||
- internal-net
|
||||
volumes:
|
||||
- ./login_server/skeema/gradido_login:/skeema/gradido_login
|
||||
|
||||
|
||||
volumes:
|
||||
frontend_node_modules:
|
||||
backend_node_modules:
|
||||
backend_database_node_modules:
|
||||
backend_database_build:
|
||||
database_node_modules:
|
||||
database_build:
|
||||
login_build_ubuntu_3.1:
|
||||
@ -23,7 +23,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./mariadb/Dockerfile
|
||||
target: mariadb_server_test
|
||||
target: mariadb_server
|
||||
environment:
|
||||
- MARIADB_ALLOW_EMPTY_PASSWORD=1
|
||||
- MARIADB_USER=root
|
||||
@ -89,19 +89,6 @@ services:
|
||||
- external-net
|
||||
volumes:
|
||||
- /sessions
|
||||
|
||||
#########################################################
|
||||
## skeema for updating dbs if changes happend ###########
|
||||
#########################################################
|
||||
skeema:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./skeema/Dockerfile
|
||||
target: skeema_run
|
||||
depends_on:
|
||||
- mariadb
|
||||
networks:
|
||||
- internal-net
|
||||
|
||||
networks:
|
||||
external-net:
|
||||
|
||||
@ -35,9 +35,8 @@ services:
|
||||
#########################################################
|
||||
mariadb:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./mariadb/Dockerfile
|
||||
target: mariadb_server_test
|
||||
context: ./mariadb
|
||||
target: mariadb_server
|
||||
environment:
|
||||
- MARIADB_ALLOW_EMPTY_PASSWORD=1
|
||||
- MARIADB_USER=root
|
||||
@ -54,7 +53,10 @@ services:
|
||||
backend:
|
||||
image: gradido/backend:latest
|
||||
build:
|
||||
context: ./backend
|
||||
# since we have to include the entities from ./database we cannot define the context as ./backend
|
||||
# this might blow build image size to the moon ?!
|
||||
context: ./
|
||||
dockerfile: ./backend/Dockerfile
|
||||
target: production
|
||||
networks:
|
||||
- internal-net
|
||||
@ -155,41 +157,6 @@ services:
|
||||
- internal-net
|
||||
volumes:
|
||||
- ./community_server/config/php-fpm/php-ini-overrides.ini:/etc/php/7.4/fpm/conf.d/99-overrides.ini
|
||||
|
||||
#########################################################
|
||||
## skeema for updating dbs if changes happend ###########
|
||||
#########################################################
|
||||
skeema:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./skeema/Dockerfile
|
||||
target: skeema_run
|
||||
depends_on:
|
||||
- mariadb
|
||||
networks:
|
||||
- internal-net
|
||||
|
||||
#########################################################
|
||||
## GRADIDO NODE v1 ######################################
|
||||
#########################################################
|
||||
# gradido-node:
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: ./gn/docker/deprecated-hedera-node/Dockerfile
|
||||
# volumes:
|
||||
# - ${GN_INSTANCE_FOLDER}:/opt/instance
|
||||
# container_name: ${GN_CONTAINER_NAME}
|
||||
|
||||
#########################################################
|
||||
## GRADIDO NODE test ###################################
|
||||
#########################################################
|
||||
# gradido-node-test:
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: ./gn/docker/deprecated-hedera-node/Dockerfile
|
||||
# container_name: gn-test
|
||||
# working_dir: /opt/gn/build
|
||||
# command: ["./unit_tests"]
|
||||
|
||||
networks:
|
||||
external-net:
|
||||
|
||||
@ -15,7 +15,7 @@ This document describes the technical overview for the Gradido infrastructur. Be
|
||||
|
||||

|
||||
|
||||
### Database Skeema
|
||||
### Database Skeema (outdated)
|
||||
|
||||

|
||||
|
||||
|
||||
BIN
docu/Gradido-Admin.epgz
Normal file
BIN
docu/Gradido-Admin.epgz
Normal file
Binary file not shown.
27
docu/create-coins-as-admin.md
Normal file
27
docu/create-coins-as-admin.md
Normal file
@ -0,0 +1,27 @@
|
||||
### User creation
|
||||
A user needs to be created on the login_server we do this when we create a User in the client https://$community_domain/vue/register.
|
||||
|
||||
### Admin user
|
||||
To set a User admin we need the following SQL query on the gradido_login database:
|
||||
```
|
||||
INSERT INTO user_roles (id, user_id, role_id) VALUES (NULL, '1', '1');
|
||||
```
|
||||
user_id has to be found in users
|
||||
Now when we login in on https://$community_domain/account/ we can create coins but we will be restricted cause we can't sign the creations.
|
||||
|
||||
### Signation account
|
||||
At first we need to enable the server user account creation with uncommenting line: 19 in
|
||||
community_server/src/Controller/ServerUsersController.php
|
||||
```php
|
||||
$this->Auth->allow(['add', 'edit']);
|
||||
```
|
||||
This enable us to use this action without being logged in.
|
||||
To add a signation account we need to go on the following url: http://$community_domain/server-users/add
|
||||
|
||||
### Coin creation process
|
||||
The coin creation for work is done in the following url: http://$community_domain/transaction-creations/create-multi
|
||||
Where we can create coins for a number of as many users as we want excepted for our self.
|
||||
Furthermore we must sign the transactions we created. Normally after clicking on the left button (Transaktion abschließen) we should be automatically forwarded to http://$community_domain/account/checkTransactions where we can do this.
|
||||
If not this page can also be reached by clicking on the shield-icon with the hook in it on the Dashboard, which is only shown if at least one transaction is waiting for signing.
|
||||
|
||||
For debug purposes you can check the `pending_tasks` table, which is used to store the transactions which are not signed yet or had errors.
|
||||
BIN
docu/graphics/gradido_admin.png
Normal file
BIN
docu/graphics/gradido_admin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
BIN
docu/graphics/userdetails.png
Normal file
BIN
docu/graphics/userdetails.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
docu/presentation/adminarea-old-new.pdf
Normal file
BIN
docu/presentation/adminarea-old-new.pdf
Normal file
Binary file not shown.
@ -27,7 +27,6 @@
|
||||
"babel-preset-vue": "^2.0.2",
|
||||
"bootstrap": "4.3.1",
|
||||
"bootstrap-vue": "^2.5.0",
|
||||
"chart.js": "^2.9.3",
|
||||
"d3": "^5.7.0",
|
||||
"datamaps": "^0.5.9",
|
||||
"date-fns": "^1.30.1",
|
||||
@ -64,7 +63,6 @@
|
||||
"vue": "^2.6.11",
|
||||
"vue-apollo": "^3.0.7",
|
||||
"vue-bootstrap-typeahead": "^0.2.6",
|
||||
"vue-chartjs": "^3.5.0",
|
||||
"vue-cli-plugin-i18n": "^1.0.1",
|
||||
"vue-clickaway": "^2.2.2",
|
||||
"vue-clipboard2": "^0.3.0",
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
<template>
|
||||
<div class="decayinformation">
|
||||
<span v-if="decaytyp === 'short'">
|
||||
<span v-if="decay.balance > 0">
|
||||
{{ decay ? ' -' + $n(decay.balance, 'decimal') + ' ' + decayStartBlockTextShort : '' }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ $t('decay.noDecay') }}
|
||||
</span>
|
||||
{{ decay ? ' - ' + $n(decay.balance, 'decimal') + ' ' + decayStartBlockTextShort : '' }}
|
||||
</span>
|
||||
|
||||
<div v-if="decaytyp === 'new'">
|
||||
@ -58,60 +53,58 @@
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<div v-if="decay.balance > 0">
|
||||
<!-- Decay-->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
<div>{{ $t('decay.decay') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
<div>- {{ $n(decay.balance, 'decimal') }}</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<hr class="mt-2 mb-2" />
|
||||
<b-row>
|
||||
<b-col class="text-center pt-3 pb-2">
|
||||
<b>{{ $t('decay.calculation_total') }}</b>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<!-- Type-->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
<div v-if="type === 'send'">{{ $t('decay.sent') }}</div>
|
||||
<div v-if="type === 'receive'">{{ $t('decay.received') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
<div v-if="type === 'send'">- {{ $n(balance, 'decimal') }}</div>
|
||||
<div v-if="type === 'receive'">+ {{ $n(balance, 'decimal') }}</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<!-- Decay-->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
<div>{{ $t('decay.decay') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
<div>- {{ $n(decay.balance, 'decimal') }}</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<!-- Total-->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
<div>{{ $t('decay.total') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
<div v-if="type === 'send'">
|
||||
<b>- {{ $n(balance + decay.balance, 'decimal') }}</b>
|
||||
</div>
|
||||
<div v-if="type === 'receive'">
|
||||
<b>{{ $n(balance - decay.balance, 'decimal') }}</b>
|
||||
</div>
|
||||
<div v-if="type === 'creation'">
|
||||
<b>- {{ $n(balance - decay.balance, 'decimal') }}</b>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
<!-- Decay-->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
<div>{{ $t('decay.decay') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
<div>- {{ $n(decay.balance, 'decimal') }}</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<hr class="mt-2 mb-2" />
|
||||
<b-row>
|
||||
<b-col class="text-center pt-3 pb-2">
|
||||
<b>{{ $t('decay.calculation_total') }}</b>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<!-- Type-->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
<div v-if="type === 'send'">{{ $t('decay.sent') }}</div>
|
||||
<div v-if="type === 'receive'">{{ $t('decay.received') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
<div v-if="type === 'send'">- {{ $n(balance, 'decimal') }}</div>
|
||||
<div v-if="type === 'receive'">+ {{ $n(balance, 'decimal') }}</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<!-- Decay-->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
<div>{{ $t('decay.decay') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
<div>- {{ $n(decay.balance, 'decimal') }}</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<!-- Total-->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
<div>{{ $t('decay.total') }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
<div v-if="type === 'send'">
|
||||
<b>- {{ $n(balance + decay.balance, 'decimal') }}</b>
|
||||
</div>
|
||||
<div v-if="type === 'receive'">
|
||||
<b>{{ $n(balance - decay.balance, 'decimal') }}</b>
|
||||
</div>
|
||||
<div v-if="type === 'creation'">
|
||||
<b>- {{ $n(balance - decay.balance, 'decimal') }}</b>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
45
frontend/src/components/Status.spec.js
Normal file
45
frontend/src/components/Status.spec.js
Normal file
@ -0,0 +1,45 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Status from './Status'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('Status', () => {
|
||||
let wrapper
|
||||
|
||||
const mocks = {
|
||||
$n: jest.fn((n) => n),
|
||||
}
|
||||
|
||||
const propsData = {
|
||||
balance: 1234,
|
||||
statusText: 'GDD',
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(Status, { localVue, mocks, propsData })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
describe('balance is pending', () => {
|
||||
it('it displays an en-dash', () => {
|
||||
expect(wrapper.find('div.gdd-status-div').text()).toEqual('— GDD')
|
||||
})
|
||||
})
|
||||
|
||||
describe('balance is loaded', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setProps({
|
||||
pending: false,
|
||||
})
|
||||
})
|
||||
|
||||
it('it displays the ammount of GDD', () => {
|
||||
expect(wrapper.find('div.gdd-status-div').text()).toEqual('1234 GDD')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
24
frontend/src/components/Status.vue
Normal file
24
frontend/src/components/Status.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<div class="gdd-status">
|
||||
<div class="p-0 gdd-status-div">
|
||||
{{ pending ? '—' : $n(balance, 'decimal') }} {{ statusText }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Status',
|
||||
props: {
|
||||
balance: { type: Number, default: 0 },
|
||||
pending: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
statusText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -1,8 +1,11 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import Transaction from './Transaction'
|
||||
import Vue from 'vue'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
const consoleErrorMock = jest.fn()
|
||||
|
||||
describe('Transaction', () => {
|
||||
let wrapper
|
||||
|
||||
@ -27,5 +30,206 @@ describe('Transaction', () => {
|
||||
it('renders the component', () => {
|
||||
expect(wrapper.find('div.gdt-transaction-list-item').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has a collapse button', () => {
|
||||
expect(wrapper.find('button[type="button"].btn-secondary').text()).toBe('i')
|
||||
})
|
||||
|
||||
describe('no valid GDT entry type', () => {
|
||||
beforeEach(async () => {
|
||||
// disable throwing Errors on warnings to catch the warning
|
||||
Vue.config.warnHandler = (w) => {}
|
||||
// eslint-disable-next-line no-console
|
||||
console.error = consoleErrorMock
|
||||
await wrapper.setProps({ gdtEntryType: 'NOT_VALID' })
|
||||
})
|
||||
|
||||
it('throws an error', () => {
|
||||
expect(consoleErrorMock).toBeCalledWith(
|
||||
expect.objectContaining({ message: 'no lines for this type: NOT_VALID' }),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('default entry type FORM', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper.setProps({
|
||||
amount: 100,
|
||||
date: '2021-05-02T17:20:11+00:00',
|
||||
comment: 'This is a comment',
|
||||
factor: 17,
|
||||
gdt: 1700,
|
||||
id: 42,
|
||||
})
|
||||
})
|
||||
|
||||
it('has the heart icon', () => {
|
||||
expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has the description gdt.contribution', () => {
|
||||
expect(wrapper.findAll('div.row').at(0).text()).toContain('gdt.contribution')
|
||||
})
|
||||
|
||||
it('renders the amount of euros', () => {
|
||||
expect(wrapper.findAll('div.row').at(0).text()).toContain('100 €')
|
||||
})
|
||||
|
||||
it('renders the amount of GDT', () => {
|
||||
expect(wrapper.findAll('div.row').at(1).text()).toContain('1700 GDT')
|
||||
})
|
||||
|
||||
it('renders the comment message', () => {
|
||||
expect(wrapper.findAll('div.row').at(2).text()).toContain('This is a comment')
|
||||
})
|
||||
|
||||
it('renders the date', () => {
|
||||
expect(wrapper.findAll('div.row').at(3).text()).toContain('Sun May 02 2021')
|
||||
})
|
||||
|
||||
it('does not show the collapse by default', () => {
|
||||
expect(wrapper.find('div#gdt-collapse-42').isVisible()).toBeFalsy()
|
||||
})
|
||||
|
||||
describe('without comment', () => {
|
||||
it('does not render the message row', async () => {
|
||||
await wrapper.setProps({ comment: undefined })
|
||||
expect(wrapper.findAll('div.row').at(2).text()).toContain('form.date')
|
||||
})
|
||||
})
|
||||
/* how to open the collapse ?????
|
||||
describe('collapse is open', () => {
|
||||
beforeEach(async () => {
|
||||
//console.log(wrapper.html())
|
||||
await wrapper.find('div#gdt-collapse-42').trigger('click')
|
||||
await wrapper.vm.$nextTick()
|
||||
await flushPromises()
|
||||
await wrapper.vm.$nextTick()
|
||||
await flushPromises()
|
||||
//console.log(wrapper.find('[enteractiveclass="collapsing"]').html())
|
||||
})
|
||||
|
||||
it('shows the collapse', () => {
|
||||
//console.log(wrapper.html())
|
||||
expect(wrapper.find('div#gdt-collapse-42').isVisible()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
*/
|
||||
})
|
||||
|
||||
describe('GdtEntryType.CVS', () => {
|
||||
it('behaves as default FORM', async () => {
|
||||
await wrapper.setProps({ gdtEntryType: 'CVS' })
|
||||
expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('GdtEntryType.ELOPAGE', () => {
|
||||
it('behaves as default FORM', async () => {
|
||||
await wrapper.setProps({ gdtEntryType: 'ELOPAGE' })
|
||||
expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('GdtEntryType.DIGISTORE', () => {
|
||||
it('behaves as default FORM', async () => {
|
||||
await wrapper.setProps({ gdtEntryType: 'DIGISTORE' })
|
||||
expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('GdtEntryType.CVS2', () => {
|
||||
it('behaves as default FORM', async () => {
|
||||
await wrapper.setProps({ gdtEntryType: 'CVS2' })
|
||||
expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('GdtEntryType.ELOPAGE_PUBLISHER', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper.setProps({
|
||||
amount: 365.67,
|
||||
date: '2020-04-10T13:28:00+00:00',
|
||||
comment: 'This is a comment',
|
||||
gdtEntryType: 'ELOPAGE_PUBLISHER',
|
||||
factor: 22,
|
||||
gdt: 967.65,
|
||||
id: 42,
|
||||
})
|
||||
})
|
||||
|
||||
it('has the person-check icon', () => {
|
||||
expect(wrapper.find('svg.bi-person-check').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has the description gdt.recruited-member', () => {
|
||||
expect(wrapper.findAll('div.row').at(0).text()).toContain('gdt.recruited-member')
|
||||
})
|
||||
|
||||
it('renders the percentage', () => {
|
||||
expect(wrapper.findAll('div.row').at(0).text()).toContain('5%')
|
||||
})
|
||||
|
||||
it('renders the amount of GDT', () => {
|
||||
expect(wrapper.findAll('div.row').at(1).text()).toContain('365.67 GDT')
|
||||
})
|
||||
|
||||
it('renders the comment message', () => {
|
||||
expect(wrapper.findAll('div.row').at(2).text()).toContain('This is a comment')
|
||||
})
|
||||
|
||||
it('renders the date', () => {
|
||||
expect(wrapper.findAll('div.row').at(3).text()).toContain('Fri Apr 10 2020')
|
||||
})
|
||||
|
||||
it('does not show the collapse by default', () => {
|
||||
expect(wrapper.find('div#gdt-collapse-42').isVisible()).toBeFalsy()
|
||||
})
|
||||
|
||||
describe('without comment', () => {
|
||||
it('does not render the message row', async () => {
|
||||
await wrapper.setProps({ comment: undefined })
|
||||
expect(wrapper.findAll('div.row').at(2).text()).toContain('form.date')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('GdtEntryType.GLOBAL_MODIFICATOR', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper.setProps({
|
||||
amount: 123.45,
|
||||
date: '2020-03-12T13:28:00+00:00',
|
||||
comment: 'This is a comment',
|
||||
gdtEntryType: 'GLOBAL_MODIFICATOR',
|
||||
factor: 19,
|
||||
gdt: 61.23,
|
||||
id: 42,
|
||||
})
|
||||
})
|
||||
|
||||
it('has the gift icon', () => {
|
||||
expect(wrapper.find('svg.bi-gift').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has the description gdt.gdt-received', () => {
|
||||
expect(wrapper.findAll('div.row').at(0).text()).toContain('gdt.gdt-received')
|
||||
})
|
||||
|
||||
it('renders the comment', () => {
|
||||
expect(wrapper.findAll('div.row').at(0).text()).toContain('This is a comment')
|
||||
})
|
||||
|
||||
it('renders the amount of GDT', () => {
|
||||
expect(wrapper.findAll('div.row').at(1).text()).toContain('61.23 GDT')
|
||||
})
|
||||
|
||||
it('renders the date', () => {
|
||||
expect(wrapper.findAll('div.row').at(2).text()).toContain('Thu Mar 12 2020')
|
||||
})
|
||||
|
||||
it('does not show the collapse by default', () => {
|
||||
expect(wrapper.find('div#gdt-collapse-42').isVisible()).toBeFalsy()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="list-group">
|
||||
<div class="list-group-item gdt-transaction-list-item" v-b-toggle="'a' + date + ''">
|
||||
<div class="list-group-item gdt-transaction-list-item" v-b-toggle="collapseId">
|
||||
<!-- icon -->
|
||||
<div class="text-right" style="position: absolute">
|
||||
<b-icon
|
||||
:icon="getLinesByType(gdtEntryType).icon"
|
||||
:class="getLinesByType(gdtEntryType).iconclasses"
|
||||
></b-icon>
|
||||
<b-icon :icon="getLinesByType.icon" :class="getLinesByType.iconclasses"></b-icon>
|
||||
</div>
|
||||
|
||||
<!-- collaps Button -->
|
||||
@ -20,10 +17,10 @@
|
||||
<!-- type -->
|
||||
<b-row>
|
||||
<b-col cols="6" class="text-right">
|
||||
{{ getLinesByType(gdtEntryType).description }}
|
||||
{{ getLinesByType.description }}
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
{{ getLinesByType(gdtEntryType).descriptiontext }}
|
||||
{{ getLinesByType.descriptiontext }}
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
@ -33,7 +30,7 @@
|
||||
{{ $t('gdt.credit') }}
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
{{ getLinesByType(gdtEntryType).credittext }}
|
||||
{{ getLinesByType.credittext }}
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
@ -58,7 +55,7 @@
|
||||
</b-row>
|
||||
|
||||
<!-- collaps trancaction info-->
|
||||
<b-collapse :id="'a' + date + ''" class="mt-2 pb-4">
|
||||
<b-collapse :id="collapseId" class="mt-2 pb-4">
|
||||
<transaction-collapse
|
||||
:amount="amount"
|
||||
:gdtEntryType="gdtEntryType"
|
||||
@ -86,15 +83,17 @@ export default {
|
||||
gdtEntryType: { type: String, default: GdtEntryType.FORM },
|
||||
factor: { type: Number },
|
||||
gdt: { type: Number },
|
||||
id: { type: Number },
|
||||
},
|
||||
computed: {
|
||||
isGlobalModificator: function () {
|
||||
collapseId() {
|
||||
return 'gdt-collapse-' + String(this.id)
|
||||
},
|
||||
isGlobalModificator() {
|
||||
return this.gdtEntryType === GdtEntryType.GLOBAL_MODIFICATOR
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getLinesByType(givenType) {
|
||||
switch (givenType) {
|
||||
getLinesByType() {
|
||||
switch (this.gdtEntryType) {
|
||||
case GdtEntryType.FORM:
|
||||
case GdtEntryType.CVS:
|
||||
case GdtEntryType.ELOPAGE:
|
||||
@ -127,7 +126,7 @@ export default {
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new Error('no lines for this type: ' + givenType)
|
||||
throw new Error('no lines for this type: ' + this.gdtEntryType)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@ -2,8 +2,12 @@ import { mount } from '@vue/test-utils'
|
||||
import TransactionCollapse from './TransactionCollapse'
|
||||
import { GdtEntryType } from '../graphql/enums'
|
||||
|
||||
import Vue from 'vue'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
const consoleErrorMock = jest.fn()
|
||||
|
||||
describe('TransactionCollapse', () => {
|
||||
let wrapper
|
||||
|
||||
@ -16,6 +20,31 @@ describe('TransactionCollapse', () => {
|
||||
return mount(TransactionCollapse, { localVue, mocks, propsData })
|
||||
}
|
||||
|
||||
describe('no valid GDT entry type', () => {
|
||||
beforeEach(async () => {
|
||||
// disable throwing Errors on warnings to catch the warning
|
||||
Vue.config.warnHandler = (w) => {}
|
||||
// eslint-disable-next-line no-console
|
||||
console.error = consoleErrorMock
|
||||
const propsData = {
|
||||
amount: 100,
|
||||
gdt: 110,
|
||||
factor: 22,
|
||||
gdtEntryType: GdtEntryType.FORM,
|
||||
}
|
||||
wrapper = Wrapper(propsData)
|
||||
await wrapper.setProps({ gdtEntryType: 'NOT_VALID' })
|
||||
})
|
||||
|
||||
it('throws an error', () => {
|
||||
expect(consoleErrorMock).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
message: 'no additional transaction info for this type: NOT_VALID',
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('mount with gdtEntryType: FORM', () => {
|
||||
beforeEach(() => {
|
||||
const propsData = {
|
||||
@ -24,7 +53,6 @@ describe('TransactionCollapse', () => {
|
||||
factor: 22,
|
||||
gdtEntryType: GdtEntryType.FORM,
|
||||
}
|
||||
|
||||
wrapper = Wrapper(propsData)
|
||||
})
|
||||
|
||||
@ -41,23 +69,23 @@ describe('TransactionCollapse', () => {
|
||||
})
|
||||
|
||||
it('renders the component collapse-headline', () => {
|
||||
expect(wrapper.find('#collapse-headline').text()).toBe('gdt.calculation')
|
||||
expect(wrapper.find('.collapse-headline').text()).toBe('gdt.calculation')
|
||||
})
|
||||
|
||||
it('renders the component collapse-first', () => {
|
||||
expect(wrapper.find('#collapse-first').text()).toBe('gdt.factor')
|
||||
expect(wrapper.find('.collapse-first').text()).toBe('gdt.factor')
|
||||
})
|
||||
|
||||
it('renders the component collapse-second', () => {
|
||||
expect(wrapper.find('#collapse-second').text()).toBe('gdt.formula')
|
||||
expect(wrapper.find('.collapse-second').text()).toBe('gdt.formula')
|
||||
})
|
||||
|
||||
it('renders the component collapse-firstMath', () => {
|
||||
expect(wrapper.find('#collapse-firstMath').text()).toBe('22 GDT pro €')
|
||||
expect(wrapper.find('.collapse-firstMath').text()).toBe('22 GDT pro €')
|
||||
})
|
||||
|
||||
it('renders the component collapse-secondMath', () => {
|
||||
expect(wrapper.find('#collapse-secondMath').text()).toBe('100 € * 22 GDT / € = 110 GDT')
|
||||
expect(wrapper.find('.collapse-secondMath').text()).toBe('100 € * 22 GDT / € = 110 GDT')
|
||||
})
|
||||
})
|
||||
|
||||
@ -86,23 +114,23 @@ describe('TransactionCollapse', () => {
|
||||
})
|
||||
|
||||
it('renders the component collapse-headline', () => {
|
||||
expect(wrapper.find('#collapse-headline').text()).toBe('gdt.conversion-gdt-euro')
|
||||
expect(wrapper.find('.collapse-headline').text()).toBe('gdt.conversion-gdt-euro')
|
||||
})
|
||||
|
||||
it('renders the component collapse-first', () => {
|
||||
expect(wrapper.find('#collapse-first').text()).toBe('gdt.raise')
|
||||
expect(wrapper.find('.collapse-first').text()).toBe('gdt.raise')
|
||||
})
|
||||
|
||||
it('renders the component collapse-second', () => {
|
||||
expect(wrapper.find('#collapse-second').text()).toBe('gdt.conversion')
|
||||
expect(wrapper.find('.collapse-second').text()).toBe('gdt.conversion')
|
||||
})
|
||||
|
||||
it('renders the component collapse-firstMath', () => {
|
||||
expect(wrapper.find('#collapse-firstMath').text()).toBe('2200 %')
|
||||
expect(wrapper.find('.collapse-firstMath').text()).toBe('2200 %')
|
||||
})
|
||||
|
||||
it('renders the component collapse-secondMath', () => {
|
||||
expect(wrapper.find('#collapse-secondMath').text()).toBe('100 GDT * 2200 % = 2200 GDT')
|
||||
expect(wrapper.find('.collapse-secondMath').text()).toBe('100 GDT * 2200 % = 2200 GDT')
|
||||
})
|
||||
})
|
||||
|
||||
@ -131,23 +159,23 @@ describe('TransactionCollapse', () => {
|
||||
})
|
||||
|
||||
it('renders the component collapse-headline', () => {
|
||||
expect(wrapper.find('#collapse-headline').text()).toBe('gdt.publisher')
|
||||
expect(wrapper.find('.collapse-headline').text()).toBe('gdt.publisher')
|
||||
})
|
||||
|
||||
it('renders the component collapse-first', () => {
|
||||
expect(wrapper.find('#collapse-first').text()).toBe('')
|
||||
expect(wrapper.find('.collapse-first').text()).toBe('')
|
||||
})
|
||||
|
||||
it('renders the component collapse-second', () => {
|
||||
expect(wrapper.find('#collapse-second').text()).toBe('')
|
||||
expect(wrapper.find('.collapse-second').text()).toBe('')
|
||||
})
|
||||
|
||||
it('renders the component collapse-firstMath', () => {
|
||||
expect(wrapper.find('#collapse-firstMath').text()).toBe('')
|
||||
expect(wrapper.find('.collapse-firstMath').text()).toBe('')
|
||||
})
|
||||
|
||||
it('renders the component collapse-secondMath', () => {
|
||||
expect(wrapper.find('#collapse-secondMath').text()).toBe('')
|
||||
expect(wrapper.find('.collapse-secondMath').text()).toBe('')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -4,19 +4,19 @@
|
||||
style="border: 0px; background-color: #f1f1f1"
|
||||
>
|
||||
<b-row class="gdt-list-collapse-header-text text-center pb-3">
|
||||
<b-col id="collapse-headline">
|
||||
<b>{{ getLinesByType(gdtEntryType).headline }}</b>
|
||||
<b-col class="collapse-headline">
|
||||
<b>{{ getLinesByType.headline }}</b>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row class="gdt-list-collapse-box--all">
|
||||
<b-col cols="6" class="text-right collapse-col-left">
|
||||
<div id="collapse-first">{{ getLinesByType(gdtEntryType).first }}</div>
|
||||
<div id="collapse-second">{{ getLinesByType(gdtEntryType).second }}</div>
|
||||
<div class="collapse-first">{{ getLinesByType.first }}</div>
|
||||
<div class="collapse-second">{{ getLinesByType.second }}</div>
|
||||
</b-col>
|
||||
<b-col cols="6" class="collapse-col-right">
|
||||
<div id="collapse-firstMath">{{ getLinesByType(gdtEntryType).firstMath }}</div>
|
||||
<div id="collapse-secondMath">
|
||||
{{ getLinesByType(gdtEntryType).secondMath }}
|
||||
<div class="collapse-firstMath">{{ getLinesByType.firstMath }}</div>
|
||||
<div class="collapse-secondMath">
|
||||
{{ getLinesByType.secondMath }}
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
@ -33,9 +33,9 @@ export default {
|
||||
factor: { type: Number },
|
||||
gdt: { type: Number },
|
||||
},
|
||||
methods: {
|
||||
getLinesByType(givenType) {
|
||||
switch (givenType) {
|
||||
computed: {
|
||||
getLinesByType() {
|
||||
switch (this.gdtEntryType) {
|
||||
case GdtEntryType.FORM:
|
||||
case GdtEntryType.CVS:
|
||||
case GdtEntryType.ELOPAGE:
|
||||
@ -80,7 +80,7 @@ export default {
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new Error('no additional transaction info for this type: ' + givenType)
|
||||
throw new Error('no additional transaction info for this type: ' + this.gdtEntryType)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@ -96,9 +96,10 @@
|
||||
"conversion-gdt-euro": "Umrechnung Euro / Gradido Transform (GDT)",
|
||||
"credit": "Gutschrift",
|
||||
"factor": "Faktor",
|
||||
"formula": "Berechungsformel",
|
||||
"formula": "Berechnungsformel",
|
||||
"funding": "Zu den Förderbeiträgen",
|
||||
"gdt-received": "Gradido Transform (GDT) erhalten",
|
||||
"no-transactions": "Du hast zur Zeit keine Transaktionen",
|
||||
"no-transactions": "Du hast noch keine Gradido Transform (GDT).",
|
||||
"publisher": "Dein geworbenes Mitglied hat einen Beitrag bezahlt",
|
||||
"raise": "Erhöhung",
|
||||
"recruited-member": "Geworbenes Mitglied"
|
||||
@ -109,6 +110,7 @@
|
||||
"logout": "Abmelden",
|
||||
"members_area": "Mitgliederbereich",
|
||||
"message": "hallo gradido !!",
|
||||
"overview": "Übersicht",
|
||||
"privacy_policy": "Datenschutzerklärung",
|
||||
"send": "Senden",
|
||||
"settings": {
|
||||
@ -130,8 +132,8 @@
|
||||
},
|
||||
"newsletter": {
|
||||
"newsletter": "Newsletter",
|
||||
"newsletterFalse": "Du bist aus Newslettersystem ausgetragen.",
|
||||
"newsletterTrue": "Du bist im Newslettersystem eingetraten."
|
||||
"newsletterFalse": "Du erhältst keine Informationen per E-Mail.",
|
||||
"newsletterTrue": "Du erhältst Informationen per E-Mail."
|
||||
},
|
||||
"password": {
|
||||
"change-password": "Passwort ändern",
|
||||
|
||||
@ -97,8 +97,9 @@
|
||||
"credit": "Credit",
|
||||
"factor": "Factor",
|
||||
"formula": "Calculation formula",
|
||||
"funding": "Regarding the funding contributions",
|
||||
"gdt-received": "Gradido Transform (GDT) received",
|
||||
"no-transactions": "You currently have no transactions",
|
||||
"no-transactions": "You do not have Gradido Transform (GDT) yet.",
|
||||
"publisher": "A member you referred has paid a contribution",
|
||||
"raise": "Increase",
|
||||
"recruited-member": "Recruited Member"
|
||||
@ -109,6 +110,7 @@
|
||||
"logout": "Logout",
|
||||
"members_area": "Member's area",
|
||||
"message": "hello gradido !!",
|
||||
"overview": "Overview",
|
||||
"privacy_policy": "Privacy policy",
|
||||
"send": "Send",
|
||||
"settings": {
|
||||
@ -130,8 +132,8 @@
|
||||
},
|
||||
"newsletter": {
|
||||
"newsletter": "Newsletter",
|
||||
"newsletterFalse": "You are unsubscribed from newsletter system.",
|
||||
"newsletterTrue": "You are subscribed to newsletter system."
|
||||
"newsletterFalse": "You will not receive any information by e-mail.",
|
||||
"newsletterTrue": "You will receive information by e-mail."
|
||||
},
|
||||
"password": {
|
||||
"change-password": "Change password",
|
||||
|
||||
@ -6,6 +6,7 @@ import { loadAllRules } from './validation-rules'
|
||||
import { ApolloClient, ApolloLink, InMemoryCache, HttpLink } from 'apollo-boost'
|
||||
import VueApollo from 'vue-apollo'
|
||||
import CONFIG from './config'
|
||||
|
||||
import addNavigationGuards from './routes/guards'
|
||||
|
||||
import { store } from './store/store'
|
||||
|
||||
@ -49,8 +49,8 @@ describe('router', () => {
|
||||
expect(routes.find((r) => r.path === '/').redirect()).toEqual({ path: '/login' })
|
||||
})
|
||||
|
||||
it('has thirteen routes defined', () => {
|
||||
expect(routes).toHaveLength(13)
|
||||
it('has fourteen routes defined', () => {
|
||||
expect(routes).toHaveLength(14)
|
||||
})
|
||||
|
||||
describe('overview', () => {
|
||||
@ -64,6 +64,17 @@ describe('router', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('send', () => {
|
||||
it('requires authorization', () => {
|
||||
expect(routes.find((r) => r.path === '/send').meta.requiresAuth).toBeTruthy()
|
||||
})
|
||||
|
||||
it('loads the "Send" component', async () => {
|
||||
const component = await routes.find((r) => r.path === '/send').component()
|
||||
expect(component.default.name).toBe('SendOverview')
|
||||
})
|
||||
})
|
||||
|
||||
describe('profile', () => {
|
||||
it('requires authorization', () => {
|
||||
expect(routes.find((r) => r.path === '/profile').meta.requiresAuth).toBeTruthy()
|
||||
|
||||
@ -14,6 +14,13 @@ const routes = [
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/send',
|
||||
component: () => import('../views/Pages/SendOverview.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
component: () => import('../views/Pages/UserProfileOverview.vue'),
|
||||
|
||||
@ -4,6 +4,8 @@ import DashboardLayoutGdd from './DashboardLayout_gdd'
|
||||
|
||||
jest.useFakeTimers()
|
||||
|
||||
jest.setTimeout(30000)
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
const storeDispatchMock = jest.fn()
|
||||
@ -87,33 +89,40 @@ describe('DashboardLayoutGdd', () => {
|
||||
navbar = wrapper.findAll('ul.navbar-nav').at(0)
|
||||
})
|
||||
|
||||
it('has three items in the navbar', () => {
|
||||
expect(navbar.findAll('ul > a')).toHaveLength(3)
|
||||
it('has four items in the navbar', () => {
|
||||
expect(navbar.findAll('ul > a')).toHaveLength(4)
|
||||
})
|
||||
|
||||
it('has first item "send" in navbar', () => {
|
||||
expect(navbar.findAll('ul > a').at(0).text()).toEqual('send')
|
||||
it('has first item "overview" in navbar', () => {
|
||||
expect(navbar.findAll('ul > a').at(0).text()).toEqual('overview')
|
||||
})
|
||||
|
||||
it('has first item "send" linked to overview in navbar', () => {
|
||||
navbar.findAll('ul > a').at(0).trigger('click')
|
||||
expect(wrapper.findComponent(RouterLinkStub).props().to).toBe('/overview')
|
||||
it('has first item "overview" linked to overview in navbar', () => {
|
||||
expect(navbar.findAll('ul > a > a').at(0).attributes('href')).toBe('/overview')
|
||||
})
|
||||
|
||||
it('has second item "transactions" in navbar', () => {
|
||||
expect(navbar.findAll('ul > a').at(1).text()).toEqual('transactions')
|
||||
it('has second item "send" in navbar', () => {
|
||||
expect(navbar.findAll('ul > a').at(1).text()).toEqual('send')
|
||||
})
|
||||
|
||||
it('has second item "transactions" linked to transactions in navbar', async () => {
|
||||
expect(wrapper.findAll('a').at(3).attributes('href')).toBe('/transactions')
|
||||
it('has second item "send" linked to /send in navbar', () => {
|
||||
expect(wrapper.findAll('ul > a > a').at(1).attributes('href')).toBe('/send')
|
||||
})
|
||||
|
||||
it('has three items in the navbar', () => {
|
||||
expect(navbar.findAll('ul > a')).toHaveLength(3)
|
||||
it('has third item "transactions" in navbar', () => {
|
||||
expect(navbar.findAll('ul > a').at(2).text()).toEqual('transactions')
|
||||
})
|
||||
|
||||
it('has third item "My profile" linked to profile in navbar', async () => {
|
||||
expect(wrapper.findAll('a').at(5).attributes('href')).toBe('/profile')
|
||||
it('has third item "transactions" linked to transactions in navbar', async () => {
|
||||
expect(wrapper.findAll('ul > a > a').at(2).attributes('href')).toBe('/transactions')
|
||||
})
|
||||
|
||||
it('has fourth item "My profile" in navbar', () => {
|
||||
expect(navbar.findAll('ul > a').at(3).text()).toEqual('site.navbar.my-profil')
|
||||
})
|
||||
|
||||
it('has fourth item "My profile" linked to profile in navbar', async () => {
|
||||
expect(wrapper.findAll('ul > a > a').at(3).attributes('href')).toBe('/profile')
|
||||
})
|
||||
|
||||
it('has a link to the members area', () => {
|
||||
@ -137,6 +146,7 @@ describe('DashboardLayoutGdd', () => {
|
||||
})
|
||||
await wrapper.findComponent({ name: 'sidebar' }).vm.$emit('logout')
|
||||
await flushPromises()
|
||||
await wrapper.vm.$nextTick()
|
||||
})
|
||||
|
||||
it('calls the API', async () => {
|
||||
@ -168,6 +178,17 @@ describe('DashboardLayoutGdd', () => {
|
||||
it('redirects to login page', () => {
|
||||
expect(routerPushMock).toBeCalledWith('/login')
|
||||
})
|
||||
|
||||
describe('redirect to login already done', () => {
|
||||
beforeEach(() => {
|
||||
mocks.$router.currentRoute.path = '/login'
|
||||
jest.resetAllMocks()
|
||||
})
|
||||
|
||||
it('does not call the redirect to login', () => {
|
||||
expect(routerPushMock).not.toBeCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('update balance', () => {
|
||||
|
||||
@ -2,11 +2,16 @@
|
||||
<div>
|
||||
<side-bar @logout="logout" :balance="balance" :pending="pending">
|
||||
<template slot="links">
|
||||
<p></p>
|
||||
<sidebar-item
|
||||
:link="{
|
||||
name: $t('overview'),
|
||||
path: '/overview',
|
||||
}"
|
||||
></sidebar-item>
|
||||
<sidebar-item
|
||||
:link="{
|
||||
name: $t('send'),
|
||||
path: '/overview',
|
||||
path: '/send',
|
||||
}"
|
||||
></sidebar-item>
|
||||
<sidebar-item
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import AccountOverview from './AccountOverview'
|
||||
|
||||
const sendMock = jest.fn()
|
||||
sendMock.mockResolvedValue('success')
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
window.scrollTo = jest.fn()
|
||||
@ -11,26 +8,16 @@ window.scrollTo = jest.fn()
|
||||
describe('AccountOverview', () => {
|
||||
let wrapper
|
||||
|
||||
const propsData = {
|
||||
balance: 123.45,
|
||||
transactionCount: 1,
|
||||
}
|
||||
|
||||
const mocks = {
|
||||
$t: jest.fn((t) => t),
|
||||
$n: jest.fn((n) => String(n)),
|
||||
$store: {
|
||||
state: {
|
||||
email: 'sender@example.org',
|
||||
},
|
||||
},
|
||||
$apollo: {
|
||||
mutate: sendMock,
|
||||
},
|
||||
$n: jest.fn(),
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(AccountOverview, { localVue, mocks, propsData })
|
||||
return mount(AccountOverview, {
|
||||
localVue,
|
||||
mocks,
|
||||
})
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
@ -38,97 +25,21 @@ describe('AccountOverview', () => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a status line', () => {
|
||||
expect(wrapper.find('div.gdd-status').exists()).toBeTruthy()
|
||||
it('has a status gdd-status-gdd', () => {
|
||||
expect(wrapper.find('div.gdd-status-gdd').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has a send field', () => {
|
||||
expect(wrapper.find('div.gdd-send').exists()).toBeTruthy()
|
||||
it('has a status gdd-status-gdt', () => {
|
||||
expect(wrapper.find('div.gdd-status-gdt').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has a transactions table', () => {
|
||||
expect(wrapper.find('div.gdd-transaction-list').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
describe('transaction form', () => {
|
||||
it('steps forward in the dialog', async () => {
|
||||
await wrapper.findComponent({ name: 'TransactionForm' }).vm.$emit('set-transaction', {
|
||||
email: 'user@example.org',
|
||||
amount: 23.45,
|
||||
memo: 'Make the best of it!',
|
||||
})
|
||||
expect(wrapper.findComponent({ name: 'TransactionConfirmation' }).exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('confirm transaction', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setData({
|
||||
currentTransactionStep: 1,
|
||||
transactionData: {
|
||||
email: 'user@example.org',
|
||||
amount: 23.45,
|
||||
memo: 'Make the best of it!',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('resets the transaction process when on-reset is emitted', async () => {
|
||||
await wrapper.findComponent({ name: 'TransactionConfirmation' }).vm.$emit('on-reset')
|
||||
expect(wrapper.findComponent({ name: 'TransactionForm' }).exists()).toBeTruthy()
|
||||
expect(wrapper.vm.transactionData).toEqual({
|
||||
email: '',
|
||||
amount: 0,
|
||||
memo: '',
|
||||
})
|
||||
})
|
||||
|
||||
describe('transaction is confirmed and server response is success', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
await wrapper
|
||||
.findComponent({ name: 'TransactionConfirmation' })
|
||||
.vm.$emit('send-transaction')
|
||||
})
|
||||
|
||||
it('calls the API when send-transaction is emitted', async () => {
|
||||
expect(sendMock).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
variables: {
|
||||
email: 'user@example.org',
|
||||
amount: 23.45,
|
||||
memo: 'Make the best of it!',
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('emits update-balance', () => {
|
||||
expect(wrapper.emitted('update-balance')).toBeTruthy()
|
||||
expect(wrapper.emitted('update-balance')).toEqual([[23.45]])
|
||||
})
|
||||
|
||||
it('shows the succes page', () => {
|
||||
expect(wrapper.find('div.card-body').text()).toContain('form.send_transaction_success')
|
||||
})
|
||||
})
|
||||
|
||||
describe('transaction is confirmed and server response is error', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
sendMock.mockRejectedValue({ message: 'receiver not found' })
|
||||
await wrapper
|
||||
.findComponent({ name: 'TransactionConfirmation' })
|
||||
.vm.$emit('send-transaction')
|
||||
})
|
||||
|
||||
it('shows the error page', () => {
|
||||
expect(wrapper.find('div.card-body').text()).toContain('form.send_transaction_error')
|
||||
})
|
||||
|
||||
it('shows recipient not found', () => {
|
||||
expect(wrapper.text()).toContain('transaction.receiverNotFound')
|
||||
})
|
||||
describe('timestamp updates', () => {
|
||||
it('emits update transactions', async () => {
|
||||
expect(wrapper.emitted('update-transactions')).toHaveLength(1)
|
||||
await wrapper.setData({ timestamp: Date.now() })
|
||||
expect(wrapper.emitted('update-transactions')).toHaveLength(2)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,83 +1,59 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-container fluid>
|
||||
<gdd-status
|
||||
v-if="showContext"
|
||||
:pending="pending"
|
||||
:balance="balance"
|
||||
:gdt-balance="GdtBalance"
|
||||
/>
|
||||
<b-row>
|
||||
<b-col class="col-6">
|
||||
<b-row>
|
||||
<b-col class="col-11 bg-gray text-white p-3">
|
||||
<status
|
||||
class="gdd-status-gdd"
|
||||
:pending="pending"
|
||||
:balance="balance"
|
||||
status-text="GDD"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
<b-col class="col-6 text-right">
|
||||
<b-row>
|
||||
<b-col class="bg-white text-gray p-3">
|
||||
<status
|
||||
class="gdd-status-gdt"
|
||||
:pending="pending"
|
||||
:balance="GdtBalance"
|
||||
status-text="GDT"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<br />
|
||||
<gdd-send :currentTransactionStep="currentTransactionStep">
|
||||
<template #transaction-form>
|
||||
<transaction-form :balance="balance" @set-transaction="setTransaction"></transaction-form>
|
||||
</template>
|
||||
<template #transaction-confirmation>
|
||||
<transaction-confirmation
|
||||
:email="transactionData.email"
|
||||
:amount="transactionData.amount"
|
||||
:memo="transactionData.memo"
|
||||
:loading="loading"
|
||||
@send-transaction="sendTransaction"
|
||||
@on-reset="onReset"
|
||||
></transaction-confirmation>
|
||||
</template>
|
||||
<template #transaction-result>
|
||||
<transaction-result
|
||||
:error="error"
|
||||
:errorResult="errorResult"
|
||||
@on-reset="onReset"
|
||||
></transaction-result>
|
||||
</template>
|
||||
</gdd-send>
|
||||
<hr />
|
||||
<gdd-transaction-list
|
||||
v-if="showContext"
|
||||
:transactions="transactions"
|
||||
:pageSize="5"
|
||||
:timestamp="timestamp"
|
||||
:transaction-count="transactionCount"
|
||||
@update-transactions="updateTransactions"
|
||||
/>
|
||||
<gdd-transaction-list-footer v-if="showContext" :count="transactionCount" />
|
||||
<gdd-transaction-list-footer :count="transactionCount" />
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import GddStatus from './AccountOverview/GddStatus.vue'
|
||||
import GddSend from './AccountOverview/GddSend.vue'
|
||||
import Status from '../../components/Status.vue'
|
||||
import GddTransactionList from './AccountOverview/GddTransactionList.vue'
|
||||
import GddTransactionListFooter from './AccountOverview/GddTransactionListFooter.vue'
|
||||
import TransactionForm from './AccountOverview/GddSend/TransactionForm.vue'
|
||||
import TransactionConfirmation from './AccountOverview/GddSend/TransactionConfirmation.vue'
|
||||
import TransactionResult from './AccountOverview/GddSend/TransactionResult.vue'
|
||||
import { sendCoins } from '../../graphql/mutations.js'
|
||||
|
||||
const EMPTY_TRANSACTION_DATA = {
|
||||
email: '',
|
||||
amount: 0,
|
||||
memo: '',
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'Overview',
|
||||
components: {
|
||||
GddStatus,
|
||||
GddSend,
|
||||
Status,
|
||||
GddTransactionList,
|
||||
GddTransactionListFooter,
|
||||
TransactionForm,
|
||||
TransactionConfirmation,
|
||||
TransactionResult,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timestamp: Date.now(),
|
||||
transactionData: { ...EMPTY_TRANSACTION_DATA },
|
||||
error: false,
|
||||
errorResult: '',
|
||||
currentTransactionStep: 0,
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
@ -92,38 +68,7 @@ export default {
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
showContext() {
|
||||
return this.currentTransactionStep === 0
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setTransaction(data) {
|
||||
this.transactionData = { ...data }
|
||||
this.currentTransactionStep = 1
|
||||
},
|
||||
async sendTransaction() {
|
||||
this.loading = true
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: sendCoins,
|
||||
variables: this.transactionData,
|
||||
})
|
||||
.then(() => {
|
||||
this.error = false
|
||||
this.$emit('update-balance', this.transactionData.amount)
|
||||
})
|
||||
.catch((err) => {
|
||||
this.errorResult = err.message
|
||||
this.error = true
|
||||
})
|
||||
this.currentTransactionStep = 2
|
||||
this.loading = false
|
||||
},
|
||||
onReset() {
|
||||
this.transactionData = { ...EMPTY_TRANSACTION_DATA }
|
||||
this.currentTransactionStep = 0
|
||||
},
|
||||
updateTransactions(pagination) {
|
||||
this.$emit('update-transactions', pagination)
|
||||
},
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import GddStatus from './GddStatus'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('GddStatus', () => {
|
||||
let wrapper
|
||||
|
||||
const mocks = {
|
||||
$n: jest.fn((n) => n),
|
||||
}
|
||||
|
||||
const propsData = {
|
||||
balance: 1234,
|
||||
GdtBalance: 9876,
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(GddStatus, { localVue, mocks, propsData })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
describe('balance is loading', () => {
|
||||
it('it displays em-dash as the ammount of GDD', () => {
|
||||
expect(wrapper.findAll('div.card-body').at(0).text()).toEqual('— GDD')
|
||||
})
|
||||
|
||||
it('it displays em-dash as the ammount of GDT', () => {
|
||||
expect(wrapper.findAll('div.card-body').at(1).text()).toEqual('— GDT')
|
||||
})
|
||||
})
|
||||
|
||||
describe('balance is loaded', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setProps({
|
||||
pending: false,
|
||||
})
|
||||
})
|
||||
|
||||
it('it displays the ammount of GDD', () => {
|
||||
expect(wrapper.findAll('div.card-body').at(0).text()).toEqual('1234 GDD')
|
||||
})
|
||||
|
||||
it('it displays the ammount of GDT', () => {
|
||||
expect(wrapper.findAll('div.card-body').at(1).text()).toEqual('9876 GDT')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,30 +0,0 @@
|
||||
<template>
|
||||
<div class="gdd-status">
|
||||
<b-row>
|
||||
<b-col class="p-0">
|
||||
<b-card class="p-0" style="background-color: #ebebeba3 !important">
|
||||
{{ pending ? '—' : $n(balance, 'decimal') }} GDD
|
||||
</b-card>
|
||||
</b-col>
|
||||
<b-col class="pr-0">
|
||||
<b-card class="p-0 text-right" style="background-color: #ebebeba3 !important">
|
||||
{{ pending ? '—' : $n(GdtBalance, 'decimal') }} GDT
|
||||
</b-card>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GddStatus',
|
||||
props: {
|
||||
balance: { type: Number, default: 0 },
|
||||
GdtBalance: { type: Number, default: 0 },
|
||||
pending: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -138,7 +138,7 @@ describe('GddTransactionList', () => {
|
||||
|
||||
it('shows the decay calculation', () => {
|
||||
expect(transaction.findAll('div.gdd-transaction-list-item-decay').at(0).text()).toContain(
|
||||
'-0.5',
|
||||
'- 0.5',
|
||||
)
|
||||
})
|
||||
})
|
||||
@ -228,7 +228,7 @@ describe('GddTransactionList', () => {
|
||||
|
||||
it('shows the decay calculation', () => {
|
||||
expect(transaction.findAll('.gdd-transaction-list-item-decay').at(0).text()).toContain(
|
||||
'-1.5',
|
||||
'- 1.5',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@ -124,7 +124,7 @@
|
||||
:per-page="pageSize"
|
||||
:total-rows="transactionCount"
|
||||
></pagination-buttons>
|
||||
<div v-if="transactions.length === 0" class="mt-4 text-center">
|
||||
<div v-if="transactionCount === 0" class="mt-4 text-center">
|
||||
<span>{{ $t('transaction.nullTransactions') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -198,4 +198,8 @@ export default {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.gdd-transaction-list-item {
|
||||
outline: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -7,41 +7,8 @@ const localVue = global.localVue
|
||||
const apolloMock = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
listGDTEntries: {
|
||||
count: 4,
|
||||
gdtEntries: [
|
||||
{
|
||||
amount: 100,
|
||||
gdt: 1700,
|
||||
factor: 17,
|
||||
comment: '',
|
||||
date: '2021-05-02T17:20:11+00:00',
|
||||
gdtEntryType: GdtEntryType.FORM,
|
||||
},
|
||||
{
|
||||
amount: 1810,
|
||||
gdt: 362,
|
||||
factor: 0.2,
|
||||
comment: 'Dezember 20',
|
||||
date: '2020-12-31T12:00:00+00:00',
|
||||
gdtEntryType: GdtEntryType.GLOBAL_MODIFICATOR,
|
||||
},
|
||||
{
|
||||
amount: 100,
|
||||
gdt: 1700,
|
||||
factor: 17,
|
||||
comment: '',
|
||||
date: '2020-05-07T17:00:00+00:00',
|
||||
gdtEntryType: GdtEntryType.FORM,
|
||||
},
|
||||
{
|
||||
amount: 100,
|
||||
gdt: 110,
|
||||
factor: 22,
|
||||
comment: '',
|
||||
date: '2020-04-10T13:28:00+00:00',
|
||||
gdtEntryType: GdtEntryType.ELOPAGE_PUBLISHER,
|
||||
},
|
||||
],
|
||||
count: 0,
|
||||
gdtEntries: [],
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -51,10 +18,18 @@ const windowScrollToMock = jest.fn()
|
||||
|
||||
window.scrollTo = windowScrollToMock
|
||||
|
||||
describe('GdtTransactionList', () => {
|
||||
const state = {
|
||||
language: 'en',
|
||||
}
|
||||
|
||||
describe('GdtTransactionList ', () => {
|
||||
let wrapper
|
||||
|
||||
const mocks = {
|
||||
$store: {
|
||||
state,
|
||||
commit: jest.fn(),
|
||||
},
|
||||
$i18n: {
|
||||
locale: 'en',
|
||||
},
|
||||
@ -73,15 +48,80 @@ describe('GdtTransactionList', () => {
|
||||
return mount(GdtTransactionList, { localVue, mocks })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
describe('mount - When no transactions are loaded', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('renders the funding button ', () => {
|
||||
expect(wrapper.find('.gdt-funding').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('links to https://gradido.net/en/memberships/ when clicking', async () => {
|
||||
expect(wrapper.find('.gdt-funding').attributes('href')).toBe(
|
||||
'https://gradido.net/' + state.language + '/memberships/',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('mount - When transactions are loaded', () => {
|
||||
beforeEach(() => {
|
||||
apolloMock.mockResolvedValue({
|
||||
data: {
|
||||
listGDTEntries: {
|
||||
count: 4,
|
||||
gdtEntries: [
|
||||
{
|
||||
id: 1,
|
||||
amount: 100,
|
||||
gdt: 1700,
|
||||
factor: 17,
|
||||
comment: '',
|
||||
date: '2021-05-02T17:20:11+00:00',
|
||||
gdtEntryType: GdtEntryType.FORM,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
amount: 1810,
|
||||
gdt: 362,
|
||||
factor: 0.2,
|
||||
comment: 'Dezember 20',
|
||||
date: '2020-12-31T12:00:00+00:00',
|
||||
gdtEntryType: GdtEntryType.GLOBAL_MODIFICATOR,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
amount: 100,
|
||||
gdt: 1700,
|
||||
factor: 17,
|
||||
comment: '',
|
||||
date: '2020-05-07T17:00:00+00:00',
|
||||
gdtEntryType: GdtEntryType.FORM,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
amount: 100,
|
||||
gdt: 110,
|
||||
factor: 22,
|
||||
comment: '',
|
||||
date: '2020-04-10T13:28:00+00:00',
|
||||
gdtEntryType: GdtEntryType.ELOPAGE_PUBLISHER,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
})
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('renders the component', () => {
|
||||
expect(wrapper.find('div.gdt-transaction-list').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('does not render the funding button ', () => {
|
||||
expect(wrapper.find('.gdt-funding').exists()).toBe(false)
|
||||
})
|
||||
|
||||
describe('server returns valid data', () => {
|
||||
it('calls the API', async () => {
|
||||
await wrapper.vm.$nextTick()
|
||||
|
||||
@ -1,21 +1,17 @@
|
||||
<template>
|
||||
<div class="gdt-transaction-list">
|
||||
<div class="list-group" style="background-color: #fff">
|
||||
<div v-if="transactionGdtCount === 0">
|
||||
<div class="list-group">
|
||||
<div v-if="transactionGdtCount === 0" class="text-center">
|
||||
{{ $t('gdt.no-transactions') }}
|
||||
<hr />
|
||||
<b-button class="gdt-funding" :href="link" target="_blank">
|
||||
{{ $t('gdt.funding') }}
|
||||
</b-button>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
v-for="{
|
||||
transactionId,
|
||||
amount,
|
||||
date,
|
||||
comment,
|
||||
gdtEntryType,
|
||||
factor,
|
||||
gdt,
|
||||
} in transactionsGdt"
|
||||
:key="transactionId"
|
||||
v-for="{ id, amount, date, comment, gdtEntryType, factor, gdt } in transactionsGdt"
|
||||
:key="id"
|
||||
>
|
||||
<transaction
|
||||
:amount="amount"
|
||||
@ -24,6 +20,7 @@
|
||||
:gdtEntryType="gdtEntryType"
|
||||
:factor="factor"
|
||||
:gdt="gdt"
|
||||
:id="id"
|
||||
></transaction>
|
||||
</div>
|
||||
</div>
|
||||
@ -52,6 +49,7 @@ export default {
|
||||
transactionGdtCount: { type: Number, default: 0 },
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
link: 'https://gradido.net/' + this.$store.state.language + '/memberships/',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -97,4 +95,8 @@ export default {
|
||||
.nav-tabs .nav-item.show .nav-link {
|
||||
background-color: #f8f9fe38;
|
||||
}
|
||||
|
||||
.gdt-transaction-list-item {
|
||||
outline: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -5,10 +5,10 @@
|
||||
<div class="header-body text-center mb-7">
|
||||
<b-row class="justify-content-center">
|
||||
<b-col xl="5" lg="6" md="8" class="px-2">
|
||||
<h1>{{ $t('checkEmail.title') }}</h1>
|
||||
<h1>{{ $t('site.checkEmail.title') }}</h1>
|
||||
<div class="pb-4" v-if="!pending">
|
||||
<span v-if="!authenticated">
|
||||
{{ $t('checkEmail.errorText') }}
|
||||
{{ $t('site.checkEmail.errorText') }}
|
||||
</span>
|
||||
</div>
|
||||
</b-col>
|
||||
|
||||
@ -205,12 +205,6 @@ export default {
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
this.form.email = ''
|
||||
this.form.firstname = ''
|
||||
this.form.lastname = ''
|
||||
this.form.password.password = ''
|
||||
this.form.password.passwordRepeat = ''
|
||||
this.language = ''
|
||||
this.$router.push('/thx/register')
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -226,7 +220,6 @@ export default {
|
||||
this.form.lastname = ''
|
||||
this.form.password.password = ''
|
||||
this.form.password.passwordRepeat = ''
|
||||
this.language = ''
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
||||
135
frontend/src/views/Pages/SendOverview.spec.js
Normal file
135
frontend/src/views/Pages/SendOverview.spec.js
Normal file
@ -0,0 +1,135 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import SendOverview from './SendOverview'
|
||||
|
||||
const sendMock = jest.fn()
|
||||
sendMock.mockResolvedValue('success')
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
// window.scrollTo = jest.fn()
|
||||
|
||||
describe('SendOverview', () => {
|
||||
let wrapper
|
||||
|
||||
const propsData = {
|
||||
balance: 123.45,
|
||||
transactionCount: 1,
|
||||
}
|
||||
|
||||
const mocks = {
|
||||
$t: jest.fn((t) => t),
|
||||
$n: jest.fn((n) => String(n)),
|
||||
$store: {
|
||||
state: {
|
||||
email: 'sender@example.org',
|
||||
},
|
||||
},
|
||||
$apollo: {
|
||||
mutate: sendMock,
|
||||
},
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
return mount(SendOverview, { localVue, mocks, propsData })
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('has a status GDD line gdd-status-gdd', () => {
|
||||
expect(wrapper.find('div.gdd-status-gdd').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
it('has a send field', () => {
|
||||
expect(wrapper.find('div.gdd-send').exists()).toBeTruthy()
|
||||
})
|
||||
|
||||
// it('has a transactions table', () => {
|
||||
// expect(wrapper.find('div.gdd-transaction-list').exists()).toBeTruthy()
|
||||
// })
|
||||
|
||||
describe('transaction form', () => {
|
||||
it('steps forward in the dialog', async () => {
|
||||
await wrapper.findComponent({ name: 'TransactionForm' }).vm.$emit('set-transaction', {
|
||||
email: 'user@example.org',
|
||||
amount: 23.45,
|
||||
memo: 'Make the best of it!',
|
||||
})
|
||||
expect(wrapper.findComponent({ name: 'TransactionConfirmation' }).exists()).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
describe('confirm transaction', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.setData({
|
||||
currentTransactionStep: 1,
|
||||
transactionData: {
|
||||
email: 'user@example.org',
|
||||
amount: 23.45,
|
||||
memo: 'Make the best of it!',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('resets the transaction process when on-reset is emitted', async () => {
|
||||
await wrapper.findComponent({ name: 'TransactionConfirmation' }).vm.$emit('on-reset')
|
||||
expect(wrapper.findComponent({ name: 'TransactionForm' }).exists()).toBeTruthy()
|
||||
expect(wrapper.vm.transactionData).toEqual({
|
||||
email: 'user@example.org',
|
||||
amount: 23.45,
|
||||
memo: 'Make the best of it!',
|
||||
})
|
||||
})
|
||||
|
||||
describe('transaction is confirmed and server response is success', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
await wrapper
|
||||
.findComponent({ name: 'TransactionConfirmation' })
|
||||
.vm.$emit('send-transaction')
|
||||
})
|
||||
|
||||
it('calls the API when send-transaction is emitted', async () => {
|
||||
expect(sendMock).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
variables: {
|
||||
email: 'user@example.org',
|
||||
amount: 23.45,
|
||||
memo: 'Make the best of it!',
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('emits update-balance', () => {
|
||||
expect(wrapper.emitted('update-balance')).toBeTruthy()
|
||||
expect(wrapper.emitted('update-balance')).toEqual([[23.45]])
|
||||
})
|
||||
|
||||
it('shows the succes page', () => {
|
||||
expect(wrapper.find('div.card-body').text()).toContain('form.send_transaction_success')
|
||||
})
|
||||
})
|
||||
|
||||
describe('transaction is confirmed and server response is error', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
sendMock.mockRejectedValue({ message: 'receiver not found' })
|
||||
await wrapper
|
||||
.findComponent({ name: 'TransactionConfirmation' })
|
||||
.vm.$emit('send-transaction')
|
||||
})
|
||||
|
||||
it('shows the error page', () => {
|
||||
expect(wrapper.find('div.card-body').text()).toContain('form.send_transaction_error')
|
||||
})
|
||||
|
||||
it('shows recipient not found', () => {
|
||||
expect(wrapper.text()).toContain('transaction.receiverNotFound')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
122
frontend/src/views/Pages/SendOverview.vue
Normal file
122
frontend/src/views/Pages/SendOverview.vue
Normal file
@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-container fluid>
|
||||
<b-row>
|
||||
<b-col class="bg-gray text-white text-center p-3">
|
||||
<status
|
||||
class="gdd-status-gdd"
|
||||
v-if="showContext"
|
||||
:pending="pending"
|
||||
:balance="balance"
|
||||
status-text="GDD"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
|
||||
<br />
|
||||
<gdd-send :currentTransactionStep="currentTransactionStep">
|
||||
<template #transaction-form>
|
||||
<transaction-form :balance="balance" @set-transaction="setTransaction"></transaction-form>
|
||||
</template>
|
||||
<template #transaction-confirmation>
|
||||
<transaction-confirmation
|
||||
:email="transactionData.email"
|
||||
:amount="transactionData.amount"
|
||||
:memo="transactionData.memo"
|
||||
:loading="loading"
|
||||
@send-transaction="sendTransaction"
|
||||
@on-reset="onReset"
|
||||
></transaction-confirmation>
|
||||
</template>
|
||||
<template #transaction-result>
|
||||
<transaction-result
|
||||
:error="error"
|
||||
:errorResult="errorResult"
|
||||
@on-reset="onReset"
|
||||
></transaction-result>
|
||||
</template>
|
||||
</gdd-send>
|
||||
<hr />
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Status from '../../components/Status.vue'
|
||||
import GddSend from './SendOverview/GddSend.vue'
|
||||
|
||||
import TransactionForm from './SendOverview/GddSend/TransactionForm.vue'
|
||||
import TransactionConfirmation from './SendOverview/GddSend/TransactionConfirmation.vue'
|
||||
import TransactionResult from './SendOverview/GddSend/TransactionResult.vue'
|
||||
import { sendCoins } from '../../graphql/mutations.js'
|
||||
|
||||
const EMPTY_TRANSACTION_DATA = {
|
||||
email: '',
|
||||
amount: 0,
|
||||
memo: '',
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'SendOverview',
|
||||
components: {
|
||||
Status,
|
||||
GddSend,
|
||||
|
||||
TransactionForm,
|
||||
TransactionConfirmation,
|
||||
TransactionResult,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
transactionData: { ...EMPTY_TRANSACTION_DATA },
|
||||
error: false,
|
||||
errorResult: '',
|
||||
currentTransactionStep: 0,
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
balance: { type: Number, default: 0 },
|
||||
GdtBalance: { type: Number, default: 0 },
|
||||
transactions: {
|
||||
default: () => [],
|
||||
},
|
||||
|
||||
pending: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
showContext() {
|
||||
return this.currentTransactionStep === 0
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setTransaction(data) {
|
||||
this.transactionData = { ...data }
|
||||
this.currentTransactionStep = 1
|
||||
},
|
||||
async sendTransaction() {
|
||||
this.loading = true
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: sendCoins,
|
||||
variables: this.transactionData,
|
||||
})
|
||||
.then(() => {
|
||||
this.error = false
|
||||
this.$emit('update-balance', this.transactionData.amount)
|
||||
})
|
||||
.catch((err) => {
|
||||
this.errorResult = err.message
|
||||
this.error = true
|
||||
})
|
||||
this.currentTransactionStep = 2
|
||||
this.loading = false
|
||||
},
|
||||
onReset() {
|
||||
this.currentTransactionStep = 0
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -62,4 +62,8 @@ export default {
|
||||
background-color: aquamarine;
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
.nav-tabs > li > a {
|
||||
outline: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1735,13 +1735,6 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.3.0"
|
||||
|
||||
"@types/chart.js@^2.7.55":
|
||||
version "2.9.30"
|
||||
resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.30.tgz#34b99897f4f5ef0f74c8fe4ced70ac52b4d752dd"
|
||||
integrity sha512-EgjxUUZFvf6ls3kW2CwyrnSJhgyKxgwrlp/W5G9wqyPEO9iFatO63zAA7L24YqgMxiDjQ+tG7ODU+2yWH91lPg==
|
||||
dependencies:
|
||||
moment "^2.10.2"
|
||||
|
||||
"@types/d3@3.5.38":
|
||||
version "3.5.38"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3/-/d3-3.5.38.tgz#76f8f2e9159ae562965b2fa0e6fbee1aa643a1bc"
|
||||
@ -3823,29 +3816,6 @@ chardet@^0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
|
||||
integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=
|
||||
|
||||
chart.js@^2.9.3:
|
||||
version "2.9.4"
|
||||
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.4.tgz#0827f9563faffb2dc5c06562f8eb10337d5b9684"
|
||||
integrity sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==
|
||||
dependencies:
|
||||
chartjs-color "^2.1.0"
|
||||
moment "^2.10.2"
|
||||
|
||||
chartjs-color-string@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71"
|
||||
integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==
|
||||
dependencies:
|
||||
color-name "^1.0.0"
|
||||
|
||||
chartjs-color@^2.1.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.4.1.tgz#6118bba202fe1ea79dd7f7c0f9da93467296c3b0"
|
||||
integrity sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==
|
||||
dependencies:
|
||||
chartjs-color-string "^0.6.0"
|
||||
color-convert "^1.9.3"
|
||||
|
||||
check-types@^8.0.3:
|
||||
version "8.0.3"
|
||||
resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552"
|
||||
@ -4073,7 +4043,7 @@ collection-visit@^1.0.0:
|
||||
map-visit "^1.0.0"
|
||||
object-visit "^1.0.0"
|
||||
|
||||
color-convert@^1.9.0, color-convert@^1.9.1, color-convert@^1.9.3:
|
||||
color-convert@^1.9.0, color-convert@^1.9.1:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
@ -9620,7 +9590,7 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
moment@^2.10.2, moment@^2.19.2:
|
||||
moment@^2.19.2:
|
||||
version "2.29.1"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
||||
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
||||
@ -13469,13 +13439,6 @@ vue-bootstrap-typeahead@^0.2.6:
|
||||
resize-observer-polyfill "^1.5.0"
|
||||
vue "^2.5.17"
|
||||
|
||||
vue-chartjs@^3.5.0:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-chartjs/-/vue-chartjs-3.5.1.tgz#d25e845708f7744ae51bed9d23a975f5f8fc6529"
|
||||
integrity sha512-foocQbJ7FtveICxb4EV5QuVpo6d8CmZFmAopBppDIGKY+esJV8IJgwmEW0RexQhxqXaL/E1xNURsgFFYyKzS/g==
|
||||
dependencies:
|
||||
"@types/chart.js" "^2.7.55"
|
||||
|
||||
vue-cli-plugin-i18n@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-cli-plugin-i18n/-/vue-cli-plugin-i18n-1.0.1.tgz#5a3077de5d62c9b4068e486db1fc97fce9fa0072"
|
||||
|
||||
1
login_server/.gitignore
vendored
1
login_server/.gitignore
vendored
@ -5,6 +5,5 @@ src/cpsp/*.h
|
||||
src/cpsp/*.cpp
|
||||
src/cpp/proto/
|
||||
build*/
|
||||
/skeema/gradido_login/insert/crypto_key.sql
|
||||
|
||||
src/LOCALE/messages.pot
|
||||
|
||||
@ -56,8 +56,7 @@ To update messages.pot run
|
||||
This will be also called by ./scripts/build_debug.sh
|
||||
|
||||
## database
|
||||
Login-Server needs a db to run, it is tested with mariadb
|
||||
table definitions are found in folder ./skeema/gradido_login
|
||||
Login-Server needs a db to run, it is tested with mariadb.
|
||||
Currently at least one group must be present in table groups.
|
||||
For example:
|
||||
```sql
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
CREATE TABLE `app_access_tokens` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int NOT NULL,
|
||||
`access_code` bigint unsigned NOT NULL,
|
||||
`created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `access_code` (`access_code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@ -1,15 +0,0 @@
|
||||
CREATE TABLE `elopage_buys` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`elopage_user_id` int DEFAULT NULL,
|
||||
`affiliate_program_id` int NOT NULL,
|
||||
`publisher_id` int NOT NULL,
|
||||
`order_id` int NOT NULL,
|
||||
`product_id` int NOT NULL,
|
||||
`product_price` int NOT NULL,
|
||||
`payer_email` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
`publisher_email` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
`payed` tinyint NOT NULL,
|
||||
`success_date` datetime NOT NULL,
|
||||
`event` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user