Compare commits

..

1 Commits

Author SHA1 Message Date
Rainer Killinger
a3a416d580 docs: update changelogs for release
ci: publish release
2023-10-13 17:49:16 +02:00
497 changed files with 14403 additions and 19204 deletions

1
.envrc
View File

@@ -1 +0,0 @@
use flake

1
.gitignore vendored
View File

@@ -24,7 +24,6 @@ report-junit.xml
# NixOS flake # NixOS flake
result result
hsperfdata_root hsperfdata_root
.direnv/
# Directory for instrumented libs generated by jscoverage/JSCover # Directory for instrumented libs generated by jscoverage/JSCover
lib-cov lib-cov

View File

@@ -133,7 +133,7 @@ audit:
allow_failure: true allow_failure: true
needs: [] needs: []
script: script:
- pnpm audit --prod --audit-level critical - pnpm audit --prod
rules: rules:
- if: $CI_COMMIT_BRANCH == 'main' - if: $CI_COMMIT_BRANCH == 'main'
allow_failure: false allow_failure: false

View File

@@ -1,11 +1,6 @@
.limit_publish_pipelines: .limit_publish_pipelines:
rules: rules:
- if: '$CI_COMMIT_BRANCH == "develop" && $CI_COMMIT_MESSAGE =~ /ci: publish prerelease/ && $CI_PIPELINE_SOURCE != "schedule"' - if: '($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop") && $CI_COMMIT_MESSAGE =~ /ci: publish release/ && $CI_PIPELINE_SOURCE != "schedule"'
variables:
PUBLISH_TAG: next
- if: '$CI_COMMIT_BRANCH == "main" && $CI_COMMIT_MESSAGE =~ /ci: publish release/ && $CI_PIPELINE_SOURCE != "schedule"'
variables:
PUBLISH_TAG: latest
deploy: deploy:
stage: publish stage: publish
@@ -29,6 +24,8 @@ publish image:
image: image:
name: gcr.io/kaniko-project/executor:v1.12.1-debug name: gcr.io/kaniko-project/executor:v1.12.1-debug
entrypoint: [""] entrypoint: [""]
variables:
PUBLISH_TAG: next
script: script:
- > - >
/kaniko/executor /kaniko/executor
@@ -53,6 +50,9 @@ publish image:
- IMAGE_NAME: app - IMAGE_NAME: app
DEPLOY_DIR: frontend/app DEPLOY_DIR: frontend/app
rules: rules:
- if: $CI_COMMIT_BRANCH == 'main'
variables:
PUBLISH_TAG: latest
- !reference [.limit_publish_pipelines, rules] - !reference [.limit_publish_pipelines, rules]
publish packages: publish packages:
@@ -61,12 +61,16 @@ publish packages:
variables: variables:
GIT_STRATEGY: clone GIT_STRATEGY: clone
GIT_DEPTH: 0 GIT_DEPTH: 0
PUBLISH_TAG: next
script: script:
- pnpm install - pnpm install
- pnpm build - pnpm build
- pnpm config set '//registry.npmjs.org/:_authToken' "${NPM_AUTH_TOKEN}" - pnpm config set '//registry.npmjs.org/:_authToken' "${NPM_AUTH_TOKEN}"
- pnpm publish -r --publish-branch ${CI_COMMIT_BRANCH} --tag ${PUBLISH_TAG} --no-git-checks # TODO: Git checks... - pnpm publish -r --publish-branch ${CI_COMMIT_BRANCH} --tag ${PUBLISH_TAG} --no-git-checks # TODO: Git checks...
rules: rules:
- if: $CI_COMMIT_BRANCH == 'main'
variables:
PUBLISH_TAG: latest
- !reference [.limit_publish_pipelines, rules] - !reference [.limit_publish_pipelines, rules]
publish docs: publish docs:
@@ -80,4 +84,5 @@ publish docs:
paths: paths:
- public - public
rules: rules:
- if: $CI_COMMIT_BRANCH == 'main'
- !reference [.limit_publish_pipelines, rules] - !reference [.limit_publish_pipelines, rules]

View File

@@ -1 +0,0 @@
pnpm-lock.yaml

View File

