mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-25 19:12:45 +00:00
fix: build
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
.turbo
|
||||||
|
node_modules
|
||||||
|
.env.local
|
||||||
28
.gitlab-ci.yml
Normal file
28
.gitlab-ci.yml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
image: node:18-buster
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- echo TURBO_API=$TURBO_API >> .env.local
|
||||||
|
- echo TURBO_TOKEN=$TURBO_TOKEN >> .env.local
|
||||||
|
- echo TURBO_TEAM=$TURBO_TEAM >> .env.local
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
|
||||||
|
build:
|
||||||
|
stage: build
|
||||||
|
before_script:
|
||||||
|
- corepack enable
|
||||||
|
- corepack prepare pnpm@latest-7 --activate
|
||||||
|
- pnpm config set store-dir .pnpm-store
|
||||||
|
script:
|
||||||
|
- pnpm install
|
||||||
|
- pnpm run syncpack
|
||||||
|
- pnpm lint
|
||||||
|
- pnpm format
|
||||||
|
- pnpm build
|
||||||
|
cache:
|
||||||
|
key:
|
||||||
|
files:
|
||||||
|
- pnpm-lock.yaml
|
||||||
|
paths:
|
||||||
|
- .pnpm-store
|
||||||
5
.gitlab/ci/setup_turbo_env.sh
Normal file
5
.gitlab/ci/setup_turbo_env.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo TURBO_API=$TURBO_API >> .env.local
|
||||||
|
echo TURBO_TOKEN=$TURBO_TOKEN >> .env.local
|
||||||
|
echo TURBO_TEAM=$TURBO_TEAM >> .env.local
|
||||||
32
.gitlab/issue_templates/bug.md
Normal file
32
.gitlab/issue_templates/bug.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
## Summary
|
||||||
|
|
||||||
|
(Summarize the bug encountered concisely)
|
||||||
|
|
||||||
|
## Steps to reproduce
|
||||||
|
|
||||||
|
(How one can reproduce the issue - this is very important)
|
||||||
|
|
||||||
|
## Example Project
|
||||||
|
|
||||||
|
(If possible, please create an example project here on GitLab.com that exhibits the problematic behaviour, and link to it here in the bug report)
|
||||||
|
|
||||||
|
(If you are using an older version of GitLab, this will also determine whether the bug has been fixed in a more recent version)
|
||||||
|
|
||||||
|
## What is the current bug behavior?
|
||||||
|
|
||||||
|
(What actually happens)
|
||||||
|
|
||||||
|
## What is the expected correct behavior?
|
||||||
|
|
||||||
|
(What you should see instead)
|
||||||
|
|
||||||
|
## Relevant logs and/or screenshots
|
||||||
|
|
||||||
|
(Paste any relevant logs - please use code blocks (```) to format console output,
|
||||||
|
logs, and code as it's very hard to read otherwise.)
|
||||||
|
|
||||||
|
## Possible fixes
|
||||||
|
|
||||||
|
(If you can, link to the line of code that might be responsible for the problem)
|
||||||
|
|
||||||
|
/label ~bug ~meeting
|
||||||
17
.gitlab/issue_templates/feature.md
Normal file
17
.gitlab/issue_templates/feature.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
## Description
|
||||||
|
|
||||||
|
(Describe the feature that you're requesting concisely)
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
(Explain why the feature is necessary)
|
||||||
|
|
||||||
|
## Mockups/Screenshots
|
||||||
|
|
||||||
|
(If possible, provide mockups or screenshots, which demonstrate the feature)
|
||||||
|
|
||||||
|
## Dependencies, issues to be resolved beforehand
|
||||||
|
|
||||||
|
(List issues or dependencies that need to be resolved before this feature can be implemented)
|
||||||
|
|
||||||
|
/label ~feature ~meeting
|
||||||
17
.gitlab/issue_templates/improvement.md
Normal file
17
.gitlab/issue_templates/improvement.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
## What needs to be changed?
|
||||||
|
|
||||||
|
??? - Describe use case!
|
||||||
|
|
||||||
|
## How is the current state not sufficient?
|
||||||
|
|
||||||
|
???
|
||||||
|
|
||||||
|
## Which changes are necessary?
|
||||||
|
|
||||||
|
???
|
||||||
|
|
||||||
|
## Do the proposed changes impact current use cases?
|
||||||
|
|
||||||
|
???
|
||||||
|
|
||||||
|
/label ~improvement ~meeting
|
||||||
90
.syncpackrc.json
Normal file
90
.syncpackrc.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"semverRange": "",
|
||||||
|
"source": [
|
||||||
|
"package.json",
|
||||||
|
"**/package.json"
|
||||||
|
],
|
||||||
|
"indent": " ",
|
||||||
|
"sortFirst": [
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"version",
|
||||||
|
"type",
|
||||||
|
"license",
|
||||||
|
"repository",
|
||||||
|
"author",
|
||||||
|
"contributors",
|
||||||
|
"prettier",
|
||||||
|
"main",
|
||||||
|
"types",
|
||||||
|
"bin",
|
||||||
|
"scripts",
|
||||||
|
"dependencies",
|
||||||
|
"devDependencies",
|
||||||
|
"peerDependencies"
|
||||||
|
],
|
||||||
|
"versionGroups": [
|
||||||
|
{
|
||||||
|
"label": "ES Mapping Generator Special Dependencies",
|
||||||
|
"dependencies": ["typescript", "typedoc", "ts-node"],
|
||||||
|
"packages": ["@openstapps/es-mapping-generator"],
|
||||||
|
"isIgnored": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Should have the same version",
|
||||||
|
"dependencies": ["**"],
|
||||||
|
"dependencyTypes": ["workspace"],
|
||||||
|
"packages": ["**"],
|
||||||
|
"pinVersion": "2.1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Packages should use workspace version",
|
||||||
|
"dependencies": ["@openstapps/**"],
|
||||||
|
"dependencyTypes": ["prod", "dev"],
|
||||||
|
"packages": ["**"],
|
||||||
|
"pinVersion": "workspace:*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Packages should be synced to configuration",
|
||||||
|
"dependencies": [
|
||||||
|
"typescript",
|
||||||
|
"ts-node",
|
||||||
|
"eslint",
|
||||||
|
"prettier"
|
||||||
|
],
|
||||||
|
"packages": [
|
||||||
|
"**"
|
||||||
|
],
|
||||||
|
"snapTo": [
|
||||||
|
"@openstapps/configuration",
|
||||||
|
"@openstapps/prettier-config",
|
||||||
|
"@openstapps/eslint-config",
|
||||||
|
"@openstapps/app"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "No Banned Dependencies",
|
||||||
|
"dependencies": [
|
||||||
|
"tslint",
|
||||||
|
"lodash",
|
||||||
|
"@types/lodash"
|
||||||
|
],
|
||||||
|
"packages": [
|
||||||
|
"**"
|
||||||
|
],
|
||||||
|
"isBanned": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "No @types package in prod dependencies of applications",
|
||||||
|
"dependencies": ["@types/**"],
|
||||||
|
"dependencyTypes": ["prod"],
|
||||||
|
"packages": [
|
||||||
|
"@openstapps/app",
|
||||||
|
"@openstapps/backend",
|
||||||
|
"@openstapps/proxy",
|
||||||
|
"@openstapps/minimal**"
|
||||||
|
],
|
||||||
|
"isBanned": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
38
README.md
Normal file
38
README.md
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Open StApps Monorepo
|
||||||
|
|
||||||
|
## Remote caching
|
||||||
|
|
||||||
|
Turbo supports remote caching, which massively speeds up build processes.
|
||||||
|
|
||||||
|
### Connecting to the remote cache locally
|
||||||
|
|
||||||
|
`.env.local`
|
||||||
|
```dotenv
|
||||||
|
TURBO_API=http://example:3000
|
||||||
|
TURBO_TEAM=openstapps
|
||||||
|
TURBO_TOKEN=abc123
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connecting to the remote cache in GitLab Pipelines
|
||||||
|
|
||||||
|
You will need to define
|
||||||
|
* `TURBO_API`
|
||||||
|
* `TURBO_TEAM`
|
||||||
|
* `TURBO_TOKEN`
|
||||||
|
Like you did locally as described in [this](https://turbo.build/repo/docs/ci/gitlabci#remote-caching)
|
||||||
|
guide.
|
||||||
|
|
||||||
|
### Hosting a cache
|
||||||
|
|
||||||
|
Self-hosting via Docker is extremely simple, just follow
|
||||||
|
[this](http://v2202207178592194230.supersrv.de:6341) guide
|
||||||
|
or in short:
|
||||||
|
|
||||||
|
`.env`
|
||||||
|
```dotenv
|
||||||
|
PORT=...
|
||||||
|
TURBO_TOKEN=...
|
||||||
|
```
|
||||||
|
```shell
|
||||||
|
docker run --env-file=.env -p 3000:3000 fox1t/turborepo-remote-cache
|
||||||
|
```
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/backend",
|
"name": "@openstapps/backend",
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "A reference implementation for a StApps backend",
|
"description": "A reference implementation for a StApps backend",
|
||||||
|
"version": "2.1.0",
|
||||||
"license": "AGPL-3.0-only",
|
"license": "AGPL-3.0-only",
|
||||||
"author": "André Bierlein <andre.mt.bierlein@gmail.com>",
|
"author": "André Bierlein <andre.mt.bierlein@gmail.com>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -18,9 +18,10 @@
|
|||||||
"build": "npm run lint && npm run compile",
|
"build": "npm run lint && npm run compile",
|
||||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md",
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md",
|
||||||
"check-configuration": "openstapps-configuration",
|
"check-configuration": "openstapps-configuration",
|
||||||
"compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'",
|
"compile": "rimraf lib && tsc",
|
||||||
"documentation": "typedoc --includeVersion --out docs --readme README.md --listInvalidSymbolLinks --entryPointStrategy expand src && openstapps-core-tools openapi ./node_modules/@openstapps/core/lib ./docs/openapi && openapi build-docs docs/openapi/openapi.json -o docs/openapi/index.html",
|
"documentation": "typedoc --includeVersion --out docs --readme README.md --listInvalidSymbolLinks --entryPointStrategy expand src && openstapps-core-tools openapi ./node_modules/@openstapps/core/lib ./docs/openapi && openapi build-docs docs/openapi/openapi.json -o docs/openapi/index.html",
|
||||||
"version": "npm run changelog",
|
"lint": "eslint -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/ test/",
|
||||||
|
"lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/ test/",
|
||||||
"prepublishOnly": "npm ci && npm run build",
|
"prepublishOnly": "npm ci && npm run build",
|
||||||
"preversion": "npm run prepublishOnly",
|
"preversion": "npm run prepublishOnly",
|
||||||
"push": "git push && git push origin \"v$npm_package_version\"",
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
@@ -29,14 +30,14 @@
|
|||||||
"test": "npm run test-unit && npm run test-integration",
|
"test": "npm run test-unit && npm run test-integration",
|
||||||
"test-unit": "cross-env NODE_CONFIG_ENV=elasticsearch ALLOW_NO_TRANSPORT=true STAPPS_LOG_LEVEL=0 nyc mocha --require ts-node/register --exit 'test/**/*.spec.ts'",
|
"test-unit": "cross-env NODE_CONFIG_ENV=elasticsearch ALLOW_NO_TRANSPORT=true STAPPS_LOG_LEVEL=0 nyc mocha --require ts-node/register --exit 'test/**/*.spec.ts'",
|
||||||
"test-integration": "docker-compose -f integration-test.yml pull && docker-compose -f integration-test.yml up --build --abort-on-container-exit --exit-code-from apicli",
|
"test-integration": "docker-compose -f integration-test.yml pull && docker-compose -f integration-test.yml up --build --abort-on-container-exit --exit-code-from apicli",
|
||||||
"lint": "eslint -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/ test/",
|
"test-unit": "env NODE_CONFIG_ENV=elasticsearch ALLOW_NO_TRANSPORT=true STAPPS_LOG_LEVEL=0 nyc mocha --require ts-node/register --exit 'test/**/*.spec.ts'",
|
||||||
"lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/ test/"
|
"version": "npm run changelog"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@elastic/elasticsearch": "8.4.0",
|
"@elastic/elasticsearch": "8.4.0",
|
||||||
"@openstapps/core": "1.0.1",
|
"@openstapps/core": "workspace:*",
|
||||||
"@openstapps/core-tools": "0.34.0",
|
"@openstapps/core-tools": "workspace:*",
|
||||||
"@openstapps/logger": "1.1.1",
|
"@openstapps/logger": "workspace:*",
|
||||||
"@redocly/cli": "1.0.0-beta.125",
|
"@redocly/cli": "1.0.0-beta.125",
|
||||||
"@types/node": "14.18.43",
|
"@types/node": "14.18.43",
|
||||||
"config": "3.3.9",
|
"config": "3.3.9",
|
||||||
@@ -44,7 +45,7 @@
|
|||||||
"express": "4.18.2",
|
"express": "4.18.2",
|
||||||
"express-prom-bundle": "6.6.0",
|
"express-prom-bundle": "6.6.0",
|
||||||
"express-promise-router": "4.1.1",
|
"express-promise-router": "4.1.1",
|
||||||
"got": "11.8.6",
|
"got": "12.6.0",
|
||||||
"moment": "2.29.4",
|
"moment": "2.29.4",
|
||||||
"morgan": "1.10.0",
|
"morgan": "1.10.0",
|
||||||
"nock": "13.3.1",
|
"nock": "13.3.1",
|
||||||
@@ -57,9 +58,9 @@
|
|||||||
"uuid": "8.3.2"
|
"uuid": "8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/configuration": "0.34.0",
|
"@openstapps/configuration": "workspace:*",
|
||||||
"@openstapps/es-mapping-generator": "0.6.0",
|
"@openstapps/es-mapping-generator": "workspace:*",
|
||||||
"@openstapps/eslint-config": "1.1.0",
|
"@openstapps/eslint-config": "workspace:*",
|
||||||
"@testdeck/mocha": "0.3.3",
|
"@testdeck/mocha": "0.3.3",
|
||||||
"@types/chai": "4.3.4",
|
"@types/chai": "4.3.4",
|
||||||
"@types/chai-as-promised": "7.1.5",
|
"@types/chai-as-promised": "7.1.5",
|
||||||
@@ -69,14 +70,15 @@
|
|||||||
"@types/geojson": "1.0.6",
|
"@types/geojson": "1.0.6",
|
||||||
"@types/mocha": "10.0.1",
|
"@types/mocha": "10.0.1",
|
||||||
"@types/morgan": "1.9.4",
|
"@types/morgan": "1.9.4",
|
||||||
|
"@types/node": "18.15.3",
|
||||||
"@types/node-cron": "3.0.7",
|
"@types/node-cron": "3.0.7",
|
||||||
"@types/nodemailer": "6.4.7",
|
"@types/nodemailer": "6.4.7",
|
||||||
"@types/promise-queue": "2.2.0",
|
"@types/promise-queue": "2.2.0",
|
||||||
"@types/sinon-express-mock": "1.3.9",
|
"@types/sinon-express-mock": "1.3.9",
|
||||||
"@types/supertest": "2.0.12",
|
"@types/supertest": "2.0.12",
|
||||||
"@types/uuid": "8.3.4",
|
"@types/uuid": "8.3.4",
|
||||||
"@typescript-eslint/eslint-plugin": "5.42.0",
|
"@typescript-eslint/eslint-plugin": "5.49.0",
|
||||||
"@typescript-eslint/parser": "5.42.0",
|
"@typescript-eslint/parser": "5.49.0",
|
||||||
"chai": "4.3.7",
|
"chai": "4.3.7",
|
||||||
"chai-as-promised": "7.1.1",
|
"chai-as-promised": "7.1.1",
|
||||||
"conventional-changelog-cli": "2.2.2",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
@@ -85,14 +87,13 @@
|
|||||||
"eslint-config-prettier": "8.8.0",
|
"eslint-config-prettier": "8.8.0",
|
||||||
"eslint-plugin-jsdoc": "39.9.1",
|
"eslint-plugin-jsdoc": "39.9.1",
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-unicorn": "43.0.2",
|
"eslint-plugin-unicorn": "45.0.2",
|
||||||
"get-port": "5.1.1",
|
"get-port": "5.1.1",
|
||||||
"mocha": "10.2.0",
|
"mocha": "10.2.0",
|
||||||
"mocked-env": "1.3.5",
|
"mocked-env": "1.3.5",
|
||||||
"nyc": "15.1.0",
|
"nyc": "15.1.0",
|
||||||
"prepend-file-cli": "1.0.6",
|
|
||||||
"prettier": "2.8.8",
|
"prettier": "2.8.8",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "4.4.0",
|
||||||
"sinon": "14.0.2",
|
"sinon": "14.0.2",
|
||||||
"sinon-express-mock": "2.2.1",
|
"sinon-express-mock": "2.2.1",
|
||||||
"supertest": "6.3.3",
|
"supertest": "6.3.3",
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 StApps
|
* Copyright (C) 2019 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@@ -68,16 +70,19 @@ async function onError(error: {code: string; syscall: string}) {
|
|||||||
|
|
||||||
// handle specific listen errors with friendly messages
|
// handle specific listen errors with friendly messages
|
||||||
switch (error.code) {
|
switch (error.code) {
|
||||||
case 'EACCES':
|
case 'EACCES': {
|
||||||
await Logger.error(`${bind} requires elevated privileges`);
|
await Logger.error(`${bind} requires elevated privileges`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
break;
|
break;
|
||||||
case 'EADDRINUSE':
|
}
|
||||||
|
case 'EADDRINUSE': {
|
||||||
await Logger.error(`${bind} is already in use`);
|
await Logger.error(`${bind} is already in use`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
default: {
|
||||||
throw error;
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,11 +92,11 @@ async function onError(error: {code: string; syscall: string}) {
|
|||||||
function onListening() {
|
function onListening() {
|
||||||
const addr = server.address();
|
const addr = server.address();
|
||||||
|
|
||||||
if (addr !== null) {
|
if (addr === null) {
|
||||||
|
void Logger.error(`Failed to start binding`);
|
||||||
|
} else {
|
||||||
const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;
|
const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;
|
||||||
Logger.ok(`Listening on ${bind}`);
|
Logger.ok(`Listening on ${bind}`);
|
||||||
} else {
|
|
||||||
void Logger.error(`Failed to start binding`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,18 +83,18 @@ export class MailQueue {
|
|||||||
throw new Error('Failed to initialize the SMTP transport for the mail queue');
|
throw new Error('Failed to initialize the SMTP transport for the mail queue');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.transport.isVerified()) {
|
if (this.transport.isVerified()) {
|
||||||
this.verificationCounter++;
|
|
||||||
setTimeout(() => {
|
|
||||||
Logger.warn('Transport not verified yet. Trying to send mails here...');
|
|
||||||
this.checkForVerification();
|
|
||||||
}, MailQueue.VERIFICATION_TIMEOUT);
|
|
||||||
} else {
|
|
||||||
Logger.ok('Transport for mail queue was verified. We can send mails now');
|
Logger.ok('Transport for mail queue was verified. We can send mails now');
|
||||||
// if the transport finally was verified send all our mails from the dry queue
|
// if the transport finally was verified send all our mails from the dry queue
|
||||||
for (const mail of this.dryQueue) {
|
for (const mail of this.dryQueue) {
|
||||||
void this.addToQueue(mail);
|
void this.addToQueue(mail);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.verificationCounter++;
|
||||||
|
setTimeout(() => {
|
||||||
|
Logger.warn('Transport not verified yet. Trying to send mails here...');
|
||||||
|
this.checkForVerification();
|
||||||
|
}, MailQueue.VERIFICATION_TIMEOUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,12 +104,12 @@ export class MailQueue {
|
|||||||
* @param mail Information required for sending a mail
|
* @param mail Information required for sending a mail
|
||||||
*/
|
*/
|
||||||
public async push(mail: MailOptions) {
|
public async push(mail: MailOptions) {
|
||||||
if (!this.transport.isVerified()) {
|
if (this.transport.isVerified()) {
|
||||||
|
await this.addToQueue(mail);
|
||||||
|
} else {
|
||||||
// the transport has verification, but is not verified yet
|
// the transport has verification, but is not verified yet
|
||||||
// push to a dry queue which gets pushed to the real queue when the transport is verified
|
// push to a dry queue which gets pushed to the real queue when the transport is verified
|
||||||
this.dryQueue.push(mail);
|
this.dryQueue.push(mail);
|
||||||
} else {
|
|
||||||
await this.addToQueue(mail);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,10 +47,12 @@ export async function pluginRegisterHandler(
|
|||||||
_app: Express.Application,
|
_app: Express.Application,
|
||||||
): Promise<SCPluginRegisterResponse> {
|
): Promise<SCPluginRegisterResponse> {
|
||||||
switch (request.action) {
|
switch (request.action) {
|
||||||
case 'add':
|
case 'add': {
|
||||||
return addPlugin(request.plugin);
|
return addPlugin(request.plugin);
|
||||||
case 'remove':
|
}
|
||||||
|
case 'remove': {
|
||||||
return removePlugin(request.route);
|
return removePlugin(request.route);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,17 +114,21 @@ export async function setUp(
|
|||||||
// make a schedule for each trigger
|
// make a schedule for each trigger
|
||||||
for (const trigger of watcher.triggers) {
|
for (const trigger of watcher.triggers) {
|
||||||
switch (trigger.executionTime) {
|
switch (trigger.executionTime) {
|
||||||
case 'hourly':
|
case 'hourly': {
|
||||||
trigger.executionTime = '5 * * * *';
|
trigger.executionTime = '5 * * * *';
|
||||||
break;
|
break;
|
||||||
case 'daily':
|
}
|
||||||
|
case 'daily': {
|
||||||
trigger.executionTime = '5 0 * * *';
|
trigger.executionTime = '5 0 * * *';
|
||||||
break;
|
break;
|
||||||
case 'weekly':
|
}
|
||||||
|
case 'weekly': {
|
||||||
trigger.executionTime = '5 0 * * 0';
|
trigger.executionTime = '5 0 * * 0';
|
||||||
break;
|
break;
|
||||||
case 'monthly':
|
}
|
||||||
|
case 'monthly': {
|
||||||
trigger.executionTime = '5 0 1 * *';
|
trigger.executionTime = '5 0 1 * *';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cron.schedule(trigger.executionTime, async () => {
|
cron.schedule(trigger.executionTime, async () => {
|
||||||
|
|||||||
0
backend/backend/src/storage/elasticsearch/query.ts
Normal file
0
backend/backend/src/storage/elasticsearch/query.ts
Normal file
4601
backend/proxy/package-lock.json
generated
4601
backend/proxy/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,34 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/proxy",
|
"name": "@openstapps/proxy",
|
||||||
"version": "1.5.1",
|
|
||||||
"description": "NGINX proxy that is dynamically configured by a Node.js script",
|
"description": "NGINX proxy that is dynamically configured by a Node.js script",
|
||||||
|
"version": "2.1.0",
|
||||||
|
"license": "AGPL-3.0-only",
|
||||||
|
"repository": "git@gitlab.com:openstapps/proxy.git",
|
||||||
|
"author": "Anselm Rochus Stordeur <anselmstordeur@gmail.com>",
|
||||||
|
"contributors": [
|
||||||
|
"André Bierlein <andre.mt.bierlein@gmail.com>",
|
||||||
|
"Benjamin Joeckel",
|
||||||
|
"Jovan Krunic <jovan.krunic@gmail.com>",
|
||||||
|
"Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
||||||
|
"Michel Jonathan Schmitz <michel.schmitz_1992@hotmail.com>",
|
||||||
|
"Rainer Killinger <mail-openstapps@killinger.co>"
|
||||||
|
],
|
||||||
"main": "./lib/cli.js",
|
"main": "./lib/cli.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "npm run lint && npm run compile",
|
||||||
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
||||||
|
"check-configuration": "openstapps-configuration",
|
||||||
|
"compile": "rimraf lib && tsc",
|
||||||
|
"documentation": "typedoc --includeVersion --out docs --readme README.md --entryPointStrategy expand src",
|
||||||
|
"lint": "eslint --ext .ts src/",
|
||||||
|
"postversion": "npm run changelog",
|
||||||
|
"prepublishOnly": "npm ci && npm run build",
|
||||||
|
"preversion": "npm run prepublishOnly",
|
||||||
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
|
"test": "nyc mocha --require ts-node/register 'test/**/*.spec.ts'"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openstapps/logger": "1.1.1",
|
"@openstapps/logger": "workspace:*",
|
||||||
"@types/config": "3.3.0",
|
"@types/config": "3.3.0",
|
||||||
"@types/dockerode": "3.3.17",
|
"@types/dockerode": "3.3.17",
|
||||||
"@types/node": "14.18.36",
|
"@types/node": "14.18.36",
|
||||||
@@ -17,66 +41,37 @@
|
|||||||
"semver": "7.3.8"
|
"semver": "7.3.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/configuration": "0.34.0",
|
"@openstapps/configuration": "workspace:*",
|
||||||
"@openstapps/eslint-config": "1.1.0",
|
"@openstapps/eslint-config": "workspace:*",
|
||||||
"@testdeck/mocha": "0.3.3",
|
"@testdeck/mocha": "0.3.3",
|
||||||
"@types/chai": "4.3.5",
|
"@types/chai": "4.3.5",
|
||||||
"@types/chai-spies": "1.0.3",
|
"@types/chai-spies": "1.0.3",
|
||||||
|
"@types/config": "3.3.0",
|
||||||
|
"@types/dockerode": "3.3.14",
|
||||||
"@types/mustache": "4.2.2",
|
"@types/mustache": "4.2.2",
|
||||||
|
"@types/node": "18.15.3",
|
||||||
"@types/proxyquire": "1.3.28",
|
"@types/proxyquire": "1.3.28",
|
||||||
"@typescript-eslint/eslint-plugin": "5.42.1",
|
"@types/semver": "7.3.13",
|
||||||
"@typescript-eslint/parser": "5.42.1",
|
"@types/sha1": "1.1.3",
|
||||||
|
"@typescript-eslint/eslint-plugin": "5.49.0",
|
||||||
|
"@typescript-eslint/parser": "5.49.0",
|
||||||
"chai": "4.3.7",
|
"chai": "4.3.7",
|
||||||
"chai-spies": "1.0.0",
|
"chai-spies": "1.0.0",
|
||||||
"conventional-changelog-cli": "2.2.2",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
"eslint": "8.31.0",
|
"eslint": "8.33.0",
|
||||||
"eslint-config-prettier": "8.6.0",
|
"eslint-config-prettier": "8.6.0",
|
||||||
"eslint-plugin-jsdoc": "39.6.4",
|
"eslint-plugin-jsdoc": "39.7.4",
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-unicorn": "44.0.2",
|
"eslint-plugin-unicorn": "45.0.2",
|
||||||
"mocha": "10.2.0",
|
"mocha": "10.2.0",
|
||||||
"nyc": "15.1.0",
|
"nyc": "15.1.0",
|
||||||
"prepend-file-cli": "1.0.6",
|
"prettier": "2.8.3",
|
||||||
"prettier": "2.8.2",
|
|
||||||
"proxyquire": "2.1.3",
|
"proxyquire": "2.1.3",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"typedoc": "0.22.18",
|
"typedoc": "0.22.18",
|
||||||
"typescript": "4.4.4"
|
"typescript": "4.4.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
|
||||||
"build": "npm run lint && npm run compile",
|
|
||||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
|
||||||
"check-configuration": "openstapps-configuration",
|
|
||||||
"compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'",
|
|
||||||
"documentation": "typedoc --includeVersion --out docs --readme README.md --entryPointStrategy expand src",
|
|
||||||
"lint": "eslint --ext .ts src/",
|
|
||||||
"postversion": "npm run changelog",
|
|
||||||
"prepublishOnly": "npm ci && npm run build",
|
|
||||||
"preversion": "npm run prepublishOnly",
|
|
||||||
"push": "git push && git push origin \"v$npm_package_version\"",
|
|
||||||
"test": "nyc mocha --require ts-node/register 'test/**/*.spec.ts'"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git@gitlab.com:openstapps/proxy.git"
|
|
||||||
},
|
|
||||||
"author": "Anselm Rochus Stordeur <anselmstordeur@gmail.com>",
|
|
||||||
"contributors": [
|
|
||||||
"André Bierlein <andre.mt.bierlein@gmail.com>",
|
|
||||||
"Benjamin Joeckel",
|
|
||||||
"Jovan Krunic <jovan.krunic@gmail.com>",
|
|
||||||
"Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
|
||||||
"Michel Jonathan Schmitz <michel.schmitz_1992@hotmail.com>",
|
|
||||||
"Rainer Killinger <mail-openstapps@killinger.co>"
|
|
||||||
],
|
|
||||||
"license": "AGPL-3.0-only",
|
|
||||||
"openstappsConfiguration": {
|
|
||||||
"forPackaging": false,
|
|
||||||
"ignoreCiEntries": [
|
|
||||||
"package"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"nyc": {
|
"nyc": {
|
||||||
"all": true,
|
"all": true,
|
||||||
"branches": 95,
|
"branches": 95,
|
||||||
@@ -99,5 +94,11 @@
|
|||||||
"text-summary"
|
"text-summary"
|
||||||
],
|
],
|
||||||
"statements": 95
|
"statements": 95
|
||||||
|
},
|
||||||
|
"openstappsConfiguration": {
|
||||||
|
"forPackaging": false,
|
||||||
|
"ignoreCiEntries": [
|
||||||
|
"package"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022 StApps
|
* Copyright (C) 2022 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -192,7 +192,6 @@ export async function generateUpstreamMap(
|
|||||||
})
|
})
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|
||||||
// eslint-disable-next-line prettier/prettier
|
|
||||||
result += '\n\}';
|
result += '\n\}';
|
||||||
|
|
||||||
if (!foundMatchingContainer) {
|
if (!foundMatchingContainer) {
|
||||||
|
|||||||
2
configuration/configuration/app.js
Normal file
2
configuration/configuration/app.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
require('./lib/cli.js')
|
||||||
2815
configuration/configuration/package-lock.json
generated
2815
configuration/configuration/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/configuration",
|
"name": "@openstapps/configuration",
|
||||||
"version": "0.34.0",
|
|
||||||
"description": "A collection of configuration base files for StApps projects.",
|
"description": "A collection of configuration base files for StApps projects.",
|
||||||
"scripts": {
|
"version": "2.1.0",
|
||||||
"build": "npm run lint && npm run compile",
|
"license": "GPL-3.0-only",
|
||||||
"compile": "rimraf lib && tsc --outDir lib && prepend lib/cli.js '#!/usr/bin/env node\n'",
|
"repository": "git@gitlab.com:openstapps/configuration.git",
|
||||||
"version": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md",
|
|
||||||
"documentation": "typedoc --out docs --readme README.md --includeVersion --listInvalidSymbolLinks --entryPointStrategy expand src",
|
|
||||||
"prepublishOnly": "npm ci && npm run build",
|
|
||||||
"preversion": "npm run prepublishOnly",
|
|
||||||
"push": "git push && git push origin \"v$npm_package_version\"",
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
|
||||||
"lint": "eslint -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git@gitlab.com:openstapps/configuration.git"
|
|
||||||
},
|
|
||||||
"author": "Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
"author": "Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Anselm Rochus Stordeur",
|
"Anselm Rochus Stordeur",
|
||||||
@@ -24,36 +11,47 @@
|
|||||||
"Rainer Killinger <mail-openstapps@killinger.co>",
|
"Rainer Killinger <mail-openstapps@killinger.co>",
|
||||||
"Thea Schöbl"
|
"Thea Schöbl"
|
||||||
],
|
],
|
||||||
"license": "GPL-3.0-only",
|
"prettier": "@openstapps/prettier-config",
|
||||||
|
"bin": {
|
||||||
|
"openstapps-configuration": "app.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "npm run lint && npm run compile",
|
||||||
|
"compile": "rimraf lib && tsc --outDir lib",
|
||||||
|
"documentation": "typedoc --out docs --readme README.md --includeVersion --listInvalidSymbolLinks --entryPointStrategy expand src",
|
||||||
|
"format:fix": "prettier --write .",
|
||||||
|
"lint": "eslint -c .eslintrc.json --ignore-path .eslintignore --ext .ts src/",
|
||||||
|
"prepublishOnly": "npm ci && npm run build",
|
||||||
|
"preversion": "npm run prepublishOnly",
|
||||||
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"version": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "14.18.36",
|
|
||||||
"@types/semver": "7.3.13",
|
|
||||||
"@types/yaml": "1.9.7",
|
|
||||||
"chalk": "4.1.2",
|
"chalk": "4.1.2",
|
||||||
"commander": "9.5.0",
|
"commander": "10.0.0",
|
||||||
"semver": "7.3.8",
|
"semver": "7.3.8",
|
||||||
"yaml": "1.10.2"
|
"yaml": "1.10.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/eslint-config": "1.1.0",
|
"@openstapps/eslint-config": "workspace:*",
|
||||||
"@typescript-eslint/eslint-plugin": "5.33.1",
|
"@openstapps/prettier-config": "workspace:*",
|
||||||
"@typescript-eslint/parser": "5.33.1",
|
"@types/node": "18.15.3",
|
||||||
|
"@types/semver": "7.3.13",
|
||||||
|
"@typescript-eslint/eslint-plugin": "5.49.0",
|
||||||
|
"@typescript-eslint/parser": "5.49.0",
|
||||||
"conventional-changelog-cli": "2.2.2",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
"eslint": "8.31.0",
|
"eslint": "8.33.0",
|
||||||
"eslint-config-prettier": "8.6.0",
|
"eslint-config-prettier": "8.6.0",
|
||||||
"eslint-plugin-jsdoc": "39.6.4",
|
"eslint-plugin-jsdoc": "39.7.4",
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-unicorn": "43.0.2",
|
"eslint-plugin-unicorn": "45.0.2",
|
||||||
"prepend-file-cli": "1.0.6",
|
"prettier": "2.8.3",
|
||||||
"prettier": "2.8.2",
|
"rimraf": "4.4.0",
|
||||||
"rimraf": "3.0.2",
|
|
||||||
"typedoc": "0.22.18",
|
"typedoc": "0.22.18",
|
||||||
"typescript": "4.4.4"
|
"typescript": "4.4.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "4.4.4"
|
"typescript": "4.4.4"
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"openstapps-configuration": "lib/cli.js"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -819,11 +819,6 @@ export function getRules(configuration: Configuration): Rules {
|
|||||||
scripts.build = 'npm run lint && npm run compile';
|
scripts.build = 'npm run lint && npm run compile';
|
||||||
scripts.compile = 'rimraf lib && tsc';
|
scripts.compile = 'rimraf lib && tsc';
|
||||||
devDependencies.push('rimraf');
|
devDependencies.push('rimraf');
|
||||||
|
|
||||||
if (configuration.hasCli) {
|
|
||||||
devDependencies.push('prepend-file-cli');
|
|
||||||
scripts.compile += " && prepend lib/cli.js '#!/usr/bin/env node\n'";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.standardDocumentation) {
|
if (configuration.standardDocumentation) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
"inlineSourceMap": true,
|
"inlineSourceMap": true,
|
||||||
"module": "CommonJS",
|
"module": "CommonJS",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"outDir": "../../../lib/",
|
"outDir": "../../../lib/",
|
||||||
|
"lib": ["ES2021", "DOM"],
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"target": "es6"
|
"target": "es6"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,12 +13,11 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
extends: [
|
extends: [
|
||||||
'plugin:@typescript-eslint/recommended',
|
'plugin:@typescript-eslint/recommended',
|
||||||
'plugin:prettier/recommended',
|
|
||||||
'plugin:prettier/recommended',
|
|
||||||
'plugin:jsdoc/recommended',
|
'plugin:jsdoc/recommended',
|
||||||
'plugin:unicorn/recommended',
|
'plugin:unicorn/recommended',
|
||||||
|
'prettier'
|
||||||
],
|
],
|
||||||
plugins: ['eslint-plugin-unicorn', 'eslint-plugin-jsdoc', 'prettier'],
|
plugins: ['eslint-plugin-unicorn', 'eslint-plugin-jsdoc'],
|
||||||
settings: {
|
settings: {
|
||||||
jsdoc: {
|
jsdoc: {
|
||||||
mode: 'typescript',
|
mode: 'typescript',
|
||||||
@@ -43,6 +42,9 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
'unicorn/no-nested-ternary': 'off',
|
'unicorn/no-nested-ternary': 'off',
|
||||||
'unicorn/better-regex': 'off',
|
'unicorn/better-regex': 'off',
|
||||||
|
'unicorn/no-typeof-undefined': 'off',
|
||||||
|
'unicorn/no-non-null-assertion': 'off',
|
||||||
|
'unicorn/prefer-array-some': 'off',
|
||||||
|
|
||||||
'jsdoc/no-types': 'error',
|
'jsdoc/no-types': 'error',
|
||||||
'jsdoc/require-param': 'off',
|
'jsdoc/require-param': 'off',
|
||||||
@@ -82,22 +84,6 @@ module.exports = {
|
|||||||
'@typescript-eslint/lines-between-class-members': ['error', 'always'],
|
'@typescript-eslint/lines-between-class-members': ['error', 'always'],
|
||||||
'@typescript-eslint/no-explicit-any': 'error',
|
'@typescript-eslint/no-explicit-any': 'error',
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
|
|
||||||
'prettier/prettier': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
tabWidth: 2,
|
|
||||||
printWidth: 110,
|
|
||||||
useTabs: false,
|
|
||||||
semi: true,
|
|
||||||
singleQuote: true,
|
|
||||||
quoteProps: 'consistent',
|
|
||||||
trailingComma: 'all',
|
|
||||||
bracketSpacing: false,
|
|
||||||
arrowParens: 'avoid',
|
|
||||||
endOfLine: 'lf',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
2652
configuration/eslint-config/package-lock.json
generated
2652
configuration/eslint-config/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,47 +1,42 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/eslint-config",
|
"name": "@openstapps/eslint-config",
|
||||||
"version": "1.1.0",
|
|
||||||
"main": "index.js",
|
|
||||||
"description": "A collection of configuration base files for StApps projects.",
|
"description": "A collection of configuration base files for StApps projects.",
|
||||||
"scripts": {
|
"version": "2.1.0",
|
||||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
"license": "GPL-3.0-only",
|
||||||
"test": "eslint -c index.js test/test-file.ts",
|
"repository": "git@gitlab.com:openstapps/eslint-config.git",
|
||||||
"prepublishOnly": "npm ci && npm test",
|
|
||||||
"postversion": "npm run changelog",
|
|
||||||
"preversion": "npm run prepublishOnly",
|
|
||||||
"push": "git push && git push origin \"v$npm_package_version\""
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git@gitlab.com:openstapps/eslint-config.git"
|
|
||||||
},
|
|
||||||
"author": "Thea Schöbl",
|
"author": "Thea Schöbl",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Rainer Killinger <mail-openstapps@killinger.co>"
|
"Rainer Killinger <mail-openstapps@killinger.co>"
|
||||||
],
|
],
|
||||||
"license": "GPL-3.0-only",
|
"main": "index.js",
|
||||||
"dependencies": {},
|
"scripts": {
|
||||||
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
||||||
|
"postversion": "npm run changelog",
|
||||||
|
"prepublishOnly": "npm ci && npm test",
|
||||||
|
"preversion": "npm run prepublishOnly",
|
||||||
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
|
"test": "eslint -c index.js test/test-file.ts"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/configuration": "0.31.0",
|
"@typescript-eslint/eslint-plugin": "5.49.0",
|
||||||
"@typescript-eslint/eslint-plugin": ">=5.29.0",
|
"@typescript-eslint/parser": "5.49.0",
|
||||||
"@typescript-eslint/parser": ">=5.29.0",
|
|
||||||
"conventional-changelog-cli": "2.2.2",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
"eslint": ">=8.18.0",
|
"eslint": "8.33.0",
|
||||||
"eslint-config-prettier": ">=8.5.0",
|
"eslint-config-prettier": "8.6.0",
|
||||||
"eslint-plugin-jsdoc": ">=39.3.3",
|
"eslint-plugin-jsdoc": "39.7.4",
|
||||||
"eslint-plugin-prettier": ">=4.0.0",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-unicorn": ">=42.0.0",
|
"eslint-plugin-unicorn": "45.0.2",
|
||||||
"prettier": ">=2.7.1",
|
"prettier": "2.8.3",
|
||||||
"typescript": "4.4.4"
|
"typescript": "4.4.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": ">=5.29.0",
|
"@typescript-eslint/eslint-plugin": "5.49.0",
|
||||||
"@typescript-eslint/parser": ">=5.29.0",
|
"@typescript-eslint/parser": "5.49.0",
|
||||||
"eslint": ">=8.18.0",
|
"eslint": "8.33.0",
|
||||||
"eslint-config-prettier": ">=8.5.0",
|
"eslint-config-prettier": "8.6.0",
|
||||||
"eslint-plugin-jsdoc": ">=39.3.3",
|
"eslint-plugin-jsdoc": "39.7.4",
|
||||||
"eslint-plugin-prettier": ">=4.0.0",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-unicorn": ">=41.0.1",
|
"eslint-plugin-unicorn": "45.0.2",
|
||||||
"prettier": ">=2.7.1"
|
"prettier": "2.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
/**
|
|
||||||
* Simple TS source file to get linted
|
|
||||||
* Can be used to verify new/changed rule behavior
|
|
||||||
*/
|
|
||||||
function addNumbers(a: number, b: number) {
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sum: number = addNumbers(10, 15);
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log('Sum of the two numbers is: ' + sum);
|
|
||||||
@@ -1,23 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/prettier-config",
|
"name": "@openstapps/prettier-config",
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "StApps Prettier Config",
|
"description": "StApps Prettier Config",
|
||||||
"main": "index.json",
|
"version": "2.1.0",
|
||||||
"author": "Thea Schöbl <dev@theaninova.de>",
|
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
|
"repository": "git@gitlab.com:openstapps/prettier-config.git",
|
||||||
|
"author": "Thea Schöbl <dev@theaninova.de>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Rainer Killinger <mail-openstapps@killinger.co>"
|
"Rainer Killinger <mail-openstapps@killinger.co>"
|
||||||
],
|
],
|
||||||
"repository": {
|
"main": "index.json",
|
||||||
"type": "git",
|
|
||||||
"url": "git@gitlab.com:openstapps/prettier-config.git"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"changelog": "npx conventional-changelog-cli -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
"changelog": "npx conventional-changelog-cli -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
||||||
"test": "npx prettier --config index.json --check \"test/*.js\"",
|
|
||||||
"prepublishOnly": "npm test",
|
|
||||||
"postversion": "npm run changelog",
|
"postversion": "npm run changelog",
|
||||||
|
"prepublishOnly": "npm test",
|
||||||
"preversion": "npm run prepublishOnly",
|
"preversion": "npm run prepublishOnly",
|
||||||
"push": "git push && git push origin \"v$npm_package_version\""
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
|
"test": "npx prettier --config index.json --check \"test/*.js\""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ remind:
|
|||||||
stage: maintenance
|
stage: maintenance
|
||||||
only:
|
only:
|
||||||
variables:
|
variables:
|
||||||
- $MAINTENANCE_MODE == "remind"
|
- $MAINTENANCE_MODE == "remind"
|
||||||
tags:
|
tags:
|
||||||
- secrecy
|
- secrecy
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ renovate:
|
|||||||
DOCKER_TLS_VERIFY: 1
|
DOCKER_TLS_VERIFY: 1
|
||||||
DOCKER_TLS_CERTDIR: /certs
|
DOCKER_TLS_CERTDIR: /certs
|
||||||
DOCKER_CERT_PATH: /certs/client
|
DOCKER_CERT_PATH: /certs/client
|
||||||
RENOVATE_EXTENDS: "gitlab>openstapps/projectmanagement"
|
RENOVATE_EXTENDS: 'gitlab>openstapps/projectmanagement'
|
||||||
RENOVATE_BASE_DIR: $CI_PROJECT_DIR/renovate
|
RENOVATE_BASE_DIR: $CI_PROJECT_DIR/renovate
|
||||||
RENOVATE_ENDPOINT: $CI_API_V4_URL
|
RENOVATE_ENDPOINT: $CI_API_V4_URL
|
||||||
RENOVATE_PLATFORM: gitlab
|
RENOVATE_PLATFORM: gitlab
|
||||||
@@ -195,7 +195,7 @@ renovate:
|
|||||||
when: always
|
when: always
|
||||||
expire_in: 1d
|
expire_in: 1d
|
||||||
paths:
|
paths:
|
||||||
- "$RENOVATE_LOG_FILE"
|
- '$RENOVATE_LOG_FILE'
|
||||||
before_script: []
|
before_script: []
|
||||||
script:
|
script:
|
||||||
- renovate $RENOVATE_EXTRA_FLAGS
|
- renovate $RENOVATE_EXTRA_FLAGS
|
||||||
|
|||||||
@@ -2,35 +2,29 @@
|
|||||||
|
|
||||||
(Summarize the bug encountered concisely)
|
(Summarize the bug encountered concisely)
|
||||||
|
|
||||||
|
|
||||||
## Steps to reproduce
|
## Steps to reproduce
|
||||||
|
|
||||||
(How one can reproduce the issue - this is very important)
|
(How one can reproduce the issue - this is very important)
|
||||||
|
|
||||||
|
|
||||||
## Example Project
|
## Example Project
|
||||||
|
|
||||||
(If possible, please create an example project here on GitLab.com that exhibits the problematic behaviour, and link to it here in the bug report)
|
(If possible, please create an example project here on GitLab.com that exhibits the problematic behaviour, and link to it here in the bug report)
|
||||||
|
|
||||||
(If you are using an older version of GitLab, this will also determine whether the bug has been fixed in a more recent version)
|
(If you are using an older version of GitLab, this will also determine whether the bug has been fixed in a more recent version)
|
||||||
|
|
||||||
|
|
||||||
## What is the current bug behavior?
|
## What is the current bug behavior?
|
||||||
|
|
||||||
(What actually happens)
|
(What actually happens)
|
||||||
|
|
||||||
|
|
||||||
## What is the expected correct behavior?
|
## What is the expected correct behavior?
|
||||||
|
|
||||||
(What you should see instead)
|
(What you should see instead)
|
||||||
|
|
||||||
|
|
||||||
## Relevant logs and/or screenshots
|
## Relevant logs and/or screenshots
|
||||||
|
|
||||||
(Paste any relevant logs - please use code blocks (```) to format console output,
|
(Paste any relevant logs - please use code blocks (```) to format console output,
|
||||||
logs, and code as it's very hard to read otherwise.)
|
logs, and code as it's very hard to read otherwise.)
|
||||||
|
|
||||||
|
|
||||||
## Possible fixes
|
## Possible fixes
|
||||||
|
|
||||||
(If you can, link to the line of code that might be responsible for the problem)
|
(If you can, link to the line of code that might be responsible for the problem)
|
||||||
|
|||||||
@@ -2,15 +2,12 @@
|
|||||||
|
|
||||||
(Describe the feature that you're requesting concisely)
|
(Describe the feature that you're requesting concisely)
|
||||||
|
|
||||||
|
|
||||||
## Explanation
|
## Explanation
|
||||||
|
|
||||||
(Explain why the feature is necessary)
|
(Explain why the feature is necessary)
|
||||||
|
|
||||||
|
|
||||||
## Dependencies, issues to be resolved beforehand
|
## Dependencies, issues to be resolved beforehand
|
||||||
|
|
||||||
(List issues or dependencies that need to be resolved before this feature can be implemented)
|
(List issues or dependencies that need to be resolved before this feature can be implemented)
|
||||||
|
|
||||||
|
|
||||||
/label ~meeting
|
/label ~meeting
|
||||||
|
|||||||
@@ -1,314 +1,206 @@
|
|||||||
# [0.25.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.24.0...v0.25.0) (2023-01-17)
|
# [0.25.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.24.0...v0.25.0) (2023-01-17)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* broken cypress build ([a37d3a9](https://gitlab.com/openstapps/projectmanagement/commit/a37d3a9ec4c8303bef7f7f29fdb8f7401ef7b02a))
|
- broken cypress build ([a37d3a9](https://gitlab.com/openstapps/projectmanagement/commit/a37d3a9ec4c8303bef7f7f29fdb8f7401ef7b02a))
|
||||||
* renovate job timeout ([116c880](https://gitlab.com/openstapps/projectmanagement/commit/116c8809e4f7d524361275e910fdc582a9baf78a))
|
- renovate job timeout ([116c880](https://gitlab.com/openstapps/projectmanagement/commit/116c8809e4f7d524361275e910fdc582a9baf78a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.24.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.23.1...v0.24.0) (2022-10-10)
|
# [0.24.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.23.1...v0.24.0) (2022-10-10)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.23.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.23.0...v0.23.1) (2022-07-05)
|
## [0.23.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.23.0...v0.23.1) (2022-07-05)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* documentation not generating ([ac226d1](https://gitlab.com/openstapps/projectmanagement/commit/ac226d178a41e24a57f5e24409255aee2cfabf8d))
|
- documentation not generating ([ac226d1](https://gitlab.com/openstapps/projectmanagement/commit/ac226d178a41e24a57f5e24409255aee2cfabf8d))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.23.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.22.0...v0.23.0) (2022-07-05)
|
# [0.23.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.22.0...v0.23.0) (2022-07-05)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.22.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.21.0...v0.22.0) (2021-12-14)
|
# [0.22.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.21.0...v0.22.0) (2021-12-14)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.21.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.20.1...v0.21.0) (2021-12-14)
|
# [0.21.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.20.1...v0.21.0) (2021-12-14)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* exclude npm audit from maintenance runs ([42e6812](https://gitlab.com/openstapps/projectmanagement/commit/42e68120b7215b6fe0f929955d99907103b7bfed))
|
- exclude npm audit from maintenance runs ([42e6812](https://gitlab.com/openstapps/projectmanagement/commit/42e68120b7215b6fe0f929955d99907103b7bfed))
|
||||||
* link to old gitlab server ([aa9991a](https://gitlab.com/openstapps/projectmanagement/commit/aa9991ad708dd80b873b738a304c94f6f21dd4ba)), closes [#27](https://gitlab.com/openstapps/projectmanagement/issues/27)
|
- link to old gitlab server ([aa9991a](https://gitlab.com/openstapps/projectmanagement/commit/aa9991ad708dd80b873b738a304c94f6f21dd4ba)), closes [#27](https://gitlab.com/openstapps/projectmanagement/issues/27)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* make slack notification optional ([84921ad](https://gitlab.com/openstapps/projectmanagement/commit/84921ad5ce90c24ce53197235e8f8a8aff0f4aba))
|
- make slack notification optional ([84921ad](https://gitlab.com/openstapps/projectmanagement/commit/84921ad5ce90c24ce53197235e8f8a8aff0f4aba))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.20.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.20.0...v0.20.1) (2020-07-27)
|
## [0.20.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.20.0...v0.20.1) (2020-07-27)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* ignore archived projects in milestone tidy ([cd768a9](https://gitlab.com/openstapps/projectmanagement/commit/cd768a9dcdb8edc62f8277a45b054e261311e404))
|
- ignore archived projects in milestone tidy ([cd768a9](https://gitlab.com/openstapps/projectmanagement/commit/cd768a9dcdb8edc62f8277a45b054e261311e404))
|
||||||
* remove invalid project name element ([e4c065d](https://gitlab.com/openstapps/projectmanagement/commit/e4c065d5058512ecab1b7fb173e34d950abb123f))
|
- remove invalid project name element ([e4c065d](https://gitlab.com/openstapps/projectmanagement/commit/e4c065d5058512ecab1b7fb173e34d950abb123f))
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add merge request assignment ([65d05bf](https://gitlab.com/openstapps/projectmanagement/commit/65d05bfe692c7589ae4138439724ba7c0c73bec5))
|
- add merge request assignment ([65d05bf](https://gitlab.com/openstapps/projectmanagement/commit/65d05bfe692c7589ae4138439724ba7c0c73bec5))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.20.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.19.0...v0.20.0) (2020-05-06)
|
# [0.20.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.19.0...v0.20.0) (2020-05-06)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* change builder base image to docker/compose ([5ea40b2](https://gitlab.com/openstapps/projectmanagement/commit/5ea40b2ece8cb2ae764096121492dd9703963f1d))
|
- change builder base image to docker/compose ([5ea40b2](https://gitlab.com/openstapps/projectmanagement/commit/5ea40b2ece8cb2ae764096121492dd9703963f1d))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.19.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.18.0...v0.19.0) (2020-01-08)
|
# [0.19.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.18.0...v0.19.0) (2020-01-08)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.18.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.17.1...v0.18.0) (2019-11-25)
|
# [0.18.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.17.1...v0.18.0) (2019-11-25)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.17.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.17.0...v0.17.1) (2019-11-19)
|
## [0.17.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.17.0...v0.17.1) (2019-11-19)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add documentation for automatic publishing ([ab45e35](https://gitlab.com/openstapps/projectmanagement/commit/ab45e35117ef0cca3f42c557e100d4e57a2571df)), closes [#23](https://gitlab.com/openstapps/projectmanagement/issues/23)
|
- add documentation for automatic publishing ([ab45e35](https://gitlab.com/openstapps/projectmanagement/commit/ab45e35117ef0cca3f42c557e100d4e57a2571df)), closes [#23](https://gitlab.com/openstapps/projectmanagement/issues/23)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.17.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.16.1...v0.17.0) (2019-11-13)
|
# [0.17.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.16.1...v0.17.0) (2019-11-13)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* update to new meeting date ([98c73b5](https://gitlab.com/openstapps/projectmanagement/commit/98c73b575846fb342c4ffb6a2cf09152a3205f95))
|
- update to new meeting date ([98c73b5](https://gitlab.com/openstapps/projectmanagement/commit/98c73b575846fb342c4ffb6a2cf09152a3205f95))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.16.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.16.0...v0.16.1) (2019-08-20)
|
## [0.16.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.16.0...v0.16.1) (2019-08-20)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* add colors to cli log output ([7d271a7](https://gitlab.com/openstapps/projectmanagement/commit/7d271a73648d2367e57a3b6c6bb5725d106dced6))
|
- add colors to cli log output ([7d271a7](https://gitlab.com/openstapps/projectmanagement/commit/7d271a73648d2367e57a3b6c6bb5725d106dced6))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.16.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.15.0...v0.16.0) (2019-08-20)
|
# [0.16.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.15.0...v0.16.0) (2019-08-20)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* only unlabel closed issues before last meeting ([d7b68ae](https://gitlab.com/openstapps/projectmanagement/commit/d7b68ae45c8321f0a1d9cba998b604507445f9fb))
|
- only unlabel closed issues before last meeting ([d7b68ae](https://gitlab.com/openstapps/projectmanagement/commit/d7b68ae45c8321f0a1d9cba998b604507445f9fb))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.15.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.14.1...v0.15.0) (2019-07-23)
|
# [0.15.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.14.1...v0.15.0) (2019-07-23)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add function and task to get version of used dependency ([067a201](https://gitlab.com/openstapps/projectmanagement/commit/067a2011c03b1e3e9d164844d594e4f332982f12)), closes [#20](https://gitlab.com/openstapps/projectmanagement/issues/20)
|
- add function and task to get version of used dependency ([067a201](https://gitlab.com/openstapps/projectmanagement/commit/067a2011c03b1e3e9d164844d594e4f332982f12)), closes [#20](https://gitlab.com/openstapps/projectmanagement/issues/20)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.14.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.14.0...v0.14.1) (2019-06-05)
|
## [0.14.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.14.0...v0.14.1) (2019-06-05)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.14.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.13.0...v0.14.0) (2019-06-04)
|
# [0.14.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.13.0...v0.14.0) (2019-06-04)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* fix regression with protected tags ([65a7233](https://gitlab.com/openstapps/projectmanagement/commit/65a723390572f48601e52dac975c9e2b4a0f06c4))
|
- fix regression with protected tags ([65a7233](https://gitlab.com/openstapps/projectmanagement/commit/65a723390572f48601e52dac975c9e2b4a0f06c4))
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add max depth for reminders ([3641ec4](https://gitlab.com/openstapps/projectmanagement/commit/3641ec4d00890f81b24301b61d689cd113e33997))
|
- add max depth for reminders ([3641ec4](https://gitlab.com/openstapps/projectmanagement/commit/3641ec4d00890f81b24301b61d689cd113e33997))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.13.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.12.1...v0.13.0) (2019-06-03)
|
# [0.13.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.12.1...v0.13.0) (2019-06-03)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add curl to Node.js image ([2ec80fb](https://gitlab.com/openstapps/projectmanagement/commit/2ec80fbb2f1256530e61a389a8444163c7aef8bd)), closes [#18](https://gitlab.com/openstapps/projectmanagement/issues/18)
|
- add curl to Node.js image ([2ec80fb](https://gitlab.com/openstapps/projectmanagement/commit/2ec80fbb2f1256530e61a389a8444163c7aef8bd)), closes [#18](https://gitlab.com/openstapps/projectmanagement/issues/18)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.12.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.12.0...v0.12.1) (2019-05-27)
|
## [0.12.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.12.0...v0.12.1) (2019-05-27)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.12.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.11.0...v0.12.0) (2019-05-27)
|
# [0.12.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.11.0...v0.12.0) (2019-05-27)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* use user 'node' in Node.js image ([0c8aa72](https://gitlab.com/openstapps/projectmanagement/commit/0c8aa7257add9fd5997105f18b69211152fd8971)), closes [#17](https://gitlab.com/openstapps/projectmanagement/issues/17)
|
- use user 'node' in Node.js image ([0c8aa72](https://gitlab.com/openstapps/projectmanagement/commit/0c8aa7257add9fd5997105f18b69211152fd8971)), closes [#17](https://gitlab.com/openstapps/projectmanagement/issues/17)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add git to node image ([c0058f9](https://gitlab.com/openstapps/projectmanagement/commit/c0058f9c2918bae3e5fce58f11802174ea08084c)), closes [#16](https://gitlab.com/openstapps/projectmanagement/issues/16)
|
- add git to node image ([c0058f9](https://gitlab.com/openstapps/projectmanagement/commit/c0058f9c2918bae3e5fce58f11802174ea08084c)), closes [#16](https://gitlab.com/openstapps/projectmanagement/issues/16)
|
||||||
* notify merge request assignee instead of author ([d60625c](https://gitlab.com/openstapps/projectmanagement/commit/d60625c461c6fe54b7c60091050a31f7f77a958e))
|
- notify merge request assignee instead of author ([d60625c](https://gitlab.com/openstapps/projectmanagement/commit/d60625c461c6fe54b7c60091050a31f7f77a958e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.11.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.10.0...v0.11.0) (2019-04-30)
|
# [0.11.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.10.0...v0.11.0) (2019-04-30)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* tidy sub groups ([de05b52](https://gitlab.com/openstapps/projectmanagement/commit/de05b52f24985a882dbacdf82cc1a7c3c4efbe88))
|
- tidy sub groups ([de05b52](https://gitlab.com/openstapps/projectmanagement/commit/de05b52f24985a882dbacdf82cc1a7c3c4efbe88))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.10.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.9.0...v0.10.0) (2019-04-17)
|
# [0.10.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.9.0...v0.10.0) (2019-04-17)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add timestamp to reports ([ad99e45](https://gitlab.com/openstapps/projectmanagement/commit/ad99e45ee3de59de4b5fcca312cb077d90d73335))
|
- add timestamp to reports ([ad99e45](https://gitlab.com/openstapps/projectmanagement/commit/ad99e45ee3de59de4b5fcca312cb077d90d73335))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.9.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.8.1...v0.9.0) (2019-04-09)
|
# [0.9.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.8.1...v0.9.0) (2019-04-09)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add check for protected tags to tidy task ([feb0c3b](https://gitlab.com/openstapps/projectmanagement/commit/feb0c3ba019b1fdfdc5912db86b20d9cc2dd650f)), closes [#14](https://gitlab.com/openstapps/projectmanagement/issues/14)
|
- add check for protected tags to tidy task ([feb0c3b](https://gitlab.com/openstapps/projectmanagement/commit/feb0c3ba019b1fdfdc5912db86b20d9cc2dd650f)), closes [#14](https://gitlab.com/openstapps/projectmanagement/issues/14)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.8.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.8.0...v0.8.1) (2019-03-20)
|
## [0.8.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.8.0...v0.8.1) (2019-03-20)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.8.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.7.0...v0.8.0) (2019-03-20)
|
# [0.8.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.7.0...v0.8.0) (2019-03-20)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* use mustache instead of tangular ([95f7521](https://gitlab.com/openstapps/projectmanagement/commit/95f7521dbddc13a6acb5835ae05dd5535cce067f))
|
- use mustache instead of tangular ([95f7521](https://gitlab.com/openstapps/projectmanagement/commit/95f7521dbddc13a6acb5835ae05dd5535cce067f))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.7.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.6.0...v0.7.0) (2019-03-20)
|
# [0.7.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.6.0...v0.7.0) (2019-03-20)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.6.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.5.0...v0.6.0) (2019-02-25)
|
# [0.6.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.5.0...v0.6.0) (2019-02-25)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* adjust reminder for unfixed merge requests ([e02939c](https://gitlab.com/openstapps/projectmanagement/commit/e02939c470ff9a63fb33c9754e06ea4dfbbd9b15))
|
- adjust reminder for unfixed merge requests ([e02939c](https://gitlab.com/openstapps/projectmanagement/commit/e02939c470ff9a63fb33c9754e06ea4dfbbd9b15))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.5.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.4.1...v0.5.0) (2019-02-05)
|
# [0.5.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.4.1...v0.5.0) (2019-02-05)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add new task to remind about open merge requests ([201ec09](https://gitlab.com/openstapps/projectmanagement/commit/201ec093b7ab676d5d7a84972c5d9e64664af7e0))
|
- add new task to remind about open merge requests ([201ec09](https://gitlab.com/openstapps/projectmanagement/commit/201ec093b7ab676d5d7a84972c5d9e64664af7e0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.4.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.4.0...v0.4.1) (2019-01-30)
|
## [0.4.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.4.0...v0.4.1) (2019-01-30)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.4.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.3.0...v0.4.0) (2019-01-30)
|
# [0.4.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.3.0...v0.4.0) (2019-01-30)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add slack reminder for open merge requests ([47e9775](https://gitlab.com/openstapps/projectmanagement/commit/47e977583bc036d48194d1e6bc9e6214dbbe6062))
|
- add slack reminder for open merge requests ([47e9775](https://gitlab.com/openstapps/projectmanagement/commit/47e977583bc036d48194d1e6bc9e6214dbbe6062))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.3.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.2.2...v0.3.0) (2019-01-28)
|
# [0.3.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.2.2...v0.3.0) (2019-01-28)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* include sub groups in report generation ([040c666](https://gitlab.com/openstapps/projectmanagement/commit/040c666e747df35b773be1a0e30b7ba99f3b6598))
|
- include sub groups in report generation ([040c666](https://gitlab.com/openstapps/projectmanagement/commit/040c666e747df35b773be1a0e30b7ba99f3b6598))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.2.2](https://gitlab.com/openstapps/projectmanagement/compare/v0.2.1...v0.2.2) (2019-01-23)
|
## [0.2.2](https://gitlab.com/openstapps/projectmanagement/compare/v0.2.1...v0.2.2) (2019-01-23)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* correctly determine project for issue ([8f06fc3](https://gitlab.com/openstapps/projectmanagement/commit/8f06fc35347f06e8409e4190079323af91fc0a37))
|
- correctly determine project for issue ([8f06fc3](https://gitlab.com/openstapps/projectmanagement/commit/8f06fc35347f06e8409e4190079323af91fc0a37))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.2.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.2.0...v0.2.1) (2019-01-17)
|
## [0.2.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.2.0...v0.2.1) (2019-01-17)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* correctly add shebang line to cli ([f2933ef](https://gitlab.com/openstapps/projectmanagement/commit/f2933ef9e23e6fa92086800d791c9e4c6685fd4b))
|
- correctly add shebang line to cli ([f2933ef](https://gitlab.com/openstapps/projectmanagement/commit/f2933ef9e23e6fa92086800d791c9e4c6685fd4b))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.2.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.1.1...v0.2.0) (2019-01-17)
|
# [0.2.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.1.1...v0.2.0) (2019-01-17)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* correct link for projects ([a95ec14](https://gitlab.com/openstapps/projectmanagement/commit/a95ec14be8e169ee1e9f84e3ef98a9712babd302))
|
- correct link for projects ([a95ec14](https://gitlab.com/openstapps/projectmanagement/commit/a95ec14be8e169ee1e9f84e3ef98a9712babd302))
|
||||||
* do not add issues to report from backlog ([e902d70](https://gitlab.com/openstapps/projectmanagement/commit/e902d705bf66e07f70a9c34f9f13160c5db5982f))
|
- do not add issues to report from backlog ([e902d70](https://gitlab.com/openstapps/projectmanagement/commit/e902d705bf66e07f70a9c34f9f13160c5db5982f))
|
||||||
* unlabel issues with label meeting only ([41a349e](https://gitlab.com/openstapps/projectmanagement/commit/41a349ead50db256916f5506829e587d1ecb4a43))
|
- unlabel issues with label meeting only ([41a349e](https://gitlab.com/openstapps/projectmanagement/commit/41a349ead50db256916f5506829e587d1ecb4a43))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.1.0...v0.1.1) (2019-01-07)
|
## [0.1.1](https://gitlab.com/openstapps/projectmanagement/compare/v0.1.0...v0.1.1) (2019-01-07)
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* remove failing deletion of labels ([ac8f2e1](https://gitlab.com/openstapps/projectmanagement/commit/ac8f2e10f965ef0e4950d8f294b6c34a26f4bad0))
|
- remove failing deletion of labels ([ac8f2e1](https://gitlab.com/openstapps/projectmanagement/commit/ac8f2e10f965ef0e4950d8f294b6c34a26f4bad0))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [0.1.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.0.2...v0.1.0) (2018-12-13)
|
# [0.1.0](https://gitlab.com/openstapps/projectmanagement/compare/v0.0.2...v0.1.0) (2018-12-13)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.0.2](https://gitlab.com/openstapps/projectmanagement/compare/v0.0.1...v0.0.2) (2018-12-03)
|
## [0.0.2](https://gitlab.com/openstapps/projectmanagement/compare/v0.0.1...v0.0.2) (2018-12-03)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add issue template for features ([8ae1a51](https://gitlab.com/openstapps/projectmanagement/commit/8ae1a5166962c5d0b41b869c6021ddc456407022))
|
- add issue template for features ([8ae1a51](https://gitlab.com/openstapps/projectmanagement/commit/8ae1a5166962c5d0b41b869c6021ddc456407022))
|
||||||
* add nyc configuration ([883ab9b](https://gitlab.com/openstapps/projectmanagement/commit/883ab9bfa55def9a0a8dd4ee5427c1eb9ad2960b))
|
- add nyc configuration ([883ab9b](https://gitlab.com/openstapps/projectmanagement/commit/883ab9bfa55def9a0a8dd4ee5427c1eb9ad2960b))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.0.1](https://gitlab.com/openstapps/projectmanagement/compare/19fd0f6e4cb8b44152333242aa17db84b2bd038a...v0.0.1) (2018-11-29)
|
## [0.0.1](https://gitlab.com/openstapps/projectmanagement/compare/19fd0f6e4cb8b44152333242aa17db84b2bd038a...v0.0.1) (2018-11-29)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add projectmanagement and pack ([19fd0f6](https://gitlab.com/openstapps/projectmanagement/commit/19fd0f6e4cb8b44152333242aa17db84b2bd038a))
|
- add projectmanagement and pack ([19fd0f6](https://gitlab.com/openstapps/projectmanagement/commit/19fd0f6e4cb8b44152333242aa17db84b2bd038a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,16 @@
|
|||||||
|
|
||||||
To contribute effectively to this or other Open StApps projects you should read the documentation in this repository first.
|
To contribute effectively to this or other Open StApps projects you should read the documentation in this repository first.
|
||||||
|
|
||||||
* What's the scope of one [project](../project-docs/workflow/PROJECT.md)?
|
- What's the scope of one [project](../project-docs/workflow/PROJECT.md)?
|
||||||
* How to create [issues](../project-docs/workflow/ISSUES.md) in projects.
|
- How to create [issues](../project-docs/workflow/ISSUES.md) in projects.
|
||||||
* How to [set up](../project-docs/SETUP.md) your machine?
|
- How to [set up](../project-docs/SETUP.md) your machine?
|
||||||
* How to contribute code?
|
- How to contribute code?
|
||||||
* What's the [branching model](../project-docsworkflow/BRANCHING.md)?
|
- What's the [branching model](../project-docsworkflow/BRANCHING.md)?
|
||||||
* How to write [code](../project-docs/workflow/CODING.md)?
|
- How to write [code](../project-docs/workflow/CODING.md)?
|
||||||
* How to create [merge requests](../project-docs/workflow/MERGING.md)?
|
- How to create [merge requests](../project-docs/workflow/MERGING.md)?
|
||||||
* How to write [documentation](../project-docs/workflow/DOCUMENTATION.md)?
|
- How to write [documentation](../project-docs/workflow/DOCUMENTATION.md)?
|
||||||
* How to [version](../project-docs/workflow/VERSIONING.md) the code?
|
- How to [version](../project-docs/workflow/VERSIONING.md) the code?
|
||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Docker cheat sheet](../project-docs/DOCKER_CHEAT_SHEET.md)
|
- [Docker cheat sheet](../project-docs/DOCKER_CHEAT_SHEET.md)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# @openstapps/projectmanagement
|
# @openstapps/projectmanagement
|
||||||
|
|
||||||
[](https://gitlab.com/openstapps/projectmanagement/commits/master)
|
[](https://gitlab.com/openstapps/projectmanagement/commits/master)
|
||||||
[](https://npmjs.com/package/@openstapps/projectmanagement)
|
[](https://npmjs.com/package/@openstapps/projectmanagement)
|
||||||
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||||
[](https://openstapps.gitlab.io/projectmanagement)
|
[](https://openstapps.gitlab.io/projectmanagement)
|
||||||
@@ -21,7 +21,7 @@ Every school gets their own subgroup on GitLab inside the group `@openstapps`.
|
|||||||
|
|
||||||
The technical name is the license plate of the school. This can be found in the [list of license plates](project-docs/SCHOOL_IDENTIFIERS.md).
|
The technical name is the license plate of the school. This can be found in the [list of license plates](project-docs/SCHOOL_IDENTIFIERS.md).
|
||||||
|
|
||||||
The official name of the school is used as the group's name and a matching logo is picked to act as the group's logo - this should be a square one because of the way that GitLab handles/shows logos.
|
The official name of the school is used as the group's name and a matching logo is picked to act as the group's logo - this should be a square one because of the way that GitLab handles/shows logos.
|
||||||
|
|
||||||
#### Permissions on the group
|
#### Permissions on the group
|
||||||
|
|
||||||
|
|||||||
2
configuration/projectmanagement/app.js
Normal file
2
configuration/projectmanagement/app.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
require('./lib/cli.js')
|
||||||
5222
configuration/projectmanagement/package-lock.json
generated
5222
configuration/projectmanagement/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/projectmanagement",
|
"name": "@openstapps/projectmanagement",
|
||||||
"version": "0.25.0",
|
|
||||||
"description": "Main documentation and scripts for maintenance.",
|
"description": "Main documentation and scripts for maintenance.",
|
||||||
"repository": {
|
"version": "2.1.0",
|
||||||
"type": "git",
|
"license": "GPL-3.0-only",
|
||||||
"url": "git@gitlab.com:openstapps/projectmanagement.git"
|
"repository": "git@gitlab.com:openstapps/projectmanagement.git",
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "npm run lint && npm run compile",
|
|
||||||
"check-configuration": "openstapps-configuration",
|
|
||||||
"compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'",
|
|
||||||
"documentation": "typedoc --out docs --readme README.md --listInvalidSymbolLinks --entryPointStrategy expand src",
|
|
||||||
"prepublishOnly": "npm ci && npm run build && npm run test",
|
|
||||||
"preversion": "npm run prepublishOnly",
|
|
||||||
"version": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md",
|
|
||||||
"push": "git push && git push origin \"v$npm_package_version\"",
|
|
||||||
"test": "nyc mocha --require ts-node/register 'test/**/*.spec.ts'",
|
|
||||||
"lint": "eslint --ext .ts src/"
|
|
||||||
},
|
|
||||||
"author": "Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
"author": "Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Anselm Stordeur <anselmstordeur@gmail.com>",
|
"Anselm Stordeur <anselmstordeur@gmail.com>",
|
||||||
@@ -26,54 +12,64 @@
|
|||||||
"Rainer Killinger <mail-openstapps@killinger.co>",
|
"Rainer Killinger <mail-openstapps@killinger.co>",
|
||||||
"Thea Schöbl <dev@theaninova.de>"
|
"Thea Schöbl <dev@theaninova.de>"
|
||||||
],
|
],
|
||||||
"license": "GPL-3.0-only",
|
"prettier": "@openstapps/prettier-config",
|
||||||
|
"main": "lib/common.js",
|
||||||
|
"bin": {
|
||||||
|
"openstapps-projectmanagement": "app.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "npm run lint && npm run compile",
|
||||||
|
"check-configuration": "openstapps-configuration",
|
||||||
|
"compile": "rimraf lib && tsc",
|
||||||
|
"documentation": "typedoc --out docs --readme README.md --listInvalidSymbolLinks --entryPointStrategy expand src",
|
||||||
|
"format:fix": "prettier --write .",
|
||||||
|
"lint": "eslint --ext .ts src/",
|
||||||
|
"prepublishOnly": "npm ci && npm run build && npm run test",
|
||||||
|
"preversion": "npm run prepublishOnly",
|
||||||
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
|
"test": "nyc mocha --require ts-node/register 'test/**/*.spec.ts'",
|
||||||
|
"version": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@krlwlfrt/async-pool": "0.4.1",
|
"@openstapps/gitlab-api": "workspace:*",
|
||||||
"@openstapps/gitlab-api": "0.10.0",
|
"@openstapps/logger": "workspace:*",
|
||||||
"@openstapps/logger": "1.1.1",
|
"@slack/web-api": "6.8.1",
|
||||||
"@slack/client": "5.0.2",
|
"commander": "10.0.0",
|
||||||
"@types/glob": "7.2.0",
|
"date-fns": "2.29.3",
|
||||||
"@types/mustache": "4.2.2",
|
|
||||||
"@types/node": "14.18.36",
|
|
||||||
"@types/tmp": "0.2.3",
|
|
||||||
"commander": "9.5.0",
|
|
||||||
"glob": "8.1.0",
|
"glob": "8.1.0",
|
||||||
"moment": "2.29.4",
|
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"tmp": "0.2.1"
|
"tmp": "0.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/configuration": "0.33.0",
|
"@openstapps/configuration": "workspace:*",
|
||||||
"@openstapps/eslint-config": "1.1.0",
|
"@openstapps/eslint-config": "workspace:*",
|
||||||
|
"@openstapps/prettier-config": "workspace:*",
|
||||||
"@testdeck/mocha": "0.3.3",
|
"@testdeck/mocha": "0.3.3",
|
||||||
"@types/chai": "4.3.4",
|
"@types/chai": "4.3.4",
|
||||||
"@types/chai-as-promised": "7.1.5",
|
"@types/chai-as-promised": "7.1.5",
|
||||||
|
"@types/glob": "8.0.1",
|
||||||
"@types/mocha": "10.0.1",
|
"@types/mocha": "10.0.1",
|
||||||
"@typescript-eslint/eslint-plugin": "5.39.0",
|
"@types/mustache": "4.2.2",
|
||||||
"@typescript-eslint/parser": "5.39.0",
|
"@types/node": "18.15.3",
|
||||||
|
"@types/tmp": "0.2.3",
|
||||||
|
"@typescript-eslint/eslint-plugin": "5.49.0",
|
||||||
|
"@typescript-eslint/parser": "5.49.0",
|
||||||
"chai": "4.3.7",
|
"chai": "4.3.7",
|
||||||
"chai-as-promised": "7.1.1",
|
"chai-as-promised": "7.1.1",
|
||||||
"conventional-changelog-cli": "2.2.2",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
"eslint": "8.32.0",
|
"eslint": "8.33.0",
|
||||||
"eslint-config-prettier": "8.6.0",
|
"eslint-config-prettier": "8.6.0",
|
||||||
"eslint-plugin-jsdoc": "39.6.4",
|
"eslint-plugin-jsdoc": "39.7.4",
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-unicorn": "44.0.2",
|
"eslint-plugin-unicorn": "45.0.2",
|
||||||
"mocha": "10.2.0",
|
"mocha": "10.2.0",
|
||||||
"nyc": "15.1.0",
|
"nyc": "15.1.0",
|
||||||
"prepend-file-cli": "1.0.6",
|
|
||||||
"prettier": "2.8.3",
|
"prettier": "2.8.3",
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "4.4.0",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"tslint": "6.1.3",
|
|
||||||
"typedoc": "0.22.18",
|
"typedoc": "0.22.18",
|
||||||
"typescript": "4.4.4"
|
"typescript": "4.4.4"
|
||||||
},
|
},
|
||||||
"main": "lib/common.js",
|
|
||||||
"typings": "lib/common.d.ts",
|
|
||||||
"bin": {
|
|
||||||
"openstapps-projectmanagement": "lib/cli.js"
|
|
||||||
},
|
|
||||||
"nyc": {
|
"nyc": {
|
||||||
"all": true,
|
"all": true,
|
||||||
"branches": 95,
|
"branches": 95,
|
||||||
@@ -98,5 +94,6 @@
|
|||||||
"ts-node/register"
|
"ts-node/register"
|
||||||
],
|
],
|
||||||
"statements": 95
|
"statements": 95
|
||||||
}
|
},
|
||||||
|
"typings": "lib/common.d.ts"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,6 @@ Please consult the [Docker documentation](https://docs.docker.com/engine/referen
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [An Exhaustive Guide to Writing Dockerfiles for Node.js Web Apps](https://blog.hasura.io/an-exhaustive-guide-to-writing-dockerfiles-for-node-js-web-apps-bbee6bd2f3c4)
|
- [An Exhaustive Guide to Writing Dockerfiles for Node.js Web Apps](https://blog.hasura.io/an-exhaustive-guide-to-writing-dockerfiles-for-node-js-web-apps-bbee6bd2f3c4)
|
||||||
* [Docker and Node.js Best Practices
|
- [Docker and Node.js Best Practices
|
||||||
](https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md)
|
](https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
## Required tools/packages
|
## Required tools/packages
|
||||||
|
|
||||||
* [SSH](https://docs.gitlab.com/ee/ssh/README.html)
|
- [SSH](https://docs.gitlab.com/ee/ssh/README.html)
|
||||||
* [Git](https://docs.gitlab.com/ee/gitlab-basics/start-using-git.html)
|
- [Git](https://docs.gitlab.com/ee/gitlab-basics/start-using-git.html)
|
||||||
* [Docker](https://docs.gitlab.com/ee/user/project/container_registry.html) & Docker-Compose
|
- [Docker](https://docs.gitlab.com/ee/user/project/container_registry.html) & Docker-Compose
|
||||||
* Node.js & NPM - be sure to install the "Fermium" (14.x) LTS version, might need a [PPA](https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions) or use NVM
|
- Node.js & NPM - be sure to install the "Fermium" (14.x) LTS version, might need a [PPA](https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions) or use NVM
|
||||||
* [NVM](https://github.com/creationix/nvm#installation) - if you want to use multiple different versions of node
|
- [NVM](https://github.com/creationix/nvm#installation) - if you want to use multiple different versions of node
|
||||||
|
|
||||||
Example for Debian based distributions:
|
Example for Debian based distributions:
|
||||||
|
|
||||||
@@ -16,13 +16,13 @@ apt install ssh git docker docker-compose nodejs
|
|||||||
|
|
||||||
## IDE - recommended choices
|
## IDE - recommended choices
|
||||||
|
|
||||||
* [VSCode](https://code.visualstudio.com/)
|
- [VSCode](https://code.visualstudio.com/)
|
||||||
* [Webstorm](https://www.jetbrains.com/webstorm/download/) - Educational or OpenSource License **cannot** be used
|
- [Webstorm](https://www.jetbrains.com/webstorm/download/) - Educational or OpenSource License **cannot** be used
|
||||||
|
|
||||||
## Optional helpful tools
|
## Optional helpful tools
|
||||||
|
|
||||||
* Curl - for executing HTTP requests on the command line
|
- Curl - for executing HTTP requests on the command line
|
||||||
* Postman or Insomnia - for executing HTTP requests with a GUI
|
- Postman or Insomnia - for executing HTTP requests with a GUI
|
||||||
|
|
||||||
## Before you start (Windows only)
|
## Before you start (Windows only)
|
||||||
|
|
||||||
@@ -31,8 +31,8 @@ Depending on your preferred settings you could consider applying `git config cor
|
|||||||
|
|
||||||
## Clone starter repositories
|
## Clone starter repositories
|
||||||
|
|
||||||
* [Minimal deployment](https://gitlab.com/openstapps/minimal-deployment) - contains backend, database, minimal connector, copy (from api) and app
|
- [Minimal deployment](https://gitlab.com/openstapps/minimal-deployment) - contains backend, database, minimal connector, copy (from api) and app
|
||||||
* [Minimal connector](https://gitlab.com/openstapps/minimal-connector) - an example connector to learn the principles of connector development
|
- [Minimal connector](https://gitlab.com/openstapps/minimal-connector) - an example connector to learn the principles of connector development
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git clone git@gitlab.com:openstapps/minimal-deployment.git
|
git clone git@gitlab.com:openstapps/minimal-deployment.git
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
## Possible branch names
|
## Possible branch names
|
||||||
|
|
||||||
* `master`
|
- `master`
|
||||||
* `develop`
|
- `develop`
|
||||||
* `$ID-$TITLE`
|
- `$ID-$TITLE`
|
||||||
|
|
||||||
### `master`
|
### `master`
|
||||||
|
|
||||||
@@ -22,4 +22,4 @@ Development of features, bugfixes or refactoring is done in branches referencing
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Git - A successful Git branching model](http://nvie.com/posts/a-successful-git-branching-model/)
|
- [Git - A successful Git branching model](http://nvie.com/posts/a-successful-git-branching-model/)
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ Inline comments should not explain what code from external projects is doing. Ad
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Commit guidelines](COMMITS.md)
|
- [Commit guidelines](COMMITS.md)
|
||||||
* [TypeScript coding guidelines](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines)
|
- [TypeScript coding guidelines](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines)
|
||||||
* [Licensing guidelines](LICENSING.md)
|
- [Licensing guidelines](LICENSING.md)
|
||||||
|
|||||||
@@ -5,24 +5,24 @@
|
|||||||
Commit subjects should match the following template:
|
Commit subjects should match the following template:
|
||||||
|
|
||||||
> `TYPE`: `SUBJECT`
|
> `TYPE`: `SUBJECT`
|
||||||
>
|
>
|
||||||
> `DESCRIPTION`
|
> `DESCRIPTION`
|
||||||
|
|
||||||
### `TYPE`
|
### `TYPE`
|
||||||
|
|
||||||
`TYPE` can have one of the following values:
|
`TYPE` can have one of the following values:
|
||||||
|
|
||||||
| value | meaning |
|
| value | meaning |
|
||||||
| --- | --- |
|
| -------- | ----------------------------------------------------------------------------------------------------------- |
|
||||||
| build | Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) |
|
| build | Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) |
|
||||||
| ci | Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) |
|
| ci | Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) |
|
||||||
| docs | Documentation only changes |
|
| docs | Documentation only changes |
|
||||||
| feat | A new feature |
|
| feat | A new feature |
|
||||||
| fix | A bug fix |
|
| fix | A bug fix |
|
||||||
| perf | A code change that improves performance |
|
| perf | A code change that improves performance |
|
||||||
| refactor | A code change that neither fixes a bug nor adds a feature |
|
| refactor | A code change that neither fixes a bug nor adds a feature |
|
||||||
| style | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) |
|
| style | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) |
|
||||||
| test | Adding missing tests or correcting existing tests |
|
| test | Adding missing tests or correcting existing tests |
|
||||||
|
|
||||||
These are the [types](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type), that angular uses. They are easily adaptable for all TypeScript based web related projects.
|
These are the [types](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type), that angular uses. They are easily adaptable for all TypeScript based web related projects.
|
||||||
|
|
||||||
@@ -56,5 +56,5 @@ conventional-changelog -p angular -i CHANGELOG.md -s -r 0
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Recommendations on commit messages](https://chris.beams.io/posts/git-commit/)
|
- [Recommendations on commit messages](https://chris.beams.io/posts/git-commit/)
|
||||||
* [Versioning](VERSIONING.md)
|
- [Versioning](VERSIONING.md)
|
||||||
|
|||||||
@@ -10,17 +10,17 @@ Code is annotated with [TypeDoc](https://typedoc.org/), which then can be used t
|
|||||||
|
|
||||||
Please follow these guidelines to reduce redundance:
|
Please follow these guidelines to reduce redundance:
|
||||||
|
|
||||||
* The purpose of inline documentation is to explain what the line of code actually does without explaining syntax or external references. Example:
|
- The purpose of inline documentation is to explain what the line of code actually does without explaining syntax or external references. Example:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// extend the template by the properties of the base template
|
// extend the template by the properties of the base template
|
||||||
templateBase.properties = mergeObjects(
|
templateBase.properties = mergeObjects(
|
||||||
templateBase.properties,
|
templateBase.properties,
|
||||||
templates['base.template.json'].mappings._default_.properties
|
templates['base.template.json'].mappings._default_.properties,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
* Follow the [recommendations](http://typedoc.org/guides/doccomments/) of `typedoc`, because it is used to generate documentation. Do not denote the types again in the documentation (`@param` and `@returns`), because they are already "documented" in the code itself. Example:
|
- Follow the [recommendations](http://typedoc.org/guides/doccomments/) of `typedoc`, because it is used to generate documentation. Do not denote the types again in the documentation (`@param` and `@returns`), because they are already "documented" in the code itself. Example:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
/**
|
/**
|
||||||
@@ -39,8 +39,8 @@ async get<T>(key: string): Promise<T> {
|
|||||||
|
|
||||||
### Inline Comments `//`
|
### Inline Comments `//`
|
||||||
|
|
||||||
* Start inline comments with a lowercase letter and a space after the `//`
|
- Start inline comments with a lowercase letter and a space after the `//`
|
||||||
* Place the comment above the line that it is referencing
|
- Place the comment above the line that it is referencing
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// lorem ipsum
|
// lorem ipsum
|
||||||
@@ -49,14 +49,14 @@ const lorem;
|
|||||||
|
|
||||||
### Doc Comments `/**`
|
### Doc Comments `/**`
|
||||||
|
|
||||||
* Start with a capital letter
|
- Start with a capital letter
|
||||||
* Keep the first line short
|
- Keep the first line short
|
||||||
* The first line should not end with a period, nor should it consist of multiple sentences
|
- The first line should not end with a period, nor should it consist of multiple sentences
|
||||||
* The first line should be easily scannable
|
- The first line should be easily scannable
|
||||||
* If you want to comment more than one line, do a short summary in the first line, then continue after a blank line with the more detailed description
|
- If you want to comment more than one line, do a short summary in the first line, then continue after a blank line with the more detailed description
|
||||||
* Document all parameters in functions using `@param`
|
- Document all parameters in functions using `@param`
|
||||||
* `@param` must not contain a type annotation, just `@param name description`
|
- `@param` must not contain a type annotation, just `@param name description`
|
||||||
* Do not include `@return`, as it is redundant information
|
- Do not include `@return`, as it is redundant information
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
/**
|
/**
|
||||||
@@ -81,4 +81,4 @@ The path `.gitlab/issue_templates` can contain markdown files which act as templ
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [GitLab issue templates](https://gitlab.com/help/user/project/description_templates.md)
|
- [GitLab issue templates](https://gitlab.com/help/user/project/description_templates.md)
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ Issues keep a discussion of the topic, are related to a [branch](BRANCHING.md),
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Always start with an issue](https://about.gitlab.com/2016/03/03/start-with-an-issue/)
|
- [Always start with an issue](https://about.gitlab.com/2016/03/03/start-with-an-issue/)
|
||||||
|
|||||||
@@ -45,4 +45,4 @@ If the file is updated in a new year after its creation, the `<year>` should be
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Coding style](CODING.md)
|
- [Coding style](CODING.md)
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ A merge request can also gather the work of multiple issues.
|
|||||||
Merge requests are used to merge the changes to the main branches (`master`, `develop`). Every merge request needs to be reviewed/commented by at least 2 other developers before they can be accepted. This ensure that all guidelines are followed and that the scope of the issue is matched.
|
Merge requests are used to merge the changes to the main branches (`master`, `develop`). Every merge request needs to be reviewed/commented by at least 2 other developers before they can be accepted. This ensure that all guidelines are followed and that the scope of the issue is matched.
|
||||||
|
|
||||||
Before any merge of an `issue`-branch into the according `master`-branch, the commits of the `issue`-branch shall be tidied up.
|
Before any merge of an `issue`-branch into the according `master`-branch, the commits of the `issue`-branch shall be tidied up.
|
||||||
Unstage your commits from the `issue`-branch (`git reset master`). Create your new commit(s) and push them to the remote repository (`git push --force`).
|
Unstage your commits from the `issue`-branch (`git reset master`). Create your new commit(s) and push them to the remote repository (`git push --force`).
|
||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Commits](COMMITS.md)
|
- [Commits](COMMITS.md)
|
||||||
|
|||||||
@@ -33,5 +33,5 @@ For the contents and purpose of `.editorconfig`, `tsconfig.json` and `tslint.jso
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Coding style](CODING.md)
|
- [Coding style](CODING.md)
|
||||||
* [Versioning](VERSIONING.md)
|
- [Versioning](VERSIONING.md)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## NPM
|
## NPM
|
||||||
|
|
||||||
All projects that use the [OpenStApps configuration](https://gitlab.com/openstapps/configuration) and implement the automatic publishing via GitLab CI can simply be published to the NPM registry by using the appropriate job. It uses the `NPM_AUTH_TOKEN` that is a [protected variable](https://gitlab.com/groups/openstapps/-/settings/ci_cd) of the OpenStApps group. To trigger this job, a new tag has to be created (on the master branch):
|
All projects that use the [OpenStApps configuration](https://gitlab.com/openstapps/configuration) and implement the automatic publishing via GitLab CI can simply be published to the NPM registry by using the appropriate job. It uses the `NPM_AUTH_TOKEN` that is a [protected variable](https://gitlab.com/groups/openstapps/-/settings/ci_cd) of the OpenStApps group. To trigger this job, a new tag has to be created (on the master branch):
|
||||||
|
|
||||||
### Use current [master branch](BRANCHING.md)
|
### Use current [master branch](BRANCHING.md)
|
||||||
|
|
||||||
@@ -19,8 +19,8 @@ npm version (major|minor|patch)
|
|||||||
|
|
||||||
After these steps there should 2 new commits:
|
After these steps there should 2 new commits:
|
||||||
|
|
||||||
* A version commit
|
- A version commit
|
||||||
* A changelog commit
|
- A changelog commit
|
||||||
|
|
||||||
Also a new git tag should be created.
|
Also a new git tag should be created.
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
We use semantic version through `npm`.
|
We use semantic version through `npm`.
|
||||||
|
|
||||||
* `npm version patch`: For fixes/patches
|
- `npm version patch`: For fixes/patches
|
||||||
* `npm version minor`: For new features
|
- `npm version minor`: For new features
|
||||||
* `npm version major`: For breaking changes in the API
|
- `npm version major`: For breaking changes in the API
|
||||||
|
|
||||||
Or directly with `git tag vMAJOR.MINOR.PATCH`.
|
Or directly with `git tag vMAJOR.MINOR.PATCH`.
|
||||||
|
|
||||||
@@ -12,4 +12,4 @@ This tag is set on the `develop`- (if present) or on the `master`-[branch](BRANC
|
|||||||
|
|
||||||
## Further resources
|
## Further resources
|
||||||
|
|
||||||
* [Commit guidelines](COMMITS.md)
|
- [Commit guidelines](COMMITS.md)
|
||||||
|
|||||||
@@ -17,15 +17,15 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"matchUpdateTypes": ["major"],
|
"matchUpdateTypes": ["major"],
|
||||||
"matchPackagePatterns": ["^@angular", "^@ionic", "^@types\/node$", "^got$"],
|
"matchPackagePatterns": ["^@angular", "^@ionic", "^@types/node$", "^got$"],
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"matchPackagePatterns": ["^@types\/geojson$"],
|
"matchPackagePatterns": ["^@types/geojson$"],
|
||||||
"allowedVersions": "1.0.6"
|
"allowedVersions": "1.0.6"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"matchPackagePatterns": ["^@elastic\/elasticsearch$"],
|
"matchPackagePatterns": ["^@elastic/elasticsearch$"],
|
||||||
"allowedVersions": "<6.0"
|
"allowedVersions": "<6.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -41,18 +41,12 @@
|
|||||||
"allowedVersions": "<5.0"
|
"allowedVersions": "<5.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"matchDepTypes": [
|
"matchDepTypes": ["peerDependencies"],
|
||||||
"peerDependencies"
|
|
||||||
],
|
|
||||||
"rangeStrategy": "replace"
|
"rangeStrategy": "replace"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lockFileMaintenance": {
|
"lockFileMaintenance": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
"reviewers": [
|
"reviewers": ["abcdev", "jovankrunic", "theaninova"]
|
||||||
"abcdev",
|
|
||||||
"jovankrunic",
|
|
||||||
"theaninova"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,23 +12,9 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {asyncPool} from '@krlwlfrt/async-pool';
|
|
||||||
import {Api} from '@openstapps/gitlab-api';
|
import {Api} from '@openstapps/gitlab-api';
|
||||||
import {Group, Project} from '@openstapps/gitlab-api/lib/types';
|
import {Project} from '@openstapps/gitlab-api/lib/types';
|
||||||
import {Logger} from '@openstapps/logger';
|
import {Logger} from '@openstapps/logger';
|
||||||
import {readFile, writeFile} from 'fs';
|
|
||||||
import {promisify} from 'util';
|
|
||||||
import {CONCURRENCY} from './configuration';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Promisified version of readFile
|
|
||||||
*/
|
|
||||||
export const readFilePromisified = promisify(readFile);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Promisified version of writeFile
|
|
||||||
*/
|
|
||||||
export const writeFilePromisified = promisify(writeFile);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get projects for a list of groups
|
* Get projects for a list of groups
|
||||||
@@ -39,37 +25,10 @@ export const writeFilePromisified = promisify(writeFile);
|
|||||||
export async function getProjects(api: Api, groups: number[]): Promise<Project[]> {
|
export async function getProjects(api: Api, groups: number[]): Promise<Project[]> {
|
||||||
Logger.info(`Fetching all projects for specified groups (${groups.length})...`);
|
Logger.info(`Fetching all projects for specified groups (${groups.length})...`);
|
||||||
|
|
||||||
const projectResults = await asyncPool(CONCURRENCY, groups, async groupId => {
|
const projectResults = await Promise.all(groups.map(api.getProjectsForGroup));
|
||||||
return api.getProjectsForGroup(groupId);
|
const projects = projectResults.flat();
|
||||||
});
|
|
||||||
|
|
||||||
const projects = flatten2dArray(projectResults);
|
|
||||||
|
|
||||||
Logger.log(`Fetched ${projects.length} project(s).`);
|
Logger.log(`Fetched ${projects.length} project(s).`);
|
||||||
|
|
||||||
return projects;
|
return projects;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get subgroups for a list of groups
|
|
||||||
*
|
|
||||||
* @param api GitLab API to make requests with
|
|
||||||
* @param groups List of groups
|
|
||||||
*/
|
|
||||||
export async function getSubGroups(api: Api, groups: number[]): Promise<Group[]> {
|
|
||||||
return flatten2dArray(
|
|
||||||
await asyncPool(CONCURRENCY, groups, async groupId => {
|
|
||||||
return api.getSubGroupsForGroup(groupId);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flatten 2d array
|
|
||||||
*
|
|
||||||
* @param array Flattened array
|
|
||||||
*/
|
|
||||||
export function flatten2dArray<T>(array: T[][]): T[] {
|
|
||||||
// eslint-disable-next-line unicorn/prefer-spread
|
|
||||||
return ([] as T[]).concat(...array);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {Label} from '@openstapps/gitlab-api/lib/types';
|
import {Label} from '@openstapps/gitlab-api/lib/types';
|
||||||
import moment from 'moment';
|
import setHours from 'date-fns/setHours';
|
||||||
|
import nextThursday from 'date-fns/nextThursday';
|
||||||
|
import previousThursday from 'date-fns/previousThursday';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of schools with their IDs
|
* List of schools with their IDs
|
||||||
@@ -183,31 +185,11 @@ export const NOTE_PREFIX = '`openstapps/projectmanagement`';
|
|||||||
*/
|
*/
|
||||||
export const SLACK_CHANNEL = 'C762UG76Z';
|
export const SLACK_CHANNEL = 'C762UG76Z';
|
||||||
|
|
||||||
/**
|
|
||||||
* Concurrency for async pool
|
|
||||||
*/
|
|
||||||
export const CONCURRENCY = 3;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum depth for merge request reminders
|
* Maximum depth for merge request reminders
|
||||||
*/
|
*/
|
||||||
export const MAX_DEPTH_FOR_REMINDER = 2;
|
export const MAX_DEPTH_FOR_REMINDER = 2;
|
||||||
|
|
||||||
/**
|
export const NEXT_MEETING = setHours(nextThursday(Date.now()), 10);
|
||||||
* Next meeting
|
|
||||||
*/
|
|
||||||
export const NEXT_MEETING = moment()
|
|
||||||
.startOf('week')
|
|
||||||
// tslint:disable-next-line:no-magic-numbers
|
|
||||||
.hour(10)
|
|
||||||
// tslint:disable-next-line:no-magic-numbers
|
|
||||||
.day(3);
|
|
||||||
|
|
||||||
if (NEXT_MEETING.isBefore(moment())) {
|
export const LAST_MEETING = setHours(previousThursday(Date.now()), 10);
|
||||||
NEXT_MEETING.add(1, 'week');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Last meeting
|
|
||||||
*/
|
|
||||||
export const LAST_MEETING = moment(NEXT_MEETING).subtract(1, 'week');
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
import {existsSync, PathLike} from 'fs';
|
import {existsSync, PathLike} from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {readFilePromisified} from '../common';
|
import {readFile} from 'fs/promises';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get used version of a dependency of a project referenced by a path
|
* Get used version of a dependency of a project referenced by a path
|
||||||
@@ -27,7 +27,7 @@ export async function getUsedVersion(directoryPath: PathLike, dependency: string
|
|||||||
throw new Error(`'package.json' does not exist in '${directoryPath}'. Not a Node.js project?`);
|
throw new Error(`'package.json' does not exist in '${directoryPath}'. Not a Node.js project?`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buffer = await readFilePromisified(path.join(directoryPath.toString(), 'package.json'));
|
const buffer = await readFile(path.join(directoryPath.toString(), 'package.json'));
|
||||||
const content = buffer.toString();
|
const content = buffer.toString();
|
||||||
const packageJson = JSON.parse(content);
|
const packageJson = JSON.parse(content);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {asyncPool} from '@krlwlfrt/async-pool';
|
|
||||||
import {Api} from '@openstapps/gitlab-api';
|
import {Api} from '@openstapps/gitlab-api';
|
||||||
import {
|
import {
|
||||||
AccessLevel,
|
AccessLevel,
|
||||||
@@ -23,8 +22,8 @@ import {
|
|||||||
User,
|
User,
|
||||||
} from '@openstapps/gitlab-api/lib/types';
|
} from '@openstapps/gitlab-api/lib/types';
|
||||||
import {Logger} from '@openstapps/logger';
|
import {Logger} from '@openstapps/logger';
|
||||||
import {WebClient} from '@slack/client';
|
import {WebClient} from '@slack/web-api';
|
||||||
import {CONCURRENCY, GROUPS, MAX_DEPTH_FOR_REMINDER, NOTE_PREFIX, SLACK_CHANNEL} from '../configuration';
|
import {GROUPS, MAX_DEPTH_FOR_REMINDER, NOTE_PREFIX, SLACK_CHANNEL} from '../configuration';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remind people of open merge requests
|
* Remind people of open merge requests
|
||||||
@@ -55,9 +54,9 @@ export async function remind(api: Api): Promise<void> {
|
|||||||
|
|
||||||
// instantiate slack client
|
// instantiate slack client
|
||||||
const client =
|
const client =
|
||||||
typeof process.env.SLACK_API_TOKEN !== 'undefined'
|
typeof process.env.SLACK_API_TOKEN === 'undefined'
|
||||||
? new WebClient(process.env.SLACK_API_TOKEN)
|
? undefined
|
||||||
: undefined;
|
: new WebClient(process.env.SLACK_API_TOKEN);
|
||||||
|
|
||||||
// get members of main group
|
// get members of main group
|
||||||
const members = await api.getMembers(MembershipScope.GROUPS, GROUPS[0]);
|
const members = await api.getMembers(MembershipScope.GROUPS, GROUPS[0]);
|
||||||
@@ -75,115 +74,117 @@ export async function remind(api: Api): Promise<void> {
|
|||||||
|
|
||||||
Logger.info(`Found ${maintainers.length} maintainer(s).`);
|
Logger.info(`Found ${maintainers.length} maintainer(s).`);
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, mergeRequests, async mergeRequest => {
|
await Promise.all(
|
||||||
// check if merge request is WIP
|
mergeRequests.map(async mergeRequest => {
|
||||||
if (mergeRequest.work_in_progress) {
|
// check if merge request is WIP
|
||||||
Logger.info(`Merge request '${mergeRequest.title}' is WIP.`);
|
if (mergeRequest.work_in_progress) {
|
||||||
|
Logger.info(`Merge request '${mergeRequest.title}' is WIP.`);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// get merge request approval
|
|
||||||
const approval = await api.getMergeRequestApproval(mergeRequest.project_id, mergeRequest.iid);
|
|
||||||
|
|
||||||
// get merge request discussions
|
|
||||||
const discussions = await api.getMergeRequestDiscussions(mergeRequest.project_id, mergeRequest.iid);
|
|
||||||
|
|
||||||
// check if at least one of the discussions is unresolved
|
|
||||||
const hasUnresolvedDiscussions = discussions.some(discussion => {
|
|
||||||
return discussion.notes.some(note => {
|
|
||||||
return note.resolvable && (typeof note.resolved === 'undefined' || !note.resolved);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hasUnresolvedDiscussions) {
|
|
||||||
let recipient = mergeRequest.author.username;
|
|
||||||
|
|
||||||
if (typeof mergeRequest.assignee !== 'undefined' && mergeRequest.assignee !== null) {
|
|
||||||
recipient = mergeRequest.assignee.username;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create note in merge request
|
// get merge request approval
|
||||||
await api.createNote(
|
const approval = await api.getMergeRequestApproval(mergeRequest.project_id, mergeRequest.iid);
|
||||||
mergeRequest.project_id,
|
|
||||||
Scope.MERGE_REQUESTS,
|
|
||||||
mergeRequest.iid,
|
|
||||||
`${NOTE_PREFIX} Please resolve pending discussions, @${recipient}!`,
|
|
||||||
);
|
|
||||||
|
|
||||||
return;
|
// get merge request discussions
|
||||||
}
|
const discussions = await api.getMergeRequestDiscussions(mergeRequest.project_id, mergeRequest.iid);
|
||||||
|
|
||||||
if (approval.merge_status === MergeRequestMergeStatus.CAN_BE_MERGED) {
|
// check if at least one of the discussions is unresolved
|
||||||
if (approval.approvals_left > 0) {
|
const hasUnresolvedDiscussions = discussions.some(discussion => {
|
||||||
Logger.warn(`Merge request '${mergeRequest.title}' needs more approvals!`);
|
return discussion.notes.some(note => {
|
||||||
|
return note.resolvable && (typeof note.resolved === 'undefined' || !note.resolved);
|
||||||
// get possible appropers, prefixed with '@' and joined with commas
|
|
||||||
const possibleApprovers = maintainerUsernames
|
|
||||||
.filter(username => {
|
|
||||||
if (mergeRequest.assignee.username === username) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (username.includes('openstapps') || username.includes('kphilipp')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (approval.approved_by.length === 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return approval.approved_by.find(
|
|
||||||
(approver: {
|
|
||||||
/**
|
|
||||||
* Possible approver
|
|
||||||
*/
|
|
||||||
user: User;
|
|
||||||
}) => {
|
|
||||||
return approver.user.username !== username;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.map(username => `@${username}`)
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
// send message to slack
|
|
||||||
await client?.chat.postMessage({
|
|
||||||
channel: SLACK_CHANNEL,
|
|
||||||
text: `Merge request '${mergeRequest.title}' needs more approvals! See ${mergeRequest.web_url}!`,
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// assign reviewers
|
if (hasUnresolvedDiscussions) {
|
||||||
await api.createNote(
|
let recipient = mergeRequest.author.username;
|
||||||
mergeRequest.project_id,
|
|
||||||
Scope.MERGE_REQUESTS,
|
|
||||||
mergeRequest.iid,
|
|
||||||
`/assign_reviewer ${possibleApprovers}`,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
Logger.log(`Merge request '${mergeRequest.title}' is ready to be merged!`);
|
|
||||||
|
|
||||||
// send message to slack
|
if (typeof mergeRequest.assignee !== 'undefined' && mergeRequest.assignee !== null) {
|
||||||
await client?.chat.postMessage({
|
recipient = mergeRequest.assignee.username;
|
||||||
channel: SLACK_CHANNEL,
|
}
|
||||||
text: `Merge request '${mergeRequest.title}' is ready to be merged! See ${mergeRequest.web_url}!`,
|
|
||||||
});
|
|
||||||
|
|
||||||
// prefix maintainers with '@' and join with commas
|
|
||||||
const possibleMergers = maintainerUsernames
|
|
||||||
.filter(username => {
|
|
||||||
return mergeRequest.assignee.username !== username;
|
|
||||||
})
|
|
||||||
.map(username => `@${username}`)
|
|
||||||
.join(', ');
|
|
||||||
|
|
||||||
// create note in merge request
|
// create note in merge request
|
||||||
await api.createNote(
|
await api.createNote(
|
||||||
mergeRequest.project_id,
|
mergeRequest.project_id,
|
||||||
Scope.MERGE_REQUESTS,
|
Scope.MERGE_REQUESTS,
|
||||||
mergeRequest.iid,
|
mergeRequest.iid,
|
||||||
`${NOTE_PREFIX} Merge request is ready to be merged, ${possibleMergers}!`,
|
`${NOTE_PREFIX} Please resolve pending discussions, @${recipient}!`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
if (approval.merge_status === MergeRequestMergeStatus.CAN_BE_MERGED) {
|
||||||
|
if (approval.approvals_left > 0) {
|
||||||
|
Logger.warn(`Merge request '${mergeRequest.title}' needs more approvals!`);
|
||||||
|
|
||||||
|
// get possible appropers, prefixed with '@' and joined with commas
|
||||||
|
const possibleApprovers = maintainerUsernames
|
||||||
|
.filter(username => {
|
||||||
|
if (mergeRequest.assignee.username === username) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (username.includes('openstapps') || username.includes('kphilipp')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (approval.approved_by.length === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return approval.approved_by.find(
|
||||||
|
(approver: {
|
||||||
|
/**
|
||||||
|
* Possible approver
|
||||||
|
*/
|
||||||
|
user: User;
|
||||||
|
}) => {
|
||||||
|
return approver.user.username !== username;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map(username => `@${username}`)
|
||||||
|
.join(' ');
|
||||||
|
|
||||||
|
// send message to slack
|
||||||
|
await client?.chat.postMessage({
|
||||||
|
channel: SLACK_CHANNEL,
|
||||||
|
text: `Merge request '${mergeRequest.title}' needs more approvals! See ${mergeRequest.web_url}!`,
|
||||||
|
});
|
||||||
|
|
||||||
|
// assign reviewers
|
||||||
|
await api.createNote(
|
||||||
|
mergeRequest.project_id,
|
||||||
|
Scope.MERGE_REQUESTS,
|
||||||
|
mergeRequest.iid,
|
||||||
|
`/assign_reviewer ${possibleApprovers}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Logger.log(`Merge request '${mergeRequest.title}' is ready to be merged!`);
|
||||||
|
|
||||||
|
// send message to slack
|
||||||
|
await client?.chat.postMessage({
|
||||||
|
channel: SLACK_CHANNEL,
|
||||||
|
text: `Merge request '${mergeRequest.title}' is ready to be merged! See ${mergeRequest.web_url}!`,
|
||||||
|
});
|
||||||
|
|
||||||
|
// prefix maintainers with '@' and join with commas
|
||||||
|
const possibleMergers = maintainerUsernames
|
||||||
|
.filter(username => {
|
||||||
|
return mergeRequest.assignee.username !== username;
|
||||||
|
})
|
||||||
|
.map(username => `@${username}`)
|
||||||
|
.join(', ');
|
||||||
|
|
||||||
|
// create note in merge request
|
||||||
|
await api.createNote(
|
||||||
|
mergeRequest.project_id,
|
||||||
|
Scope.MERGE_REQUESTS,
|
||||||
|
mergeRequest.iid,
|
||||||
|
`${NOTE_PREFIX} Merge request is ready to be merged, ${possibleMergers}!`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {asyncPool} from '@krlwlfrt/async-pool';
|
|
||||||
import {Api} from '@openstapps/gitlab-api';
|
import {Api} from '@openstapps/gitlab-api';
|
||||||
import {
|
import {
|
||||||
Issue,
|
Issue,
|
||||||
@@ -23,12 +22,16 @@ import {
|
|||||||
User,
|
User,
|
||||||
} from '@openstapps/gitlab-api/lib/types';
|
} from '@openstapps/gitlab-api/lib/types';
|
||||||
import {Logger} from '@openstapps/logger';
|
import {Logger} from '@openstapps/logger';
|
||||||
import moment from 'moment';
|
|
||||||
import {render} from 'mustache';
|
import {render} from 'mustache';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {cwd} from 'process';
|
import {cwd} from 'process';
|
||||||
import {flatten2dArray, getProjects, readFilePromisified, writeFilePromisified} from '../common';
|
import {getProjects} from '../common';
|
||||||
import {BOLD_LABELS, CONCURRENCY, GROUPS, LABEL_WEIGHTS, NEXT_MEETING} from '../configuration';
|
import {BOLD_LABELS, GROUPS, LABEL_WEIGHTS, NEXT_MEETING} from '../configuration';
|
||||||
|
import differenceInWeeks from 'date-fns/differenceInWeeks';
|
||||||
|
import formatISO from 'date-fns/formatISO';
|
||||||
|
import format from 'date-fns/format';
|
||||||
|
import de from 'date-fns/locale/de';
|
||||||
|
import {readFile, writeFile} from 'fs/promises';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A structure for template compilation
|
* A structure for template compilation
|
||||||
@@ -188,13 +191,15 @@ export function getMergeRequestUrls(
|
|||||||
* @param groups List of groups to get issues for
|
* @param groups List of groups to get issues for
|
||||||
*/
|
*/
|
||||||
export async function getIssues(api: Api, label: string, groups: number[]): Promise<Issue[]> {
|
export async function getIssues(api: Api, label: string, groups: number[]): Promise<Issue[]> {
|
||||||
const issueResults = await asyncPool(CONCURRENCY, groups, async groupId => {
|
const issueResults = await Promise.all(
|
||||||
return api.getIssues({
|
groups.map(groupId =>
|
||||||
groupId: groupId,
|
api.getIssues({
|
||||||
});
|
groupId: groupId,
|
||||||
});
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
const issues = flatten2dArray(issueResults).filter(issue => {
|
const issues = issueResults.flat().filter(issue => {
|
||||||
return issue.labels.includes(label);
|
return issue.labels.includes(label);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -212,21 +217,23 @@ export async function getIssues(api: Api, label: string, groups: number[]): Prom
|
|||||||
export async function getIssueBranches(api: Api, projects: Project[]): Promise<{[k: string]: number[]}> {
|
export async function getIssueBranches(api: Api, projects: Project[]): Promise<{[k: string]: number[]}> {
|
||||||
const projectBranches: {[k: string]: number[]} = {};
|
const projectBranches: {[k: string]: number[]} = {};
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, projects, async project => {
|
await Promise.all(
|
||||||
const branches = await api.getBranchesForProject(project.id);
|
projects.map(async project => {
|
||||||
|
const branches = await api.getBranchesForProject(project.id);
|
||||||
|
|
||||||
// extract issue number from branch
|
// extract issue number from branch
|
||||||
projectBranches[project.id] = branches
|
projectBranches[project.id] = branches
|
||||||
.map(branch => {
|
.map(branch => {
|
||||||
return branch.name.split('-')[0];
|
return branch.name.split('-')[0];
|
||||||
})
|
})
|
||||||
.filter(branchNameStart => {
|
.filter(branchNameStart => {
|
||||||
return branchNameStart.match(/^[0-9]+$/);
|
return branchNameStart.match(/^[0-9]+$/);
|
||||||
})
|
})
|
||||||
.map(branchNameStart => {
|
.map(branchNameStart => {
|
||||||
return Number.parseInt(branchNameStart, 10);
|
return Number.parseInt(branchNameStart, 10);
|
||||||
});
|
});
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
return projectBranches;
|
return projectBranches;
|
||||||
}
|
}
|
||||||
@@ -240,14 +247,14 @@ export async function getIssueBranches(api: Api, projects: Project[]): Promise<{
|
|||||||
export async function getIssuesGroupedByAssignees(api: Api, label: string): Promise<AssigneeWithIssues[]> {
|
export async function getIssuesGroupedByAssignees(api: Api, label: string): Promise<AssigneeWithIssues[]> {
|
||||||
const issuesByAssignee: IssuesGroupedByAssigneeId = {};
|
const issuesByAssignee: IssuesGroupedByAssigneeId = {};
|
||||||
|
|
||||||
const groups = flatten2dArray(
|
const groups = await Promise.all(
|
||||||
await asyncPool(CONCURRENCY, GROUPS, async groupId => {
|
GROUPS.map(async groupId => {
|
||||||
const subGroups = await api.getSubGroupsForGroup(groupId);
|
const subGroups = await api.getSubGroupsForGroup(groupId);
|
||||||
return subGroups.map(group => {
|
return subGroups.map(group => {
|
||||||
return group.id;
|
return group.id;
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
);
|
).then(it => it.flat());
|
||||||
groups.push(...groups, ...GROUPS);
|
groups.push(...groups, ...GROUPS);
|
||||||
|
|
||||||
const [issues, projects] = await Promise.all([getIssues(api, label, groups), getProjects(api, groups)]);
|
const [issues, projects] = await Promise.all([getIssues(api, label, groups), getProjects(api, groups)]);
|
||||||
@@ -292,7 +299,7 @@ export async function getIssuesGroupedByAssignees(api: Api, label: string): Prom
|
|||||||
}),
|
}),
|
||||||
$mergeRequestUrl: getMergeRequestUrls(mergeRequests, issue.project_id, issue.iid)[0],
|
$mergeRequestUrl: getMergeRequestUrls(mergeRequests, issue.project_id, issue.iid)[0],
|
||||||
$project: issue.web_url.replace('https://gitlab.com/', '').split('/-/issues/')[0],
|
$project: issue.web_url.replace('https://gitlab.com/', '').split('/-/issues/')[0],
|
||||||
$weeksOpen: moment().diff(moment(issue.created_at), 'weeks'),
|
$weeksOpen: differenceInWeeks(Date.now(), new Date(issue.created_at)),
|
||||||
};
|
};
|
||||||
|
|
||||||
const issueWithMeta: IssueWithMeta = {
|
const issueWithMeta: IssueWithMeta = {
|
||||||
@@ -370,7 +377,7 @@ export async function getIssuesGroupedByAssignees(api: Api, label: string): Prom
|
|||||||
* Get next meeting day
|
* Get next meeting day
|
||||||
*/
|
*/
|
||||||
export function getNextMeetingDay() {
|
export function getNextMeetingDay() {
|
||||||
const meetingDay = NEXT_MEETING.format('YYYY-MM-DD');
|
const meetingDay = formatISO(NEXT_MEETING, {representation: 'date'});
|
||||||
|
|
||||||
// log found meeting day
|
// log found meeting day
|
||||||
Logger.info(`Generating report for '${meetingDay}' of '${GROUPS.length}' group(s)...`);
|
Logger.info(`Generating report for '${meetingDay}' of '${GROUPS.length}' group(s)...`);
|
||||||
@@ -388,35 +395,37 @@ export async function getMergeRequests(api: Api, projects: Project[]): Promise<M
|
|||||||
const projectMergeRequests: MergeRequestsForProjects = {};
|
const projectMergeRequests: MergeRequestsForProjects = {};
|
||||||
|
|
||||||
// iterate over projects
|
// iterate over projects
|
||||||
await asyncPool(CONCURRENCY, projects, async project => {
|
await Promise.all(
|
||||||
// check if project can have merge requests
|
projects.map(async project => {
|
||||||
if (!project.merge_requests_enabled) {
|
// check if project can have merge requests
|
||||||
return;
|
if (!project.merge_requests_enabled) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get all merge requests for project
|
// get all merge requests for project
|
||||||
const mergeRequests = await api.getMergeRequests(
|
const mergeRequests = await api.getMergeRequests(
|
||||||
MembershipScope.PROJECTS,
|
MembershipScope.PROJECTS,
|
||||||
project.id,
|
project.id,
|
||||||
MergeRequestState.OPENED,
|
MergeRequestState.OPENED,
|
||||||
);
|
);
|
||||||
|
|
||||||
// extract issue number from merge request
|
// extract issue number from merge request
|
||||||
projectMergeRequests[project.id] = mergeRequests
|
projectMergeRequests[project.id] = mergeRequests
|
||||||
.map(mergeRequest => {
|
.map(mergeRequest => {
|
||||||
// keep information about web url too
|
// keep information about web url too
|
||||||
return {issue_iid: mergeRequest.source_branch.split('-')[0], web_url: mergeRequest.web_url};
|
return {issue_iid: mergeRequest.source_branch.split('-')[0], web_url: mergeRequest.web_url};
|
||||||
})
|
})
|
||||||
.filter(branchNameStartAndUrl => {
|
.filter(branchNameStartAndUrl => {
|
||||||
return branchNameStartAndUrl.issue_iid.match(/^[0-9]+$/);
|
return branchNameStartAndUrl.issue_iid.match(/^[0-9]+$/);
|
||||||
})
|
})
|
||||||
.map(branchNameStartAndUrl => {
|
.map(branchNameStartAndUrl => {
|
||||||
return {
|
return {
|
||||||
issue_iid: Number.parseInt(branchNameStartAndUrl.issue_iid, 10),
|
issue_iid: Number.parseInt(branchNameStartAndUrl.issue_iid, 10),
|
||||||
web_url: branchNameStartAndUrl.web_url,
|
web_url: branchNameStartAndUrl.web_url,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
return projectMergeRequests;
|
return projectMergeRequests;
|
||||||
}
|
}
|
||||||
@@ -434,7 +443,7 @@ export async function generateReport(api: Api, label: string, template: string):
|
|||||||
const structureForTemplate: StructureForTemplate = {
|
const structureForTemplate: StructureForTemplate = {
|
||||||
issuesByAssignee: issuesGroupedByAssignee,
|
issuesByAssignee: issuesGroupedByAssignee,
|
||||||
meetingDay: getNextMeetingDay(),
|
meetingDay: getNextMeetingDay(),
|
||||||
timestamp: moment().format('LLL'),
|
timestamp: format(Date.now(), 'PPPPpp', {locale: de}),
|
||||||
};
|
};
|
||||||
|
|
||||||
return render(template, structureForTemplate);
|
return render(template, structureForTemplate);
|
||||||
@@ -449,7 +458,7 @@ export async function generateReport(api: Api, label: string, template: string):
|
|||||||
export async function report(api: Api, label: string) {
|
export async function report(api: Api, label: string) {
|
||||||
const meetingDay = getNextMeetingDay();
|
const meetingDay = getNextMeetingDay();
|
||||||
|
|
||||||
const readReportFile = await readFilePromisified(
|
const readReportFile = await readFile(
|
||||||
// eslint-disable-next-line unicorn/prefer-module
|
// eslint-disable-next-line unicorn/prefer-module
|
||||||
path.resolve(__dirname, '..', '..', 'templates', 'report.md.mustache'),
|
path.resolve(__dirname, '..', '..', 'templates', 'report.md.mustache'),
|
||||||
);
|
);
|
||||||
@@ -462,7 +471,7 @@ export async function report(api: Api, label: string) {
|
|||||||
filename = path.join(cwd(), 'reports', `${label}.md`);
|
filename = path.join(cwd(), 'reports', `${label}.md`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await writeFilePromisified(filename, markdown);
|
await writeFile(filename, markdown);
|
||||||
|
|
||||||
Logger.ok(`Wrote file '${filename}'.`);
|
Logger.ok(`Wrote file '${filename}'.`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {asyncPool} from '@krlwlfrt/async-pool';
|
|
||||||
import {Api} from '@openstapps/gitlab-api';
|
import {Api} from '@openstapps/gitlab-api';
|
||||||
import {
|
import {
|
||||||
AccessLevel,
|
AccessLevel,
|
||||||
@@ -24,9 +23,8 @@ import {
|
|||||||
Scope,
|
Scope,
|
||||||
} from '@openstapps/gitlab-api/lib/types';
|
} from '@openstapps/gitlab-api/lib/types';
|
||||||
import {Logger} from '@openstapps/logger';
|
import {Logger} from '@openstapps/logger';
|
||||||
import {flatten2dArray, getProjects} from '../common';
|
import {getProjects} from '../common';
|
||||||
import {
|
import {
|
||||||
CONCURRENCY,
|
|
||||||
GROUPS,
|
GROUPS,
|
||||||
NEEDED_LABELS,
|
NEEDED_LABELS,
|
||||||
NEEDED_MILESTONES,
|
NEEDED_MILESTONES,
|
||||||
@@ -44,51 +42,52 @@ import {
|
|||||||
*/
|
*/
|
||||||
export async function tidyIssuesWithoutMilestone(api: Api): Promise<void> {
|
export async function tidyIssuesWithoutMilestone(api: Api): Promise<void> {
|
||||||
// fetch issues without milestone from all groups
|
// fetch issues without milestone from all groups
|
||||||
const issueResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => {
|
const issuesWithoutMilestone = await Promise.all(
|
||||||
return api.getIssues({
|
GROUPS.map(groupId =>
|
||||||
groupId: groupId,
|
api.getIssues({
|
||||||
milestone: 'No Milestone',
|
groupId: groupId,
|
||||||
state: IssueState.OPENED,
|
milestone: 'No Milestone',
|
||||||
});
|
state: IssueState.OPENED,
|
||||||
});
|
}),
|
||||||
|
),
|
||||||
// flatten structure, e.g. put all issues in one array
|
).then(it => it.flat());
|
||||||
const issuesWithoutMilestone = flatten2dArray(issueResults);
|
|
||||||
|
|
||||||
Logger.info(`Found '${issuesWithoutMilestone.length}' issue(s) without milestone.`);
|
Logger.info(`Found '${issuesWithoutMilestone.length}' issue(s) without milestone.`);
|
||||||
|
|
||||||
const milestoneCache: {[s: number]: Milestone[]} = {};
|
const milestoneCache: {[s: number]: Milestone[]} = {};
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, issuesWithoutMilestone, async issue => {
|
await Promise.all(
|
||||||
if (typeof milestoneCache[issue.project_id] === 'undefined') {
|
issuesWithoutMilestone.map(async issue => {
|
||||||
milestoneCache[issue.project_id] = await api.getMilestonesForProject(issue.project_id);
|
if (typeof milestoneCache[issue.project_id] === 'undefined') {
|
||||||
}
|
milestoneCache[issue.project_id] = await api.getMilestonesForProject(issue.project_id);
|
||||||
|
|
||||||
let milestoneId;
|
|
||||||
|
|
||||||
for (const milestone of milestoneCache[issue.project_id]) {
|
|
||||||
if (milestone.title === 'Meeting') {
|
|
||||||
milestoneId = milestone.id;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof milestoneId === 'undefined') {
|
let milestoneId;
|
||||||
Logger.warn(`Milestone 'Meeting' was not available for issue ${issue.title} (${issue.web_url}).`);
|
|
||||||
|
|
||||||
return;
|
for (const milestone of milestoneCache[issue.project_id]) {
|
||||||
}
|
if (milestone.title === 'Meeting') {
|
||||||
|
milestoneId = milestone.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await api.setMilestoneForIssue(issue, milestoneId);
|
if (typeof milestoneId === 'undefined') {
|
||||||
|
Logger.warn(`Milestone 'Meeting' was not available for issue ${issue.title} (${issue.web_url}).`);
|
||||||
|
|
||||||
Logger.log(`Milestone was set to 'Meeting' for issue ${issue.title} (${issue.web_url})`);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await api.createNote(
|
await api.setMilestoneForIssue(issue, milestoneId);
|
||||||
issue.project_id,
|
|
||||||
Scope.ISSUES,
|
Logger.log(`Milestone was set to 'Meeting' for issue ${issue.title} (${issue.web_url})`);
|
||||||
issue.iid,
|
|
||||||
`${NOTE_PREFIX} Milestone was set automatically to 'Meeting'.`,
|
await api.createNote(
|
||||||
);
|
issue.project_id,
|
||||||
});
|
Scope.ISSUES,
|
||||||
|
issue.iid,
|
||||||
|
`${NOTE_PREFIX} Milestone was set automatically to 'Meeting'.`,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok('Tidied issues without milestones.');
|
Logger.ok('Tidied issues without milestones.');
|
||||||
}
|
}
|
||||||
@@ -102,15 +101,14 @@ export async function tidyIssuesWithoutMilestone(api: Api): Promise<void> {
|
|||||||
*/
|
*/
|
||||||
export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise<void> {
|
export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise<void> {
|
||||||
// fetch all open issues
|
// fetch all open issues
|
||||||
const issueResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => {
|
const openIssues = await Promise.all(
|
||||||
return api.getIssues({
|
GROUPS.map(groupId =>
|
||||||
groupId: groupId,
|
api.getIssues({
|
||||||
state: IssueState.OPENED,
|
groupId: groupId,
|
||||||
});
|
state: IssueState.OPENED,
|
||||||
});
|
}),
|
||||||
|
),
|
||||||
// flatten structure, e.g. put all issues in one array
|
).then(it => it.flat());
|
||||||
const openIssues = flatten2dArray(issueResults);
|
|
||||||
|
|
||||||
Logger.info(`Found ${openIssues.length} open issue(s).`);
|
Logger.info(`Found ${openIssues.length} open issue(s).`);
|
||||||
|
|
||||||
@@ -121,20 +119,22 @@ export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise<void>
|
|||||||
|
|
||||||
Logger.info(`Filtered ${openIssuesWithoutMeetingLabel.length} open issue(s) without label 'meeting'.`);
|
Logger.info(`Filtered ${openIssuesWithoutMeetingLabel.length} open issue(s) without label 'meeting'.`);
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, openIssuesWithoutMeetingLabel, async issue => {
|
await Promise.all(
|
||||||
if (issue.milestone !== null && issue.milestone.title === 'Backlog') {
|
openIssuesWithoutMeetingLabel.map(async issue => {
|
||||||
Logger.info(`Skipping issue "${issue.title}" because it is in backlog.`);
|
if (issue.milestone !== null && issue.milestone.title === 'Backlog') {
|
||||||
|
Logger.info(`Skipping issue "${issue.title}" because it is in backlog.`);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.createNote(
|
return api.createNote(
|
||||||
issue.project_id,
|
issue.project_id,
|
||||||
Scope.ISSUES,
|
Scope.ISSUES,
|
||||||
issue.iid,
|
issue.iid,
|
||||||
`${NOTE_PREFIX} Automatically adding label 'meeting'\n\n/label ~meeting`,
|
`${NOTE_PREFIX} Automatically adding label 'meeting'\n\n/label ~meeting`,
|
||||||
);
|
);
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok(`Tidied open issues without label 'meeting'.`);
|
Logger.ok(`Tidied open issues without label 'meeting'.`);
|
||||||
}
|
}
|
||||||
@@ -146,39 +146,43 @@ export async function tidyOpenIssuesWithoutMeetingLabel(api: Api): Promise<void>
|
|||||||
* @param projects List of projects to tidy labels on
|
* @param projects List of projects to tidy labels on
|
||||||
*/
|
*/
|
||||||
export async function tidyLabels(api: Api, projects: Project[]): Promise<void> {
|
export async function tidyLabels(api: Api, projects: Project[]): Promise<void> {
|
||||||
await asyncPool(CONCURRENCY, projects, async project => {
|
await Promise.all(
|
||||||
const labels = await api.getLabels(project.id);
|
projects.map(async project => {
|
||||||
|
const labels = await api.getLabels(project.id);
|
||||||
|
|
||||||
const neededLabels = [...NEEDED_LABELS];
|
const neededLabels = [...NEEDED_LABELS];
|
||||||
// const extraneousLabels: Label[] = [];
|
// const extraneousLabels: Label[] = [];
|
||||||
|
|
||||||
for (const label of labels) {
|
for (const label of labels) {
|
||||||
// let needed = false;
|
// let needed = false;
|
||||||
|
|
||||||
for (const [neededLabelIndex, neededLabel] of neededLabels.entries()) {
|
for (const [neededLabelIndex, neededLabel] of neededLabels.entries()) {
|
||||||
if (neededLabel.name.toLowerCase() === label.name.toLowerCase()) {
|
if (neededLabel.name.toLowerCase() === label.name.toLowerCase()) {
|
||||||
neededLabels.splice(neededLabelIndex, 1);
|
neededLabels.splice(neededLabelIndex, 1);
|
||||||
// needed = true;
|
// needed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* if (!needed) {
|
/* if (!needed) {
|
||||||
extraneousLabels.push(label);
|
extraneousLabels.push(label);
|
||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, neededLabels, async neededLabel => {
|
await Promise.all(
|
||||||
await api.createLabel(project.id, neededLabel.name, neededLabel.description, neededLabel.color);
|
neededLabels.map(async neededLabel => {
|
||||||
|
await api.createLabel(project.id, neededLabel.name, neededLabel.description, neededLabel.color);
|
||||||
|
|
||||||
Logger.log(`Created label '${neededLabel.name}' in '${project.name_with_namespace}'.`);
|
Logger.log(`Created label '${neededLabel.name}' in '${project.name_with_namespace}'.`);
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// await asyncPool(2, extraneousLabels, async (extraneousLabel) => {
|
// await asyncPool(2, extraneousLabels, async (extraneousLabel) => {
|
||||||
// await api.deleteLabel(project.id, extraneousLabel.name);
|
// await api.deleteLabel(project.id, extraneousLabel.name);
|
||||||
//
|
//
|
||||||
// Logger.log('Deleted label `' + extraneousLabel.name + '` from ' + project.name_with_namespace + '.');
|
// Logger.log('Deleted label `' + extraneousLabel.name + '` from ' + project.name_with_namespace + '.');
|
||||||
// });
|
// });
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok('Tidied labels.');
|
Logger.ok('Tidied labels.');
|
||||||
}
|
}
|
||||||
@@ -190,25 +194,29 @@ export async function tidyLabels(api: Api, projects: Project[]): Promise<void> {
|
|||||||
* @param projects List of projects to tidy milestones on
|
* @param projects List of projects to tidy milestones on
|
||||||
*/
|
*/
|
||||||
export async function tidyMilestones(api: Api, projects: Project[]): Promise<void> {
|
export async function tidyMilestones(api: Api, projects: Project[]): Promise<void> {
|
||||||
await asyncPool(CONCURRENCY, projects, async project => {
|
await Promise.all(
|
||||||
const milestones = await api.getMilestonesForProject(project.id);
|
projects.map(async project => {
|
||||||
const missingMilestones = [...NEEDED_MILESTONES];
|
const milestones = await api.getMilestonesForProject(project.id);
|
||||||
|
const missingMilestones = [...NEEDED_MILESTONES];
|
||||||
|
|
||||||
for (const milestone of milestones) {
|
for (const milestone of milestones) {
|
||||||
const index = missingMilestones.indexOf(milestone.title);
|
const index = missingMilestones.indexOf(milestone.title);
|
||||||
|
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
missingMilestones.splice(index, 1);
|
missingMilestones.splice(index, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (missingMilestones.length > 0 && !project.archived) {
|
if (missingMilestones.length > 0 && !project.archived) {
|
||||||
await asyncPool(CONCURRENCY, missingMilestones, async milestone => {
|
await Promise.all(
|
||||||
await api.createMilestone(project.id, milestone);
|
missingMilestones.map(async milestone => {
|
||||||
Logger.log(`Created milestone '${milestone}' for project ${project.name_with_namespace}'.`);
|
await api.createMilestone(project.id, milestone);
|
||||||
});
|
Logger.log(`Created milestone '${milestone}' for project ${project.name_with_namespace}'.`);
|
||||||
}
|
}),
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok('Tidied milestones.');
|
Logger.ok('Tidied milestones.');
|
||||||
}
|
}
|
||||||
@@ -220,23 +228,29 @@ export async function tidyMilestones(api: Api, projects: Project[]): Promise<voi
|
|||||||
* @param projects List of projects to tidy milestones on
|
* @param projects List of projects to tidy milestones on
|
||||||
*/
|
*/
|
||||||
export async function tidyProtectedBranches(api: Api, projects: Project[]): Promise<void> {
|
export async function tidyProtectedBranches(api: Api, projects: Project[]): Promise<void> {
|
||||||
await asyncPool(CONCURRENCY, projects, async project => {
|
await Promise.all(
|
||||||
const branches = await api.getBranchesForProject(project.id);
|
projects.map(async project => {
|
||||||
|
const branches = await api.getBranchesForProject(project.id);
|
||||||
|
|
||||||
const protectableBranches = branches.filter(branch => {
|
const protectableBranches = branches.filter(branch => {
|
||||||
return PROTECTED_BRANCHES.includes(branch.name);
|
return PROTECTED_BRANCHES.includes(branch.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
const unprotectedBranches = protectableBranches.filter(branch => {
|
const unprotectedBranches = protectableBranches.filter(branch => {
|
||||||
return !branch.protected;
|
return !branch.protected;
|
||||||
});
|
});
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, unprotectedBranches, async branch => {
|
await Promise.all(
|
||||||
await api.protectBranch(project.id, branch.name);
|
unprotectedBranches.map(async branch => {
|
||||||
|
await api.protectBranch(project.id, branch.name);
|
||||||
|
|
||||||
Logger.log(`Added protected branch '${branch.name}' in project '${project.name_with_namespace}'...`);
|
Logger.log(
|
||||||
});
|
`Added protected branch '${branch.name}' in project '${project.name_with_namespace}'...`,
|
||||||
});
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok('Tidied protected branches.');
|
Logger.ok('Tidied protected branches.');
|
||||||
}
|
}
|
||||||
@@ -248,44 +262,48 @@ export async function tidyProtectedBranches(api: Api, projects: Project[]): Prom
|
|||||||
* @param projects List of projects to tidy protected tags on
|
* @param projects List of projects to tidy protected tags on
|
||||||
*/
|
*/
|
||||||
export async function tidyProtectedTags(api: Api, projects: Project[]): Promise<void> {
|
export async function tidyProtectedTags(api: Api, projects: Project[]): Promise<void> {
|
||||||
await asyncPool(CONCURRENCY, projects, async project => {
|
await Promise.all(
|
||||||
// TODO: move this to GitLab API
|
projects.map(async project => {
|
||||||
const protectedTags = (await api.makeGitLabAPIRequest(`projects/${project.id}/protected_tags`)) as Array<{
|
// TODO: move this to GitLab API
|
||||||
/**
|
const protectedTags = (await api.makeGitLabAPIRequest(
|
||||||
* List of access levels to create a tag
|
`projects/${project.id}/protected_tags`,
|
||||||
*/
|
)) as Array<{
|
||||||
create_access_levels: Array<{
|
|
||||||
/**
|
/**
|
||||||
* Access level
|
* List of access levels to create a tag
|
||||||
*/
|
*/
|
||||||
access_level: AccessLevel;
|
create_access_levels: Array<{
|
||||||
|
/**
|
||||||
|
* Access level
|
||||||
|
*/
|
||||||
|
access_level: AccessLevel;
|
||||||
|
/**
|
||||||
|
* Description of access level
|
||||||
|
*/
|
||||||
|
access_level_description: string;
|
||||||
|
}>;
|
||||||
/**
|
/**
|
||||||
* Description of access level
|
* Name of the tag
|
||||||
*/
|
*/
|
||||||
access_level_description: string;
|
name: string;
|
||||||
}>;
|
}>;
|
||||||
/**
|
|
||||||
* Name of the tag
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
protectedTags.findIndex(protectedTag => {
|
protectedTags.findIndex(protectedTag => {
|
||||||
return protectedTag.name === 'v*';
|
return protectedTag.name === 'v*';
|
||||||
}) === -1
|
}) === -1
|
||||||
) {
|
) {
|
||||||
await api.makeGitLabAPIRequest(`projects/${project.id}/protected_tags`, {
|
await api.makeGitLabAPIRequest(`projects/${project.id}/protected_tags`, {
|
||||||
data: {
|
data: {
|
||||||
create_access_level: AccessLevel.Maintainer,
|
create_access_level: AccessLevel.Maintainer,
|
||||||
name: 'v*',
|
name: 'v*',
|
||||||
},
|
},
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
});
|
});
|
||||||
|
|
||||||
Logger.log(`Added protected version tag in project '${project.name_with_namespace}'.`);
|
Logger.log(`Added protected version tag in project '${project.name_with_namespace}'.`);
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok('Tidied protected tags.');
|
Logger.ok('Tidied protected tags.');
|
||||||
}
|
}
|
||||||
@@ -305,26 +323,32 @@ export async function tidySubGroupMembers(api: Api): Promise<void> {
|
|||||||
groupIdsToSchool[SCHOOLS[school]] = school;
|
groupIdsToSchool[SCHOOLS[school]] = school;
|
||||||
});
|
});
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, GROUPS.slice(1), async groupId => {
|
await Promise.all(
|
||||||
const members = await api.getMembers(MembershipScope.GROUPS, groupId);
|
GROUPS.slice(1).map(async groupId => {
|
||||||
const memberIds = new Set(members.map(member => member.id));
|
const members = await api.getMembers(MembershipScope.GROUPS, groupId);
|
||||||
|
const memberIds = new Set(members.map(member => member.id));
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, stappsMembers, async stappsMember => {
|
await Promise.all(
|
||||||
if (!memberIds.has(stappsMember.id)) {
|
stappsMembers.map(async stappsMember => {
|
||||||
await api.addMember(MembershipScope.GROUPS, groupId, stappsMember.id, AccessLevel.Developer);
|
if (!memberIds.has(stappsMember.id)) {
|
||||||
|
await api.addMember(MembershipScope.GROUPS, groupId, stappsMember.id, AccessLevel.Developer);
|
||||||
|
|
||||||
Logger.log(`Added '${stappsMember.name}' to group '${groupIdsToSchool[groupId]}'.`);
|
Logger.log(`Added '${stappsMember.name}' to group '${groupIdsToSchool[groupId]}'.`);
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, members, async member => {
|
await Promise.all(
|
||||||
if (!stappsMemberIds.has(member.id)) {
|
members.map(async member => {
|
||||||
await api.deleteMember(MembershipScope.GROUPS, groupId, member.id);
|
if (!stappsMemberIds.has(member.id)) {
|
||||||
|
await api.deleteMember(MembershipScope.GROUPS, groupId, member.id);
|
||||||
|
|
||||||
Logger.log(`Deleted member '${member.name}' from group '${groupIdsToSchool[groupId]}'.`);
|
Logger.log(`Deleted member '${member.name}' from group '${groupIdsToSchool[groupId]}'.`);
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
});
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok(`Tidied 'sub' group members.`);
|
Logger.ok(`Tidied 'sub' group members.`);
|
||||||
}
|
}
|
||||||
@@ -338,15 +362,14 @@ export async function tidySubGroupMembers(api: Api): Promise<void> {
|
|||||||
*/
|
*/
|
||||||
export async function tidyIssuesWithoutAssignee(api: Api): Promise<void> {
|
export async function tidyIssuesWithoutAssignee(api: Api): Promise<void> {
|
||||||
// fetch issues without milestone from all groups
|
// fetch issues without milestone from all groups
|
||||||
const issueResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => {
|
const issues = await Promise.all(
|
||||||
return api.getIssues({
|
GROUPS.map(async groupId => {
|
||||||
groupId: groupId,
|
return api.getIssues({
|
||||||
state: IssueState.OPENED,
|
groupId: groupId,
|
||||||
});
|
state: IssueState.OPENED,
|
||||||
});
|
});
|
||||||
|
}),
|
||||||
// flatten structure, e.g. put all issues in one array
|
).then(it => it.flat());
|
||||||
const issues = flatten2dArray(issueResults);
|
|
||||||
|
|
||||||
const issuesWithoutAssignee = issues.filter(issue => {
|
const issuesWithoutAssignee = issues.filter(issue => {
|
||||||
return issue.assignee === null;
|
return issue.assignee === null;
|
||||||
@@ -354,18 +377,20 @@ export async function tidyIssuesWithoutAssignee(api: Api): Promise<void> {
|
|||||||
|
|
||||||
Logger.info(`Found '${issuesWithoutAssignee.length}' issue(s) without assignee.`);
|
Logger.info(`Found '${issuesWithoutAssignee.length}' issue(s) without assignee.`);
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, issuesWithoutAssignee, async issue => {
|
await Promise.all(
|
||||||
await api.setAssigneeForIssue(issue, issue.author.id);
|
issuesWithoutAssignee.map(async issue => {
|
||||||
|
await api.setAssigneeForIssue(issue, issue.author.id);
|
||||||
|
|
||||||
Logger.log(`Set assignee for '${issue.title}' to '${issue.author.name}'.`);
|
Logger.log(`Set assignee for '${issue.title}' to '${issue.author.name}'.`);
|
||||||
|
|
||||||
await api.createNote(
|
await api.createNote(
|
||||||
issue.project_id,
|
issue.project_id,
|
||||||
Scope.ISSUES,
|
Scope.ISSUES,
|
||||||
issue.iid,
|
issue.iid,
|
||||||
`${NOTE_PREFIX} Assignee was set automatically to author.`,
|
`${NOTE_PREFIX} Assignee was set automatically to author.`,
|
||||||
);
|
);
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok('Tidied issues without assignee.');
|
Logger.ok('Tidied issues without assignee.');
|
||||||
}
|
}
|
||||||
@@ -378,12 +403,11 @@ export async function tidyIssuesWithoutAssignee(api: Api): Promise<void> {
|
|||||||
* @param api GitLab API instance to use for the requests
|
* @param api GitLab API instance to use for the requests
|
||||||
*/
|
*/
|
||||||
export async function tidyMergeRequestsWithoutAssignee(api: Api): Promise<void> {
|
export async function tidyMergeRequestsWithoutAssignee(api: Api): Promise<void> {
|
||||||
const mergeRequestResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => {
|
const mergeRequests = await Promise.all(
|
||||||
return api.getMergeRequests(MembershipScope.GROUPS, groupId, MergeRequestState.OPENED);
|
GROUPS.map(async groupId => {
|
||||||
});
|
return api.getMergeRequests(MembershipScope.GROUPS, groupId, MergeRequestState.OPENED);
|
||||||
|
}),
|
||||||
// flatten structure, e.g. put all issues in one array
|
).then(it => it.flat());
|
||||||
const mergeRequests = flatten2dArray(mergeRequestResults);
|
|
||||||
|
|
||||||
const mergeRequestsWithoutAssignee = mergeRequests.filter(mergeRequest => {
|
const mergeRequestsWithoutAssignee = mergeRequests.filter(mergeRequest => {
|
||||||
return mergeRequest.assignee === null;
|
return mergeRequest.assignee === null;
|
||||||
@@ -391,18 +415,20 @@ export async function tidyMergeRequestsWithoutAssignee(api: Api): Promise<void>
|
|||||||
|
|
||||||
Logger.info(`Found '${mergeRequestsWithoutAssignee.length}' merge requests without assignee.`);
|
Logger.info(`Found '${mergeRequestsWithoutAssignee.length}' merge requests without assignee.`);
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, mergeRequestsWithoutAssignee, async mergeRequest => {
|
await Promise.all(
|
||||||
await api.setAssigneeForMergeRequest(mergeRequest, mergeRequest.author.id);
|
mergeRequestsWithoutAssignee.map(async mergeRequest => {
|
||||||
|
await api.setAssigneeForMergeRequest(mergeRequest, mergeRequest.author.id);
|
||||||
|
|
||||||
Logger.log(`Set assignee for '${mergeRequest.title}' to '${mergeRequest.author.name}'.`);
|
Logger.log(`Set assignee for '${mergeRequest.title}' to '${mergeRequest.author.name}'.`);
|
||||||
|
|
||||||
await api.createNote(
|
await api.createNote(
|
||||||
mergeRequest.project_id,
|
mergeRequest.project_id,
|
||||||
Scope.MERGE_REQUESTS,
|
Scope.MERGE_REQUESTS,
|
||||||
mergeRequest.iid,
|
mergeRequest.iid,
|
||||||
`${NOTE_PREFIX} Assignee was set automatically to author.`,
|
`${NOTE_PREFIX} Assignee was set automatically to author.`,
|
||||||
);
|
);
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok('Tidied merge requests without assignee.');
|
Logger.ok('Tidied merge requests without assignee.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,11 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {asyncPool} from '@krlwlfrt/async-pool';
|
|
||||||
import {Api} from '@openstapps/gitlab-api';
|
import {Api} from '@openstapps/gitlab-api';
|
||||||
import {IssueState, Scope} from '@openstapps/gitlab-api/lib/types';
|
import {IssueState, Scope} from '@openstapps/gitlab-api/lib/types';
|
||||||
import {Logger} from '@openstapps/logger';
|
import {Logger} from '@openstapps/logger';
|
||||||
import moment from 'moment';
|
import {GROUPS, LAST_MEETING, NOTE_PREFIX} from '../configuration';
|
||||||
import {flatten2dArray} from '../common';
|
import isBefore from 'date-fns/isBefore';
|
||||||
import {CONCURRENCY, GROUPS, LAST_MEETING, NOTE_PREFIX} from '../configuration';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove label `meeting` from closed issues
|
* Remove label `meeting` from closed issues
|
||||||
@@ -26,34 +24,38 @@ import {CONCURRENCY, GROUPS, LAST_MEETING, NOTE_PREFIX} from '../configuration';
|
|||||||
* @param api Instance of GitLabAPI to send requests with
|
* @param api Instance of GitLabAPI to send requests with
|
||||||
*/
|
*/
|
||||||
export async function unlabel(api: Api) {
|
export async function unlabel(api: Api) {
|
||||||
const issueResults = await asyncPool(CONCURRENCY, GROUPS, async groupId => {
|
const issues = await Promise.all(
|
||||||
return api.getIssues({
|
GROUPS.map(async groupId => {
|
||||||
groupId: groupId,
|
return api.getIssues({
|
||||||
state: IssueState.CLOSED,
|
groupId: groupId,
|
||||||
});
|
state: IssueState.CLOSED,
|
||||||
});
|
});
|
||||||
|
}),
|
||||||
const issues = flatten2dArray(issueResults);
|
).then(it => it.flat());
|
||||||
|
|
||||||
Logger.log(`Fetched ${issues.length} closed issue(s).`);
|
Logger.log(`Fetched ${issues.length} closed issue(s).`);
|
||||||
|
|
||||||
await asyncPool(CONCURRENCY, issues, async issue => {
|
await Promise.all(
|
||||||
if (
|
issues.map(async issue => {
|
||||||
issue.labels.includes('meeting') &&
|
if (
|
||||||
issue.closed_at !== null &&
|
issue.labels.includes('meeting') &&
|
||||||
moment(issue.closed_at).isBefore(LAST_MEETING)
|
issue.closed_at !== null &&
|
||||||
) {
|
isBefore(new Date(issue.closed_at), LAST_MEETING)
|
||||||
Logger.info(`Issue ${issue.title} is closed before last meeting and has label "meeting". Removing it.`);
|
) {
|
||||||
|
Logger.info(
|
||||||
|
`Issue ${issue.title} is closed before last meeting and has label "meeting". Removing it.`,
|
||||||
|
);
|
||||||
|
|
||||||
await api.createNote(
|
await api.createNote(
|
||||||
issue.project_id,
|
issue.project_id,
|
||||||
Scope.ISSUES,
|
Scope.ISSUES,
|
||||||
issue.iid,
|
issue.iid,
|
||||||
`${NOTE_PREFIX} Removed label \`meeting\` automatically.
|
`${NOTE_PREFIX} Removed label \`meeting\` automatically.
|
||||||
/unlabel ~meeting`,
|
/unlabel ~meeting`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
Logger.ok('Label `meeting` has been removed from closed issues.');
|
Logger.ok('Label `meeting` has been removed from closed issues.');
|
||||||
}
|
}
|
||||||
|
|||||||
5839
examples/minimal-connector/package-lock.json
generated
5839
examples/minimal-connector/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,60 +1,55 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/minimal-connector",
|
"name": "@openstapps/minimal-connector",
|
||||||
"version": "0.2.0",
|
|
||||||
"description": "This is a minimal connector which serves as an example",
|
"description": "This is a minimal connector which serves as an example",
|
||||||
"repository": {
|
"version": "2.1.0",
|
||||||
"type": "git",
|
|
||||||
"url": "git@gitlab.com:openstapps/minimal-connector.git"
|
|
||||||
},
|
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
|
"repository": "git@gitlab.com:openstapps/minimal-connector.git",
|
||||||
"author": "Anselm Stordeur <anselmstordeur@gmail.com>",
|
"author": "Anselm Stordeur <anselmstordeur@gmail.com>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Jovan Krunić <jovan.krunic@gmail.com>",
|
"Jovan Krunić <jovan.krunic@gmail.com>",
|
||||||
"Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
"Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
||||||
"Rainer Killinger <git@killinger.co>",
|
"Michel Jonathan Schmitz <michel.schmitz1992@gmail.com>",
|
||||||
"Michel Jonathan Schmitz <michel.schmitz1992@gmail.com>"
|
"Rainer Killinger <git@killinger.co>"
|
||||||
],
|
],
|
||||||
"main": "lib/cli.js",
|
"main": "lib/cli.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run tslint && npm run compile",
|
"build": "npm run compile",
|
||||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
||||||
"check-configuration": "openstapps-configuration",
|
"check-configuration": "openstapps-configuration",
|
||||||
"compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'",
|
"compile": "rimraf lib && tsc",
|
||||||
"documentation": "typedoc --includeDeclarations --mode modules --out docs --readme README.md --listInvalidSymbolLinks src",
|
"documentation": "typedoc --includeDeclarations --mode modules --out docs --readme README.md --listInvalidSymbolLinks src",
|
||||||
|
"lint": "tslint -p tsconfig.json -c tslint.json 'src/**/*.ts'",
|
||||||
"postversion": "npm run changelog",
|
"postversion": "npm run changelog",
|
||||||
"prepublishOnly": "npm ci && npm run build",
|
"prepublishOnly": "npm ci && npm run build",
|
||||||
"preversion": "npm run prepublishOnly",
|
"preversion": "npm run prepublishOnly",
|
||||||
"push": "git push && git push origin \"v$npm_package_version\"",
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
"test": "nyc mocha --require ts-node/register --require source-map-support/register --recursive 'test/*.spec.ts'",
|
"test": "nyc mocha --require ts-node/register --require source-map-support/register --recursive 'test/*.spec.ts'"
|
||||||
"tslint": "tslint -p tsconfig.json -c tslint.json 'src/**/*.ts'"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openstapps/api": "0.28.0",
|
"@openstapps/api": "workspace:*",
|
||||||
"@openstapps/core": "0.46.0",
|
"@openstapps/core": "workspace:*",
|
||||||
"@openstapps/logger": "0.7.0",
|
"@openstapps/logger": "workspace:*",
|
||||||
"commander": "6.2.1"
|
"commander": "10.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/configuration": "0.27.0",
|
"@openstapps/configuration": "workspace:*",
|
||||||
"@openstapps/core-tools": "0.21.0",
|
"@openstapps/core-tools": "workspace:*",
|
||||||
"@testdeck/mocha": "0.1.2",
|
"@testdeck/mocha": "0.3.3",
|
||||||
"@types/chai": "4.2.18",
|
"@types/chai": "4.3.4",
|
||||||
"@types/chai-as-promised": "7.1.4",
|
"@types/chai-as-promised": "7.1.5",
|
||||||
"@types/mocha": "8.2.2",
|
"@types/mocha": "10.0.1",
|
||||||
"@types/node": "14.17.1",
|
"@types/node": "18.15.3",
|
||||||
"chai": "4.3.4",
|
"chai": "4.3.7",
|
||||||
"chai-as-promised": "7.1.1",
|
"chai-as-promised": "7.1.1",
|
||||||
"conventional-changelog-cli": "2.1.1",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
"mocha": "8.4.0",
|
"mocha": "10.2.0",
|
||||||
"nock": "13.1.0",
|
"nock": "13.3.0",
|
||||||
"nyc": "15.1.0",
|
"nyc": "15.1.0",
|
||||||
"prepend-file-cli": "1.0.6",
|
"rimraf": "4.4.0",
|
||||||
"rimraf": "3.0.2",
|
"ts-node": "10.9.1",
|
||||||
"ts-node": "9.1.1",
|
"typedoc": "0.22.18",
|
||||||
"tslint": "6.1.3",
|
"typescript": "4.4.4"
|
||||||
"typedoc": "0.18.0",
|
|
||||||
"typescript": "3.8.3"
|
|
||||||
},
|
},
|
||||||
"nyc": {
|
"nyc": {
|
||||||
"all": true,
|
"all": true,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018, 2019 StApps
|
* Copyright (C) 2018, 2019 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export abstract class Connector<T extends SCThings> {
|
|||||||
*
|
*
|
||||||
* Implementation according to your schools requirements
|
* Implementation according to your schools requirements
|
||||||
*/
|
*/
|
||||||
protected abstract async fetchItems(): Promise<T[]>;
|
protected abstract fetchItems(): Promise<T[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a remote origin with the current date-time
|
* Creates a remote origin with the current date-time
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ export class MinimalConnector extends Connector<SCMessage> {
|
|||||||
const importedItems: SCMessage[] = [
|
const importedItems: SCMessage[] = [
|
||||||
{
|
{
|
||||||
audiences: ['students', 'employees'],
|
audiences: ['students', 'employees'],
|
||||||
|
categories: [],
|
||||||
description: 'Some description 1',
|
description: 'Some description 1',
|
||||||
messageBody: 'Some message 1',
|
messageBody: 'Some message 1',
|
||||||
name: 'Some name 1',
|
name: 'Some name 1',
|
||||||
@@ -62,6 +63,7 @@ export class MinimalConnector extends Connector<SCMessage> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
audiences: ['students', 'employees'],
|
audiences: ['students', 'employees'],
|
||||||
|
categories: [],
|
||||||
description: 'Some description 2',
|
description: 'Some description 2',
|
||||||
messageBody: 'Some message 2',
|
messageBody: 'Some message 2',
|
||||||
name: 'Some name 2',
|
name: 'Some name 2',
|
||||||
@@ -71,6 +73,7 @@ export class MinimalConnector extends Connector<SCMessage> {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
audiences: ['students', 'employees'],
|
audiences: ['students', 'employees'],
|
||||||
|
categories: [],
|
||||||
description: 'Some description 3',
|
description: 'Some description 3',
|
||||||
messageBody: 'Some message 3',
|
messageBody: 'Some message 3',
|
||||||
name: 'Some name 3',
|
name: 'Some name 3',
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./node_modules/@openstapps/configuration/tslint.json"
|
|
||||||
}
|
|
||||||
4113
examples/minimal-plugin/package-lock.json
generated
4113
examples/minimal-plugin/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,44 +1,42 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/minimal-plugin",
|
"name": "@openstapps/minimal-plugin",
|
||||||
"version": "0.0.1",
|
|
||||||
"description": "Minimal Plugin",
|
"description": "Minimal Plugin",
|
||||||
|
"version": "2.1.0",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"author": "Wieland Schöbl",
|
"author": "Thea Schöbl",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
"Jovan Krunić <jovan.krunic@gmail.com>",
|
"Jovan Krunić <jovan.krunic@gmail.com>",
|
||||||
"Rainer Killinger <mail-openstapps@killinger.co>"
|
"Rainer Killinger <mail-openstapps@killinger.co>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run tslint && npm run compile",
|
"build": "npm run compile",
|
||||||
"compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'",
|
|
||||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'",
|
||||||
"check-configuration": "openstapps-configuration",
|
"check-configuration": "openstapps-configuration",
|
||||||
|
"compile": "rimraf lib && tsc",
|
||||||
"documentation": "typedoc --includeVersion --out docs src",
|
"documentation": "typedoc --includeVersion --out docs src",
|
||||||
"start": "node lib/cli.js",
|
"lint": "tslint -p tsconfig.json -c tslint.json 'src/**/*.ts'",
|
||||||
"tslint": "tslint -p tsconfig.json -c tslint.json 'src/**/*.ts'",
|
|
||||||
"prepublishOnly": "npm ci && npm run build",
|
|
||||||
"postversion": "npm run changelog",
|
"postversion": "npm run changelog",
|
||||||
|
"prepublishOnly": "npm ci && npm run build",
|
||||||
"preversion": "npm run prepublishOnly",
|
"preversion": "npm run prepublishOnly",
|
||||||
"push": "git push && git push origin \"v$npm_package_version\""
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
|
"start": "node lib/cli.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openstapps/api": "0.33.0",
|
"@openstapps/api": "workspace:*",
|
||||||
"@openstapps/core": "0.52.0",
|
"@openstapps/core": "workspace:*",
|
||||||
"@openstapps/core-tools": "0.25.0",
|
"@openstapps/core-tools": "workspace:*",
|
||||||
"@openstapps/logger": "0.7.0",
|
"@openstapps/logger": "workspace:*",
|
||||||
"commander": "8.2.0",
|
"commander": "10.0.0",
|
||||||
"express": "4.17.1",
|
"express": "4.18.2",
|
||||||
"ts-node": "10.2.1"
|
"ts-node": "10.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/configuration": "0.28.1",
|
"@openstapps/configuration": "workspace:*",
|
||||||
"@types/express": "4.17.13",
|
"@types/express": "4.17.16",
|
||||||
"@types/node": "14.17.12",
|
"@types/node": "18.15.3",
|
||||||
"conventional-changelog-cli": "2.1.1",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
"prepend-file-cli": "1.0.6",
|
"rimraf": "4.4.0",
|
||||||
"rimraf": "3.0.2",
|
"typedoc": "0.22.18",
|
||||||
"tslint": "6.1.3",
|
"typescript": "4.4.4"
|
||||||
"typedoc": "0.22.4",
|
|
||||||
"typescript": "4.4.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2021 StApps
|
* Copyright (C) 2019-2021 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"extends": "./node_modules/@openstapps/configuration/tsconfig.json"
|
"extends": "../../../node_modules/@openstapps/configuration/tsconfig.json"
|
||||||
}
|
}
|
||||||
|
|||||||
18376
frontend/app/package-lock.json
generated
18376
frontend/app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@openstapps/app",
|
"name": "@openstapps/app",
|
||||||
"version": "2.1.1",
|
|
||||||
"description": "The generic app tailored to fulfill needs of German universities, written using Ionic Framework.",
|
"description": "The generic app tailored to fulfill needs of German universities, written using Ionic Framework.",
|
||||||
|
"version": "2.1.0",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"author": "Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
"author": "Karl-Philipp Wulfert <krlwlfrt@gmail.com>",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
"build:stats": "ng build --configuration=production --stats-json",
|
"build:stats": "ng build --configuration=production --stats-json",
|
||||||
"changelog": "conventional-changelog -p angular -i src/assets/about/CHANGELOG.md -s -r 0",
|
"changelog": "conventional-changelog -p angular -i src/assets/about/CHANGELOG.md -s -r 0",
|
||||||
"check-configuration": "openstapps-configuration",
|
"check-configuration": "openstapps-configuration",
|
||||||
|
"check-icons": "ts-node scripts/check-icon-correctness.ts",
|
||||||
"cypress:open": "cypress open",
|
"cypress:open": "cypress open",
|
||||||
"cypress:run": "cypress run",
|
"cypress:run": "cypress run",
|
||||||
"docker:build": "sudo docker run -p 8100:8100 -p 35729:35729 -p 53703:53703 -v $PWD:/app -it registry.gitlab.com/openstapps/app bash -c \"npm install && npm run build\"",
|
"docker:build": "sudo docker run -p 8100:8100 -p 35729:35729 -p 53703:53703 -v $PWD:/app -it registry.gitlab.com/openstapps/app bash -c \"npm install && npm run build\"",
|
||||||
@@ -31,16 +32,14 @@
|
|||||||
"docker:serve": "sudo docker run -p 8100:8100 -p 35729:35729 -p 53703:53703 -v $PWD:/app -it registry.gitlab.com/openstapps/app bash -c \"npm run start:external\"",
|
"docker:serve": "sudo docker run -p 8100:8100 -p 35729:35729 -p 53703:53703 -v $PWD:/app -it registry.gitlab.com/openstapps/app bash -c \"npm run start:external\"",
|
||||||
"documentation": "compodoc -p tsconfig.json -d docs",
|
"documentation": "compodoc -p tsconfig.json -d docs",
|
||||||
"e2e": "ng e2e",
|
"e2e": "ng e2e",
|
||||||
"licenses": "license-checker --json > src/assets/about/licenses.json && ts-node ./scripts/accumulate-licenses.ts",
|
|
||||||
"minify-icons": "ts-node scripts/minify-icon-font.ts",
|
|
||||||
"check-icons": "ts-node scripts/check-icon-correctness.ts",
|
|
||||||
"format:check": "prettier --check .",
|
"format:check": "prettier --check .",
|
||||||
"format:fix": "prettier --write .",
|
"format:fix": "prettier --write .",
|
||||||
|
"licenses": "license-checker --json > src/assets/about/licenses.json && ts-node ./scripts/accumulate-licenses.ts && git add src/assets/about/licenses.json",
|
||||||
"lint": "ng lint",
|
"lint": "ng lint",
|
||||||
"lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts,.html src/",
|
"lint:fix": "eslint --fix -c .eslintrc.json --ignore-path .eslintignore --ext .ts,.html src/",
|
||||||
|
"minify-icons": "ts-node scripts/minify-icon-font.ts",
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"postinstall": "npx jetify",
|
"postinstall": "npx jetify",
|
||||||
"version": "npm run changelog && npm run licenses && npm run format:fix && git add src/assets/about/CHANGELOG.md && git add src/assets/about/licenses.json",
|
|
||||||
"prepublishOnly": "npm ci && npm run build && npm run lint && npm run format:check",
|
"prepublishOnly": "npm ci && npm run build && npm run lint && npm run format:check",
|
||||||
"preversion": "npm run prepublishOnly",
|
"preversion": "npm run prepublishOnly",
|
||||||
"push": "git push && git push origin \"v$npm_package_version\"",
|
"push": "git push && git push origin \"v$npm_package_version\"",
|
||||||
@@ -50,7 +49,8 @@
|
|||||||
"start": "ionic serve",
|
"start": "ionic serve",
|
||||||
"start:external": "ionic serve --external",
|
"start:external": "ionic serve --external",
|
||||||
"start:prod": "ionic serve -- --configuration=production",
|
"start:prod": "ionic serve -- --configuration=production",
|
||||||
"test": "ng test"
|
"test": "ng test",
|
||||||
|
"version": "npm run changelog && npm run licenses && npm run format:fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "13.3.11",
|
"@angular/animations": "13.3.11",
|
||||||
@@ -83,16 +83,18 @@
|
|||||||
"@hugotomazi/capacitor-navigation-bar": "2.0.0",
|
"@hugotomazi/capacitor-navigation-bar": "2.0.0",
|
||||||
"@ionic-native/core": "5.36.0",
|
"@ionic-native/core": "5.36.0",
|
||||||
"@ionic/angular": "6.3.9",
|
"@ionic/angular": "6.3.9",
|
||||||
|
"@ionic/core": "6.6.1",
|
||||||
"@ionic/storage-angular": "3.0.6",
|
"@ionic/storage-angular": "3.0.6",
|
||||||
"@ngx-translate/core": "14.0.0",
|
"@ngx-translate/core": "14.0.0",
|
||||||
"@ngx-translate/http-loader": "7.0.0",
|
"@ngx-translate/http-loader": "7.0.0",
|
||||||
"@openstapps/api": "1.0.1",
|
"@openid/appauth": "1.3.1",
|
||||||
"@openstapps/configuration": "0.34.0",
|
"@openstapps/api": "workspace:*",
|
||||||
"@openstapps/core": "1.0.1",
|
"@openstapps/configuration": "workspace:*",
|
||||||
|
"@openstapps/core": "workspace:*",
|
||||||
"@transistorsoft/capacitor-background-fetch": "1.0.2",
|
"@transistorsoft/capacitor-background-fetch": "1.0.2",
|
||||||
"capacitor-secure-storage-plugin": "0.8.1",
|
"capacitor-secure-storage-plugin": "0.8.1",
|
||||||
"cordova-plugin-calendar": "5.1.6",
|
"cordova-plugin-calendar": "5.1.6",
|
||||||
"deepmerge": "4.2.2",
|
"deepmerge": "4.3.0",
|
||||||
"form-data": "4.0.0",
|
"form-data": "4.0.0",
|
||||||
"geojson": "0.5.0",
|
"geojson": "0.5.0",
|
||||||
"ionic-appauth": "0.9.0",
|
"ionic-appauth": "0.9.0",
|
||||||
@@ -131,27 +133,28 @@
|
|||||||
"@cypress/schematic": "1.7.0",
|
"@cypress/schematic": "1.7.0",
|
||||||
"@ionic/angular-toolkit": "6.1.0",
|
"@ionic/angular-toolkit": "6.1.0",
|
||||||
"@ionic/cli": "6.20.4",
|
"@ionic/cli": "6.20.4",
|
||||||
"@openstapps/prettier-config": "1.0.0",
|
"@openstapps/prettier-config": "workspace:*",
|
||||||
"@types/fontkit": "1.8.0",
|
"@types/fontkit": "1.8.0",
|
||||||
"@types/glob": "7.2.0",
|
"@types/geojson": "1.0.6",
|
||||||
|
"@types/glob": "8.0.1",
|
||||||
"@types/jasmine": "4.3.1",
|
"@types/jasmine": "4.3.1",
|
||||||
"@types/jasminewd2": "2.0.10",
|
"@types/jasminewd2": "2.0.10",
|
||||||
"@types/jsonpath": "0.2.0",
|
"@types/jsonpath": "0.2.0",
|
||||||
"@types/leaflet": "1.9.0",
|
"@types/leaflet": "1.9.0",
|
||||||
"@types/leaflet.markercluster": "1.5.1",
|
"@types/leaflet.markercluster": "1.5.1",
|
||||||
"@types/node": "14.18.24",
|
"@types/node": "18.15.3",
|
||||||
"@typescript-eslint/eslint-plugin": "5.45.1",
|
"@typescript-eslint/eslint-plugin": "5.49.0",
|
||||||
"@typescript-eslint/parser": "5.45.1",
|
"@typescript-eslint/parser": "5.49.0",
|
||||||
"conventional-changelog-cli": "2.2.2",
|
"conventional-changelog-cli": "2.2.2",
|
||||||
"cordova-res": "0.15.4",
|
"cordova-res": "0.15.4",
|
||||||
"cypress": "12.0.1",
|
"cypress": "12.0.1",
|
||||||
"eslint": "8.29.0",
|
"eslint": "8.33.0",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.6.0",
|
||||||
"eslint-plugin-jsdoc": "39.6.4",
|
"eslint-plugin-jsdoc": "39.7.4",
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-unicorn": "43.0.2",
|
"eslint-plugin-unicorn": "45.0.2",
|
||||||
"fontkit": "2.0.2",
|
"fontkit": "2.0.2",
|
||||||
"glob": "8.0.3",
|
"glob": "8.1.0",
|
||||||
"is-docker": "2.2.1",
|
"is-docker": "2.2.1",
|
||||||
"jasmine-core": "4.5.0",
|
"jasmine-core": "4.5.0",
|
||||||
"jasmine-spec-reporter": "7.0.0",
|
"jasmine-spec-reporter": "7.0.0",
|
||||||
@@ -163,17 +166,13 @@
|
|||||||
"karma-jasmine-html-reporter": "2.0.0",
|
"karma-jasmine-html-reporter": "2.0.0",
|
||||||
"karma-mocha-reporter": "2.2.5",
|
"karma-mocha-reporter": "2.2.5",
|
||||||
"license-checker": "25.0.1",
|
"license-checker": "25.0.1",
|
||||||
"prettier": "2.7.1",
|
"prettier": "2.8.3",
|
||||||
"protractor": "7.0.0",
|
"protractor": "7.0.0",
|
||||||
"surge": "0.23.1",
|
"surge": "0.23.1",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"typescript": "4.4.4",
|
"typescript": "4.4.4",
|
||||||
"webpack-bundle-analyzer": "4.7.0"
|
"webpack-bundle-analyzer": "4.7.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
|
||||||
"node": "^14.20.0",
|
|
||||||
"npm": "^6.14.17"
|
|
||||||
},
|
|
||||||
"cordova": {
|
"cordova": {
|
||||||
"plugins": {},
|
"plugins": {},
|
||||||
"platforms": [
|
"platforms": [
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ export class AppComponent implements AfterContentInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async showMessage(message?: string) {
|
private async showMessage(message?: string) {
|
||||||
if (typeof message === 'undefined') {
|
if (message === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const toast = await this.toastController.create({
|
const toast = await this.toastController.create({
|
||||||
|
|||||||
@@ -58,12 +58,14 @@ export class AuthHelperService {
|
|||||||
public getAuthMessage(provider: SCAuthorizationProviderType, action: IAuthAction | IPAIAAuthAction) {
|
public getAuthMessage(provider: SCAuthorizationProviderType, action: IAuthAction | IPAIAAuthAction) {
|
||||||
let message: string | undefined;
|
let message: string | undefined;
|
||||||
switch (action.action) {
|
switch (action.action) {
|
||||||
case AuthActions.SignInSuccess:
|
case AuthActions.SignInSuccess: {
|
||||||
message = this.translateService.instant(`auth.messages.${provider}.logged_in_success`);
|
message = this.translateService.instant(`auth.messages.${provider}.logged_in_success`);
|
||||||
break;
|
break;
|
||||||
case AuthActions.SignOutSuccess:
|
}
|
||||||
|
case AuthActions.SignOutSuccess: {
|
||||||
message = this.translateService.instant(`auth.messages.${provider}.logged_out_success`);
|
message = this.translateService.instant(`auth.messages.${provider}.logged_out_success`);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,10 +166,10 @@ export abstract class AuthService implements IAuthService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._configuration != undefined) {
|
if (this._configuration == undefined) {
|
||||||
return Promise.resolve(this._configuration);
|
|
||||||
} else {
|
|
||||||
throw new Error('Unable To Obtain Server Configuration');
|
throw new Error('Unable To Obtain Server Configuration');
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(this._configuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,36 +186,43 @@ export abstract class AuthService implements IAuthService {
|
|||||||
case AuthActions.RefreshFailed:
|
case AuthActions.RefreshFailed:
|
||||||
case AuthActions.SignInFailed:
|
case AuthActions.SignInFailed:
|
||||||
case AuthActions.SignOutSuccess:
|
case AuthActions.SignOutSuccess:
|
||||||
case AuthActions.SignOutFailed:
|
case AuthActions.SignOutFailed: {
|
||||||
this._tokenSubject.next(undefined);
|
this._tokenSubject.next(undefined);
|
||||||
this._userSubject.next(undefined);
|
this._userSubject.next(undefined);
|
||||||
this._authenticatedSubject.next(false);
|
this._authenticatedSubject.next(false);
|
||||||
break;
|
break;
|
||||||
case AuthActions.LoadTokenFromStorageFailed:
|
}
|
||||||
|
case AuthActions.LoadTokenFromStorageFailed: {
|
||||||
this._tokenSubject.next(undefined);
|
this._tokenSubject.next(undefined);
|
||||||
this._userSubject.next(undefined);
|
this._userSubject.next(undefined);
|
||||||
this._authenticatedSubject.next(false);
|
this._authenticatedSubject.next(false);
|
||||||
this._initComplete.next(true);
|
this._initComplete.next(true);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case AuthActions.SignInSuccess:
|
case AuthActions.SignInSuccess:
|
||||||
case AuthActions.RefreshSuccess:
|
case AuthActions.RefreshSuccess: {
|
||||||
this._tokenSubject.next(action.tokenResponse);
|
this._tokenSubject.next(action.tokenResponse);
|
||||||
this._authenticatedSubject.next(true);
|
this._authenticatedSubject.next(true);
|
||||||
break;
|
break;
|
||||||
case AuthActions.LoadTokenFromStorageSuccess:
|
}
|
||||||
|
case AuthActions.LoadTokenFromStorageSuccess: {
|
||||||
this._tokenSubject.next(action.tokenResponse);
|
this._tokenSubject.next(action.tokenResponse);
|
||||||
this._authenticatedSubject.next((action.tokenResponse as TokenResponse).isValid(0));
|
this._authenticatedSubject.next((action.tokenResponse as TokenResponse).isValid(0));
|
||||||
this._initComplete.next(true);
|
this._initComplete.next(true);
|
||||||
break;
|
break;
|
||||||
case AuthActions.RevokeTokensSuccess:
|
}
|
||||||
|
case AuthActions.RevokeTokensSuccess: {
|
||||||
this._tokenSubject.next(undefined);
|
this._tokenSubject.next(undefined);
|
||||||
break;
|
break;
|
||||||
case AuthActions.LoadUserInfoSuccess:
|
}
|
||||||
|
case AuthActions.LoadUserInfoSuccess: {
|
||||||
this._userSubject.next(action.user);
|
this._userSubject.next(action.user);
|
||||||
break;
|
break;
|
||||||
case AuthActions.LoadUserInfoFailed:
|
}
|
||||||
|
case AuthActions.LoadUserInfoFailed: {
|
||||||
this._userSubject.next(undefined);
|
this._userSubject.next(undefined);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._authSubjectV2.next(action);
|
this._authSubjectV2.next(action);
|
||||||
@@ -240,10 +247,10 @@ export abstract class AuthService implements IAuthService {
|
|||||||
|
|
||||||
if (response != undefined) {
|
if (response != undefined) {
|
||||||
this.requestAccessToken(response.code, codeVerifier);
|
this.requestAccessToken(response.code, codeVerifier);
|
||||||
} else if (error != undefined) {
|
} else if (error == undefined) {
|
||||||
throw new Error(error.errorDescription);
|
|
||||||
} else {
|
|
||||||
throw new Error('Unknown Error With Authentication');
|
throw new Error('Unknown Error With Authentication');
|
||||||
|
} else {
|
||||||
|
throw new Error(error.errorDescription);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +267,10 @@ export abstract class AuthService implements IAuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async performEndSessionRequest(state?: string): Promise<void> {
|
protected async performEndSessionRequest(state?: string): Promise<void> {
|
||||||
if (this._tokenSubject.value != undefined) {
|
if (this._tokenSubject.value == undefined) {
|
||||||
|
//if user has no token they should not be logged in in the first place
|
||||||
|
this.endSessionCallback();
|
||||||
|
} else {
|
||||||
const requestJson: EndSessionRequestJson = {
|
const requestJson: EndSessionRequestJson = {
|
||||||
postLogoutRedirectURI: this.authConfig.end_session_redirect_url,
|
postLogoutRedirectURI: this.authConfig.end_session_redirect_url,
|
||||||
idTokenHint: this._tokenSubject.value.idToken || '',
|
idTokenHint: this._tokenSubject.value.idToken || '',
|
||||||
@@ -277,9 +287,6 @@ export abstract class AuthService implements IAuthService {
|
|||||||
if (returnedUrl != undefined) {
|
if (returnedUrl != undefined) {
|
||||||
this.endSessionCallback();
|
this.endSessionCallback();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
//if user has no token they should not be logged in in the first place
|
|
||||||
this.endSessionCallback();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,13 +467,13 @@ export abstract class AuthService implements IAuthService {
|
|||||||
|
|
||||||
public async getValidToken(buffer: number = AUTH_EXPIRY_BUFFER): Promise<TokenResponse> {
|
public async getValidToken(buffer: number = AUTH_EXPIRY_BUFFER): Promise<TokenResponse> {
|
||||||
if (this._tokenSubject.value) {
|
if (this._tokenSubject.value) {
|
||||||
if (!this._tokenSubject.value.isValid(buffer)) {
|
if (this._tokenSubject.value.isValid(buffer)) {
|
||||||
|
return this._tokenSubject.value;
|
||||||
|
} else {
|
||||||
await this.refreshToken();
|
await this.refreshToken();
|
||||||
if (this._tokenSubject.value) {
|
if (this._tokenSubject.value) {
|
||||||
return this._tokenSubject.value;
|
return this._tokenSubject.value;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return this._tokenSubject.value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,14 +28,18 @@ export class CapacitorRequestor extends Requestor {
|
|||||||
if (!settings.method) settings.method = 'GET';
|
if (!settings.method) settings.method = 'GET';
|
||||||
|
|
||||||
switch (settings.method) {
|
switch (settings.method) {
|
||||||
case 'GET':
|
case 'GET': {
|
||||||
return this.get(settings.url, settings.headers);
|
return this.get(settings.url, settings.headers);
|
||||||
case 'POST':
|
}
|
||||||
|
case 'POST': {
|
||||||
return this.post(settings.url, settings.data, settings.headers);
|
return this.post(settings.url, settings.data, settings.headers);
|
||||||
case 'PUT':
|
}
|
||||||
|
case 'PUT': {
|
||||||
return this.put(settings.url, settings.data, settings.headers);
|
return this.put(settings.url, settings.data, settings.headers);
|
||||||
case 'DELETE':
|
}
|
||||||
|
case 'DELETE': {
|
||||||
return this.delete(settings.url, settings.headers);
|
return this.delete(settings.url, settings.headers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,26 +33,30 @@ export class NgHttpService implements Requestor {
|
|||||||
let observable: Observable<T>;
|
let observable: Observable<T>;
|
||||||
|
|
||||||
switch (settings.method) {
|
switch (settings.method) {
|
||||||
case 'GET':
|
case 'GET': {
|
||||||
observable = this.http.get<T>(settings.url, {
|
observable = this.http.get<T>(settings.url, {
|
||||||
headers: this.getHeaders(settings.headers),
|
headers: this.getHeaders(settings.headers),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'POST':
|
}
|
||||||
|
case 'POST': {
|
||||||
observable = this.http.post<T>(settings.url, settings.data, {
|
observable = this.http.post<T>(settings.url, settings.data, {
|
||||||
headers: this.getHeaders(settings.headers),
|
headers: this.getHeaders(settings.headers),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'PUT':
|
}
|
||||||
|
case 'PUT': {
|
||||||
observable = this.http.put<T>(settings.url, settings.data, {
|
observable = this.http.put<T>(settings.url, settings.data, {
|
||||||
headers: this.getHeaders(settings.headers),
|
headers: this.getHeaders(settings.headers),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'DELETE':
|
}
|
||||||
|
case 'DELETE': {
|
||||||
observable = this.http.delete<T>(settings.url, {
|
observable = this.http.delete<T>(settings.url, {
|
||||||
headers: this.getHeaders(settings.headers),
|
headers: this.getHeaders(settings.headers),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return firstValueFrom(observable);
|
return firstValueFrom(observable);
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export class PAIAAuthorizationRequestHandler {
|
|||||||
const returnedUrl: string | undefined = await this.browser.showWindow(url, request.redirectUri);
|
const returnedUrl: string | undefined = await this.browser.showWindow(url, request.redirectUri);
|
||||||
|
|
||||||
// callback may come from showWindow or via another method
|
// callback may come from showWindow or via another method
|
||||||
if (typeof returnedUrl !== 'undefined') {
|
if (returnedUrl !== undefined) {
|
||||||
await this.storage.setItem(AUTHORIZATION_RESPONSE_KEY, returnedUrl);
|
await this.storage.setItem(AUTHORIZATION_RESPONSE_KEY, returnedUrl);
|
||||||
await this.completeAuthorizationRequestIfPossible();
|
await this.completeAuthorizationRequestIfPossible();
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ export class PAIAAuthorizationRequestHandler {
|
|||||||
|
|
||||||
return <PAIAAuthorizationRequestResponse>{
|
return <PAIAAuthorizationRequestResponse>{
|
||||||
request: request, // request
|
request: request, // request
|
||||||
response: !error ? this.getAuthorizationResponse(queryParameters) : undefined,
|
response: error ? undefined : this.getAuthorizationResponse(queryParameters),
|
||||||
error: error ? this.getAuthorizationError(queryParameters) : undefined,
|
error: error ? this.getAuthorizationError(queryParameters) : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -128,14 +128,14 @@ export class PAIAAuthorizationRequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getQueryParams(authResponse: string | null): StringMap {
|
private getQueryParams(authResponse: string | null): StringMap {
|
||||||
if (authResponse != undefined) {
|
if (authResponse == undefined) {
|
||||||
|
return {};
|
||||||
|
} else {
|
||||||
const querySide: string = authResponse.split('#')[0];
|
const querySide: string = authResponse.split('#')[0];
|
||||||
const parts: string[] = querySide.split('?');
|
const parts: string[] = querySide.split('?');
|
||||||
if (parts.length !== 2) throw new Error('Invalid auth response string');
|
if (parts.length !== 2) throw new Error('Invalid auth response string');
|
||||||
const hash = parts[1];
|
const hash = parts[1];
|
||||||
return this.utils.parseQueryString(hash);
|
return this.utils.parseQueryString(hash);
|
||||||
} else {
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,35 +166,42 @@ export class PAIAAuthService {
|
|||||||
switch (action.action) {
|
switch (action.action) {
|
||||||
case AuthActions.SignInFailed:
|
case AuthActions.SignInFailed:
|
||||||
case AuthActions.SignOutSuccess:
|
case AuthActions.SignOutSuccess:
|
||||||
case AuthActions.SignOutFailed:
|
case AuthActions.SignOutFailed: {
|
||||||
this._tokenSubject.next(undefined);
|
this._tokenSubject.next(undefined);
|
||||||
this._userSubject.next(undefined);
|
this._userSubject.next(undefined);
|
||||||
this._authenticatedSubject.next(false);
|
this._authenticatedSubject.next(false);
|
||||||
break;
|
break;
|
||||||
case AuthActions.LoadTokenFromStorageFailed:
|
}
|
||||||
|
case AuthActions.LoadTokenFromStorageFailed: {
|
||||||
this._tokenSubject.next(undefined);
|
this._tokenSubject.next(undefined);
|
||||||
this._userSubject.next(undefined);
|
this._userSubject.next(undefined);
|
||||||
this._authenticatedSubject.next(false);
|
this._authenticatedSubject.next(false);
|
||||||
this._initComplete.next(true);
|
this._initComplete.next(true);
|
||||||
break;
|
break;
|
||||||
case AuthActions.SignInSuccess:
|
}
|
||||||
|
case AuthActions.SignInSuccess: {
|
||||||
this._tokenSubject.next(action.tokenResponse);
|
this._tokenSubject.next(action.tokenResponse);
|
||||||
this._authenticatedSubject.next(true);
|
this._authenticatedSubject.next(true);
|
||||||
break;
|
break;
|
||||||
case AuthActions.LoadTokenFromStorageSuccess:
|
}
|
||||||
|
case AuthActions.LoadTokenFromStorageSuccess: {
|
||||||
this._tokenSubject.next(action.tokenResponse);
|
this._tokenSubject.next(action.tokenResponse);
|
||||||
this._authenticatedSubject.next((action.tokenResponse as TokenResponse).isValid(0));
|
this._authenticatedSubject.next((action.tokenResponse as TokenResponse).isValid(0));
|
||||||
this._initComplete.next(true);
|
this._initComplete.next(true);
|
||||||
break;
|
break;
|
||||||
case AuthActions.RevokeTokensSuccess:
|
}
|
||||||
|
case AuthActions.RevokeTokensSuccess: {
|
||||||
this._tokenSubject.next(undefined);
|
this._tokenSubject.next(undefined);
|
||||||
break;
|
break;
|
||||||
case AuthActions.LoadUserInfoSuccess:
|
}
|
||||||
|
case AuthActions.LoadUserInfoSuccess: {
|
||||||
this._userSubject.next(action.user);
|
this._userSubject.next(action.user);
|
||||||
break;
|
break;
|
||||||
case AuthActions.LoadUserInfoFailed:
|
}
|
||||||
|
case AuthActions.LoadUserInfoFailed: {
|
||||||
this._userSubject.next(undefined);
|
this._userSubject.next(undefined);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._authSubjectV2.next(action);
|
this._authSubjectV2.next(action);
|
||||||
@@ -219,10 +226,10 @@ export class PAIAAuthService {
|
|||||||
|
|
||||||
if (response != undefined) {
|
if (response != undefined) {
|
||||||
this.requestAccessToken(response.code, response.patron, codeVerifier);
|
this.requestAccessToken(response.code, response.patron, codeVerifier);
|
||||||
} else if (error != undefined) {
|
} else if (error == undefined) {
|
||||||
throw new Error(error.errorDescription);
|
|
||||||
} else {
|
|
||||||
throw new Error('Unknown Error With Authentication');
|
throw new Error('Unknown Error With Authentication');
|
||||||
|
} else {
|
||||||
|
throw new Error(error.errorDescription);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,11 @@ export class ScheduleSyncService implements OnDestroy {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (status !== BackgroundFetch.STATUS_AVAILABLE) {
|
if (status === BackgroundFetch.STATUS_AVAILABLE) {
|
||||||
|
console.info('Starting background fetch.');
|
||||||
|
|
||||||
|
await BackgroundFetch.start();
|
||||||
|
} else {
|
||||||
if (status === BackgroundFetch.STATUS_DENIED) {
|
if (status === BackgroundFetch.STATUS_DENIED) {
|
||||||
console.error(
|
console.error(
|
||||||
'The user explicitly disabled background behavior for this app or for the whole system.',
|
'The user explicitly disabled background behavior for this app or for the whole system.',
|
||||||
@@ -101,10 +105,6 @@ export class ScheduleSyncService implements OnDestroy {
|
|||||||
} else if (status === BackgroundFetch.STATUS_RESTRICTED) {
|
} else if (status === BackgroundFetch.STATUS_RESTRICTED) {
|
||||||
console.error('Background updates are unavailable and the user cannot enable them again.');
|
console.error('Background updates are unavailable and the user cannot enable them again.');
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.info('Starting background fetch.');
|
|
||||||
|
|
||||||
await BackgroundFetch.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export class ConfigProvider {
|
|||||||
* @param attribute requested attribute from app configuration
|
* @param attribute requested attribute from app configuration
|
||||||
*/
|
*/
|
||||||
public getValue(attribute: keyof SCAppConfiguration) {
|
public getValue(attribute: keyof SCAppConfiguration) {
|
||||||
if (typeof this.config.app[attribute] !== 'undefined') {
|
if (this.config.app[attribute] !== undefined) {
|
||||||
return this.config.app[attribute];
|
return this.config.app[attribute];
|
||||||
}
|
}
|
||||||
throw new ConfigValueNotAvailable(attribute);
|
throw new ConfigValueNotAvailable(attribute);
|
||||||
@@ -106,7 +106,7 @@ export class ConfigProvider {
|
|||||||
* @param attribute requested attribute from the configuration
|
* @param attribute requested attribute from the configuration
|
||||||
*/
|
*/
|
||||||
public getAnyValue(attribute: keyof SCIndexResponse) {
|
public getAnyValue(attribute: keyof SCIndexResponse) {
|
||||||
if (typeof this.config[attribute] !== 'undefined') {
|
if (this.config[attribute] !== undefined) {
|
||||||
return this.config[attribute];
|
return this.config[attribute];
|
||||||
}
|
}
|
||||||
throw new ConfigValueNotAvailable(attribute);
|
throw new ConfigValueNotAvailable(attribute);
|
||||||
@@ -141,13 +141,13 @@ export class ConfigProvider {
|
|||||||
fetchError = error;
|
fetchError = error;
|
||||||
}
|
}
|
||||||
// check for occurred errors and throw them
|
// check for occurred errors and throw them
|
||||||
if (typeof loadError !== 'undefined' && typeof fetchError !== 'undefined') {
|
if (loadError !== undefined && fetchError !== undefined) {
|
||||||
throw new ConfigInitError();
|
throw new ConfigInitError();
|
||||||
}
|
}
|
||||||
if (typeof loadError !== 'undefined') {
|
if (loadError !== undefined) {
|
||||||
this.logger.warn(loadError);
|
this.logger.warn(loadError);
|
||||||
}
|
}
|
||||||
if (typeof fetchError !== 'undefined') {
|
if (fetchError !== undefined) {
|
||||||
this.logger.warn(fetchError);
|
this.logger.warn(fetchError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export class DashboardProvider {
|
|||||||
from: from,
|
from: from,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof filters !== 'undefined') {
|
if (filters !== undefined) {
|
||||||
for (const filter of filters) {
|
for (const filter of filters) {
|
||||||
((query.filter as SCSearchBooleanFilter).arguments as SCBooleanFilterArguments).filters.push(filter);
|
((query.filter as SCSearchBooleanFilter).arguments as SCBooleanFilterArguments).filters.push(filter);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,15 +189,18 @@ export class AddEventActionChipComponent implements OnDestroy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (associatedDateSeries.map(it => it.uid).filter(it => !this.uuids.includes(it)).length) {
|
switch (associatedDateSeries.map(it => it.uid).filter(it => !this.uuids.includes(it)).length) {
|
||||||
case 0:
|
case 0: {
|
||||||
this.applyState(AddEventStates.ADDED_ALL);
|
this.applyState(AddEventStates.ADDED_ALL);
|
||||||
break;
|
break;
|
||||||
case associatedDateSeries.length:
|
}
|
||||||
|
case associatedDateSeries.length: {
|
||||||
this.applyState(AddEventStates.REMOVED_ALL);
|
this.applyState(AddEventStates.REMOVED_ALL);
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
|
default: {
|
||||||
this.applyState(AddEventStates.ADDED_SOME);
|
this.applyState(AddEventStates.ADDED_SOME);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,11 +34,7 @@ export class DataFacetsProvider {
|
|||||||
// eslint-disable-next-line class-methods-use-this
|
// eslint-disable-next-line class-methods-use-this
|
||||||
addBuckets(bucketsMap: {[key: string]: number}, fields: string[]): {[key: string]: number} {
|
addBuckets(bucketsMap: {[key: string]: number}, fields: string[]): {[key: string]: number} {
|
||||||
for (const field of fields) {
|
for (const field of fields) {
|
||||||
if (typeof bucketsMap[field] !== 'undefined') {
|
bucketsMap[field] = bucketsMap[field] === undefined ? 1 : bucketsMap[field] + 1;
|
||||||
bucketsMap[field] = bucketsMap[field] + 1;
|
|
||||||
} else {
|
|
||||||
bucketsMap[field] = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bucketsMap;
|
return bucketsMap;
|
||||||
@@ -82,13 +78,13 @@ export class DataFacetsProvider {
|
|||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
for (const aggregation of aggregations) {
|
for (const aggregation of aggregations) {
|
||||||
let fieldValues = item[aggregation.fieldName as keyof SCThing] as string | string[] | undefined;
|
let fieldValues = item[aggregation.fieldName as keyof SCThing] as string | string[] | undefined;
|
||||||
if (typeof fieldValues === 'undefined') {
|
if (fieldValues === undefined) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (typeof fieldValues === 'string') {
|
if (typeof fieldValues === 'string') {
|
||||||
fieldValues = [fieldValues];
|
fieldValues = [fieldValues];
|
||||||
}
|
}
|
||||||
if (typeof aggregation.onlyOnTypes === 'undefined') {
|
if (aggregation.onlyOnTypes === undefined) {
|
||||||
combinedFacetsMap[aggregation.fieldName] = this.addBuckets(
|
combinedFacetsMap[aggregation.fieldName] = this.addBuckets(
|
||||||
combinedFacetsMap[aggregation.fieldName] || {},
|
combinedFacetsMap[aggregation.fieldName] || {},
|
||||||
fieldValues,
|
fieldValues,
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ export class DataProvider {
|
|||||||
|
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const value =
|
const value =
|
||||||
typeof bucketMap.get(item.type) === 'undefined' ? 1 : (bucketMap.get(item.type) as number) + 1;
|
bucketMap.get(item.type) === undefined ? 1 : (bucketMap.get(item.type) as number) + 1;
|
||||||
bucketMap.set(item.type, value);
|
bucketMap.set(item.type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ export class DataProvider {
|
|||||||
created: new Date().toISOString(),
|
created: new Date().toISOString(),
|
||||||
type: SCThingOriginType.User,
|
type: SCThingOriginType.User,
|
||||||
},
|
},
|
||||||
type: typeof type === 'undefined' ? item.type : type,
|
type: type === undefined ? item.type : type,
|
||||||
uid: item.uid,
|
uid: item.uid,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export class DataDetailComponent implements ViewWillEnter {
|
|||||||
* Type guard for SCSavableThing
|
* Type guard for SCSavableThing
|
||||||
*/
|
*/
|
||||||
static isSCSavableThing(thing: SCThings | SCSaveableThing): thing is SCSaveableThing {
|
static isSCSavableThing(thing: SCThings | SCSaveableThing): thing is SCSaveableThing {
|
||||||
return typeof (thing as SCSaveableThing).data !== 'undefined';
|
return (thing as SCSaveableThing).data !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,12 +126,13 @@ export class DataDetailComponent implements ViewWillEnter {
|
|||||||
)
|
)
|
||||||
: this.dataProvider.get(uid, DataScope.Remote)));
|
: this.dataProvider.get(uid, DataScope.Remote)));
|
||||||
|
|
||||||
this.item = !item
|
this.item = item
|
||||||
? // eslint-disable-next-line unicorn/no-null
|
? // eslint-disable-next-line unicorn/no-null
|
||||||
null
|
DataDetailComponent.isSCSavableThing(item)
|
||||||
: DataDetailComponent.isSCSavableThing(item)
|
|
||||||
? item.data
|
? item.data
|
||||||
: item;
|
: item
|
||||||
|
// eslint-disable-next-line unicorn/no-null
|
||||||
|
: null;
|
||||||
} catch {
|
} catch {
|
||||||
// eslint-disable-next-line unicorn/no-null
|
// eslint-disable-next-line unicorn/no-null
|
||||||
this.item = null;
|
this.item = null;
|
||||||
@@ -150,7 +151,7 @@ export class DataDetailComponent implements ViewWillEnter {
|
|||||||
.get(uid)
|
.get(uid)
|
||||||
.pipe(take(1))
|
.pipe(take(1))
|
||||||
.subscribe(item => {
|
.subscribe(item => {
|
||||||
if (typeof item !== 'undefined') {
|
if (item !== undefined) {
|
||||||
this.item = item.data;
|
this.item = item.data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export class FavoriteButtonComponent {
|
|||||||
this._item = item;
|
this._item = item;
|
||||||
this.isFavorite$ = this.favoritesService.get(this.item.uid).pipe(
|
this.isFavorite$ = this.favoritesService.get(this.item.uid).pipe(
|
||||||
map(favorite => {
|
map(favorite => {
|
||||||
return typeof favorite !== 'undefined';
|
return favorite !== undefined;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export class TitleCardComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
@HostListener('window:resize', ['$event'])
|
||||||
checkTextElipsis() {
|
checkTextElipsis() {
|
||||||
if (typeof this.accordionTextArea === 'undefined') {
|
if (this.accordionTextArea === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const element = this.accordionTextArea.nativeElement as HTMLElement;
|
const element = this.accordionTextArea.nativeElement as HTMLElement;
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ export class DataListComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
if (Array.isArray(this.items) && typeof changes.items !== 'undefined') {
|
if (Array.isArray(this.items) && changes.items !== undefined) {
|
||||||
this.itemStream.next(this.items);
|
this.itemStream.next(this.items);
|
||||||
this.infiniteScroll.complete();
|
this.infiniteScroll.complete();
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ export class DataListComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.calcSkeletonItems();
|
this.calcSkeletonItems();
|
||||||
if (typeof this.resetToTop !== 'undefined') {
|
if (this.resetToTop !== undefined) {
|
||||||
this.subscriptions.push(
|
this.subscriptions.push(
|
||||||
this.resetToTop.subscribe(() => {
|
this.resetToTop.subscribe(() => {
|
||||||
// this.viewPort.scrollToIndex(0);
|
// this.viewPort.scrollToIndex(0);
|
||||||
|
|||||||
@@ -90,10 +90,10 @@ export class ScThingListItemVirtualScrollStrategy implements VirtualScrollStrate
|
|||||||
for (const node of renderedItems) {
|
for (const node of renderedItems) {
|
||||||
const [item, group] = this.getItemByNode(node, renderedItems);
|
const [item, group] = this.getItemByNode(node, renderedItems);
|
||||||
|
|
||||||
if (!this.heights.has(item)) {
|
if (this.heights.has(item)) {
|
||||||
this.intersectionObserver.observe(node);
|
|
||||||
} else {
|
|
||||||
node.style.height = `${this.getHeight(item, group)}px`;
|
node.style.height = `${this.getHeight(item, group)}px`;
|
||||||
|
} else {
|
||||||
|
this.intersectionObserver.observe(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ export class SearchPageComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const filter of [this.forcedFilter, this.filterQuery]) {
|
for (const filter of [this.forcedFilter, this.filterQuery]) {
|
||||||
if (typeof filter !== 'undefined') {
|
if (filter !== undefined) {
|
||||||
filters.push(filter);
|
filters.push(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -324,7 +324,7 @@ export class SearchPageComponent implements OnInit, OnDestroy {
|
|||||||
this.filterQuery = query[1];
|
this.filterQuery = query[1];
|
||||||
this.sortQuery = query[2];
|
this.sortQuery = query[2];
|
||||||
this.from = 0;
|
this.from = 0;
|
||||||
if (typeof this.filterQuery !== 'undefined' || this.queryText?.length > 0 || this.showDefaultData) {
|
if (this.filterQuery !== undefined || this.queryText?.length > 0 || this.showDefaultData) {
|
||||||
await this.fetchAndUpdateItems();
|
await this.fetchAndUpdateItems();
|
||||||
this.queryChanged.next();
|
this.queryChanged.next();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export class PlaceDetailContentComponent implements OnInit, OnDestroy {
|
|||||||
* @param item TODO
|
* @param item TODO
|
||||||
*/
|
*/
|
||||||
hasCategories(item: SCThings): item is SCThings & {categories: string[]} {
|
hasCategories(item: SCThings): item is SCThings & {categories: string[]} {
|
||||||
return typeof (item as {categories: string[]}).categories !== 'undefined';
|
return (item as {categories: string[]}).categories !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export class FavoritesPageComponent extends SearchPageComponent implements OnIni
|
|||||||
this.filterQuery = query[1];
|
this.filterQuery = query[1];
|
||||||
this.sortQuery = query[2];
|
this.sortQuery = query[2];
|
||||||
this.from = 0;
|
this.from = 0;
|
||||||
if (typeof this.filterQuery !== 'undefined' || this.queryText?.length > 0 || this.showDefaultData) {
|
if (this.filterQuery !== undefined || this.queryText?.length > 0 || this.showDefaultData) {
|
||||||
await this.fetchAndUpdateItems();
|
await this.fetchAndUpdateItems();
|
||||||
this.queryChanged.next();
|
this.queryChanged.next();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ export class FavoritesService {
|
|||||||
return this.favoritesChanged$.pipe(
|
return this.favoritesChanged$.pipe(
|
||||||
map(favoritesMap => {
|
map(favoritesMap => {
|
||||||
let items = [...favoritesMap.values()].map(favorite => favorite.data);
|
let items = [...favoritesMap.values()].map(favorite => favorite.data);
|
||||||
if (typeof queryText !== 'undefined') {
|
if (queryText !== undefined) {
|
||||||
const textFilteredItems: SCIndexableThings[] = [];
|
const textFilteredItems: SCIndexableThings[] = [];
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (
|
if (
|
||||||
@@ -199,7 +199,7 @@ export class FavoritesService {
|
|||||||
items = textFilteredItems;
|
items = textFilteredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof filterQuery !== 'undefined') {
|
if (filterQuery !== undefined) {
|
||||||
const filterType = FavoritesService.getFilterType(
|
const filterType = FavoritesService.getFilterType(
|
||||||
filterQuery as SCSearchBooleanFilter | SCSearchValueFilter,
|
filterQuery as SCSearchBooleanFilter | SCSearchValueFilter,
|
||||||
);
|
);
|
||||||
@@ -212,7 +212,7 @@ export class FavoritesService {
|
|||||||
items = filteredItems;
|
items = filteredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof sortQuery !== 'undefined') {
|
if (sortQuery !== undefined) {
|
||||||
items = this.sortItems(items, sortQuery[0].arguments.field as 'name' | 'type', sortQuery[0].order);
|
items = this.sortItems(items, sortQuery[0].arguments.field as 'name' | 'type', sortQuery[0].order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export class DaiaAvailabilityComponent extends DataDetailComponent implements On
|
|||||||
*/
|
*/
|
||||||
async getAvailability(uid: SCUuid) {
|
async getAvailability(uid: SCUuid) {
|
||||||
this.daiaDataProvider.getAvailability(uid).then(holdings => {
|
this.daiaDataProvider.getAvailability(uid).then(holdings => {
|
||||||
if (typeof holdings !== 'undefined') {
|
if (holdings !== undefined) {
|
||||||
this.holdings = holdings;
|
this.holdings = holdings;
|
||||||
this.holdingsByDepartments = groupByStable(holdings, holding => holding.department.id);
|
this.holdingsByDepartments = groupByStable(holdings, holding => holding.department.id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export class DaiaDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getAvailability(id: string): Promise<DaiaHolding[] | undefined> {
|
async getAvailability(id: string): Promise<DaiaHolding[] | undefined> {
|
||||||
if (typeof this.daiaServiceUrl === 'undefined') {
|
if (this.daiaServiceUrl === undefined) {
|
||||||
try {
|
try {
|
||||||
const features = this.configProvider.getValue('features') as SCFeatureConfiguration;
|
const features = this.configProvider.getValue('features') as SCFeatureConfiguration;
|
||||||
if (features.extern?.daia?.url) {
|
if (features.extern?.daia?.url) {
|
||||||
@@ -134,7 +134,7 @@ export class DaiaDataProvider {
|
|||||||
dueDate: dueDate,
|
dueDate: dueDate,
|
||||||
online:
|
online:
|
||||||
Array.isArray(available) &&
|
Array.isArray(available) &&
|
||||||
typeof available.find(item => item.service === 'remote') !== 'undefined',
|
available.find(item => item.service === 'remote') !== undefined,
|
||||||
available:
|
available:
|
||||||
(Array.isArray(available) &&
|
(Array.isArray(available) &&
|
||||||
available.find(item =>
|
available.find(item =>
|
||||||
@@ -171,7 +171,7 @@ export class DaiaDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getHoldingLink(holding: DaiaHolding, open = false) {
|
getHoldingLink(holding: DaiaHolding, open = false) {
|
||||||
if (typeof this.hebisProxyUrl === 'undefined') {
|
if (this.hebisProxyUrl === undefined) {
|
||||||
this.logger.error('HeBIS proxy url undefined');
|
this.logger.error('HeBIS proxy url undefined');
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -194,7 +194,7 @@ export class DaiaDataProvider {
|
|||||||
unavailable: unavailable.findIndex(item => item.service === 'presentation'),
|
unavailable: unavailable.findIndex(item => item.service === 'presentation'),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (loan.unavailable !== -1 && typeof unavailable[loan.unavailable].expected !== 'undefined') {
|
if (loan.unavailable !== -1 && unavailable[loan.unavailable].expected !== undefined) {
|
||||||
return 'checked_out';
|
return 'checked_out';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export class HebisDataProvider extends DataProvider {
|
|||||||
|
|
||||||
let page: number | undefined = searchRequest.page;
|
let page: number | undefined = searchRequest.page;
|
||||||
|
|
||||||
if (typeof page === 'undefined') {
|
if (page === undefined) {
|
||||||
const preFlightResponse = await this.client.invokeRoute<HebisSearchResponse>(
|
const preFlightResponse = await this.client.invokeRoute<HebisSearchResponse>(
|
||||||
this.hebisSearchRoute,
|
this.hebisSearchRoute,
|
||||||
undefined,
|
undefined,
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ export class LibraryAccountService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getDocumentFromHDS(edition: string) {
|
async getDocumentFromHDS(edition: string) {
|
||||||
if (typeof edition === 'undefined') {
|
if (edition === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,11 +166,13 @@ export class LibraryAccountService {
|
|||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
const handleDocument = () => {
|
const handleDocument = () => {
|
||||||
switch (documentAction.action) {
|
switch (documentAction.action) {
|
||||||
case 'cancel':
|
case 'cancel': {
|
||||||
return this.cancelReservation(documentAction.doc);
|
return this.cancelReservation(documentAction.doc);
|
||||||
break;
|
break;
|
||||||
case 'renew':
|
}
|
||||||
|
case 'renew': {
|
||||||
return this.renewLending(documentAction.doc);
|
return this.renewLending(documentAction.doc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const alert = await this.alertController.create({
|
const alert = await this.alertController.create({
|
||||||
|
|||||||
@@ -75,8 +75,13 @@ export class MapProvider {
|
|||||||
icon: divIcon({
|
icon: divIcon({
|
||||||
className: className,
|
className: className,
|
||||||
html:
|
html:
|
||||||
typeof position.heading !== 'undefined'
|
position.heading === undefined
|
||||||
? `<span
|
? `<span
|
||||||
|
name="${SCIcon`person_pin_circle`}"
|
||||||
|
class="material-symbols-rounded map-location-pin"
|
||||||
|
style="font-size: ${iconSize}px; color: var(--ion-color-primary);"
|
||||||
|
>${SCIcon`person_pin_circle`}</span>`
|
||||||
|
: `<span
|
||||||
class="material-symbols-rounded map-location-pin"
|
class="material-symbols-rounded map-location-pin"
|
||||||
style="
|
style="
|
||||||
transform-origin: center;
|
transform-origin: center;
|
||||||
@@ -84,12 +89,7 @@ export class MapProvider {
|
|||||||
font-size: ${iconSize}px;
|
font-size: ${iconSize}px;
|
||||||
color: var(--ion-color-primary);
|
color: var(--ion-color-primary);
|
||||||
"
|
"
|
||||||
>${SCIcon`navigation`}</span>`
|
>${SCIcon`navigation`}</span>`,
|
||||||
: `<span
|
|
||||||
name="${SCIcon`person_pin_circle`}"
|
|
||||||
class="material-symbols-rounded map-location-pin"
|
|
||||||
style="font-size: ${iconSize}px; color: var(--ion-color-primary);"
|
|
||||||
>${SCIcon`person_pin_circle`}</span>`,
|
|
||||||
iconSize: [iconSize, iconSize],
|
iconSize: [iconSize, iconSize],
|
||||||
}),
|
}),
|
||||||
zIndexOffset: 1000,
|
zIndexOffset: 1000,
|
||||||
@@ -202,7 +202,7 @@ export class MapProvider {
|
|||||||
|
|
||||||
let filter = baseFilter;
|
let filter = baseFilter;
|
||||||
|
|
||||||
if (typeof contextFilter !== 'undefined') {
|
if (contextFilter !== undefined) {
|
||||||
filter = {
|
filter = {
|
||||||
arguments: {
|
arguments: {
|
||||||
operation: 'and',
|
operation: 'and',
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ export class MapPageComponent {
|
|||||||
* @param latLng Coordinates to animate to
|
* @param latLng Coordinates to animate to
|
||||||
*/
|
*/
|
||||||
private focus(latLng?: LatLng) {
|
private focus(latLng?: LatLng) {
|
||||||
if (typeof latLng !== 'undefined') {
|
if (latLng !== undefined) {
|
||||||
this.map.flyTo(latLng, this.MAX_ZOOM);
|
this.map.flyTo(latLng, this.MAX_ZOOM);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -173,7 +173,7 @@ export class MapPageComponent {
|
|||||||
this.removeAll();
|
this.removeAll();
|
||||||
}
|
}
|
||||||
const addSCPlace = (place: SCPlace): Layer | Marker => {
|
const addSCPlace = (place: SCPlace): Layer | Marker => {
|
||||||
if (typeof place.geo.polygon !== 'undefined') {
|
if (place.geo.polygon !== undefined) {
|
||||||
const polygonLayer = geoJSON(place.geo.polygon, {
|
const polygonLayer = geoJSON(place.geo.polygon, {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -190,7 +190,7 @@ export class MapPageComponent {
|
|||||||
|
|
||||||
items.map(thing => {
|
items.map(thing => {
|
||||||
// IMPORTANT: change this to support inPlace.geo when there is a need to show floors (the building of the floor)
|
// IMPORTANT: change this to support inPlace.geo when there is a need to show floors (the building of the floor)
|
||||||
if (typeof thing.geo !== 'undefined') {
|
if (thing.geo !== undefined) {
|
||||||
this.layers.push(addSCPlace(thing as SCPlace));
|
this.layers.push(addSCPlace(thing as SCPlace));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -233,7 +233,7 @@ export class MapPageComponent {
|
|||||||
this.items = result.data as SCPlace[];
|
this.items = result.data as SCPlace[];
|
||||||
this.addToMap(result.data as Array<SCBuilding | SCRoom>, true, animate);
|
this.addToMap(result.data as Array<SCBuilding | SCRoom>, true, animate);
|
||||||
// update filter options if result contains facets
|
// update filter options if result contains facets
|
||||||
if (typeof result.facets !== 'undefined') {
|
if (result.facets !== undefined) {
|
||||||
this.contextMenuService.updateContextFilter(result.facets);
|
this.contextMenuService.updateContextFilter(result.facets);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -313,9 +313,9 @@ export class MapPageComponent {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const uid = this.route.snapshot.paramMap.get('uid');
|
const uid = this.route.snapshot.paramMap.get('uid');
|
||||||
const response = await (uid !== null
|
const response = await (uid === null
|
||||||
? this.mapProvider.searchPlace(uid)
|
? this.mapProvider.searchPlaces()
|
||||||
: this.mapProvider.searchPlaces());
|
: this.mapProvider.searchPlace(uid));
|
||||||
|
|
||||||
if (response.data.length === 0) {
|
if (response.data.length === 0) {
|
||||||
return;
|
return;
|
||||||
@@ -345,9 +345,9 @@ export class MapPageComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.locationStatus = await (!Capacitor.isNativePlatform()
|
this.locationStatus = await (Capacitor.isNativePlatform()
|
||||||
? Geolocation.checkPermissions()
|
? Geolocation.requestPermissions()
|
||||||
: Geolocation.requestPermissions());
|
: Geolocation.checkPermissions());
|
||||||
|
|
||||||
this.translateService
|
this.translateService
|
||||||
.get(['map.page.geolocation', 'app.errors.UNKNOWN'])
|
.get(['map.page.geolocation', 'app.errors.UNKNOWN'])
|
||||||
@@ -362,9 +362,9 @@ export class MapPageComponent {
|
|||||||
message: `${
|
message: `${
|
||||||
this.locationStatus?.location === 'denied'
|
this.locationStatus?.location === 'denied'
|
||||||
? location.NOT_ALLOWED
|
? location.NOT_ALLOWED
|
||||||
: this.locationStatus?.location !== 'granted'
|
: this.locationStatus?.location === 'granted'
|
||||||
? location.NOT_ENABLED
|
? unknownError
|
||||||
: unknownError
|
: location.NOT_ENABLED
|
||||||
}`,
|
}`,
|
||||||
buttons: ['OK'],
|
buttons: ['OK'],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export class MapListModalComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
let geofencedFilter: SCSearchBooleanFilter | undefined;
|
let geofencedFilter: SCSearchBooleanFilter | undefined;
|
||||||
if (typeof this.mapBounds !== 'undefined') {
|
if (this.mapBounds !== undefined) {
|
||||||
geofencedFilter = {
|
geofencedFilter = {
|
||||||
arguments: {
|
arguments: {
|
||||||
operation: 'and',
|
operation: 'and',
|
||||||
@@ -77,7 +77,7 @@ export class MapListModalComponent implements OnInit {
|
|||||||
},
|
},
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
};
|
};
|
||||||
if (typeof this.filterQuery !== 'undefined') {
|
if (this.filterQuery !== undefined) {
|
||||||
geofencedFilter.arguments.filters.push(this.filterQuery);
|
geofencedFilter.arguments.filters.push(this.filterQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user