Compare commits

...
Author SHA1 Message Date
Jovan Krunić c1a42808b5 fix: enable starting the app without backend
Closes #223
2024-09-30 11:03:56 +00:00
Jovan KrunićandThea Schöbl bb1f596bfc fix: enable starting the app without backend
Closes #223
2024-09-30 11:03:53 +00:00
Theaninova 0c49fd8c34 refactor: update nix dependencies 2024-09-30 13:00:59 +02:00
Thea SchöblandJovan Krunić ce5016a992 fix: text of the feedback form not fully visible
Closes #227
2024-09-18 09:53:50 +00:00
Theaninova 3ac8c04765 fix: date range is now pipe has issues around boundaries 2024-08-06 17:43:59 +02:00
Rainer Killinger 5c260dd26b refactor: update android build dependencies for API level 34 2024-08-05 12:51:47 +00:00
Rainer Killinger f2e1a6ddd5 docs: update changelogs for release
ci: publish release
2024-08-02 10:19:44 +02:00
Rainer Killinger ccacfbf710 fix: publish-packages script 2024-08-02 10:18:57 +02:00
Rainer Killinger b249b329f7 refactor: use development backend for non production environment 2024-08-01 17:44:21 +02:00
Jovan KrunićandRainer Killinger 7afc24f1bc fix: use major version config from storage when offline
Closes #218
2024-08-01 17:44:20 +02:00
Rainer Killinger 7276525dfa fix: app-builder image build due to nodejs versions <18.19 not being supported by angular 17 2024-08-01 15:24:59 +02:00
Jovan Krunić c9e881582f refactor: set production version of the backend 2024-07-19 15:20:06 +02:00
Jovan Krunić df681de083 feat: show title if available on library account profile
Closes #215
2024-07-19 15:20:06 +02:00
TheaninovaandJovan Krunić 802a7a3fa7 fix: docs generation 2024-07-19 15:20:06 +02:00
Jovan Krunić 343d03e647 feat: library account adjustments
Closes #214
2024-07-19 15:20:06 +02:00
TheaninovaandJovan Krunić 727b92911e fix: list item layout broken 2024-07-19 15:20:06 +02:00
TheaninovaandJovan Krunić 11bc987807 fix: elasticsearch integration spams errors 2024-07-19 15:20:06 +02:00
Rainer Killinger b8faae5988 docs: update changelogs for release
ci: publish release
2024-06-28 17:39:39 +02:00
TheaninovaandRainer Killinger 67ab1fd613 fix: geo.point has wrong mapping 2024-06-28 17:25:32 +02:00
Rainer Killinger 142079bf0e refactor: set app backend to dev version 2024-06-28 12:02:59 +02:00
Rainer Killinger 5050ac90eb docs: update changelogs for release
ci: publish release
2024-06-28 09:28:39 +02:00
Rainer Killinger 688bc5f2e7 refactor: add changeset 2024-06-28 09:03:54 +02:00
Rainer Killinger ad174dd7d7 refactor: use static map files from backend 2024-06-28 08:59:08 +02:00
Rainer Killinger 26e654f5b8 fix: app license overview 2024-06-27 14:57:24 +02:00
Rainer Killinger 5439484a90 fix: changelog typo 2024-06-27 12:06:52 +02:00
Rainer Killinger 68f3366a27 refactor: adjustments for recent PAIA changes 2024-06-27 09:23:55 +00:00
Jovan KrunićandThea Schöbl dea9a82105 fix: do not fetch remote configuration if offline
Closes #206
2024-06-17 09:55:29 +00:00
Theaninova 39d2801114 feat: store id cards 2024-06-12 13:51:46 +02:00
Rainer KillingerandThea Schöbl 341b209092 refactor: display id-cards in their own modal 2024-06-05 11:07:30 +00:00
Rainer Killinger a6b88d3534 refactor: add f-u specific changelogs 2024-05-27 16:27:37 +02:00
Rainer Killinger be863daaef refactor: updated used licences within the app 2024-05-27 15:36:00 +02:00
TheaninovaandRainer Killinger 2f64d69693 feat: migrate to protomaps and maplibre 2024-05-27 15:07:27 +02:00
TheaninovaandRainer Killinger 964516d3cf fix: remove noUnused* TSConfig options
TSConfig options prevent Angular from compiling the app. This is
specifically harsh with the noUnused* rules, which require you to
strictly remove any unused variables even in dev mode while testing.
Since this case is already covered by ESLint, the TSConfig option was
removed.
2024-05-27 15:07:27 +02:00
TheaninovaandRainer Killinger 71ff9fd960 fix: favorite button 2024-05-27 15:07:27 +02:00
TheaninovaandRainer Killinger abf9999461 feat: type-safe sc-icons 2024-05-27 15:07:26 +02:00
TheaninovaandRainer Killinger 53c3d0ba0c refactor: replace rfdc with native structuredClone 2024-05-27 15:07:25 +02:00
Rainer Killinger 622481a3c9 docs: update changelogs for release\n\nci: publish release 2024-03-28 14:27:56 +01:00
Thea Schöbl 1ab5c0c355 fix: inPlace in list items is placed weird 2024-03-27 13:45:22 +00:00
Rainer Killinger b0f6ffb21c refactor: ajdust app environment to backend version >= v3.1.0 2024-03-27 10:11:32 +01:00
Rainer Killinger e658cff9d2 refactor: use GET for id-cards requests 2024-03-27 09:55:31 +01:00
Rainer Killinger e71355a2fb fix: malformed Bearer header in id-cards provider 2024-03-27 09:55:30 +01:00
TheaninovaandRainer Killinger 100607740b fix: angular lsp broken 2024-03-27 09:55:30 +01:00
Thea SchöblandRainer Killinger 10c4466b37 feat: update to angular 17 2024-03-27 09:55:30 +01:00
Rainer Killinger 09faa66e98 fix: broken build and test stage 2024-03-27 09:55:30 +01:00
Rainer Killinger 7c5687111f fix: check-icons script in app 2024-03-27 09:55:30 +01:00
Rainer Killinger c066028e49 refactor: update asdf .tool-versions 2024-03-27 09:55:30 +01:00
TheaninovaandRainer Killinger 0858a26dc1 fix: dish prices sometimes go missing 2024-03-27 09:55:30 +01:00
TheaninovaandRainer Killinger 8667603bd6 feat: export core version in package 2024-03-27 09:55:29 +01:00
TheaninovaandRainer Killinger 65bc9a76b6 feat: add syncpack semver ranges 2024-03-27 09:55:29 +01:00
TheaninovaandRainer Killinger 912ae42270 feat: add ability to check for existence of a field 2024-03-27 09:55:29 +01:00
TheaninovaandRainer Killinger c4a5d6e73b fix: exclude app.js and lib from typescript compliation 2024-03-27 09:55:29 +01:00
TheaninovaandRainer Killinger deed376c24 feat: enable checkJs by default 2024-03-27 09:55:29 +01:00
TheaninovaandRainer Killinger a4cc23e9a8 feat: add direnv for nix
feat: update nix flake to not rely on buildFHSUserEnv
2024-03-27 09:55:29 +01:00
TheaninovaandRainer Killinger e8d72683ef fix: backend tests break every year
refactor: update some backend unit tests
2024-03-27 09:55:28 +01:00
Rainer Killinger e3d068f8d4 fix: iOS build resources 2024-03-27 09:55:28 +01:00
Rainer Killinger b346d216a3 refactor: add asdf tool versioning file 2024-03-27 09:55:28 +01:00
TheaninovaandRainer Killinger dbb558508f fix: changeset crashes because it uses internal prettier version 2024-03-27 09:55:28 +01:00
Rainer Killinger 754d99c1b4 refactor: overhaul minimal-deployment compose file 2024-03-27 09:55:27 +01:00
Rainer Killinger 689ac68be3 fix: pin alpine version to 3.18 and add healthchecks 2024-03-06 11:45:40 +01:00
Rainer Killinger d36d9596fc docs: update changelogs for release 2023-12-19 15:32:42 +01:00
Thea SchöblandRainer Killinger 8d50f669e7 feat: collapse detail titles into header bar 2023-12-19 14:16:38 +01:00
Jovan KrunićandRainer Killinger dce08d9c03 fix: reverse workaround after update of capacitor
Closes #179
2023-12-19 13:12:25 +00:00
Rainer Killinger 296054c8e0 docs: update changelogs for release
ci: publish release
2023-12-13 16:42:45 +01:00
Theaninova 859763367e fix: throw error if config import fails
feat: log used config in backend
2023-12-12 14:37:24 +01:00
Rainer Killinger 848fde4660 refactor: increase maxRequestBodySize to 2 MB 2023-12-11 13:00:52 +01:00
Rainer Killinger bd1046a19a docs: update changelogs for release
ci: publish release
2023-12-08 18:03:41 +01:00
Rainer Killinger 3b9068197c fix: pettier config causing changeset to crash 2023-12-08 17:35:00 +01:00
Thea SchöblandRainer Killinger d2c8120255 feat: simplify version history api 2023-12-08 13:49:53 +00:00
Theaninova d44204cf8d fix: remove old console.log statements 2023-12-06 17:15:03 +01:00
Theaninova 9d5dd05bb6 refactor: remove nullish coalecing pipe 2023-12-06 17:15:03 +01:00
Theaninova 288a49113f refactor: migrate to strict template checking 2023-12-06 17:14:55 +01:00
TheaninovaandThea Schöbl 791b5c895d fix: hide navigation from jop posting search 2023-12-05 15:51:57 +00:00
TheaninovaandThea Schöbl d7a85b7fae feat: improved e2e tests 2023-12-05 15:17:00 +00:00
Rainer Killinger bff2d985aa refactor: use latest backend (4.1.0) 2023-12-05 12:06:11 +00:00
Rainer Killinger 655efc9d29 fix: map location preview collapsed in webkit 2023-12-05 12:06:11 +00:00
Rainer KillingerandThea Schöbl 66712bdd24 fix: iOS app not starting 2023-12-05 11:19:46 +00:00
TheaninovaandThea Schöbl 8b5b4c765b fix: my app card layout 2023-12-05 10:36:22 +00:00
Thea Schöbl 31a6ebfd3f feat: upgrade prettier to v3 2023-12-05 10:36:04 +00:00
Rainer Killinger 991ed1cb1f docs: update changelogs for release
ci: publish release
2023-12-01 19:05:06 +01:00
Rainer Killinger 1efe5c1449 refactor: don't open webpack-bundle-analyzer 2023-12-01 18:28:41 +01:00
Rainer Killinger 4dbeb9936c refactor: adjust f-u release version history 2023-12-01 18:19:36 +01:00
Rainer Killinger 29e6128141 fix: resources:ios script not being BSD compatible 2023-12-01 18:15:15 +01:00
Rainer Killinger 753dc7cd11 docs: update changelogs for release
ci: publish release
2023-12-01 16:42:33 +01:00
Rainer Killinger 4f3834c20e refactor: update capacitor-secure-storage-plugin 2023-12-01 13:42:22 +00:00
Rainer Killinger cfb4aa364f refactor: add new book and periodical categories 2023-12-01 12:50:28 +00:00
Thea Schöbl 37945f7d19 feat: app release notes 2023-12-01 12:34:20 +00:00
Theaninova 5d47a17629 fix: android system bars always have light buttons 2023-12-01 12:23:38 +01:00
TheaninovaandRainer Killinger 61587c7ba1 feat: add alert when critical errors prevent an app launch 2023-11-28 09:01:23 +00:00
TheaninovaandRainer Killinger 066e374462 feat: upgrade to capacitor 5.0 2023-11-28 09:01:23 +00:00
Theaninova a02190fe5a fix: flaky tests due to console.error checks 2023-11-27 19:54:28 +01:00
Theaninova 04e275e967 feat: add share option in detail views 2023-11-14 16:37:12 +01:00
611 changed files with 23841 additions and 17156 deletions
-7
View File
@@ -1,7 +0,0 @@
---
'@openstapps/backend': minor
'@openstapps/core': minor
'@openstapps/app': minor
---
Add job portal feature
-5
View File
@@ -1,5 +0,0 @@
---
'@openstapps/api-cli': minor
---
Add "\*" option to copy command that allows for a full database clone
+1
View File
@@ -0,0 +1 @@
use flake
+1
View File
@@ -24,6 +24,7 @@ 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
+1
View File
@@ -0,0 +1 @@
pnpm-lock.yaml
+8 -2
View File
@@ -2,7 +2,13 @@
/** @type {import('syncpack').RcFile} */ /** @type {import('syncpack').RcFile} */
const config = { const config = {
semverRange: '', semverGroups: [
{
range: '',
dependencies: ['**'],
packages: ['**'],
}
],
source: ['package.json', '**/package.json'], source: ['package.json', '**/package.json'],
indent: ' ', indent: ' ',
sortFirst: [ sortFirst: [
@@ -49,7 +55,7 @@ const config = {
{ {
label: 'Packages should use workspace version', label: 'Packages should use workspace version',
dependencies: ['@openstapps/**'], dependencies: ['@openstapps/**'],
dependencyTypes: ['prod', 'dev'], dependencyTypes: ['prod', 'dev', 'peer'],
packages: ['**'], packages: ['**'],
pinVersion: 'workspace:*', pinVersion: 'workspace:*',
}, },
+3
View File
@@ -0,0 +1,3 @@
nodejs 18.19.1
pnpm 8.15.4
python 3.11.5
+67
View File
@@ -1,5 +1,72 @@
# @openstapps/backend # @openstapps/backend
## 3.3.2
### Patch Changes
- @openstapps/core@3.3.2
- @openstapps/core-tools@3.3.2
## 3.3.1
### Patch Changes
- 67ab1fd6: fix for geo.point mapping
## 3.3.0
### Minor Changes
- 688bc5f2: v3.3.0 changes
### Patch Changes
- Updated dependencies [688bc5f2]
- @openstapps/core@3.3.0
- @openstapps/core-tools@3.3.0
- @openstapps/logger@3.0.0
## 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 ## 3.0.1
### Patch Changes ### Patch Changes
+2
View File
@@ -9,4 +9,6 @@ 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"]
@@ -1,5 +1,3 @@
// @ts-check
/** /**
* This is the database configuration for the technical university of berlin * This is the database configuration for the technical university of berlin
* *
@@ -22,6 +22,7 @@ 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;
@@ -1,4 +1,3 @@
// @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} */
@@ -1,4 +1,3 @@
// @ts-check
/** @type {import('@openstapps/core').SCAppConfigurationMenuCategory[]} */ /** @type {import('@openstapps/core').SCAppConfigurationMenuCategory[]} */
const menus = [ const menus = [
{ {
@@ -1,4 +1,3 @@
// @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} */
@@ -1,4 +1,3 @@
// @ts-check
import {SCThingType} from '@openstapps/core'; import {SCThingType} from '@openstapps/core';
/** @type {import('@openstapps/core').SCBackendAggregationConfiguration[]} */ /** @type {import('@openstapps/core').SCBackendAggregationConfiguration[]} */
@@ -1,4 +1,3 @@
// @ts-check
import { import {
month, month,
sommerRange, sommerRange,
@@ -1,4 +1,3 @@
// @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';
@@ -17,7 +16,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: 512 * 1024, maxRequestBodySize: 2e6,
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: [
@@ -1,4 +1,3 @@
// @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';
@@ -1,5 +1,3 @@
// @ts-check
/** /**
* This is the default configuration for elasticsearch (a database) * This is the default configuration for elasticsearch (a database)
* *
@@ -11,13 +9,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')} * @type {import('../../src/storage/elasticsearch/types/elasticsearch-config.js').ElasticsearchConfigFile}
*/ */
const config = { const config = {
internal: { internal: {
database: { database: {
name: 'elasticsearch', name: 'elasticsearch',
version: '5.6', version: '8.4.2',
query: { query: {
minMatch: '75%', minMatch: '75%',
queryType: 'dis_max', queryType: 'dis_max',
@@ -1,4 +1,3 @@
// @ts-check
import {readFile} from 'fs/promises'; import {readFile} from 'fs/promises';
import {SCAboutPageContentType} from '@openstapps/core'; import {SCAboutPageContentType} from '@openstapps/core';
@@ -1,4 +1,3 @@
// @ts-check
/** /**
* Generates a range of numbers that represent consecutive calendar months * Generates a range of numbers that represent consecutive calendar months
* *
@@ -0,0 +1,37 @@
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)));
}
@@ -1,4 +1,3 @@
// @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';
@@ -1,4 +1,3 @@
// @ts-check
import {SCAboutPageContentType} from '@openstapps/core'; import {SCAboutPageContentType} from '@openstapps/core';
/** @type {import('@openstapps/core').SCAboutPage} */ /** @type {import('@openstapps/core').SCAboutPage} */
@@ -1,4 +1,3 @@
// @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';
@@ -1,4 +1,3 @@
// @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} */
+2 -1
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,6 +76,7 @@ const config = {
} */ } */
}, },
}, },
versionHistory,
aboutPages, aboutPages,
}, },
backend: defaultBackend, backend: defaultBackend,
@@ -0,0 +1,52 @@
# 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.
@@ -0,0 +1,49 @@
# 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.
@@ -0,0 +1,15 @@
# Goethe-Uni App 2.5
Die Goethe-Uni App ist noch besser geworden!
## Komplett neue Kartenansicht
Wir haben die Karte überarbeitet, um eine klarere und schnellere Übersicht zu bieten.
## Deutschlandticket mit an Bord
Wenn du das Upgrade des Semesterticket zum Deutschlandticket gemacht hast und eingeloggt bist, findet es sich jetzt auch in der App.
## Bibliotheksdienste sind wieder voll funktionsfähig
Aufgrund einiger Adhoc-Änderungen im Bibliothekssystem haben wir die App so angepasst, dass sie damit umgehen kann.
@@ -0,0 +1,15 @@
# Goethe-Uni App 2.5
The Goethe-Uni App got even better!
## Completely new map view
We overhauled the map to offer you a clearer and faster and overview.
## Deutschlandticket included
If you upgraded your Semesterticket to a Deutschlandticket it will now reside in the App if you are logged in.
## Library services are fully functional again
Due to some adhoc changes in the library system we adjusted the app to handle them properly.
@@ -0,0 +1,6 @@
import {versions} from '../../default/tools/version.js';
/** @type {import('@openstapps/core').SCAppVersionInfo[]} */
const versionHistory = await versions(import.meta.url);
export default versionHistory;
+4 -4
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.0.1", "version": "3.3.2",
"private": true, "private": true,
"type": "module", "type": "module",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
@@ -64,7 +64,7 @@
"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.29.4", "moment": "2.30.1",
"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 +98,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.1", "ts-node": "10.9.2",
"tsup": "6.7.0", "tsup": "6.7.0",
"typescript": "5.1.6" "typescript": "5.4.2"
}, },
"tsup": { "tsup": {
"entry": [ "entry": [
+15 -20
View File
@@ -2,6 +2,7 @@ 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';
@@ -23,31 +24,25 @@ 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));
if (config) {
Logger.info(`Using ${namespace} config for ${moduleName}`);
return config.config;
} else {
Logger.info(`Using ${fallbackNamespace} config for ${moduleName}`);
return configLoader(moduleName) return configLoader(moduleName)
.search(path.posix.join('.', configPath, namespace))
.then(it => it!.config as T)
.catch(() =>
configLoader(moduleName)
.search(path.posix.join('.', configPath, fallbackNamespace)) .search(path.posix.join('.', configPath, fallbackNamespace))
.then(it => it!.config), .then(it => it!.config);
); }
} }
/**
* Loads a config file
*/
async function loadConfig<T>(moduleName: string): Promise<T> {
const namespace = process.env.NODE_APP_INSTANCE; const namespace = process.env.NODE_APP_INSTANCE;
const database = process.env.NODE_CONFIG_ENV; const database = process.env.NODE_CONFIG_ENV;
const config = await findConfig<T>(moduleName, namespace); export const prometheusConfig = await findConfig<unknown>('prometheus', namespace);
if (database) {
const databaseConfig = await findConfig<T>(database, namespace);
return deepmerge(config, databaseConfig);
}
return config; const backendConfigWithoutDatabase = await findConfig<SCConfigFile>('backend', namespace);
} export const backendConfig = database
? deepmerge(backendConfigWithoutDatabase, await findConfig<never>(database, namespace))
export const backendConfig = await loadConfig<SCConfigFile>('backend'); : backendConfigWithoutDatabase;
export const prometheusConfig = await loadConfig<unknown>('prometheus');
+25 -1
View File
@@ -13,15 +13,34 @@
* 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 {SCConfigFile, SCSearchQuery, SCSearchResponse, SCThings, SCUuid} from '@openstapps/core'; import {
SCConfigFile,
SCPlace,
SCPlaceWithoutReferences,
SCSearchQuery,
SCSearchResponse,
SCThingWithCategoriesWithoutReferences,
SCThings,
SCUuid,
} from '@openstapps/core';
import {MailQueue} from '../notification/mail-queue.js'; import {MailQueue} from '../notification/mail-queue.js';
import {Bulk} from './bulk-storage.js'; import {Bulk} from './bulk-storage.js';
import {FeatureCollection, Point, Polygon} from 'geojson';
/** /**
* Creates an instance of a database * Creates an instance of a database
*/ */
export type DatabaseConstructor = new (config: SCConfigFile, mailQueue?: MailQueue) => Database; export type DatabaseConstructor = new (config: SCConfigFile, mailQueue?: MailQueue) => Database;
export type SupplementaryGeoJSON = FeatureCollection<Point | Polygon, SupplementaryGeoJSONThing>;
export type SupplementaryGeoJSONThing = Pick<
Extract<SCThings, SCPlace>,
Exclude<
keyof SCPlaceWithoutReferences | keyof SCThingWithCategoriesWithoutReferences<never, never>,
'geo' | 'origin' | 'translations'
>
>;
/** /**
* Defines what one database class needs to have defined * Defines what one database class needs to have defined
*/ */
@@ -82,4 +101,9 @@ export interface Database {
* @param params Parameters which form a search query to search the backend data * @param params Parameters which form a search query to search the backend data
*/ */
search(parameters: SCSearchQuery): Promise<SCSearchResponse>; search(parameters: SCSearchQuery): Promise<SCSearchResponse>;
/**
* Get geo info for display on a map
*/
geo(): Promise<SupplementaryGeoJSON>;
} }
@@ -26,7 +26,7 @@ import {Logger} from '@openstapps/logger';
import moment from 'moment'; import moment from 'moment';
import {MailQueue} from '../../notification/mail-queue.js'; import {MailQueue} from '../../notification/mail-queue.js';
import {Bulk} from '../bulk-storage.js'; import {Bulk} from '../bulk-storage.js';
import {Database} from '../database.js'; import {Database, SupplementaryGeoJSON, SupplementaryGeoJSONThing} from '../database.js';
import {parseAggregations} from './aggregations.js'; import {parseAggregations} from './aggregations.js';
import * as Monitoring from './monitoring.js'; import * as Monitoring from './monitoring.js';
import {buildQuery} from './query/query.js'; import {buildQuery} from './query/query.js';
@@ -46,6 +46,7 @@ import {
} from './util/index.js'; } from './util/index.js';
import {noUndefined} from './util/no-undefined.js'; import {noUndefined} from './util/no-undefined.js';
import {retryCatch, RetryOptions} from './util/retry.js'; import {retryCatch, RetryOptions} from './util/retry.js';
import {Feature, Point, Polygon} from 'geojson';
/** /**
* A database interface for elasticsearch * A database interface for elasticsearch
@@ -84,7 +85,10 @@ 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(private readonly config: SCConfigFile, mailQueue?: MailQueue) { constructor(
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');
} }
@@ -402,4 +406,49 @@ export class Elasticsearch implements Database {
}, },
}; };
} }
async geo(): Promise<SupplementaryGeoJSON> {
const searchResponse = await this.client.search<Extract<SCThings, {geo: unknown}>>({
body: {
query: {
exists: {
field: 'geo',
},
},
},
from: 0,
allow_no_indices: true,
index: ACTIVE_INDICES_ALIAS,
size: 1,
});
return {
type: 'FeatureCollection',
features: searchResponse.hits.hits
.map(thing => {
return thing._source?.geo
? ({
id: Number(thing._source.identifiers?.['OSM']) || undefined,
type: 'Feature',
geometry: thing._source.geo.polygon ?? thing._source.geo.point,
properties: {
name: thing._source.name,
sameAs: thing._source.sameAs,
image: thing._source.image,
alternateNames: thing._source.alternateNames,
description: thing._source.description,
identifiers: thing._source.identifiers,
categories: thing._source.categories,
categorySpecificValues: thing._source.categorySpecificValues,
openingHours: thing._source.openingHours,
address: thing._source.address,
uid: thing._source.uid,
type: thing._source.type,
},
} satisfies Feature<Polygon | Point, SupplementaryGeoJSONThing>)
: undefined;
})
.filter(noUndefined),
};
}
} }
@@ -25,7 +25,7 @@ export function buildDistanceFilter(
): QueryDslSpecificQueryContainer<'geo_distance'> { ): QueryDslSpecificQueryContainer<'geo_distance'> {
const geoObject: QueryDslGeoDistanceQuery = { const geoObject: QueryDslGeoDistanceQuery = {
distance: `${filter.arguments.distance}m`, distance: `${filter.arguments.distance}m`,
[`${filter.arguments.field}.point.coordinates`]: { [`${filter.arguments.field}.point`]: {
lat: filter.arguments.position[1], lat: filter.arguments.position[1],
lon: filter.arguments.position[0], lon: filter.arguments.position[0],
}, },
@@ -19,8 +19,11 @@ import {QueryDslSpecificQueryContainer} from '../../types/util.js';
* Converts a geo filter to elasticsearch syntax * Converts a geo filter to elasticsearch syntax
* @param filter A search filter for the retrieval of the data * @param filter A search filter for the retrieval of the data
*/ */
export function buildGeoFilter(filter: SCGeoFilter): QueryDslSpecificQueryContainer<'geo_shape'> { export function buildGeoFilter(filter: SCGeoFilter): QueryDslSpecificQueryContainer<'bool'> {
return { return {
bool: {
should: [
{
geo_shape: { geo_shape: {
ignore_unmapped: true, ignore_unmapped: true,
[`${filter.arguments.field}.polygon`]: { [`${filter.arguments.field}.polygon`]: {
@@ -28,5 +31,17 @@ export function buildGeoFilter(filter: SCGeoFilter): QueryDslSpecificQueryContai
relation: filter.arguments.spatialRelation, relation: filter.arguments.spatialRelation,
}, },
}, },
} satisfies QueryDslSpecificQueryContainer<'geo_shape'>,
{
geo_shape: {
ignore_unmapped: true,
[`${filter.arguments.field}.point`]: {
shape: filter.arguments.shape,
relation: filter.arguments.spatialRelation,
},
},
} satisfies QueryDslSpecificQueryContainer<'geo_shape'>,
],
},
}; };
} }
@@ -21,16 +21,31 @@ import {QueryDslSpecificQueryContainer} from '../../types/util.js';
*/ */
export function buildValueFilter( export function buildValueFilter(
filter: SCSearchValueFilter, filter: SCSearchValueFilter,
): QueryDslSpecificQueryContainer<'term'> | QueryDslSpecificQueryContainer<'terms'> { ):
return Array.isArray(filter.arguments.value) | QueryDslSpecificQueryContainer<'exists'>
? { | QueryDslSpecificQueryContainer<'term'>
terms: { | QueryDslSpecificQueryContainer<'terms'> {
[`${filter.arguments.field}.raw`]: filter.arguments.value, switch (typeof 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,
},
};
}
}
}
@@ -25,7 +25,7 @@ export function buildDistanceSort(sort: SCDistanceSort): SortOptions {
mode: 'avg', mode: 'avg',
order: sort.order, order: sort.order,
unit: 'm', unit: 'm',
[`${sort.arguments.field}.point.coordinates`]: { [`${sort.arguments.field}.point`]: {
lat: sort.arguments.position[1], lat: sort.arguments.position[1],
lon: sort.arguments.position[0], lon: sort.arguments.position[0],
}, },
+5 -2
View File
@@ -22,7 +22,7 @@ import http from 'http';
import {MailQueue} from '../src/notification/mail-queue.js'; import {MailQueue} from '../src/notification/mail-queue.js';
import {Bulk, BulkStorage} from '../src/storage/bulk-storage.js'; import {Bulk, BulkStorage} from '../src/storage/bulk-storage.js';
import getPort from 'get-port'; import getPort from 'get-port';
import {Database} from '../src/storage/database.js'; import {Database, SupplementaryGeoJSON} from '../src/storage/database.js';
import {v4} from 'uuid'; import {v4} from 'uuid';
import {backendConfig} from '../src/config.js'; import {backendConfig} from '../src/config.js';
import {getIndexUID} from '../src/storage/elasticsearch/util/index.js'; import {getIndexUID} from '../src/storage/elasticsearch/util/index.js';
@@ -58,7 +58,6 @@ export async function startApp(): Promise<Express> {
* An elasticsearch mock * An elasticsearch mock
*/ */
export class ElasticsearchMock implements Database { export class ElasticsearchMock implements Database {
// @ts-expect-error never read
private bulk: Bulk | undefined; private bulk: Bulk | undefined;
private storageMock = new Map<string, SCThings>(); private storageMock = new Map<string, SCThings>();
@@ -67,6 +66,10 @@ export class ElasticsearchMock implements Database {
// Nothing to do here // Nothing to do here
} }
geo(): Promise<SupplementaryGeoJSON> {
throw new Error('Method not implemented.');
}
bulkCreated(bulk: Bulk): Promise<void> { bulkCreated(bulk: Bulk): Promise<void> {
this.bulk = bulk; this.bulk = bulk;
return Promise.resolve(undefined); return Promise.resolve(undefined);
+14 -12
View File
@@ -14,6 +14,7 @@
* 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,
@@ -23,29 +24,30 @@ 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 = JSON.parse( const book = bookFile.instance as SCBook;
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);
const request: SCBulkRequest = { let request: SCBulkRequest;
let bulkRoute: SCBulkRoute;
let bulkAddRoute: SCBulkAddRoute;
let bulkDoneRoute: SCBulkDoneRoute;
before(function () {
request = {
expiration: bulk.expiration, expiration: bulk.expiration,
source: bulk.source, source: bulk.source,
type: bulk.type, type: bulk.type,
}; };
const bulkRoute = new SCBulkRoute(); bulkRoute = new SCBulkRoute();
const bulkAddRoute = new SCBulkAddRoute(); bulkAddRoute = new SCBulkAddRoute();
const bulkDoneRoute = new SCBulkDoneRoute(); bulkDoneRoute = new SCBulkDoneRoute();
});
// afterEach(async function() {
// TODO: Delete saved bulks
// });
it('should create bulk', async function () { it('should create bulk', async function () {
const {status, body, error} = await testApp const {status, body, error} = await testApp
@@ -21,7 +21,12 @@ 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 = {};
@@ -30,15 +30,11 @@ 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 {readFile} from 'fs/promises'; import registerRequest from '@openstapps/core/test/resources/PluginRegisterRequest.1.json' assert {type: 'json'};
// 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;
+5 -2
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();
const validationError = new SCValidationErrorResponse([]); let validationError: SCValidationErrorResponse;
const internalServerError = new SCInternalServerErrorResponse(); let internalServerError: SCInternalServerErrorResponse;
beforeEach(function () { beforeEach(function () {
app = express(); app = express();
@@ -64,6 +64,9 @@ 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 () {
@@ -29,14 +29,21 @@ 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);
const searchRoute = new SCSearchRoute(); let searchRoute: SCSearchRoute;
const multiSearchRoute = new SCMultiSearchRoute(); let multiSearchRoute: SCMultiSearchRoute;
const syntaxError = new SCSyntaxErrorResponse('Foo Message'); let syntaxError: SCSyntaxErrorResponse;
const methodNotAllowedError = new SCMethodNotAllowedErrorResponse(); let methodNotAllowedError: SCMethodNotAllowedErrorResponse;
const tooManyRequestsError = new SCTooManyRequestsErrorResponse(); let tooManyRequestsError: 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 {status} = await testApp.get('/search').set('Accept', 'application/json').send({ const {status} = await testApp.get('/search').set('Accept', 'application/json').send({
query: 'Some search terms', query: 'Some search terms',
}); });
@@ -13,23 +13,25 @@
* 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 {SCThingUpdateRoute} from '@openstapps/core'; import {SCBook, 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 {readFile} from 'fs/promises'; import bookFile from '@openstapps/core/test/resources/indexable/Book.1.json' assert {type: 'json'};
use(chaiAsPromised); use(chaiAsPromised);
const book = JSON.parse( const book = bookFile.instance as SCBook;
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);
const thingUpdateRoute = new SCThingUpdateRoute(); let thingUpdateRoute: 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
@@ -39,7 +39,6 @@ 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,
@@ -50,6 +49,11 @@ 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);
@@ -60,13 +64,6 @@ 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);
@@ -74,8 +71,15 @@ 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();
@@ -445,7 +449,7 @@ describe('Elasticsearch', function () {
_id: '', _id: '',
_index: '', _index: '',
_score: 0, _score: 0,
_source: message as SCMessage, _source: message,
}; };
sandbox.stub(es.client, 'search').resolves(searchResponse(foundObject)); sandbox.stub(es.client, 'search').resolves(searchResponse(foundObject));
@@ -475,7 +479,7 @@ describe('Elasticsearch', function () {
const object: SearchHit<SCMessage> = { const object: SearchHit<SCMessage> = {
_id: '', _id: '',
_index: oldIndex, _index: oldIndex,
_source: message as SCMessage, _source: message,
}; };
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);
@@ -489,7 +493,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 as SCMessage, bulk)).to.rejectedWith('creation'); return expect(es.post(message, bulk)).to.rejectedWith('creation');
}); });
it('should create a new object', async function () { it('should create a new object', async function () {
@@ -502,7 +506,7 @@ describe('Elasticsearch', function () {
}); });
await es.init(); await es.init();
await es.post(message as SCMessage, bulk); await es.post(message, 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({
@@ -527,7 +531,7 @@ describe('Elasticsearch', function () {
_id: '', _id: '',
_index: getIndex(), _index: getIndex(),
_score: 0, _score: 0,
_source: message as SCMessage, _source: message,
}; };
sandbox.stub(es.client, 'search').resolves(searchResponse()); sandbox.stub(es.client, 'search').resolves(searchResponse());
@@ -541,7 +545,7 @@ describe('Elasticsearch', function () {
_id: '', _id: '',
_index: getIndex(), _index: getIndex(),
_score: 0, _score: 0,
_source: message as SCMessage, _source: message,
}; };
sandbox.stub(es.client, 'search').resolves(searchResponse(object)); sandbox.stub(es.client, 'search').resolves(searchResponse(object));
// @ts-expect-error unused // @ts-expect-error unused
@@ -564,13 +568,13 @@ describe('Elasticsearch', function () {
_id: '123', _id: '123',
_index: getIndex(), _index: getIndex(),
_score: 0, _score: 0,
_source: message as SCMessage, _source: message,
}; };
const objectBook: SearchHit<SCBook> = { const objectBook: SearchHit<SCBook> = {
_id: '321', _id: '321',
_index: getIndex(), _index: getIndex(),
_score: 0, _score: 0,
_source: book as SCBook, _source: book,
}; };
const fakeEsAggregations = { const fakeEsAggregations = {
'@all': { '@all': {
@@ -466,7 +466,7 @@ describe('Query', function () {
const expectedFilter: QueryDslSpecificQueryContainer<'geo_distance'> = { const expectedFilter: QueryDslSpecificQueryContainer<'geo_distance'> = {
geo_distance: { geo_distance: {
'distance': '1000m', 'distance': '1000m',
'geo.point.coordinates': { 'geo.point': {
lat: 8.123, lat: 8.123,
lon: 50.123, lon: 50.123,
}, },
@@ -479,19 +479,40 @@ describe('Query', function () {
it('should build geo filter for shapes and points', function () { it('should build geo filter for shapes and points', function () {
const filter = buildFilter(searchFilters.geoPoint); const filter = buildFilter(searchFilters.geoPoint);
const expectedFilter = { const expectedFilter = {
bool: {
should: [
{
geo_shape: { geo_shape: {
'geo.polygon': { 'geo.polygon': {
relation: undefined, relation: undefined,
shape: { shape: {
type: 'envelope',
coordinates: [ coordinates: [
[50.123, 8.123], [50.123, 8.123],
[50.123, 8.123], [50.123, 8.123],
], ],
type: 'envelope',
}, },
}, },
'ignore_unmapped': true, 'ignore_unmapped': true,
}, },
},
{
geo_shape: {
'geo.point': {
relation: undefined,
shape: {
coordinates: [
[50.123, 8.123],
[50.123, 8.123],
],
type: 'envelope',
},
},
'ignore_unmapped': true,
},
},
],
},
}; };
expect(filter).to.be.eql(expectedFilter); expect(filter).to.be.eql(expectedFilter);
@@ -500,19 +521,40 @@ describe('Query', function () {
it('should build geo filter for shapes only', function () { it('should build geo filter for shapes only', function () {
const filter = buildFilter(searchFilters.geoShape); const filter = buildFilter(searchFilters.geoShape);
const expectedFilter = { const expectedFilter = {
bool: {
should: [
{
geo_shape: { geo_shape: {
'geo.polygon': { 'geo.polygon': {
relation: 'contains', relation: 'contains',
shape: { shape: {
type: 'envelope',
coordinates: [ coordinates: [
[50.123, 8.123], [50.123, 8.123],
[50.123, 8.123], [50.123, 8.123],
], ],
type: 'envelope',
}, },
}, },
'ignore_unmapped': true, 'ignore_unmapped': true,
}, },
},
{
geo_shape: {
'geo.point': {
relation: 'contains',
shape: {
coordinates: [
[50.123, 8.123],
[50.123, 8.123],
],
type: 'envelope',
},
},
'ignore_unmapped': true,
},
},
],
},
}; };
expect(filter).to.be.eql(expectedFilter); expect(filter).to.be.eql(expectedFilter);
@@ -594,7 +636,7 @@ describe('Query', function () {
'mode': 'avg', 'mode': 'avg',
'order': 'desc', 'order': 'desc',
'unit': 'm', 'unit': 'm',
'geo.point.coordinates': { 'geo.point': {
lat: 50.123, lat: 50.123,
lon: 8.123, lon: 8.123,
}, },
+3 -3
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"]
} }
+6
View File
@@ -1,5 +1,11 @@
# @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
+2
View File
@@ -14,4 +14,6 @@ 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"]
@@ -3,3 +3,4 @@ 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
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@openstapps/database", "name": "@openstapps/database",
"version": "3.0.0", "version": "3.2.0",
"private": true, "private": true,
"files": [ "files": [
"config", "config",
+1 -3
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} */
const configFile = { module.exports = {
activeVersions: ['1\\.0\\.\\d+', '2\\.0\\.\\d+'], activeVersions: ['1\\.0\\.\\d+', '2\\.0\\.\\d+'],
hiddenRoutes: ['/bulk'], hiddenRoutes: ['/bulk'],
logFormat: 'default', logFormat: 'default',
@@ -31,5 +31,3 @@ const configFile = {
dhparam: '/etc/nginx/certs/dhparam.pem', dhparam: '/etc/nginx/certs/dhparam.pem',
}, },
}; };
export default configFile;
+4 -4
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.3.8", "semver": "7.6.0",
"typescript": "5.1.6" "typescript": "5.4.2"
}, },
"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.3.13", "@types/semver": "7.5.8",
"@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.1", "ts-node": "10.9.2",
"tsup": "6.7.0" "tsup": "6.7.0"
}, },
"tsup": { "tsup": {
+1 -1
View File
@@ -1,4 +1,4 @@
{ {
"extends": "@openstapps/tsconfig", "extends": "@openstapps/tsconfig",
"exclude": ["./config/", "./lib/"] "exclude": ["config", "lib", "app.js"]
} }
@@ -1,4 +1,3 @@
// @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");
@@ -1,4 +1,3 @@
// @ts-check
"use strict" "use strict"
const rule = require('./copyright-header-rule') const rule = require('./copyright-header-rule')
-2
View File
@@ -1,5 +1,3 @@
// @ts-check
/** @type {import('eslint').Linter.Config} */ /** @type {import('eslint').Linter.Config} */
const config = { const config = {
root: true, root: true,
+8 -9
View File
@@ -18,16 +18,15 @@
"devDependencies": { "devDependencies": {
"@openstapps/tsconfig": "workspace:*", "@openstapps/tsconfig": "workspace:*",
"@types/node": "18.15.3", "@types/node": "18.15.3",
"eslint": "8.43.0", "eslint": "8.57.0",
"typescript": "5.1.6" "typescript": "5.4.2"
}, },
"peerDependencies": { "peerDependencies": {
"@typescript-eslint/eslint-plugin": "5.60.1", "@typescript-eslint/eslint-plugin": "7.2.0",
"@typescript-eslint/parser": "5.60.1", "@typescript-eslint/parser": "7.2.0",
"eslint": "8.43.0", "eslint": "8.57.0",
"eslint-config-prettier": "8.8.0", "eslint-config-prettier": "9.1.0",
"eslint-plugin-jsdoc": "46.4.2", "eslint-plugin-jsdoc": "48.2.1",
"eslint-plugin-prettier": "4.2.1", "eslint-plugin-unicorn": "51.0.1"
"eslint-plugin-unicorn": "47.0.0"
} }
} }
+20 -8
View File
@@ -1,5 +1,11 @@
# @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
@@ -30,7 +36,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
@@ -69,11 +75,14 @@
- 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(path, fs.readFileSync(path, 'utf8').replace(/^#+\s+\[/gm, '## [')); fs.writeFileSync(
path,
fs.readFileSync(path, "utf8").replace(/^#+\s+\[/gm, "## ["),
);
``` ```
- 98546a97: Migrate away from @openstapps/configuration - 98546a97: Migrate away from @openstapps/configuration
@@ -115,7 +124,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
@@ -154,11 +163,14 @@
- 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(path, fs.readFileSync(path, 'utf8').replace(/^#+\s+\[/gm, '## [')); fs.writeFileSync(
path,
fs.readFileSync(path, "utf8").replace(/^#+\s+\[/gm, "## ["),
);
``` ```
- 98546a97: Migrate away from @openstapps/configuration - 98546a97: Migrate away from @openstapps/configuration
+15
View File
@@ -0,0 +1,15 @@
/** @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;
-13
View File
@@ -1,13 +0,0 @@
{
"$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"
}
+8 -5
View File
@@ -1,7 +1,7 @@
{ {
"name": "@openstapps/prettier-config", "name": "@openstapps/prettier-config",
"description": "StApps Prettier Config", "description": "StApps Prettier Config",
"version": "3.0.0", "version": "3.2.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,16 +9,19 @@
"contributors": [ "contributors": [
"Rainer Killinger <mail-openstapps@killinger.co>" "Rainer Killinger <mail-openstapps@killinger.co>"
], ],
"main": "index.json", "main": "index.js",
"files": [ "files": [
"index.json", "index.js",
"CHANGELOG.md", "CHANGELOG.md",
"README.md" "README.md"
], ],
"scripts": { "scripts": {
"test": "npx prettier --config index.json --check \"test/*.js\"" "test": "prettier --config index.js --check \"test/*.js\""
},
"devDependencies": {
"prettier": "3.1.1"
}, },
"peerDependencies": { "peerDependencies": {
"prettier": "2.8.6" "prettier": "3.1.1"
} }
} }
+5 -5
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": "2.30.0", "date-fns": "3.6.0",
"glob": "10.2.7", "glob": "10.3.10",
"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.0.1", "@types/glob": "8.1.0",
"@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.1", "ts-node": "10.9.2",
"tsup": "6.7.0", "tsup": "6.7.0",
"typescript": "5.1.6" "typescript": "5.4.2"
}, },
"tsup": { "tsup": {
"entry": [ "entry": [
@@ -1,3 +1,4 @@
{ {
"extends": "@openstapps/tsconfig" "extends": "@openstapps/tsconfig",
"exclude": ["lib", "app.js"]
} }
+8 -2
View File
@@ -1,5 +1,11 @@
# @openstapps/tsconfig # @openstapps/tsconfig
## 3.3.0
### Minor Changes
- 688bc5f2: v3.3.0 changes
## 3.0.0 ## 3.0.0
### Major Changes ### Major Changes
@@ -30,7 +36,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
@@ -105,7 +111,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
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "@openstapps/tsconfig", "name": "@openstapps/tsconfig",
"description": "The tsconfig for the openstapps project", "description": "The tsconfig for the openstapps project",
"version": "3.0.0", "version": "3.3.0",
"type": "commonjs", "type": "commonjs",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"repository": "git@gitlab.com:openstapps/eslint-config.git", "repository": "git@gitlab.com:openstapps/eslint-config.git",
+11 -4
View File
@@ -14,19 +14,26 @@
"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,
"noImplicitReturns": true, "noImplicitReturns": true,
"noUnusedLocals": true, "noUnusedLocals": false,
"noUnusedParameters": true, "noUnusedParameters": false,
"outDir": "../../../lib/", "outDir": "../../../lib/",
"lib": ["ES2022", "DOM"], "lib": [
"ES2022",
"DOM"
],
"strict": true, "strict": true,
"target": "ES2022" "target": "ES2022"
}, },
"ts-node": { "ts-node": {
"transpileOnly": true "transpileOnly": true
}, },
"exclude": ["../../../app.js", "../../../lib/"] "exclude": [
"../../../app.js",
"../../../lib/"
]
} }
+41
View File
@@ -1,5 +1,46 @@
# @openstapps/minimal-connector # @openstapps/minimal-connector
## 3.3.2
### Patch Changes
- @openstapps/core@3.3.2
- @openstapps/api@3.3.2
## 3.3.0
### Patch Changes
- Updated dependencies [688bc5f2]
- @openstapps/api@3.3.0
- @openstapps/core@3.3.0
- @openstapps/logger@3.0.0
## 3.2.0
### Patch Changes
- Updated dependencies [912ae422]
- @openstapps/core@3.2.0
- @openstapps/api@3.2.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
+3 -3
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.0.0", "version": "3.3.2",
"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.1", "ts-node": "10.9.2",
"tsup": "6.7.0", "tsup": "6.7.0",
"typescript": "5.1.6" "typescript": "5.4.2"
}, },
"tsup": { "tsup": {
"entry": [ "entry": [
+2 -1
View File
@@ -1,3 +1,4 @@
{ {
"extends": "@openstapps/tsconfig" "extends": "@openstapps/tsconfig",
"exclude": ["lib", "app.js"]
} }
+42 -24
View File
@@ -1,44 +1,62 @@
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:2.0.0 image: registry.gitlab.com/openstapps/openstapps/database:3.0.0
volumes: # If you need persistence for debugging purposes uncomment the following lines
- ./database:/usr/share/elasticsearch/data #volumes:
# - ./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.0.0-next.0 image: registry.gitlab.com/openstapps/openstapps/backend:3.1.0
environment: environment:
<<: *development-variables
ES_ADDR: "http://database:9200" ES_ADDR: "http://database:9200"
NODE_CONFIG_ENV: "elasticsearch" NODE_CONFIG_ENV: "elasticsearch"
ALLOW_NO_TRANSPORT: "true" NODE_APP_INSTANCE: "f-u"
PROMETHEUS_MIDDLEWARE: "false"
expose: expose:
- 3000 - 3000
ports: ports:
- 3000:3000 - 127.0.0.1:3000:3000
links:
- "database"
labels: labels:
- stapps.version=1.0.0 - stapps.version=4.1.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:
- "backend" - database
minimal-connector: # api:
image: registry.gitlab.com/openstapps/minimal-connector:core-0.23 # image: registry.gitlab.com/openstapps/openstapps/api:3.0.0
container_name: minimal-connector-0.23 # links:
command: ["http://backend:3000", "minimal-connector", "f-u"] # - backend
app: # minimal-connector:
image: registry.gitlab.com/openstapps/app/executable:core-0.23 # image: registry.gitlab.com/openstapps/minimal-connector:core-0.23
expose: # container_name: minimal-connector-0.23
- 8100 # command: ["http://backend:3000", "minimal-connector", "f-u"]
ports:
- 8100:8100 # app:
# image: registry.gitlab.com/openstapps/app/executable:core-0.23
# expose:
# - 8100
# ports:
# - 8100:8100
+49
View File
@@ -1,5 +1,54 @@
# @openstapps/minimal-plugin # @openstapps/minimal-plugin
## 3.3.2
### Patch Changes
- @openstapps/core@3.3.2
- @openstapps/core-tools@3.3.2
- @openstapps/api-plugin@3.3.2
- @openstapps/api@3.3.2
## 3.3.0
### Patch Changes
- Updated dependencies [688bc5f2]
- @openstapps/api@3.3.0
- @openstapps/core@3.3.0
- @openstapps/api-plugin@3.3.0
- @openstapps/core-tools@3.3.0
- @openstapps/logger@3.0.0
## 3.2.0
### Patch Changes
- Updated dependencies [912ae422]
- @openstapps/core@3.2.0
- @openstapps/api@3.2.0
- @openstapps/api-plugin@3.2.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
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"name": "@openstapps/minimal-plugin", "name": "@openstapps/minimal-plugin",
"description": "Minimal Plugin", "description": "Minimal Plugin",
"version": "3.0.0", "version": "3.3.2",
"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.1" "ts-node": "10.9.2"
}, },
"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.1.6" "typescript": "5.4.2"
}, },
"tsup": { "tsup": {
"entry": [ "entry": [
+2 -1
View File
@@ -1,3 +1,4 @@
{ {
"extends": "@openstapps/tsconfig" "extends": "@openstapps/tsconfig",
"exclude": ["lib", "app.js"]
} }
Generated
+37 -3
View File
@@ -1,12 +1,30 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1709126324,
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1689752456, "lastModified": 1709747860,
"narHash": "sha256-VOChdECcEI8ixz8QY+YC4JaNEFwQd1V8bA0G4B28Ki0=", "narHash": "sha256-RT4zuBy579m+l8VyIQFOR66WXfcs4g1jntZUHjh6eoI=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "7f256d7da238cb627ef189d56ed590739f42f13b", "rev": "58ae79ea707579c40102ddf62d84b902a987c58b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -18,8 +36,24 @@
}, },
"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",
+55 -43
View File
@@ -1,19 +1,40 @@
{ {
description = "A Nix-flake-based development environment for OpenStApps"; description = "A Nix-flake-based development environment for OpenStApps";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; inputs = {
outputs = { self, nixpkgs }: nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs =
{
self,
nixpkgs,
flake-utils,
}:
let let
buildToolsVersion = "30.0.3"; aapt2buildToolsVersion = "33.0.2";
in
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ overlays = [
(final: prev: rec { (final: prev: rec {
nodejs = prev.nodejs-18_x; fontMin = prev.python311.withPackages (
pnpm = prev.nodePackages.pnpm; ps:
chrome = prev.google-chrome; with ps;
firefox = prev.firefox; [
webkit = prev.epiphany; # Safari-ish browser brotli
fonttools
]
++ (with fonttools.optional-dependencies; [ woff ])
);
android = prev.androidenv.composeAndroidPackages { android = prev.androidenv.composeAndroidPackages {
buildToolsVersions = [ "${buildToolsVersion}" ]; buildToolsVersions = [
platformVersions = [ "32" ]; "34.0.0"
aapt2buildToolsVersion
];
platformVersions = [ "34" ];
}; };
cypress = prev.cypress.overrideAttrs (cyPrev: rec { cypress = prev.cypress.overrideAttrs (cyPrev: rec {
version = "13.2.0"; version = "13.2.0";
@@ -22,56 +43,47 @@
hash = "sha256-9o0nprGcJhudS1LNm+T7Vf0Dwd1RBauYKI+w1FBQ3ZM="; hash = "sha256-9o0nprGcJhudS1LNm+T7Vf0Dwd1RBauYKI+w1FBQ3ZM=";
}; };
}); });
nodejs = prev.nodejs_18;
corepack = prev.corepack_18;
}) })
]; ];
# TODO: aarch64-linux, x68_64-darwin, aarch64-darwin
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 {
name = "android-env";
targetPkgs = pkgs: with pkgs; [ ];
runScript = "bash";
profile = ''
export ALLOW_NINJA_ENV=true
export USE_CCACHE=1
export LD_LIBRARY_PATH=/usr/lib:/usr/lib32
'';
};
in in
{ {
devShells = forEachSupportedSystem ({ pkgs }: devShell = pkgs.mkShell rec {
let nativeBuildInputs = [ androidFhs ];
python = (pkgs.python311.withPackages(ps: with ps; [ brotli fonttools ] ++ (with fonttools.optional-dependencies; [ ufo lxml unicode woff ]))); buildInputs = with pkgs; [
in
{
default = (pkgs.buildFHSUserEnv {
name = "StApps Dev";
targetPkgs = pkgs: with pkgs; [
nodejs nodejs
pnpm corepack
python
docker
# tools # tools
curl curl
jq jq
# browsers fontMin
firefox
chrome
webkit
cypress cypress
# android # android
jdk17 jdk17
android.androidsdk android.androidsdk
musl
]; ];
runScript = "bash"; ANDROID_JAVA_HOME = "${pkgs.jdk.home}";
profile = '' ANDROID_SDK_ROOT = "${pkgs.android.androidsdk}/libexec/android-sdk";
export CYPRESS_INSTALL_BINARY=0 GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${ANDROID_SDK_ROOT}/build-tools/${aapt2buildToolsVersion}/aapt2";
export CYPRESS_RUN_BINARY=${pkgs.cypress}/bin/Cypress CYPRESS_INSTALL_BINARY = "0";
export ANDROID_SDK_ROOT=${pkgs.android.androidsdk}/libexec/android-sdk CYPRESS_RUN_BINARY = "${pkgs.cypress}/bin/Cypress";
export ANDROID_JAVA_HOME=${pkgs.jdk.home}
export DOCKER_HOST=unix:///run/user/1000/docker.sock
{ dockerd-rootless & } 2>/dev/null
'';
}).env;
});
}; };
} }
);
}
+1 -7
View File
@@ -5,10 +5,4 @@
# 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% > 0.5% in DE and last 2 major versions and supports es6 and not dead
last 2 versions
Firefox ESR
not dead
not kaios 2.5
not op_mini all
not IE 9-11
+1
View File
@@ -37,6 +37,7 @@ 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
+68
View File
@@ -1,5 +1,73 @@
# @openstapps/app # @openstapps/app
## 3.3.2
### Patch Changes
- 7afc24f1: fixed config version comparison
- @openstapps/core@3.3.2
- @openstapps/api@3.3.2
## 3.3.0
### Minor Changes
- 688bc5f2: v3.3.0 changes
### Patch Changes
- Updated dependencies [688bc5f2]
- @openstapps/api@3.2.0
- @openstapps/core@3.2.0
- @openstapps/collection-utils@3.0.0
## 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
+1 -1
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-alpine FROM node:18-alpine3.18
WORKDIR /app WORKDIR /app
COPY www/ /app/www COPY www/ /app/www
+2 -2
View File
@@ -50,11 +50,11 @@ the config file.
Icon font minification is done automatically, but requires you to Icon font minification is done automatically, but requires you to
follow a few simple rules: follow a few simple rules:
1. Use the tagged template literal for referencing icon names in 1. Use the type-safe proxy for referencing icon names in
TypeScript files and code TypeScript files and code
```ts ```ts
SCIcon`icon_name`; SCIcon.icon_name;
``` ```
2. When using `ion-icon` in HTML, reference either icons that went through 2. When using `ion-icon` in HTML, reference either icons that went through
+64 -18
View File
@@ -13,25 +13,25 @@ The StApps 1.x.x (legacy app, but current app in stores) is written using Ionic
There are (`npm`) scripts defined to get the app running as quickly as possible. Those scripts (shortcuts for docker commands) are called using the syntax `npm run + <script-name>`. So we have the following commands available: There are (`npm`) scripts defined to get the app running as quickly as possible. Those scripts (shortcuts for docker commands) are called using the syntax `npm run + <script-name>`. So we have the following commands available:
``` ```sh
npm run docker:pull npm run docker:pull
``` ```
which pulls the up-to-date image ([Dockerfile](Dockerfile)) which contains all the tools needed for building, serving and deploying the app. which pulls the up-to-date image ([Dockerfile](Dockerfile)) which contains all the tools needed for building, serving and deploying the app.
``` ```sh
npm run docker:enter npm run docker:enter
``` ```
which enters the container on docker builder image, where we can run `npm install` (to install the required npm packages) and `npm build` (to build the app: convert into executable files), but also any other arbitrary commands with the tools available in the docker image. which enters the container on docker builder image, where we can run `npm install` (to install the required npm packages) and `npm build` (to build the app: convert into executable files), but also any other arbitrary commands with the tools available in the docker image.
``` ```sh
npm run docker:build npm run docker:build
``` ```
which runs `npm install` (to install the required npm packages) and `npm build` (to build the app: convert into executable files) in the docker container which runs on the docker builder image. which runs `npm install` (to install the required npm packages) and `npm build` (to build the app: convert into executable files) in the docker container which runs on the docker builder image.
``` ```sh
npm run docker:serve npm run docker:serve
``` ```
@@ -39,7 +39,7 @@ which serves the app for running it in the browser. It basically runs `ionic ser
## How to build and start the app using the default backend? ## How to build and start the app using the default backend?
``` ```sh
npm run build npm run build
npm run start npm run start
``` ```
@@ -86,52 +86,98 @@ addToIonicDB(
You'll need to run _Chromium_ using You'll need to run _Chromium_ using
```shell ```sh
pnpm chromium:no-cors pnpm chromium:no-cors
``` ```
### Help, I can't log in! ### Help, I can't log in!
Login services will often block hosts not coming from the production Login services will often block hosts not coming from the production
server. You can circumvent this locally by using the `:virtual-host` server.
scripts:
```shell #### Web
On the web you can circumvent this locally by using the `:virtual-host` scripts:
```sh
# Start the dev server on mobile.app.uni-frankfurt.de # Start the dev server on mobile.app.uni-frankfurt.de
pnpm start:virtual-host pnpm start:virtual-host
# Run chromium with flags that redirect mobile.app.uni-frankfurt.de to localhost:8100 # Run chromium with flags that redirect mobile.app.uni-frankfurt.de to localhost:8100
pnpm chromium:virtual-host pnpm chromium:virtual-host
``` ```
#### Android
On Android you will need to change the `custom_url_scheme` values
to `de.unifrankfurt.app` in the following files:
- `android/app/src/main/res/values/strings.xml`
- `src/environment/environment.ts`
Then start the app normally as you would
```sh
pnpm run:android
```
**This alone will not make auth work**, only the login flow.
If you need to test login, you have to disable live reload:
```sh
pnpm ionic capacitor run android
```
_**CAUTION:** a remote chrome debugging session can in some
cases hijack the device's ADB connection. If the connection
fails for no obvious reason, close chrome and uninstall the
app, then try again._
#### iOS
On Android you will need to change the `custom_url_scheme` value in
`src/environment/environment.ts` as well as the `CFBundleURLTypes`
in `ios/App/App/Info.plist`.
- make sure to remove any `Info.plist.orig` as capacitor might override
the modified `Info.plist` with that.
- make sure you have a valid device in XCode (Simulator or real device).
After that, run
```sh
pnpm run:ios
```
### 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):
``` ```sh
npm install npm install
``` ```
Check the code for linter issues: Check the code for linter issues:
``` ```sh
npm run lint npm run lint
``` ```
Automatically fix linter issues (those where autofix is possible): Automatically fix linter issues (those where autofix is possible):
``` ```sh
npm run lint:fix npm run lint:fix
``` ```
Build the app (transpile etc.): Build the app (transpile etc.):
``` ```sh
npm run build npm run build
``` ```
Open the app in the browser: Open the app in the browser:
``` ```sh
ionic serve ionic serve
``` ```
@@ -139,7 +185,7 @@ ionic serve
Run the app for testing on an android device (with live reload in the webview / device, when files are changed): Run the app for testing on an android device (with live reload in the webview / device, when files are changed):
``` ```sh
npm run build # if needed npm run build # if needed
npm run resources:android # generate needed resources (icons and splashscreens) npm run resources:android # generate needed resources (icons and splashscreens)
npm run docker:run:android # runs "ionic capacitor run android --livereload --external" on a selected device npm run docker:run:android # runs "ionic capacitor run android --livereload --external" on a selected device
@@ -159,7 +205,7 @@ Besides that, it is possible to monitor processes (and so the processes related
Build the (debug) app for testing on an android device (creates an APK file in the android's build outputs path): Build the (debug) app for testing on an android device (creates an APK file in the android's build outputs path):
``` ```sh
npm run docker:build:android npm run docker:build:android
``` ```
@@ -169,13 +215,13 @@ The mentioned `docker:*:android` npm commands are executed in a docker container
Execute unit tests: Execute unit tests:
``` ```sh
npm test npm test
``` ```
Execute e2e tests: Execute e2e tests:
``` ```sh
npm run e2e npm run e2e
``` ```
+2 -1
View File
@@ -1,7 +1,8 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion rootProject.ext.compileSdkVersion namespace "de.anyschool.app"
compileSdk rootProject.ext.compileSdkVersion
defaultConfig { defaultConfig {
applicationId "de.anyschool.app" applicationId "de.anyschool.app"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
@@ -2,13 +2,14 @@
android { android {
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_11 sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_17
} }
} }
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies { dependencies {
implementation project(':capacitor-community-screen-brightness')
implementation project(':capacitor-app') implementation project(':capacitor-app')
implementation project(':capacitor-browser') implementation project(':capacitor-browser')
implementation project(':capacitor-clipboard') implementation project(':capacitor-clipboard')
@@ -21,10 +22,9 @@ dependencies {
implementation project(':capacitor-local-notifications') implementation project(':capacitor-local-notifications')
implementation project(':capacitor-network') implementation project(':capacitor-network')
implementation project(':capacitor-preferences') implementation project(':capacitor-preferences')
implementation project(':capacitor-screen-orientation')
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')
@@ -1,7 +1,5 @@
<?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"
@@ -10,16 +8,14 @@
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|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout"
android:name="de.anyschool.app.MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask"
android:exported="true" android:exported="true"
android:label="@string/title_activity_main"
android:launchMode="singleTask"
android:name="de.anyschool.app.MainActivity"
android:theme="@style/AppTheme.NoActionBarLaunch"
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" />
@@ -37,20 +33,14 @@
<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"
<meta-data android:name="androidx.core.content.FileProvider">
android:name="android.support.FILE_PROVIDER_PATHS" <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_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" />
@@ -1,4 +1,8 @@
[ [
{
"pkg": "@capacitor-community/screen-brightness",
"classpath": "com.elylucas.capscreenbrightness.ScreenBrightnessPlugin"
},
{ {
"pkg": "@capacitor/app", "pkg": "@capacitor/app",
"classpath": "com.capacitorjs.plugins.app.AppPlugin" "classpath": "com.capacitorjs.plugins.app.AppPlugin"
@@ -47,6 +51,10 @@
"pkg": "@capacitor/preferences", "pkg": "@capacitor/preferences",
"classpath": "com.capacitorjs.plugins.preferences.PreferencesPlugin" "classpath": "com.capacitorjs.plugins.preferences.PreferencesPlugin"
}, },
{
"pkg": "@capacitor/screen-orientation",
"classpath": "com.capacitorjs.plugins.screenorientation.ScreenOrientationPlugin"
},
{ {
"pkg": "@capacitor/share", "pkg": "@capacitor/share",
"classpath": "com.capacitorjs.plugins.share.SharePlugin" "classpath": "com.capacitorjs.plugins.share.SharePlugin"
@@ -55,14 +63,6 @@
"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.

After

Width:  |  Height:  |  Size: 7.2 KiB

@@ -1,34 +0,0 @@
<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>
@@ -1,170 +0,0 @@
<?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>
@@ -0,0 +1,27 @@
<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>
@@ -1,5 +1,6 @@
<?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="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>
@@ -1,5 +1,6 @@
<?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="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

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