@appsemble/node-utils 0.29.5 → 0.29.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/container/helpers.js +3 -3
- package/container/index.d.ts +1 -0
- package/container/index.js +1 -0
- package/container/logs.d.ts +2 -0
- package/container/logs.js +91 -0
- package/getMessagesUtil.d.ts +3 -0
- package/getMessagesUtil.js +70 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +3 -3
- package/server/controllers/action.js +2 -1
- package/server/controllers/appMessages.d.ts +1 -1
- package/server/controllers/appMessages.js +3 -67
- package/server/types.d.ts +2 -0
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
#  Appsemble Node Utilities
|
|
2
2
|
|
|
3
3
|
> NodeJS utilities used by Appsemble internally.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@appsemble/node-utils)
|
|
6
|
-
[](https://gitlab.com/appsemble/appsemble/-/releases/0.29.7)
|
|
7
7
|
[](https://prettier.io)
|
|
8
8
|
|
|
9
9
|
## Table of Contents
|
|
@@ -26,5 +26,5 @@ compatibility is not guaranteed.
|
|
|
26
26
|
|
|
27
27
|
## License
|
|
28
28
|
|
|
29
|
-
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.29.
|
|
29
|
+
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.29.7/LICENSE.md) ©
|
|
30
30
|
[Appsemble](https://appsemble.com)
|
package/container/helpers.js
CHANGED
|
@@ -5,7 +5,7 @@ export const maxCPU = (_a = process.env.MAX_CONTAINER_CPU) !== null && _a !== vo
|
|
|
5
5
|
// In gigabytes
|
|
6
6
|
export const maxMemoryGi = (_b = process.env.MAX_CONTAINER_MEMORY) !== null && _b !== void 0 ? _b : 3;
|
|
7
7
|
export const appIdLabel = 'appId';
|
|
8
|
-
export const resourceDefaults = { memory: '
|
|
8
|
+
export const resourceDefaults = { memory: '128Mi', cpu: '0.1' };
|
|
9
9
|
export function getKubeConfig() {
|
|
10
10
|
const kubeconfig = new KubeConfig();
|
|
11
11
|
kubeconfig.loadFromDefault();
|
|
@@ -15,7 +15,7 @@ export function getKubeConfig() {
|
|
|
15
15
|
}
|
|
16
16
|
export function getContainerNamespace() {
|
|
17
17
|
var _a;
|
|
18
|
-
return (_a = process.env.
|
|
18
|
+
return `companion-containers-${(_a = process.env.SERVICE_NAME) !== null && _a !== void 0 ? _a : 'appsemble'}`;
|
|
19
19
|
}
|
|
20
20
|
export function formatServiceName(containerName, appName, appId) {
|
|
21
21
|
const serviceName = `${containerName}-${appName}-${appId}`.replaceAll(' ', '-').toLowerCase();
|
|
@@ -92,7 +92,7 @@ export function validateContainerResources(resources) {
|
|
|
92
92
|
unit === 'Gi' && parsedValue > maxMemoryGi,
|
|
93
93
|
unit === 'Mi' && parsedValue > maxMemoryGi * 1024,
|
|
94
94
|
];
|
|
95
|
-
if (conditionsMemory.some(
|
|
95
|
+
if (conditionsMemory.some(Boolean)) {
|
|
96
96
|
result.limits.memory = resourceDefaults.memory;
|
|
97
97
|
}
|
|
98
98
|
}
|
package/container/index.d.ts
CHANGED
package/container/index.js
CHANGED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import stream from 'node:stream';
|
|
3
|
+
import { Log } from '@kubernetes/client-node';
|
|
4
|
+
import { getContainerNamespace, getKubeConfig, handleKubernetesError } from './helpers.js';
|
|
5
|
+
import { logger } from '../logger.js';
|
|
6
|
+
function fetchLogs(namespace, podName, containerName) {
|
|
7
|
+
const { kubeconfig } = getKubeConfig();
|
|
8
|
+
const log = new Log(kubeconfig);
|
|
9
|
+
const logStream = new stream.PassThrough();
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
log
|
|
12
|
+
.log(namespace, podName, containerName || '', logStream)
|
|
13
|
+
.then(() => {
|
|
14
|
+
let logs = '';
|
|
15
|
+
logStream.on('data', (chunk) => {
|
|
16
|
+
logs += String(chunk);
|
|
17
|
+
});
|
|
18
|
+
logStream.on('end', () => {
|
|
19
|
+
resolve(logs);
|
|
20
|
+
});
|
|
21
|
+
logStream.on('error', (err) => {
|
|
22
|
+
reject(err);
|
|
23
|
+
});
|
|
24
|
+
})
|
|
25
|
+
.catch((err) => {
|
|
26
|
+
reject(err);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function filterLogEntries(entries, deploymentName, fromAppsemble) {
|
|
31
|
+
let res = entries;
|
|
32
|
+
if (fromAppsemble) {
|
|
33
|
+
res = entries.filter((e) => e.includes(deploymentName));
|
|
34
|
+
}
|
|
35
|
+
return res;
|
|
36
|
+
}
|
|
37
|
+
export async function getLogs(deploymentName, fromAppsemble) {
|
|
38
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
39
|
+
const { coreApi } = getKubeConfig();
|
|
40
|
+
let pods;
|
|
41
|
+
const containerNamespace = getContainerNamespace();
|
|
42
|
+
let appsembleNamespace = 'appsemble';
|
|
43
|
+
const appsembleServiceName = (_a = process.env.SERVICE_NAME) !== null && _a !== void 0 ? _a : 'appsemble';
|
|
44
|
+
logger.silly(`Using service name ${appsembleServiceName}`);
|
|
45
|
+
try {
|
|
46
|
+
const NAMESPACE_FILE_PATH = '/var/run/secrets/kubernetes.io/serviceaccount/namespace';
|
|
47
|
+
const namespace = await readFile(NAMESPACE_FILE_PATH, 'utf8');
|
|
48
|
+
appsembleNamespace = namespace.trim();
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
logger.error('Error fetching namespace name. Using `appsemble` as default');
|
|
52
|
+
logger.error(error);
|
|
53
|
+
}
|
|
54
|
+
logger.silly(`Using namespace ${appsembleNamespace}`);
|
|
55
|
+
try {
|
|
56
|
+
pods = (await coreApi.listNamespacedPod(fromAppsemble ? appsembleNamespace : containerNamespace)).body;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
handleKubernetesError(error);
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
if (pods.items.length === 0) {
|
|
63
|
+
logger.warn(`No pods found for deployment ${deploymentName} in namespace ${containerNamespace}`);
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const podLogs = [];
|
|
67
|
+
for (const pod of pods.items) {
|
|
68
|
+
if (((_c = (_b = pod.metadata) === null || _b === void 0 ? void 0 : _b.ownerReferences) === null || _c === void 0 ? void 0 : _c.find((r) => r.kind === 'ReplicaSet')) &&
|
|
69
|
+
((_d = pod.status) === null || _d === void 0 ? void 0 : _d.phase) === 'Running') {
|
|
70
|
+
if (fromAppsemble && !((_e = pod.metadata) === null || _e === void 0 ? void 0 : _e.name.includes(appsembleServiceName))) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (!fromAppsemble && !((_f = pod.metadata) === null || _f === void 0 ? void 0 : _f.name.includes(deploymentName))) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
logger.silly(`Pod: ${(_g = pod.metadata) === null || _g === void 0 ? void 0 : _g.name}, status: ${pod.status}, deployment: ${deploymentName}`);
|
|
77
|
+
try {
|
|
78
|
+
const res = await fetchLogs(fromAppsemble ? appsembleNamespace : containerNamespace, (_h = pod.metadata) === null || _h === void 0 ? void 0 : _h.name, fromAppsemble ? 'appsemble' : deploymentName);
|
|
79
|
+
let entries = res.split('\n');
|
|
80
|
+
logger.silly(`Number of entries found for pod ${(_j = pod.metadata) === null || _j === void 0 ? void 0 : _j.name}: ${entries.length}`);
|
|
81
|
+
entries = filterLogEntries([...entries], deploymentName, fromAppsemble);
|
|
82
|
+
podLogs.push({ fromAppsemble, entries });
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
handleKubernetesError(error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return podLogs;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type Options } from '@appsemble/node-utils';
|
|
2
|
+
import { type Context } from 'koa';
|
|
3
|
+
export declare function getMessagesUtil(ctx: Context, language: string, appId: number, merge: string[] | string, { getApp, getAppMessages, getBlockMessages }: Options, override?: string[] | string): Promise<Record<string, any>>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { getAppsembleMessages, mergeMessages, } from '@appsemble/node-utils';
|
|
2
|
+
import { defaultLocale, extractAppMessages, normalizeBlockName, } from '@appsemble/utils';
|
|
3
|
+
import tags from 'language-tags';
|
|
4
|
+
import { assertKoaError, throwKoaError } from './koa.js';
|
|
5
|
+
export async function getMessagesUtil(ctx, language, appId, merge, { getApp, getAppMessages, getBlockMessages }, override = 'true') {
|
|
6
|
+
var _a, _b, _c, _d, _e;
|
|
7
|
+
if (!tags.check(language)) {
|
|
8
|
+
throwKoaError(ctx, 400, '`Language “${language}” is invalid`');
|
|
9
|
+
}
|
|
10
|
+
const lang = language.toLowerCase();
|
|
11
|
+
const baseLanguage = tags(language)
|
|
12
|
+
.subtags()
|
|
13
|
+
.find((sub) => sub.type() === 'language');
|
|
14
|
+
const baseLang = baseLanguage && String(baseLanguage).toLowerCase();
|
|
15
|
+
const app = await getApp({ context: ctx, query: { where: { id: appId } } });
|
|
16
|
+
assertKoaError(!app, ctx, 404, 'App not found');
|
|
17
|
+
const blockPrefixes = [];
|
|
18
|
+
const blockQuery = [];
|
|
19
|
+
const appMessages = await getAppMessages({ context: ctx, app, language });
|
|
20
|
+
const coreMessages = await getAppsembleMessages(lang, baseLang);
|
|
21
|
+
const messages = {
|
|
22
|
+
core: Object.fromEntries(Object.entries(coreMessages).filter(([key]) => key.startsWith('app') || key.startsWith('react-components') || key.startsWith('server'))),
|
|
23
|
+
blocks: {},
|
|
24
|
+
...extractAppMessages(app.definition, (block, prefix) => {
|
|
25
|
+
const blockName = normalizeBlockName(block.type);
|
|
26
|
+
const [org, name] = blockName.split('/');
|
|
27
|
+
blockQuery.push({ version: block.version, OrganizationId: org.slice(1), name });
|
|
28
|
+
blockPrefixes.push([blockName, prefix]);
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
const blockMessages = await getBlockMessages({ context: ctx, blockQuery, baseLang, lang });
|
|
32
|
+
if ((!appMessages.length || (merge && !appMessages.some((m) => m.language === lang))) &&
|
|
33
|
+
lang !== (app.definition.defaultLanguage || defaultLocale)) {
|
|
34
|
+
throwKoaError(ctx, 404, `Language “${language}” could not be found`);
|
|
35
|
+
}
|
|
36
|
+
const baseLanguageMessages = override === 'true' && appMessages.find((m) => m.language === baseLang);
|
|
37
|
+
const languageMessages = override === 'true' && appMessages.find((m) => m.language === lang);
|
|
38
|
+
for (const block of blockMessages) {
|
|
39
|
+
const { name } = block;
|
|
40
|
+
const defaultMessages = (_a = block.messages) === null || _a === void 0 ? void 0 : _a[defaultLocale];
|
|
41
|
+
const blockBaseLanguageMessages = baseLang && ((_b = block.messages) === null || _b === void 0 ? void 0 : _b[baseLang]);
|
|
42
|
+
const blockLanguageMessages = (_c = block.messages) === null || _c === void 0 ? void 0 : _c[language];
|
|
43
|
+
const blockVersionMessages = {
|
|
44
|
+
...defaultMessages,
|
|
45
|
+
...Object.fromEntries(Object.entries(blockBaseLanguageMessages !== null && blockBaseLanguageMessages !== void 0 ? blockBaseLanguageMessages : {}).filter(([, value]) => value)),
|
|
46
|
+
...Object.fromEntries(Object.entries(blockLanguageMessages !== null && blockLanguageMessages !== void 0 ? blockLanguageMessages : {}).filter(([, value]) => value)),
|
|
47
|
+
};
|
|
48
|
+
if (messages.blocks[name]) {
|
|
49
|
+
messages.blocks[name][block.version] = blockVersionMessages;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
messages.blocks[name] = {
|
|
53
|
+
[block.version]: blockVersionMessages,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (override !== 'true') {
|
|
57
|
+
const prefixed = blockPrefixes.filter(([b]) => b === name);
|
|
58
|
+
for (const [messageId, value] of Object.entries(blockVersionMessages)) {
|
|
59
|
+
for (const [, prefix] of prefixed) {
|
|
60
|
+
messages.app[`${prefix.join('.')}.${messageId}`] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
language: lang,
|
|
67
|
+
messages: mergeMessages(messages, (_d = baseLanguageMessages === null || baseLanguageMessages === void 0 ? void 0 : baseLanguageMessages.messages) !== null && _d !== void 0 ? _d : {}, (_e = languageMessages === null || languageMessages === void 0 ? void 0 : languageMessages.messages) !== null && _e !== void 0 ? _e : {}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=getMessagesUtil.js.map
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -35,5 +35,6 @@ export * from './EmailQuotaExceededError.js';
|
|
|
35
35
|
export * from './EmailError.js';
|
|
36
36
|
export * from './UserPropertiesError.js';
|
|
37
37
|
export * from './authentication.js';
|
|
38
|
+
export * from './getMessagesUtil.js';
|
|
38
39
|
export * from './container/index.js';
|
|
39
40
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsemble/node-utils",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.7",
|
|
4
4
|
"description": "NodeJS utilities used by Appsemble internally.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"app",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"test": "vitest"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@appsemble/types": "0.29.
|
|
42
|
-
"@appsemble/utils": "0.29.
|
|
41
|
+
"@appsemble/types": "0.29.7",
|
|
42
|
+
"@appsemble/utils": "0.29.7",
|
|
43
43
|
"@formatjs/fast-memoize": "^2.0.0",
|
|
44
44
|
"@fortawesome/fontawesome-free": "^6.0.0",
|
|
45
45
|
"@kubernetes/client-node": "0.21.0",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertKoaError, createFormData, getRemapperContext, logger, parseServiceUrl, scaleDeployment, setLastRequestAnnotation, throwKoaError, version, waitForPodReadiness, } from '@appsemble/node-utils';
|
|
1
|
+
import { assertKoaError, createFormData, getContainerNamespace, getRemapperContext, logger, parseServiceUrl, scaleDeployment, setLastRequestAnnotation, throwKoaError, version, waitForPodReadiness, } from '@appsemble/node-utils';
|
|
2
2
|
import { defaultLocale, remap } from '@appsemble/utils';
|
|
3
3
|
import axios from 'axios';
|
|
4
4
|
import { get, mapValues, pick } from 'lodash-es';
|
|
@@ -137,6 +137,7 @@ async function handleRequestProxy(ctx, app, action, useBody, options) {
|
|
|
137
137
|
const urlPattern = /^http:\/\/(([\da-z-]+).){2}svc.cluster.local/;
|
|
138
138
|
// Restricting access to only the containers defined by the app
|
|
139
139
|
if (urlPattern.test(String(proxyUrl))) {
|
|
140
|
+
axiosConfig.url = axiosConfig.url.replace(axiosConfig.url.split('.')[1], getContainerNamespace());
|
|
140
141
|
const { appId } = parseServiceUrl(String(proxyUrl));
|
|
141
142
|
if (appId !== String(app.id)) {
|
|
142
143
|
throwKoaError(ctx, 403, 'Forbidden');
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { type Options } from '@appsemble/node-utils';
|
|
2
2
|
import { type Middleware } from 'koa';
|
|
3
|
-
export declare function createGetMessages(
|
|
3
|
+
export declare function createGetMessages(options: Options): Middleware;
|
|
@@ -1,72 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import tags from 'language-tags';
|
|
4
|
-
export function createGetMessages({ getApp, getAppMessages, getBlockMessages, }) {
|
|
1
|
+
import { getMessagesUtil } from '@appsemble/node-utils';
|
|
2
|
+
export function createGetMessages(options) {
|
|
5
3
|
return async (ctx) => {
|
|
6
|
-
var _a, _b, _c, _d, _e;
|
|
7
4
|
const { pathParams: { appId, language }, query: { merge, override = 'true' }, } = ctx;
|
|
8
|
-
|
|
9
|
-
throwKoaError(ctx, 400, '`Language “${language}” is invalid`');
|
|
10
|
-
}
|
|
11
|
-
const lang = language.toLowerCase();
|
|
12
|
-
const baseLanguage = tags(language)
|
|
13
|
-
.subtags()
|
|
14
|
-
.find((sub) => sub.type() === 'language');
|
|
15
|
-
const baseLang = baseLanguage && String(baseLanguage).toLowerCase();
|
|
16
|
-
const app = await getApp({ context: ctx, query: { where: { id: appId } } });
|
|
17
|
-
assertKoaError(!app, ctx, 404, 'App not found');
|
|
18
|
-
const blockPrefixes = [];
|
|
19
|
-
const blockQuery = [];
|
|
20
|
-
const appMessages = await getAppMessages({ context: ctx, app, language });
|
|
21
|
-
const coreMessages = await getAppsembleMessages(lang, baseLang);
|
|
22
|
-
const messages = {
|
|
23
|
-
core: Object.fromEntries(Object.entries(coreMessages).filter(([key]) => key.startsWith('app') || key.startsWith('react-components') || key.startsWith('server'))),
|
|
24
|
-
blocks: {},
|
|
25
|
-
...extractAppMessages(app.definition, (block, prefix) => {
|
|
26
|
-
const blockName = normalizeBlockName(block.type);
|
|
27
|
-
const [org, name] = blockName.split('/');
|
|
28
|
-
blockQuery.push({ version: block.version, OrganizationId: org.slice(1), name });
|
|
29
|
-
blockPrefixes.push([blockName, prefix]);
|
|
30
|
-
}),
|
|
31
|
-
};
|
|
32
|
-
const blockMessages = await getBlockMessages({ context: ctx, blockQuery, baseLang, lang });
|
|
33
|
-
if ((!appMessages.length || (merge && !appMessages.some((m) => m.language === lang))) &&
|
|
34
|
-
lang !== (app.definition.defaultLanguage || defaultLocale)) {
|
|
35
|
-
throwKoaError(ctx, 404, `Language “${language}” could not be found`);
|
|
36
|
-
}
|
|
37
|
-
const baseLanguageMessages = override === 'true' && appMessages.find((m) => m.language === baseLang);
|
|
38
|
-
const languageMessages = override === 'true' && appMessages.find((m) => m.language === lang);
|
|
39
|
-
for (const block of blockMessages) {
|
|
40
|
-
const { name } = block;
|
|
41
|
-
const defaultMessages = (_a = block.messages) === null || _a === void 0 ? void 0 : _a[defaultLocale];
|
|
42
|
-
const blockBaseLanguageMessages = baseLang && ((_b = block.messages) === null || _b === void 0 ? void 0 : _b[baseLang]);
|
|
43
|
-
const blockLanguageMessages = (_c = block.messages) === null || _c === void 0 ? void 0 : _c[language];
|
|
44
|
-
const blockVersionMessages = {
|
|
45
|
-
...defaultMessages,
|
|
46
|
-
...Object.fromEntries(Object.entries(blockBaseLanguageMessages !== null && blockBaseLanguageMessages !== void 0 ? blockBaseLanguageMessages : {}).filter(([, value]) => value)),
|
|
47
|
-
...Object.fromEntries(Object.entries(blockLanguageMessages !== null && blockLanguageMessages !== void 0 ? blockLanguageMessages : {}).filter(([, value]) => value)),
|
|
48
|
-
};
|
|
49
|
-
if (messages.blocks[name]) {
|
|
50
|
-
messages.blocks[name][block.version] = blockVersionMessages;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
messages.blocks[name] = {
|
|
54
|
-
[block.version]: blockVersionMessages,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
if (override !== 'true') {
|
|
58
|
-
const prefixed = blockPrefixes.filter(([b]) => b === name);
|
|
59
|
-
for (const [messageId, value] of Object.entries(blockVersionMessages)) {
|
|
60
|
-
for (const [, prefix] of prefixed) {
|
|
61
|
-
messages.app[`${prefix.join('.')}.${messageId}`] = value;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
ctx.body = {
|
|
67
|
-
language: lang,
|
|
68
|
-
messages: mergeMessages(messages, (_d = baseLanguageMessages === null || baseLanguageMessages === void 0 ? void 0 : baseLanguageMessages.messages) !== null && _d !== void 0 ? _d : {}, (_e = languageMessages === null || languageMessages === void 0 ? void 0 : languageMessages.messages) !== null && _e !== void 0 ? _e : {}),
|
|
69
|
-
};
|
|
5
|
+
ctx.body = await getMessagesUtil(ctx, language, appId, merge, options, override);
|
|
70
6
|
};
|
|
71
7
|
}
|
|
72
8
|
//# sourceMappingURL=appMessages.js.map
|
package/server/types.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ declare module 'koas-parameters' {
|
|
|
86
86
|
memberEmail: string;
|
|
87
87
|
trainingBlockId: number;
|
|
88
88
|
trainingId: number;
|
|
89
|
+
container: string;
|
|
89
90
|
}
|
|
90
91
|
interface QueryParams {
|
|
91
92
|
domains: string[];
|
|
@@ -104,6 +105,7 @@ declare module 'koas-parameters' {
|
|
|
104
105
|
screenshots: boolean;
|
|
105
106
|
readmes: boolean;
|
|
106
107
|
roles: string[];
|
|
108
|
+
includeMessages: boolean;
|
|
107
109
|
}
|
|
108
110
|
}
|
|
109
111
|
export type Operator = 'and' | 'not' | 'or';
|