@@ -2,7 +2,7 @@
/** @type {import('syncpack').RcFile} */ /** @type {import('syncpack').RcFile} */
const config = { const config = {
semverGroups: [{range: ''}], semverRange: '',
source: ['package.json', '**/package.json'], source: ['package.json', '**/package.json'],
indent: ' ', indent: ' ',
sortFirst: [ sortFirst: [
@@ -49,7 +49,7 @@ const config = {
{ {
label: 'Packages should use workspace version', label: 'Packages should use workspace version',
dependencies: ['@openstapps/**'], dependencies: ['@openstapps/**'],
dependencyTypes: ['prod', 'dev', 'peer'], dependencyTypes: ['prod', 'dev'],
packages: ['**'], packages: ['**'],
pinVersion: 'workspace:*', pinVersion: 'workspace:*',
}, },

View File

@@ -1,3 +0,0 @@
nodejs 18.19.1
pnpm 8.15.4
python 3.11.5

View File

@@ -37,13 +37,13 @@ Adding new types requires changes at multiple locations for it to work correctly
- Add your SCThing and SCThingWithoutReferences to `src/things/your-thing-name.ts` and make them extend `SCThingWithoutReferences` and `SCThing` respectively - Add your SCThing and SCThingWithoutReferences to `src/things/your-thing-name.ts` and make them extend `SCThingWithoutReferences` and `SCThing` respectively
- Add your SCThingMeta to `src/things/your-thing-name.ts` and make it extend `SCThingMeta` - Add your SCThingMeta to `src/things/your-thing-name.ts` and make it extend `SCThingMeta`
- Add your SCThingMeta to `SCClasses` in `src/meta.ts` - Add your SCThingMeta to `SCClasses` in `src/meta.ts`
- Add your SCThing to `SCIndexableThings ` in `src/meta.ts` - Add your SCThing to `SCThingsWithoutDiff` in `src/meta.ts`
- Add your SCThingWithoutReferences to `SCAssociatedThingWithoutReferences` in `src/meta.ts` - Add your SCThingWithoutReferences to `SCAssociatedThingWithoutReferences` in `src/meta.ts`
- Add your SCThing to `SCAssociatedThing` in `src/meta.ts` - Add your SCThing to `SCAssociatedThing` in `src/meta.ts`
- Add your SCThing to the `SCThingType` enum in `src/things/abstract/thing.ts` - Add your SCThing to the `SCThingType` enum in `src/things/abstract/thing.ts`
- Add an example file for your SCThing in `test/resources/YourThingName.json` - Add an example file for your SCThing in `test/resources/YourThingName.json`
- Add the following lines for your SCThing in `test/type.spec.ts`: - Add the following lines for your SCThing in `test/type.spec.ts`:
- Make sure your SCThing (but not SCThingWithoutReferences!) includes the `@indexable` and `@validatable` JSDoc annotations, otherwise neither JSON Schemas nor Elasticsearch mappings will be generated
```typescript ```typescript
/** /**
* Types of properties of SCYourThingName * Types of properties of SCYourThingName

View File

@@ -1,52 +1,5 @@
# @openstapps/backend # @openstapps/backend
## 3.2.0
### Minor Changes
- 912ae422: Add the ability to filter by existence of a field
### Patch Changes
- 689ac68b: pin alpine version to 3.18 and add healthchecks
- e8d72683: Backend unit tests break every year
- Updated dependencies [912ae422]
- @openstapps/core@4.0.0
- @openstapps/core-tools@3.0.0
- @openstapps/logger@3.0.0
## 3.1.2
### Patch Changes
- Fix backend rejecting plugins
- Fix backend sliently falling back to default configs
## 3.1.1
### Patch Changes
- Fix version history offered by backend
- Updated dependencies
- @openstapps/core@3.1.1
## 3.1.0
### Minor Changes
- 06b8ca10: Add job portal feature
### Patch Changes
- Updated dependencies [06b8ca10]
- @openstapps/core@3.1.0
## 3.0.1
### Patch Changes
- Fix missing dependency
## 3.0.0 ## 3.0.0
### Major Changes ### Major Changes

View File

@@ -9,6 +9,4 @@ ENV NODE_ENV=production
WORKDIR /app WORKDIR /app
EXPOSE 3000 EXPOSE 3000
HEALTHCHECK --interval=10s --timeout=10s --start-period=10s --retries=12 CMD curl -s --fail --request POST --data '{}' --header 'Content-Type: application/json' http://localhost:3000/ >/dev/null || exit 1
ENTRYPOINT ["node", "app.js"] ENTRYPOINT ["node", "app.js"]

View File

@@ -1,3 +1,5 @@
// @ts-check
/** /**
* This is the database configuration for the technical university of berlin * This is the database configuration for the technical university of berlin
* *

View File

@@ -22,7 +22,6 @@ const app = {
name: 'Goethe-Uni', name: 'Goethe-Uni',
privacyPolicyUrl: 'https://mobile.server.uni-frankfurt.de/_static/privacy.md', privacyPolicyUrl: 'https://mobile.server.uni-frankfurt.de/_static/privacy.md',
settings: [userGroupSetting, languageSetting], settings: [userGroupSetting, languageSetting],
versionHistory: [],
}; };
export default app; export default app;

View File

@@ -1,3 +1,4 @@
// @ts-check
import {SCSettingInputType, SCThingOriginType, SCThingType} from '@openstapps/core'; import {SCSettingInputType, SCThingOriginType, SCThingType} from '@openstapps/core';
/** @type {import('@openstapps/core').SCLanguageSetting} */ /** @type {import('@openstapps/core').SCLanguageSetting} */

View File

@@ -1,3 +1,4 @@
// @ts-check
/** @type {import('@openstapps/core').SCAppConfigurationMenuCategory[]} */ /** @type {import('@openstapps/core').SCAppConfigurationMenuCategory[]} */
const menus = [ const menus = [
{ {
@@ -55,19 +56,6 @@ const menus = [
}, },
}, },
}, },
{
icon: 'work',
route: '/jobs',
title: 'job postings',
translations: {
de: {
title: 'Jobangebote',
},
en: {
title: 'job postings',
},
},
},
], ],
title: 'overview', title: 'overview',
route: '/overview', route: '/overview',

View File

@@ -1,3 +1,4 @@
// @ts-check
import {SCSettingInputType, SCThingOriginType, SCThingType} from '@openstapps/core'; import {SCSettingInputType, SCThingOriginType, SCThingType} from '@openstapps/core';
/** @type {import('@openstapps/core').SCUserGroupSetting} */ /** @type {import('@openstapps/core').SCUserGroupSetting} */

View File

@@ -1,3 +1,4 @@
// @ts-check
import {SCThingType} from '@openstapps/core'; import {SCThingType} from '@openstapps/core';
/** @type {import('@openstapps/core').SCBackendAggregationConfiguration[]} */ /** @type {import('@openstapps/core').SCBackendAggregationConfiguration[]} */

View File

@@ -1,3 +1,4 @@
// @ts-check
import { import {
month, month,
sommerRange, sommerRange,

View File

@@ -1,3 +1,4 @@
// @ts-check
import {SCThingType} from '@openstapps/core'; import {SCThingType} from '@openstapps/core';
import aggregations from './aggregations.js'; import aggregations from './aggregations.js';
import boostings from './boostings.js'; import boostings from './boostings.js';
@@ -16,7 +17,7 @@ export const backend = {
hiddenTypes: [SCThingType.DateSeries, SCThingType.Diff, SCThingType.Floor], hiddenTypes: [SCThingType.DateSeries, SCThingType.Diff, SCThingType.Floor],
mappingIgnoredTags: ['minlength', 'pattern', 'see', 'tjs-format'], mappingIgnoredTags: ['minlength', 'pattern', 'see', 'tjs-format'],
maxMultiSearchRouteQueries: 5, maxMultiSearchRouteQueries: 5,
maxRequestBodySize: 2e6, maxRequestBodySize: 512 * 1024,
name: 'Goethe-Universität Frankfurt am Main', name: 'Goethe-Universität Frankfurt am Main',
namespace: '909a8cbc-8520-456c-b474-ef1525f14209', namespace: '909a8cbc-8520-456c-b474-ef1525f14209',
sortableFields: [ sortableFields: [

View File

@@ -1,3 +1,4 @@
// @ts-check
import app from './app/index.js'; import app from './app/index.js';
import {backend, internal} from './backend/index.js'; import {backend, internal} from './backend/index.js';

View File

@@ -1,3 +1,5 @@
// @ts-check
/** /**
* This is the default configuration for elasticsearch (a database) * This is the default configuration for elasticsearch (a database)
* *
@@ -9,13 +11,13 @@
* *
* To get more information about the meaning of specific fields, please use your IDE to read the TSDoc documentation. * To get more information about the meaning of specific fields, please use your IDE to read the TSDoc documentation.
* *
* @type {import('../../src/storage/elasticsearch/types/elasticsearch-config.js').ElasticsearchConfigFile} * @type {import('../../src/storage/elasticsearch/types/elasticsearch-config.js')}
*/ */
const config = { const config = {
internal: { internal: {
database: { database: {
name: 'elasticsearch', name: 'elasticsearch',
version: '8.4.2', version: '5.6',
query: { query: {
minMatch: '75%', minMatch: '75%',
queryType: 'dis_max', queryType: 'dis_max',

View File

@@ -1,3 +1,4 @@
// @ts-check
import {readFile} from 'fs/promises'; import {readFile} from 'fs/promises';
import {SCAboutPageContentType} from '@openstapps/core'; import {SCAboutPageContentType} from '@openstapps/core';

View File

@@ -1,3 +1,4 @@
// @ts-check
/** /**
* Generates a range of numbers that represent consecutive calendar months * Generates a range of numbers that represent consecutive calendar months
* *

View File

@@ -1,37 +0,0 @@
import {readFile, readdir} from 'fs/promises';
import url from 'url';
import path from 'path';
/**
* @example version(1, import.meta.url)
* @param options {Omit<import('@openstapps/core').SCAppVersionInfo, 'releaseNotes' | 'translations'>}
* @param base {string}
* @returns {Promise<import('@openstapps/core').SCAppVersionInfo>}
*/
export async function version(options, base) {
const de = await readFile(new URL(`${options.version}.de.md`, base), 'utf8');
const en = await readFile(new URL(`${options.version}.en.md`, base), 'utf8');
return {
...options,
releaseNotes: de,
translations: {
en: {
releaseNotes: en,
},
},
};
}
/**
* @param base {string} Base path of the file as `import.meta.url`
* @returns {Promise<import('@openstapps/core').SCAppVersionInfo[]>}
*/
export async function versions(base) {
const directory = await readdir(path.dirname(url.fileURLToPath(base)));
const versions = [
...new Set(directory.filter(it => it.endsWith('.md')).map(it => it.replace(/\.\w+\.md$/, ''))),
].sort((a, b) => -a.localeCompare(b, undefined, {numeric: true}));
return Promise.all(versions.map(versionName => version({version: versionName}, base)));
}

View File

@@ -1,3 +1,4 @@
// @ts-check
import {SCAboutPageContentType} from '@openstapps/core'; import {SCAboutPageContentType} from '@openstapps/core';
import {markdown} from '../../default/tools/markdown.js'; import {markdown} from '../../default/tools/markdown.js';

View File

@@ -1,3 +1,4 @@
// @ts-check
import {SCAboutPageContentType} from '@openstapps/core'; import {SCAboutPageContentType} from '@openstapps/core';
/** @type {import('@openstapps/core').SCAboutPage} */ /** @type {import('@openstapps/core').SCAboutPage} */

View File

@@ -1,3 +1,4 @@
// @ts-check
import about from './about.js'; import about from './about.js';
import imprint from './imprint.js'; import imprint from './imprint.js';
import privacy from './privacy.js'; import privacy from './privacy.js';

View File

@@ -1,3 +1,4 @@
// @ts-check
import {markdown} from '../../default/tools/markdown.js'; import {markdown} from '../../default/tools/markdown.js';
/** @type {import('@openstapps/core').SCAboutPage} */ /** @type {import('@openstapps/core').SCAboutPage} */

View File

@@ -1,7 +1,7 @@
// @ts-check
import aboutPages from './about-pages/index.js'; import aboutPages from './about-pages/index.js';
import defaultApp from '../default/app/index.js'; import defaultApp from '../default/app/index.js';
import {backend as defaultBackend, internal as defaultInternal} from '../default/backend/index.js'; import {backend as defaultBackend, internal as defaultInternal} from '../default/backend/index.js';
import versionHistory from './version-history/index.js';
/** /**
* This is the default configuration for the Goethe university of Frankfurt * This is the default configuration for the Goethe university of Frankfurt
@@ -76,7 +76,6 @@ const config = {
} */ } */
}, },
}, },
versionHistory,
aboutPages, aboutPages,
}, },
backend: defaultBackend, backend: defaultBackend,

View File

@@ -1,52 +0,0 @@
# Goethe-Uni App 2.4
Wir freuen uns euch mehr in der Goethe-Uni App
bieten zu können.
## Navigation zu Gebäuden und Orten
Als eines der Ergebnisse des Ideenwettbewerbs wurde jetzt
ein Navigationsfeature in die App integriert.
Orte auf der Karte, Mensen, sowie sogar Termine (wenn hinterlegt)
bieten jetzt direkt die Option eine Verbindung zu finden, gestützt
durch die Karten App auf deinem Gerät.
## Integration der Jobbörse
Jobs findest du ab sofort auch in der Goethe-Uni App.
Auch das ist ein Ergebnis des Ideenwettbewerbs,
und wir freuen uns es euch hier präsentieren zu können!
## Der Umweltscore
Der Umweltscore für Gerichte wird nun auch in der App angezeigt.
> Nachhaltigkeit, Umweltschutz, Gesundheit und Klimawandel sind
> zentrale Begriffe im gesellschaftlichen Miteinander.
> Unsere Ernährung spielt hierbei eine wichtige Rolle.
> Das Studierendenwerk Frankfurt am Main zeichnet seine Speisenpläne
> ab sofort mit einem Umweltscore aus.
> Anhand dieser Bewertung können Sie direkt ersehen,
> welchen Einfluss Ihre Essenauswahl auf das Klima hat.
## Weitere Verbesserungen
### Performance
Die Performance der App beim Navigieren wurde stark verbessert und ist datensparender.
### Kalender
Die Kalenderabschnitte haben jetzt neue Namen bekommen:
- Der _Kalender_ zeigt Termine für spezifische Tage
- Die _Wochenübersicht_ ist ein Stundenplan mit allen Termine, die sich wiederholen (z. B. Vorlesungen)
- Die _Einzeltermine_ zeigen alle Termine, die sich nicht wiederholen
(z. B. Klausuren)
### Meine App
Der "Meine Kurse" Abschnitt wurde überarbeitet, und zeigt jetzt Termine
für die nächsten Tage und mit mehr Details an.

View File

@@ -1,49 +0,0 @@
# Goethe-Uni App 2.4
The Goethe-Uni App got even better!
## Navigation to buildings and places
As part of the "Ideenwettbewerb," the idea competition,
we have now integrated a navigation feature into the app.
Orte auf der Karte, Mensen, sowie sogar Termine (wenn hinterlegt)
bieten jetzt direkt die Option eine Verbindung zu finden, gestützt
durch die Karten App auf deinem Gerät.
## Integration of the job market
Jobs are now also available in the Goethe-Uni App.
This feature is also a result of the idea competition,
and we're happy to be able to present it to you here!
## The environment score
The environment score for dishes is now displayed inside the app.
> Sustainability, environment protection, health, and climate change are
> central topics in how we live today in our society.
> Our eating habits play an important role in it.
> The "Studierendenwerk Frankfurt am Main" is marking up its menus
> from now on with the so-called "Umweltscore," the environment score.
> Based on this rating, you can see the impact your meal choice would have on our climate.
## Further improvements
### Performance
The performance while navigating around the app has been heavily improved and requires less data to work.
### Calendar
The calendar sections have new names:
- The _calendar_ shows appointments on specific days
- The _week overview_ is a schedule with all events that repeat (e.g. lectures)
- The _single events_ show all appointments that don't repeat (e.g. exams)
### My App
The "my courses" section has been revamped,
and now shows events for the next days and with more detail.

View File

@@ -1,6 +0,0 @@
import {versions} from '../../default/tools/version.js';
/** @type {import('@openstapps/core').SCAppVersionInfo[]} */
const versionHistory = await versions(import.meta.url);
export default versionHistory;

View File

@@ -1,7 +1,7 @@
{ {
"name": "@openstapps/backend", "name": "@openstapps/backend",
"description": "A reference implementation for a StApps backend", "description": "A reference implementation for a StApps backend",
"version": "3.2.0", "version": "3.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
@@ -59,12 +59,11 @@
"body-parser": "1.20.2", "body-parser": "1.20.2",
"cors": "2.8.5", "cors": "2.8.5",
"cosmiconfig": "8.1.3", "cosmiconfig": "8.1.3",
"deepmerge": "4.3.1",
"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": "12.6.0", "got": "12.6.0",
"moment": "2.30.1", "moment": "2.29.4",
"morgan": "1.10.0", "morgan": "1.10.0",
"nock": "13.3.1", "nock": "13.3.1",
"node-cache": "5.1.2", "node-cache": "5.1.2",
@@ -98,9 +97,9 @@
"sinon": "15.0.4", "sinon": "15.0.4",
"sinon-express-mock": "2.2.1", "sinon-express-mock": "2.2.1",
"supertest": "6.3.3", "supertest": "6.3.3",
"ts-node": "10.9.2", "ts-node": "10.9.1",
"tsup": "6.7.0", "tsup": "6.7.0",
"typescript": "5.4.2" "typescript": "5.1.6"
}, },
"tsup": { "tsup": {
"entry": [ "entry": [

View File

@@ -2,7 +2,6 @@ import {cosmiconfig, PublicExplorer} from 'cosmiconfig';
import {SCConfigFile} from '@openstapps/core'; import {SCConfigFile} from '@openstapps/core';
import path from 'path'; import path from 'path';
import deepmerge from 'deepmerge'; import deepmerge from 'deepmerge';
import {Logger} from '@openstapps/logger';
const fallbackNamespace = 'default'; const fallbackNamespace = 'default';
const configPath = 'config'; const configPath = 'config';
@@ -24,25 +23,31 @@ function configLoader(moduleName: string): PublicExplorer {
* Find and load a config file * Find and load a config file
*/ */
async function findConfig<T>(moduleName: string, namespace = fallbackNamespace): Promise<T> { async function findConfig<T>(moduleName: string, namespace = fallbackNamespace): Promise<T> {
const config = await configLoader(moduleName).search(path.posix.join('.', configPath, namespace)); return configLoader(moduleName)
.search(path.posix.join('.', configPath, namespace))
if (config) { .then(it => it!.config as T)
Logger.info(`Using ${namespace} config for ${moduleName}`); .catch(() =>
return config.config; configLoader(moduleName)
} else { .search(path.posix.join('.', configPath, fallbackNamespace))
Logger.info(`Using ${fallbackNamespace} config for ${moduleName}`); .then(it => it!.config),
return configLoader(moduleName) );
.search(path.posix.join('.', configPath, fallbackNamespace))
.then(it => it!.config);
}
} }
const namespace = process.env.NODE_APP_INSTANCE; /**
const database = process.env.NODE_CONFIG_ENV; * Loads a config file
*/
async function loadConfig<T>(moduleName: string): Promise<T> {
const namespace = process.env.NODE_APP_INSTANCE;
const database = process.env.NODE_CONFIG_ENV;
export const prometheusConfig = await findConfig<unknown>('prometheus', namespace); const config = await findConfig<T>(moduleName, namespace);
if (database) {
const databaseConfig = await findConfig<T>(database, namespace);
return deepmerge(config, databaseConfig);
}
const backendConfigWithoutDatabase = await findConfig<SCConfigFile>('backend', namespace); return config;
export const backendConfig = database }
? deepmerge(backendConfigWithoutDatabase, await findConfig<never>(database, namespace))
: backendConfigWithoutDatabase; export const backendConfig = await loadConfig<SCConfigFile>('backend');
export const prometheusConfig = await loadConfig<unknown>('prometheus');

View File

@@ -84,10 +84,7 @@ export class Elasticsearch implements Database {
* @param config an assembled config file * @param config an assembled config file
* @param mailQueue a mail queue for monitoring * @param mailQueue a mail queue for monitoring
*/ */
constructor( constructor(private readonly config: SCConfigFile, mailQueue?: MailQueue) {
private readonly config: SCConfigFile,
mailQueue?: MailQueue,
) {
if (config.internal.database === undefined || typeof config.internal.database.version !== 'string') { if (config.internal.database === undefined || typeof config.internal.database.version !== 'string') {
throw new TypeError('Database version is undefined. Check your config file'); throw new TypeError('Database version is undefined. Check your config file');
} }

View File

@@ -21,31 +21,16 @@ import {QueryDslSpecificQueryContainer} from '../../types/util.js';
*/ */
export function buildValueFilter( export function buildValueFilter(
filter: SCSearchValueFilter, filter: SCSearchValueFilter,
): ): QueryDslSpecificQueryContainer<'term'> | QueryDslSpecificQueryContainer<'terms'> {
| QueryDslSpecificQueryContainer<'exists'> return Array.isArray(filter.arguments.value)
| QueryDslSpecificQueryContainer<'term'> ? {
| QueryDslSpecificQueryContainer<'terms'> { terms: {
switch (typeof filter.arguments.value) { [`${filter.arguments.field}.raw`]: filter.arguments.value,
case 'undefined': {
return {
exists: {
field: filter.arguments.field,
}, },
}; }
} : {
case 'string': {
return {
term: { term: {
[`${filter.arguments.field}.raw`]: filter.arguments.value, [`${filter.arguments.field}.raw`]: filter.arguments.value,
}, },
}; };
}
case 'object': {
return {
terms: {
[`${filter.arguments.field}.raw`]: filter.arguments.value,
},
};
}
}
} }

View File

@@ -14,7 +14,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { import {
SCBook,
SCBulkAddRoute, SCBulkAddRoute,
SCBulkDoneRoute, SCBulkDoneRoute,
SCBulkRequest, SCBulkRequest,
@@ -24,30 +23,29 @@ import {
import {expect} from 'chai'; import {expect} from 'chai';
import {bulk, DEFAULT_TEST_TIMEOUT} from '../common.js'; import {bulk, DEFAULT_TEST_TIMEOUT} from '../common.js';
import {testApp} from '../tests-setup.js'; import {testApp} from '../tests-setup.js';
import {readFile} from 'fs/promises';
import {v4} from 'uuid'; import {v4} from 'uuid';
import bookFile from '@openstapps/core/test/resources/indexable/Book.2.json' assert {type: 'json'};
const book = bookFile.instance as SCBook; const book = JSON.parse(
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.2.json', 'utf8'),
).instance;
describe('Bulk routes', async function () { describe('Bulk routes', async function () {
// increase timeout for the suite // increase timeout for the suite
this.timeout(DEFAULT_TEST_TIMEOUT); this.timeout(DEFAULT_TEST_TIMEOUT);
let request: SCBulkRequest; const request: SCBulkRequest = {
let bulkRoute: SCBulkRoute; expiration: bulk.expiration,
let bulkAddRoute: SCBulkAddRoute; source: bulk.source,
let bulkDoneRoute: SCBulkDoneRoute; type: bulk.type,
};
const bulkRoute = new SCBulkRoute();
const bulkAddRoute = new SCBulkAddRoute();
const bulkDoneRoute = new SCBulkDoneRoute();
before(function () { // afterEach(async function() {
request = { // TODO: Delete saved bulks
expiration: bulk.expiration, // });
source: bulk.source,
type: bulk.type,
};
bulkRoute = new SCBulkRoute();
bulkAddRoute = new SCBulkAddRoute();
bulkDoneRoute = new SCBulkDoneRoute();
});
it('should create bulk', async function () { it('should create bulk', async function () {
const {status, body, error} = await testApp const {status, body, error} = await testApp

View File

@@ -21,12 +21,7 @@ import {expect} from 'chai';
describe('Index route', async function () { describe('Index route', async function () {
// increase timeout for the suite // increase timeout for the suite
this.timeout(DEFAULT_TEST_TIMEOUT); this.timeout(DEFAULT_TEST_TIMEOUT);
const indexRoute = new SCIndexRoute();
let indexRoute: SCIndexRoute;
before(function () {
indexRoute = new SCIndexRoute();
});
it('should respond with both app and backend configuration', async function () { it('should respond with both app and backend configuration', async function () {
const request: SCIndexRequest = {}; const request: SCIndexRequest = {};

View File

@@ -30,11 +30,15 @@ import chaiAsPromised from 'chai-as-promised';
import {DEFAULT_TEST_TIMEOUT} from '../common.js'; import {DEFAULT_TEST_TIMEOUT} from '../common.js';
import {testApp} from '../tests-setup.js'; import {testApp} from '../tests-setup.js';
import {backendConfig} from '../../src/config.js'; import {backendConfig} from '../../src/config.js';
import registerRequest from '@openstapps/core/test/resources/PluginRegisterRequest.1.json' assert {type: 'json'}; import {readFile} from 'fs/promises';
// for using promises in expectations (to.eventually.be...) // for using promises in expectations (to.eventually.be...)
use(chaiAsPromised); use(chaiAsPromised);
const registerRequest = JSON.parse(
await readFile('node_modules/@openstapps/core/test/resources/PluginRegisterRequest.1.json', 'utf8'),
);
// cast it because of "TS2322: Type 'string' is not assignable to type '"add"'" // cast it because of "TS2322: Type 'string' is not assignable to type '"add"'"
export const registerAddRequest: SCPluginAdd = registerRequest.instance as SCPluginAdd; export const registerAddRequest: SCPluginAdd = registerRequest.instance as SCPluginAdd;

View File

@@ -47,8 +47,8 @@ describe('Create route', async function () {
const statusCodeSuccess = 222; const statusCodeSuccess = 222;
const bodySuccess = {foo: true}; const bodySuccess = {foo: true};
const sandbox = sinon.createSandbox(); const sandbox = sinon.createSandbox();
let validationError: SCValidationErrorResponse; const validationError = new SCValidationErrorResponse([]);
let internalServerError: SCInternalServerErrorResponse; const internalServerError = new SCInternalServerErrorResponse();
beforeEach(function () { beforeEach(function () {
app = express(); app = express();
@@ -64,9 +64,6 @@ describe('Create route', async function () {
handler = (_request, _app) => { handler = (_request, _app) => {
return Promise.resolve(bodySuccess); return Promise.resolve(bodySuccess);
}; };
validationError = new SCValidationErrorResponse([]);
internalServerError = new SCInternalServerErrorResponse();
}); });
afterEach(function () { afterEach(function () {

View File

@@ -29,19 +29,11 @@ import {backendConfig} from '../../src/config.js';
describe('Search route', async function () { describe('Search route', async function () {
// increase timeout for the suite // increase timeout for the suite
this.timeout(DEFAULT_TEST_TIMEOUT); this.timeout(DEFAULT_TEST_TIMEOUT);
let searchRoute: SCSearchRoute; const searchRoute = new SCSearchRoute();
let multiSearchRoute: SCMultiSearchRoute; const multiSearchRoute = new SCMultiSearchRoute();
let syntaxError: SCSyntaxErrorResponse; const syntaxError = new SCSyntaxErrorResponse('Foo Message');
let methodNotAllowedError: SCMethodNotAllowedErrorResponse; const methodNotAllowedError = new SCMethodNotAllowedErrorResponse();
let tooManyRequestsError: SCTooManyRequestsErrorResponse; const tooManyRequestsError = new SCTooManyRequestsErrorResponse();
before(function () {
searchRoute = new SCSearchRoute();
multiSearchRoute = new SCMultiSearchRoute();
syntaxError = new SCSyntaxErrorResponse('Foo Message');
methodNotAllowedError = new SCMethodNotAllowedErrorResponse();
tooManyRequestsError = new SCTooManyRequestsErrorResponse();
});
it('should reject GET, PUT with a valid search query', async function () { it('should reject GET, PUT with a valid search query', async function () {
// const expectedParams = JSON.parse(JSON.stringify(defaultParams)); // const expectedParams = JSON.parse(JSON.stringify(defaultParams));

View File

@@ -13,25 +13,23 @@
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import {SCBook, SCThingUpdateRoute} from '@openstapps/core'; import {SCThingUpdateRoute} from '@openstapps/core';
import chaiAsPromised from 'chai-as-promised'; import chaiAsPromised from 'chai-as-promised';
import {bulkStorageMock, DEFAULT_TEST_TIMEOUT} from '../common.js'; import {bulkStorageMock, DEFAULT_TEST_TIMEOUT} from '../common.js';
import {expect, use} from 'chai'; import {expect, use} from 'chai';
import {testApp} from '../tests-setup.js'; import {testApp} from '../tests-setup.js';
import bookFile from '@openstapps/core/test/resources/indexable/Book.1.json' assert {type: 'json'}; import {readFile} from 'fs/promises';
use(chaiAsPromised); use(chaiAsPromised);
const book = bookFile.instance as SCBook; const book = JSON.parse(
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.1.json', 'utf8'),
).instance;
describe('Thing update route', async function () { describe('Thing update route', async function () {
// increase timeout for the suite // increase timeout for the suite
this.timeout(DEFAULT_TEST_TIMEOUT); this.timeout(DEFAULT_TEST_TIMEOUT);
let thingUpdateRoute: SCThingUpdateRoute; const thingUpdateRoute = new SCThingUpdateRoute();
before(function () {
thingUpdateRoute = new SCThingUpdateRoute();
});
it('should update a thing', async function () { it('should update a thing', async function () {
const thingUpdateRouteurlPath = thingUpdateRoute.urlPath const thingUpdateRouteurlPath = thingUpdateRoute.urlPath

View File

@@ -39,6 +39,7 @@ import {Elasticsearch} from '../../../src/storage/elasticsearch/elasticsearch.js
import {bulk, DEFAULT_TEST_TIMEOUT, getTransport, getIndex} from '../../common.js'; import {bulk, DEFAULT_TEST_TIMEOUT, getTransport, getIndex} from '../../common.js';
import fs from 'fs'; import fs from 'fs';
import {backendConfig} from '../../../src/config.js'; import {backendConfig} from '../../../src/config.js';
import {readFile} from 'fs/promises';
import { import {
ACTIVE_INDICES_ALIAS, ACTIVE_INDICES_ALIAS,
getIndexUID, getIndexUID,
@@ -49,11 +50,6 @@ import {
} from '../../../src/storage/elasticsearch/util/index.js'; } from '../../../src/storage/elasticsearch/util/index.js';
import cron from 'node-cron'; import cron from 'node-cron';
import {query} from './query.js'; import {query} from './query.js';
import messageFile from '@openstapps/core/test/resources/indexable/Message.1.json' assert {type: 'json'};
import bookFile from '@openstapps/core/test/resources/indexable/Book.1.json' assert {type: 'json'};
const message = messageFile.instance as SCMessage;
const book = bookFile.instance as SCBook;
use(chaiAsPromised); use(chaiAsPromised);
@@ -64,6 +60,13 @@ function searchResponse<T>(...hits: SearchHit<T>[]): SearchResponse<T> {
return {hits: {hits}, took: 0, timed_out: false, _shards: {total: 1, failed: 0, successful: 1}}; return {hits: {hits}, took: 0, timed_out: false, _shards: {total: 1, failed: 0, successful: 1}};
} }
const message = JSON.parse(
await readFile('node_modules/@openstapps/core/test/resources/indexable/Message.1.json', 'utf8'),
);
const book = JSON.parse(
await readFile('node_modules/@openstapps/core/test/resources/indexable/Book.1.json', 'utf8'),
);
describe('Elasticsearch', function () { describe('Elasticsearch', function () {
// increase timeout for the suite // increase timeout for the suite
this.timeout(DEFAULT_TEST_TIMEOUT); this.timeout(DEFAULT_TEST_TIMEOUT);
@@ -71,15 +74,8 @@ describe('Elasticsearch', function () {
before(function () { before(function () {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('before');
sandbox.stub(fs, 'readFileSync').returns('{}'); sandbox.stub(fs, 'readFileSync').returns('{}');
sandbox.stub(backendConfig.internal.boostings.default[0], 'fields').value({
'academicTerms.acronym': {
'SS 2023': 1.05,
'WS 2023/24': 1.1,
'SoSe 2023': 1.05,
'WiSe 2023/24': 1.1,
},
});
}); });
after(function () { after(function () {
sandbox.restore(); sandbox.restore();
@@ -449,7 +445,7 @@ describe('Elasticsearch', function () {
_id: '', _id: '',
_index: '', _index: '',
_score: 0, _score: 0,
_source: message, _source: message as SCMessage,
}; };
sandbox.stub(es.client, 'search').resolves(searchResponse(foundObject)); sandbox.stub(es.client, 'search').resolves(searchResponse(foundObject));
@@ -479,7 +475,7 @@ describe('Elasticsearch', function () {
const object: SearchHit<SCMessage> = { const object: SearchHit<SCMessage> = {
_id: '', _id: '',
_index: oldIndex, _index: oldIndex,
_source: message, _source: message as SCMessage,
}; };
sandbox.stub(es.client, 'search').resolves(searchResponse<SCMessage>(object)); sandbox.stub(es.client, 'search').resolves(searchResponse<SCMessage>(object));
sandbox.stub(es, 'prepareBulkWrite').resolves(index); sandbox.stub(es, 'prepareBulkWrite').resolves(index);
@@ -493,7 +489,7 @@ describe('Elasticsearch', function () {
sandbox.stub(es.client, 'create').resolves({result: 'not_found'} as CreateResponse); sandbox.stub(es.client, 'create').resolves({result: 'not_found'} as CreateResponse);
await es.init(); await es.init();
return expect(es.post(message, bulk)).to.rejectedWith('creation'); return expect(es.post(message as SCMessage, bulk)).to.rejectedWith('creation');
}); });
it('should create a new object', async function () { it('should create a new object', async function () {
@@ -506,7 +502,7 @@ describe('Elasticsearch', function () {
}); });
await es.init(); await es.init();
await es.post(message, bulk); await es.post(message as SCMessage, bulk);
expect(createStub.called).to.be.true; expect(createStub.called).to.be.true;
expect(caughtParameter.document).to.be.eql({ expect(caughtParameter.document).to.be.eql({
@@ -531,7 +527,7 @@ describe('Elasticsearch', function () {
_id: '', _id: '',
_index: getIndex(), _index: getIndex(),
_score: 0, _score: 0,
_source: message, _source: message as SCMessage,
}; };
sandbox.stub(es.client, 'search').resolves(searchResponse()); sandbox.stub(es.client, 'search').resolves(searchResponse());
@@ -545,7 +541,7 @@ describe('Elasticsearch', function () {
_id: '', _id: '',
_index: getIndex(), _index: getIndex(),
_score: 0, _score: 0,
_source: message, _source: message as SCMessage,
}; };
sandbox.stub(es.client, 'search').resolves(searchResponse(object)); sandbox.stub(es.client, 'search').resolves(searchResponse(object));
// @ts-expect-error unused // @ts-expect-error unused
@@ -568,13 +564,13 @@ describe('Elasticsearch', function () {
_id: '123', _id: '123',
_index: getIndex(), _index: getIndex(),
_score: 0, _score: 0,
_source: message, _source: message as SCMessage,
}; };
const objectBook: SearchHit<SCBook> = { const objectBook: SearchHit<SCBook> = {
_id: '321', _id: '321',
_index: getIndex(), _index: getIndex(),
_score: 0, _score: 0,
_source: book, _source: book as SCBook,
}; };
const fakeEsAggregations = { const fakeEsAggregations = {
'@all': { '@all': {

View File

@@ -2,7 +2,7 @@
"extends": "@openstapps/tsconfig", "extends": "@openstapps/tsconfig",
"compilerOptions": { "compilerOptions": {
"resolveJsonModule": true, "resolveJsonModule": true,
"useUnknownInCatchVariables": false "useUnknownInCatchVariables": false,
}, "allowJs": true
"exclude": ["lib", "app.js"] }
} }

View File

@@ -1,11 +1,5 @@
# @openstapps/database # @openstapps/database
## 3.2.0
### Patch Changes
- 689ac68b: pin alpine version to 3.18 and add healthchecks
## 3.0.0 ## 3.0.0
### Patch Changes ### Patch Changes

View File

@@ -14,6 +14,4 @@ RUN chown elasticsearch:elasticsearch config/elasticsearch.yml
USER elasticsearch USER elasticsearch
HEALTHCHECK --interval=10s --timeout=10s --start-period=60s --retries=12 CMD curl --fail -s http://localhost:9200/ >/dev/null || exit 1
CMD ["/usr/share/elasticsearch/bin/elasticsearch"] CMD ["/usr/share/elasticsearch/bin/elasticsearch"]

View File

@@ -3,4 +3,3 @@ discovery.type: "single-node"
cluster.routing.allocation.disk.threshold_enabled: false cluster.routing.allocation.disk.threshold_enabled: false
network.bind_host: 0.0.0.0 network.bind_host: 0.0.0.0
xpack.security.enabled: false xpack.security.enabled: false
ingest.geoip.downloader.enabled: false

View File

@@ -1,6 +1,6 @@
{ {
"name": "@openstapps/database", "name": "@openstapps/database",
"version": "3.2.0", "version": "3.0.0",
"private": true, "private": true,
"files": [ "files": [
"config", "config",

View File

@@ -16,7 +16,7 @@
// ESM is not supported, and cts is not detected, so we use type-checked cjs instead. // ESM is not supported, and cts is not detected, so we use type-checked cjs instead.
/** @type {import('../src/common').ConfigFile} */ /** @type {import('../src/common').ConfigFile} */
module.exports = { const configFile = {
activeVersions: ['1\\.0\\.\\d+', '2\\.0\\.\\d+'], activeVersions: ['1\\.0\\.\\d+', '2\\.0\\.\\d+'],
hiddenRoutes: ['/bulk'], hiddenRoutes: ['/bulk'],
logFormat: 'default', logFormat: 'default',
@@ -31,3 +31,5 @@ module.exports = {
dhparam: '/etc/nginx/certs/dhparam.pem', dhparam: '/etc/nginx/certs/dhparam.pem',
}, },
}; };
export default configFile;

View File

@@ -50,8 +50,8 @@
"dockerode": "3.3.5", "dockerode": "3.3.5",
"is-cidr": "4.0.2", "is-cidr": "4.0.2",
"mustache": "4.2.0", "mustache": "4.2.0",
"semver": "7.6.0", "semver": "7.3.8",
"typescript": "5.4.2" "typescript": "5.1.6"
}, },
"devDependencies": { "devDependencies": {
"@openstapps/api-cli": "workspace:*", "@openstapps/api-cli": "workspace:*",
@@ -65,7 +65,7 @@
"@types/mustache": "4.2.2", "@types/mustache": "4.2.2",
"@types/node": "18.15.3", "@types/node": "18.15.3",
"@types/proxyquire": "1.3.28", "@types/proxyquire": "1.3.28",
"@types/semver": "7.5.8", "@types/semver": "7.3.13",
"@types/sha1": "1.1.3", "@types/sha1": "1.1.3",
"@types/sinon": "10.0.14", "@types/sinon": "10.0.14",
"@types/sinon-chai": "3.2.9", "@types/sinon-chai": "3.2.9",
@@ -75,7 +75,7 @@
"mocha-junit-reporter": "2.2.0", "mocha-junit-reporter": "2.2.0",
"sinon": "15.0.4", "sinon": "15.0.4",
"sinon-chai": "3.7.0", "sinon-chai": "3.7.0",
"ts-node": "10.9.2", "ts-node": "10.9.1",
"tsup": "6.7.0" "tsup": "6.7.0"
}, },
"tsup": { "tsup": {

View File

@@ -1,4 +1,4 @@
{ {
"extends": "@openstapps/tsconfig", "extends": "@openstapps/tsconfig",
"exclude": ["config", "lib", "app.js"] "exclude": ["./config/", "./lib/"]
} }

View File

@@ -5,7 +5,6 @@
<item title="search" title.de="Suche" icon="search" route="/search"/> <item title="search" title.de="Suche" icon="search" route="/search"/>
<item title="library catalog" title.de="Bibliothekskatalog" icon="local_library" route="/hebis-search"/> <item title="library catalog" title.de="Bibliothekskatalog" icon="local_library" route="/hebis-search"/>
<item title="course catalog" title.de="Vorlesungsverzeichnis" icon="inventory_2" route="/catalog"/> <item title="course catalog" title.de="Vorlesungsverzeichnis" icon="inventory_2" route="/catalog"/>
<item title="job postings" title.de="Jobangebote" icon="work" route="/jobs"/>
</group> </group>
<group title="canteen" title.de="Mensa" icon="local_cafe" route="/canteen"/> <group title="canteen" title.de="Mensa" icon="local_cafe" route="/canteen"/>
<group title="campus map" title.de="Campus Karte" icon="map" route="/map"/> <group title="campus map" title.de="Campus Karte" icon="map" route="/map"/>

View File

@@ -5,7 +5,6 @@
<item title="search" title.de="Suche" icon="search" route="/search"/> <item title="search" title.de="Suche" icon="search" route="/search"/>
<item title="library catalog" title.de="Bibliothekskatalog" icon="local_library" route="/hebis-search"/> <item title="library catalog" title.de="Bibliothekskatalog" icon="local_library" route="/hebis-search"/>
<item title="course catalog" title.de="Vorlesungsverzeichnis" icon="inventory_2" route="/catalog"/> <item title="course catalog" title.de="Vorlesungsverzeichnis" icon="inventory_2" route="/catalog"/>
<item title="job postings" title.de="Jobangebote" icon="work" route="/jobs"/>
</group> </group>
<group title="canteen" title.de="Mensa" icon="local_cafe" route="/canteen"/> <group title="canteen" title.de="Mensa" icon="local_cafe" route="/canteen"/>
<group title="campus map" title.de="Campus Karte" icon="map" route="/map"/> <group title="campus map" title.de="Campus Karte" icon="map" route="/map"/>

View File

@@ -1,3 +1,4 @@
// @ts-check
const fs = require("fs"); const fs = require("fs");
const path = require("node:path"); const path = require("node:path");
const child_process = require("child_process"); const child_process = require("child_process");

View File

@@ -1,3 +1,4 @@
// @ts-check
"use strict" "use strict"
const rule = require('./copyright-header-rule') const rule = require('./copyright-header-rule')

View File

@@ -1,3 +1,5 @@
// @ts-check
/** @type {import('eslint').Linter.Config} */ /** @type {import('eslint').Linter.Config} */
const config = { const config = {
root: true, root: true,

View File

@@ -18,15 +18,16 @@
"devDependencies": { "devDependencies": {
"@openstapps/tsconfig": "workspace:*", "@openstapps/tsconfig": "workspace:*",
"@types/node": "18.15.3", "@types/node": "18.15.3",
"eslint": "8.57.0", "eslint": "8.43.0",
"typescript": "5.4.2" "typescript": "5.1.6"
}, },
"peerDependencies": { "peerDependencies": {
"@typescript-eslint/eslint-plugin": "7.2.0", "@typescript-eslint/eslint-plugin": "5.60.1",
"@typescript-eslint/parser": "7.2.0", "@typescript-eslint/parser": "5.60.1",
"eslint": "8.57.0", "eslint": "8.43.0",
"eslint-config-prettier": "9.1.0", "eslint-config-prettier": "8.8.0",
"eslint-plugin-jsdoc": "48.2.1", "eslint-plugin-jsdoc": "46.4.2",
"eslint-plugin-unicorn": "51.0.1" "eslint-plugin-prettier": "4.2.1",
"eslint-plugin-unicorn": "47.0.0"
} }
} }

View File

@@ -1,11 +1,5 @@
# @openstapps/prettier-config # @openstapps/prettier-config
## 3.2.0
### Patch Changes
- dbb55850: Update Prettier to 3.1.1
## 3.0.0 ## 3.0.0
### Major Changes ### Major Changes
@@ -36,7 +30,7 @@
```js ```js
#!/usr/bin/env node #!/usr/bin/env node
import "./lib/app.js"; import './lib/app.js';
``` ```
- 64caebaf: Migrate to ESM - 64caebaf: Migrate to ESM
@@ -75,14 +69,11 @@
- 64caebaf: Migrated changelogs to changeset format - 64caebaf: Migrated changelogs to changeset format
```js ```js
import fs from "fs"; import fs from 'fs';
const path = "packages/logger/CHANGELOG.md"; const path = 'packages/logger/CHANGELOG.md';
fs.writeFileSync( fs.writeFileSync(path, fs.readFileSync(path, 'utf8').replace(/^#+\s+\[/gm, '## ['));
path,
fs.readFileSync(path, "utf8").replace(/^#+\s+\[/gm, "## ["),
);
``` ```
- 98546a97: Migrate away from @openstapps/configuration - 98546a97: Migrate away from @openstapps/configuration
@@ -124,7 +115,7 @@
```js ```js
#!/usr/bin/env node #!/usr/bin/env node
import "./lib/app.js"; import './lib/app.js';
``` ```
- 64caebaf: Migrate to ESM - 64caebaf: Migrate to ESM
@@ -163,14 +154,11 @@
- 64caebaf: Migrated changelogs to changeset format - 64caebaf: Migrated changelogs to changeset format
```js ```js
import fs from "fs"; import fs from 'fs';
const path = "packages/logger/CHANGELOG.md"; const path = 'packages/logger/CHANGELOG.md';
fs.writeFileSync( fs.writeFileSync(path, fs.readFileSync(path, 'utf8').replace(/^#+\s+\[/gm, '## ['));
path,
fs.readFileSync(path, "utf8").replace(/^#+\s+\[/gm, "## ["),
);
``` ```
- 98546a97: Migrate away from @openstapps/configuration - 98546a97: Migrate away from @openstapps/configuration

View File

@@ -1,15 +0,0 @@
/** @type {import('prettier').Config} */
const config = {
tabWidth: 2,
printWidth: 110,
useTabs: false,
semi: true,
singleQuote: true,
quoteProps: 'consistent',
trailingComma: 'all',
bracketSpacing: false,
arrowParens: 'avoid',
endOfLine: 'lf'
}
export default config;

View File

@@ -0,0 +1,13 @@
{
"$schema": "http://json.schemastore.org/prettierrc",
"tabWidth": 2,
"printWidth": 110,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "consistent",
"trailingComma": "all",
"bracketSpacing": false,
"arrowParens": "avoid",
"endOfLine": "lf"
}

View File

@@ -1,7 +1,7 @@
{ {
"name": "@openstapps/prettier-config", "name": "@openstapps/prettier-config",
"description": "StApps Prettier Config", "description": "StApps Prettier Config",
"version": "3.2.0", "version": "3.0.0",
"type": "module", "type": "module",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"repository": "git@gitlab.com:openstapps/prettier-config.git", "repository": "git@gitlab.com:openstapps/prettier-config.git",
@@ -9,19 +9,16 @@
"contributors": [ "contributors": [
"Rainer Killinger <mail-openstapps@killinger.co>" "Rainer Killinger <mail-openstapps@killinger.co>"
], ],
"main": "index.js", "main": "index.json",
"files": [ "files": [
"index.js", "index.json",
"CHANGELOG.md", "CHANGELOG.md",
"README.md" "README.md"
], ],
"scripts": { "scripts": {
"test": "prettier --config index.js --check \"test/*.js\"" "test": "npx prettier --config index.json --check \"test/*.js\""
},
"devDependencies": {
"prettier": "3.1.1"
}, },
"peerDependencies": { "peerDependencies": {
"prettier": "3.1.1" "prettier": "2.8.6"
} }
} }

View File

@@ -43,8 +43,8 @@
"@openstapps/logger": "workspace:*", "@openstapps/logger": "workspace:*",
"@slack/web-api": "6.8.1", "@slack/web-api": "6.8.1",
"commander": "10.0.0", "commander": "10.0.0",
"date-fns": "3.6.0", "date-fns": "2.30.0",
"glob": "10.3.10", "glob": "10.2.7",
"mustache": "4.2.0" "mustache": "4.2.0"
}, },
"devDependencies": { "devDependencies": {
@@ -53,7 +53,7 @@
"@openstapps/tsconfig": "workspace:*", "@openstapps/tsconfig": "workspace:*",
"@types/chai": "4.3.5", "@types/chai": "4.3.5",
"@types/chai-as-promised": "7.1.5", "@types/chai-as-promised": "7.1.5",
"@types/glob": "8.1.0", "@types/glob": "8.0.1",
"@types/mocha": "10.0.1", "@types/mocha": "10.0.1",
"@types/mustache": "4.2.2", "@types/mustache": "4.2.2",
"@types/node": "18.15.3", "@types/node": "18.15.3",
@@ -63,9 +63,9 @@
"chai-as-promised": "7.1.1", "chai-as-promised": "7.1.1",
"mocha": "10.2.0", "mocha": "10.2.0",
"mocha-junit-reporter": "2.2.0", "mocha-junit-reporter": "2.2.0",
"ts-node": "10.9.2", "ts-node": "10.9.1",
"tsup": "6.7.0", "tsup": "6.7.0",
"typescript": "5.4.2" "typescript": "5.1.6"
}, },
"tsup": { "tsup": {
"entry": [ "entry": [

View File

@@ -1,4 +1,3 @@
{ {
"extends": "@openstapps/tsconfig", "extends": "@openstapps/tsconfig"
"exclude": ["lib", "app.js"]
} }

View File

@@ -14,7 +14,6 @@
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"isolatedModules": true, "isolatedModules": true,
"allowJs": true, "allowJs": true,
"checkJs": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"noImplicitAny": true, "noImplicitAny": true,

View File

@@ -1,30 +1,5 @@
# @openstapps/minimal-connector # @openstapps/minimal-connector
## 3.2.0
### Patch Changes
- Updated dependencies [912ae422]
- @openstapps/core@4.0.0
- @openstapps/api@4.0.0
- @openstapps/logger@3.0.0
## 3.1.1
### Patch Changes
- Updated dependencies
- @openstapps/api@3.1.1
- @openstapps/core@3.1.1
## 3.1.0
### Patch Changes
- Updated dependencies [06b8ca10]
- @openstapps/core@3.1.0
- @openstapps/api@3.1.0
## 3.0.0 ## 3.0.0
### Major Changes ### Major Changes

View File

@@ -1,7 +1,7 @@
{ {
"name": "@openstapps/minimal-connector", "name": "@openstapps/minimal-connector",
"description": "This is a minimal connector which serves as an example", "description": "This is a minimal connector which serves as an example",
"version": "3.2.0", "version": "3.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
@@ -53,9 +53,9 @@
"mocha": "10.2.0", "mocha": "10.2.0",
"mocha-junit-reporter": "2.2.0", "mocha-junit-reporter": "2.2.0",
"nock": "13.3.1", "nock": "13.3.1",
"ts-node": "10.9.2", "ts-node": "10.9.1",
"tsup": "6.7.0", "tsup": "6.7.0",
"typescript": "5.4.2" "typescript": "5.1.6"
}, },
"tsup": { "tsup": {
"entry": [ "entry": [

View File

@@ -51,7 +51,7 @@ export class MinimalConnector extends Connector<SCMessage> {
protected async fetchItems(): Promise<SCMessage[]> { protected async fetchItems(): Promise<SCMessage[]> {
return [ return [
{ {
audiences: ['students', 'employees', 'guests'], audiences: ['students', 'employees'],
categories: [], categories: [],
description: 'Some description 1', description: 'Some description 1',
messageBody: 'Some message 1', messageBody: 'Some message 1',
@@ -61,7 +61,7 @@ export class MinimalConnector extends Connector<SCMessage> {
uid: createUUID({id: 'message_1'}, this.licensePlate), uid: createUUID({id: 'message_1'}, this.licensePlate),
}, },
{ {
audiences: ['students', 'employees', 'guests'], audiences: ['students', 'employees'],
categories: [], categories: [],
description: 'Some description 2', description: 'Some description 2',
messageBody: 'Some message 2', messageBody: 'Some message 2',
@@ -71,7 +71,7 @@ export class MinimalConnector extends Connector<SCMessage> {
uid: '', // see Connetor.getItems() uid: '', // see Connetor.getItems()
}, },
{ {
audiences: ['students', 'employees', 'guests'], audiences: ['students', 'employees'],
categories: [], categories: [],
description: 'Some description 3', description: 'Some description 3',
messageBody: 'Some message 3', messageBody: 'Some message 3',

View File

@@ -1,4 +1,3 @@
{ {
"extends": "@openstapps/tsconfig", "extends": "@openstapps/tsconfig"
"exclude": ["lib", "app.js"]
} }

View File

@@ -1,62 +1,44 @@
version: '3.7' version: '3.7'
x-development-variables: &development-variables
NODE_ENV: "development"
ALLOW_NO_TRANSPORT: "true"
services: services:
database: database:
image: registry.gitlab.com/openstapps/openstapps/database:3.0.0 image: registry.gitlab.com/openstapps/openstapps/database:2.0.0
# If you need persistence for debugging purposes uncomment the following lines volumes:
#volumes: - ./database:/usr/share/elasticsearch/data
# - ./database:/usr/share/elasticsearch/data
expose: expose:
- 9200 - "9200"
ports:
- 127.0.0.1:9200:9200
environment:
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms2g -Xmx2g"
- discovery.type=single-node
ulimits:
memlock:
soft: -1
hard: -1
restart: unless-stopped restart: unless-stopped
backend: backend:
image: registry.gitlab.com/openstapps/openstapps/backend:3.1.0 image: registry.gitlab.com/openstapps/openstapps/backend:3.0.0-next.0
environment: environment:
<<: *development-variables
ES_ADDR: "http://database:9200" ES_ADDR: "http://database:9200"
NODE_CONFIG_ENV: "elasticsearch" NODE_CONFIG_ENV: "elasticsearch"
NODE_APP_INSTANCE: "f-u" ALLOW_NO_TRANSPORT: "true"
PROMETHEUS_MIDDLEWARE: "false"
expose: expose:
- 3000 - 3000
ports: ports:
- 127.0.0.1:3000:3000 - 3000:3000
links:
- "database"
labels: labels:
- stapps.version=4.1.0 - stapps.version=1.0.0
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- database - database
api:
image: registry.gitlab.com/openstapps/openstapps/api:3.0.0-next.0
links: links:
- database - "backend"
# api: minimal-connector:
# image: registry.gitlab.com/openstapps/openstapps/api:3.0.0 image: registry.gitlab.com/openstapps/minimal-connector:core-0.23
# links: container_name: minimal-connector-0.23
# - backend command: ["http://backend:3000", "minimal-connector", "f-u"]
# minimal-connector: app:
# image: registry.gitlab.com/openstapps/minimal-connector:core-0.23 image: registry.gitlab.com/openstapps/app/executable:core-0.23
# container_name: minimal-connector-0.23 expose:
# command: ["http://backend:3000", "minimal-connector", "f-u"] - 8100
ports:
# app: - 8100:8100
# image: registry.gitlab.com/openstapps/app/executable:core-0.23
# expose:
# - 8100
# ports:
# - 8100:8100

View File

@@ -1,34 +1,5 @@
# @openstapps/minimal-plugin # @openstapps/minimal-plugin
## 3.2.0
### Patch Changes
- Updated dependencies [912ae422]
- @openstapps/core@4.0.0
- @openstapps/api@4.0.0
- @openstapps/api-plugin@4.0.0
- @openstapps/core-tools@3.0.0
- @openstapps/logger@3.0.0
## 3.1.1
### Patch Changes
- Updated dependencies
- @openstapps/api@3.1.1
- @openstapps/api-plugin@3.1.1
- @openstapps/core@3.1.1
## 3.1.0
### Patch Changes
- Updated dependencies [06b8ca10]
- @openstapps/core@3.1.0
- @openstapps/api@3.1.0
- @openstapps/api-plugin@3.1.0
## 3.0.0 ## 3.0.0
### Major Changes ### Major Changes

View File

@@ -1,7 +1,7 @@
{ {
"name": "@openstapps/minimal-plugin", "name": "@openstapps/minimal-plugin",
"description": "Minimal Plugin", "description": "Minimal Plugin",
"version": "3.2.0", "version": "3.0.0",
"private": true, "private": true,
"type": "module", "type": "module",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
@@ -35,7 +35,7 @@
"@openstapps/logger": "workspace:*", "@openstapps/logger": "workspace:*",
"commander": "10.0.0", "commander": "10.0.0",
"express": "4.18.2", "express": "4.18.2",
"ts-node": "10.9.2" "ts-node": "10.9.1"
}, },
"devDependencies": { "devDependencies": {
"@openstapps/eslint-config": "workspace:*", "@openstapps/eslint-config": "workspace:*",
@@ -44,7 +44,7 @@
"@types/express": "4.17.17", "@types/express": "4.17.17",
"@types/node": "18.15.3", "@types/node": "18.15.3",
"tsup": "6.7.0", "tsup": "6.7.0",
"typescript": "5.4.2" "typescript": "5.1.6"
}, },
"tsup": { "tsup": {
"entry": [ "entry": [

View File

@@ -1,4 +1,3 @@
{ {
"extends": "@openstapps/tsconfig", "extends": "@openstapps/tsconfig"
"exclude": ["lib", "app.js"]
} }

40
flake.lock generated
View File

@@ -1,30 +1,12 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1701626906, "lastModified": 1689752456,
"narHash": "sha256-ugr1QyzzwNk505ICE4VMQzonHQ9QS5W33xF2FXzFQ00=", "narHash": "sha256-VOChdECcEI8ixz8QY+YC4JaNEFwQd1V8bA0G4B28Ki0=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "0c6d8c783336a59f4c59d4a6daed6ab269c4b361", "rev": "7f256d7da238cb627ef189d56ed590739f42f13b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -36,24 +18,8 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
} }
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

142
flake.nix
View File

@@ -1,75 +1,77 @@
{ {
description = "A Nix-flake-based development environment for OpenStApps"; description = "A Nix-flake-based development environment for OpenStApps";
inputs = { inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; outputs = { self, nixpkgs }:
flake-utils.url = "github:numtide/flake-utils"; let
}; buildToolsVersion = "30.0.3";
outputs = { overlays = [
self, (final: prev: rec {
nixpkgs, nodejs = prev.nodejs-18_x;
flake-utils, pnpm = prev.nodePackages.pnpm;
}: let chrome = prev.google-chrome;
aapt2buildToolsVersion = "33.0.2"; firefox = prev.firefox;
in webkit = prev.epiphany; # Safari-ish browser
flake-utils.lib.eachDefaultSystem (system: let android = prev.androidenv.composeAndroidPackages {
pkgs = import nixpkgs { buildToolsVersions = [ "${buildToolsVersion}" ];
inherit system; platformVersions = [ "32" ];
overlays = [ };
(final: prev: rec { cypress = prev.cypress.overrideAttrs(cyPrev: rec {
fontMin = prev.python311.withPackages (ps: with ps; [brotli fonttools] ++ (with fonttools.optional-dependencies; [woff])); version = "13.2.0";
android = prev.androidenv.composeAndroidPackages { src = prev.fetchzip {
buildToolsVersions = ["30.0.3" aapt2buildToolsVersion]; url = "https://cdn.cypress.io/desktop/${version}/linux-x64/cypress.zip";
platformVersions = ["33"]; hash = "sha256-9o0nprGcJhudS1LNm+T7Vf0Dwd1RBauYKI+w1FBQ3ZM=";
}; };
cypress = prev.cypress.overrideAttrs (cyPrev: rec { });
version = "13.2.0"; })
src = prev.fetchzip { ];
url = "https://cdn.cypress.io/desktop/${version}/linux-x64/cypress.zip"; # TODO: aarch64-linux, x68_64-darwin, aarch64-darwin
hash = "sha256-9o0nprGcJhudS1LNm+T7Vf0Dwd1RBauYKI+w1FBQ3ZM="; supportedSystems = [ "x86_64-linux" ];
}; forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
}); pkgs = import nixpkgs {
}) inherit overlays system;
]; config = {
config = { allowUnfree = true;
allowUnfree = true; android_sdk.accept_license = true;
android_sdk.accept_license = true; };
}; };
}; });
androidFhs = pkgs.buildFHSUserEnv { in
name = "android-env"; {
targetPkgs = pkgs: with pkgs; []; devShells = forEachSupportedSystem ({ pkgs }:
runScript = "bash"; let
profile = '' python = (pkgs.python311.withPackages(ps: with ps; [ brotli fonttools ] ++ (with fonttools.optional-dependencies; [ ufo lxml unicode woff ])));
export ALLOW_NINJA_ENV=true in
export USE_CCACHE=1 {
export LD_LIBRARY_PATH=/usr/lib:/usr/lib32 default = (pkgs.buildFHSUserEnv {
''; name = "StApps Dev";
}; targetPkgs = pkgs: with pkgs; [
in { nodejs
devShell = pkgs.mkShell rec { pnpm
nativeBuildInputs = [androidFhs]; python
buildInputs = with pkgs; [ docker
nodejs-18_x # tools
nodePackages.pnpm curl
# tools jq
curl # browsers
jq firefox
fontMin chrome
# browsers webkit
firefox cypress
google-chrome # android
epiphany # Safari-ish browser jdk17
cypress android.androidsdk
# android musl
jdk17 ];
android.androidsdk runScript = "bash";
musl profile = ''
]; export CYPRESS_INSTALL_BINARY=0
ANDROID_JAVA_HOME = "${pkgs.jdk.home}"; export CYPRESS_RUN_BINARY=${pkgs.cypress}/bin/Cypress
ANDROID_SDK_ROOT = "${pkgs.android.androidsdk}/libexec/android-sdk"; export ANDROID_SDK_ROOT=${pkgs.android.androidsdk}/libexec/android-sdk
GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_SDK_ROOT}/build-tools/${aapt2buildToolsVersion}/aapt2"; export ANDROID_JAVA_HOME=${pkgs.jdk.home}
CYPRESS_INSTALL_BINARY = "0"; export DOCKER_HOST=unix:///run/user/1000/docker.sock
CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress"; { dockerd-rootless & } 2>/dev/null
}; '';
}); }).env;
});
};
} }

View File

@@ -5,4 +5,10 @@
# You can see what browsers were selected by your queries by running: # You can see what browsers were selected by your queries by running:
# npx browserslist # npx browserslist
> 0.5% in DE and last 2 major versions and supports es6 and not dead > 0.5%
last 2 versions
Firefox ESR
not dead
not kaios 2.5
not op_mini all
not IE 9-11

View File

@@ -46,7 +46,6 @@
"unicorn/no-nested-ternary": "off", "unicorn/no-nested-ternary": "off",
"unicorn/better-regex": "off", "unicorn/better-regex": "off",
"unicorn/no-non-null-assertion": "off", "unicorn/no-non-null-assertion": "off",
"unicorn/consistent-function-scoping": ["error", {"checkArrowFunctions": false}],
"jsdoc/no-types": "error", "jsdoc/no-types": "error",
"jsdoc/require-param": "off", "jsdoc/require-param": "off",
"jsdoc/require-param-description": "error", "jsdoc/require-param-description": "error",

View File

@@ -37,7 +37,6 @@ resources/*/icon/
resources/*/splash/ resources/*/splash/
android/app/src/main/res/**/*.png android/app/src/main/res/**/*.png
ios/App/App/Assets.xcassets/**/*.png ios/App/App/Assets.xcassets/**/*.png
AndroidManifest.xml.orig
.DS_Store .DS_Store
Thumbs.db Thumbs.db

View File

@@ -1,4 +1,3 @@
// @ts-check
/* /*
* Copyright (C) 2022 StApps * Copyright (C) 2022 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
@@ -13,11 +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 prettierConfig from '@openstapps/prettier-config';
/** @type {import('prettier').Config} */ module.exports = {
const config = { ...require('@openstapps/prettier-config'),
...prettierConfig,
overrides: [ overrides: [
{ {
files: 'src/**/*.html', files: 'src/**/*.html',
@@ -26,6 +23,5 @@ const config = {
}, },
}, },
], ],
ignorePath: ['.prettierignore', '../../.gitignore'],
}; };
export default config;

View File

@@ -1,52 +1,5 @@
# @openstapps/app # @openstapps/app
## 3.2.0
### Patch Changes
- 689ac68b: pin alpine version to 3.18 and add healthchecks
- Updated dependencies [912ae422]
- @openstapps/core@4.0.0
- @openstapps/api@4.0.0
- @openstapps/collection-utils@3.0.0
## 3.1.2
### Patch Changes
- Fix for Android users not being able to log in
## 3.1.1
### Patch Changes
- Fix version history offered by backend
- Updated dependencies
- @openstapps/api@3.1.1
- @openstapps/core@3.1.1
## 3.1.1
### Patch Changes
- last minute deployment changes
## 3.1.0
### Minor Changes
- 06b8ca10: Add job portal feature
- 066e3744: Update to Capacitor 5.x
### Patch Changes
- 066e3744: Update logo flow to use capacitor-assets (single asset)
- 066e3744: Replace NavigationBar/StatusBar plugins with native color setting
- 066e3744: Hide splash screen only when app is ready
- Updated dependencies [06b8ca10]
- @openstapps/core@3.1.0
- @openstapps/api@3.1.0
## 3.0.0 ## 3.0.0
### Major Changes ### Major Changes

View File

@@ -1,7 +1,7 @@
# Creates a docker image with only the app as an executable unit # Creates a docker image with only the app as an executable unit
# Dependencies need to be installed beforehand # Dependencies need to be installed beforehand
# Needs to be build beforehand # Needs to be build beforehand
FROM node:18-alpine3.18 FROM node:18-alpine
WORKDIR /app WORKDIR /app
COPY www/ /app/www COPY www/ /app/www

View File

@@ -52,7 +52,7 @@ All the npm scripts are defined in `package.json` [file](package.json). It is re
## Most useful commands ## Most useful commands
### Editing the Ionic Database from the browser ## Editing the Ionic Database from the browser
Add the following function using the browser console Add the following function using the browser console
@@ -90,19 +90,6 @@ You'll need to run _Chromium_ using
pnpm chromium:no-cors pnpm chromium:no-cors
``` ```
### Help, I can't log in!
Login services will often block hosts not coming from the production
server. You can circumvent this locally by using the `:virtual-host`
scripts:
```shell
# Start the dev server on mobile.app.uni-frankfurt.de
pnpm start:virtual-host
# Run chromium with flags that redirect mobile.app.uni-frankfurt.de to localhost:8100
pnpm chromium:virtual-host
```
### Running the app ### Running the app
Install the npm packages needed for running the app (as for any other node project which uses npm): Install the npm packages needed for running the app (as for any other node project which uses npm):

View File

@@ -1,7 +1,6 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
namespace "de.anyschool.app"
compileSdkVersion rootProject.ext.compileSdkVersion compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig { defaultConfig {
applicationId "de.anyschool.app" applicationId "de.anyschool.app"

View File

@@ -2,8 +2,8 @@
android { android {
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_17 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_11
} }
} }
@@ -23,6 +23,8 @@ dependencies {
implementation project(':capacitor-preferences') implementation project(':capacitor-preferences')
implementation project(':capacitor-share') implementation project(':capacitor-share')
implementation project(':capacitor-splash-screen') implementation project(':capacitor-splash-screen')
implementation project(':capacitor-status-bar')
implementation project(':hugotomazi-capacitor-navigation-bar')
implementation project(':transistorsoft-capacitor-background-fetch') implementation project(':transistorsoft-capacitor-background-fetch')
implementation project(':capacitor-secure-storage-plugin') implementation project(':capacitor-secure-storage-plugin')

View File

@@ -1,5 +1,7 @@
<?xml version='1.0' encoding='utf-8' ?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.anyschool.app">
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@@ -8,14 +10,16 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"> android:usesCleartextTraffic="true">
<activity <activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
android:exported="true"
android:label="@string/title_activity_main"
android:launchMode="singleTask"
android:name="de.anyschool.app.MainActivity" android:name="de.anyschool.app.MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch" android:theme="@style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask"
android:exported="true"
android:windowSoftInputMode="adjustPan"> android:windowSoftInputMode="adjustPan">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
@@ -33,14 +37,20 @@
<data android:host="@string/app_host" android:scheme="https" /> <data android:host="@string/app_host" android:scheme="https" />
</intent-filter> </intent-filter>
</activity> </activity>
<provider <provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider" android:authorities="${applicationId}.fileprovider"
android:exported="false" android:exported="false"
android:grantUriPermissions="true" android:grantUriPermissions="true">
android:name="androidx.core.content.FileProvider"> <meta-data
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider> </provider>
</application> </application>
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

View File

@@ -55,6 +55,14 @@
"pkg": "@capacitor/splash-screen", "pkg": "@capacitor/splash-screen",
"classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin" "classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin"
}, },
{
"pkg": "@capacitor/status-bar",
"classpath": "com.capacitorjs.plugins.statusbar.StatusBarPlugin"
},
{
"pkg": "@hugotomazi/capacitor-navigation-bar",
"classpath": "br.com.tombus.capacitor.plugin.navigationbar.NavigationBarPlugin"
},
{ {
"pkg": "@transistorsoft/capacitor-background-fetch", "pkg": "@transistorsoft/capacitor-background-fetch",
"classpath": "com.transistorsoft.bgfetch.capacitor.BackgroundFetchPlugin" "classpath": "com.transistorsoft.bgfetch.capacitor.BackgroundFetchPlugin"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>

View File

@@ -1,27 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<group android:scaleX="0.649"
android:scaleY="0.649"
android:translateX="176.63525"
android:translateY="179.712">
<path
android:pathData="M272.4,232.1L483.6,232.1A38,38 0,0 1,521.6 270.2L521.6,481.4A38,38 0,0 1,483.6 519.4L272.4,519.4A38,38 0,0 1,234.4 481.4L234.4,270.2A38,38 0,0 1,272.4 232.1z"
android:strokeWidth="0.839386"
android:fillColor="#00b5cc"/>
<path
android:pathData="M584.2,402.8L662,402.8A19.4,19.4 0,0 1,681.4 422.2L681.4,499.9A19.4,19.4 0,0 1,662 519.4L584.2,519.4A19.4,19.4 0,0 1,564.8 499.9L564.8,422.2A19.4,19.4 0,0 1,584.2 402.8z"
android:strokeWidth="0.842212"
android:fillColor="#3be40b"/>
<path
android:pathData="M591.8,562.6L769.3,562.6A27,27 0,0 1,796.3 589.6L796.3,767A27,27 0,0 1,769.3 794.1L591.8,794.1A27,27 0,0 1,564.8 767L564.8,589.6A27,27 0,0 1,591.8 562.6z"
android:strokeWidth="0.832623"
android:fillColor="#c90e20"/>
<path
android:pathData="M371.2,562.6L496.3,562.6A25.3,25.3 0,0 1,521.6 587.9L521.6,713A25.3,25.3 0,0 1,496.3 738.3L371.2,738.3A25.3,25.3 0,0 1,345.9 713L345.9,587.9A25.3,25.3 0,0 1,371.2 562.6z"
android:strokeWidth="0.846446"
android:fillColor="#e4a20b"/>
</group>
</vector>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" /> </adaptive-icon>
</adaptive-icon>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" /> </adaptive-icon>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Some files were not shown because too many files have changed in this diff Show More