@nzz/q-cli 1.8.2 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- package/bin/commands/bootstrap.js +0 -1
- package/bin/q.js +28 -3
- package/package.json +2 -2
- package/skeletons/et-utils-package-skeleton/README.md +5 -0
- package/skeletons/et-utils-package-skeleton/package.json +13 -10
- package/skeletons/et-utils-package-skeleton/scripts/package-fixup.sh +13 -0
- package/skeletons/et-utils-package-skeleton/test/tsconfig.json +4 -1
- package/skeletons/et-utils-package-skeleton/tsconfig-base.json +10 -0
- package/skeletons/et-utils-package-skeleton/tsconfig-cjs.json +8 -0
- package/skeletons/et-utils-package-skeleton/tsconfig.json +4 -5
- package/skeletons/toolv2-skeleton/.husky/pre-commit +6 -0
- package/skeletons/toolv2-skeleton/.nvmrc +1 -0
- package/skeletons/toolv2-skeleton/.prettierrc.cjs +15 -0
- package/skeletons/toolv2-skeleton/.travis.yml +30 -0
- package/skeletons/toolv2-skeleton/.vscode/settings.json +6 -0
- package/skeletons/toolv2-skeleton/Dockerfile +19 -0
- package/skeletons/toolv2-skeleton/LICENSE +21 -0
- package/skeletons/toolv2-skeleton/README.md +99 -0
- package/skeletons/toolv2-skeleton/dev.js +7 -0
- package/skeletons/toolv2-skeleton/index.js +39 -0
- package/skeletons/toolv2-skeleton/jest.config.ts +39 -0
- package/skeletons/toolv2-skeleton/nodemon.json +4 -0
- package/skeletons/toolv2-skeleton/package-lock.json +21382 -0
- package/skeletons/toolv2-skeleton/package.json +80 -0
- package/skeletons/toolv2-skeleton/resources/display-options-schema.json +11 -0
- package/skeletons/toolv2-skeleton/resources/locales/de/translation.json +8 -0
- package/skeletons/toolv2-skeleton/resources/locales/en/translation.json +10 -0
- package/skeletons/toolv2-skeleton/resources/locales/fr/translation.json +10 -0
- package/skeletons/toolv2-skeleton/resources/schema.json +66 -0
- package/skeletons/toolv2-skeleton/rollup.config.js +48 -0
- package/skeletons/toolv2-skeleton/scripts/postinstall.sh +5 -0
- package/skeletons/toolv2-skeleton/src/.eslintrc.cjs +52 -0
- package/skeletons/toolv2-skeleton/src/components/Main.spec.ts +15 -0
- package/skeletons/toolv2-skeleton/src/components/Main.svelte +32 -0
- package/skeletons/toolv2-skeleton/src/enums.ts +11 -0
- package/skeletons/toolv2-skeleton/src/helpers/fixture-generators.ts +38 -0
- package/skeletons/toolv2-skeleton/src/helpers/toolRuntimeConfig.ts +15 -0
- package/skeletons/toolv2-skeleton/src/interfaces.ts +82 -0
- package/skeletons/toolv2-skeleton/src/modules.d.ts +8 -0
- package/skeletons/toolv2-skeleton/src/routes/dynamic-schemas/exampleDynamicSchema.ts +49 -0
- package/skeletons/toolv2-skeleton/src/routes/dynamic-schemas/index.ts +5 -0
- package/skeletons/toolv2-skeleton/src/routes/health.ts +14 -0
- package/skeletons/toolv2-skeleton/src/routes/locales.ts +31 -0
- package/skeletons/toolv2-skeleton/src/routes/notifications/exampleNotification.ts +46 -0
- package/skeletons/toolv2-skeleton/src/routes/option-availability.ts +27 -0
- package/skeletons/toolv2-skeleton/src/routes/rendering-info/web.ts +150 -0
- package/skeletons/toolv2-skeleton/src/routes/routes.ts +21 -0
- package/skeletons/toolv2-skeleton/src/routes/schema.ts +21 -0
- package/skeletons/toolv2-skeleton/src/routes/stylesheet.ts +31 -0
- package/skeletons/toolv2-skeleton/src/styles/main.scss +6 -0
- package/skeletons/toolv2-skeleton/svelte.config.cjs +6 -0
- package/skeletons/toolv2-skeleton/tasks/compileStyleFiles.cjs +101 -0
- package/skeletons/toolv2-skeleton/tests/e2e-tests.spec.ts +158 -0
- package/skeletons/toolv2-skeleton/tests/helpers.ts +21 -0
- package/skeletons/toolv2-skeleton/tsconfig.json +48 -0
- package/skeletons/et-utils-package-skeleton/rollup.config.js +0 -17
@@ -0,0 +1,80 @@
|
|
1
|
+
{
|
2
|
+
"name": "[tool-name]",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "",
|
5
|
+
"main": "index.js",
|
6
|
+
"type": "module",
|
7
|
+
"scripts": {
|
8
|
+
"build": "rollup -c rollup.config.js && npm run compile-style-files",
|
9
|
+
"compile-style-files": "node tasks/compileStyleFiles.cjs",
|
10
|
+
"dev": "npm run build && node dev.js",
|
11
|
+
"jest": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node' jest --config jest.config.ts",
|
12
|
+
"lint": "eslint --fix --ext .svelte,.ts --config src/.eslintrc.cjs src",
|
13
|
+
"lint:all": "run-s -c lint ts-check svelte-check",
|
14
|
+
"postinstall": "scripts/postinstall.sh",
|
15
|
+
"prettier-format": "prettier --write src/",
|
16
|
+
"start": "nodemon --exec \"npm run dev\"",
|
17
|
+
"svelte-check": "svelte-check",
|
18
|
+
"test": "npm run build && npm run jest",
|
19
|
+
"ts-check": "tsc --noEmit"
|
20
|
+
},
|
21
|
+
"author": "",
|
22
|
+
"license": "MIT",
|
23
|
+
"dependencies": {
|
24
|
+
"@hapi/boom": "^9.1.3",
|
25
|
+
"@hapi/hapi": "^20.2.1",
|
26
|
+
"@hapi/inert": "^6.0.3",
|
27
|
+
"ajv": "^6.12.6",
|
28
|
+
"clone": "^2.1.2",
|
29
|
+
"d3-format": "^1.4.5",
|
30
|
+
"joi": "^17.4.2",
|
31
|
+
"simple-statistics": "^7.7.0",
|
32
|
+
"svelte": "^3.48.0",
|
33
|
+
"uglify-js": "^3.14.3"
|
34
|
+
},
|
35
|
+
"devDependencies": {
|
36
|
+
"@hapi/code": "^8.0.5",
|
37
|
+
"@ota-meshi/eslint-plugin-svelte": "^0.34.1",
|
38
|
+
"@rollup/plugin-alias": "^3.1.9",
|
39
|
+
"@rollup/plugin-json": "^4.1.0",
|
40
|
+
"@rollup/plugin-node-resolve": "^13.3.0",
|
41
|
+
"@rollup/plugin-typescript": "^8.3.3",
|
42
|
+
"@testing-library/jest-dom": "^5.16.4",
|
43
|
+
"@testing-library/svelte": "^3.1.3",
|
44
|
+
"@tsconfig/svelte": "^3.0.0",
|
45
|
+
"@types/d3": "^7.4.0",
|
46
|
+
"@types/hapi__inert": "^5.2.3",
|
47
|
+
"@types/jest": "^28.1.1",
|
48
|
+
"@types/jsdom": "^16.2.14",
|
49
|
+
"@types/node": "^17.0.35",
|
50
|
+
"@types/uglify-js": "^3.13.2",
|
51
|
+
"@typescript-eslint/eslint-plugin": "^5.27.0",
|
52
|
+
"@typescript-eslint/parser": "^5.27.0",
|
53
|
+
"autoprefixer": "^9.8.8",
|
54
|
+
"cssnano": "^4.1.11",
|
55
|
+
"eslint": "^8.16.0",
|
56
|
+
"eslint-svelte3-preprocess": "^0.0.5",
|
57
|
+
"html-minifier": "^4.0.0",
|
58
|
+
"husky": "^8.0.1",
|
59
|
+
"jest": "^28.1.1",
|
60
|
+
"jest-environment-jsdom": "^28.1.2",
|
61
|
+
"jsdom": "^16.7.0",
|
62
|
+
"nodemon": "^2.0.16",
|
63
|
+
"npm-run-all": "^4.1.5",
|
64
|
+
"postcss": "^7.0.39",
|
65
|
+
"postcss-import": "^12.0.1",
|
66
|
+
"prettier": "^2.7.1",
|
67
|
+
"prettier-plugin-svelte": "^2.7.0",
|
68
|
+
"rollup": "^2.75.6",
|
69
|
+
"rollup-plugin-svelte": "^7.1.0",
|
70
|
+
"rollup-plugin-terser": "^7.0.2",
|
71
|
+
"sass": "^1.43.5",
|
72
|
+
"svelte-check": "^2.8.0",
|
73
|
+
"svelte-jester": "^2.3.2",
|
74
|
+
"svelte-preprocess": "^4.10.7",
|
75
|
+
"svelte-strip": "^1.0.1",
|
76
|
+
"ts-jest": "^28.0.5",
|
77
|
+
"ts-node": "^10.8.0",
|
78
|
+
"typescript": "^4.7.4"
|
79
|
+
}
|
80
|
+
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
3
|
+
"type": "object",
|
4
|
+
"title": "[tool-name]",
|
5
|
+
"properties": {
|
6
|
+
"title": {
|
7
|
+
"title": "Titel",
|
8
|
+
"type": "string"
|
9
|
+
},
|
10
|
+
"subtitle": {
|
11
|
+
"title": "Untertitel",
|
12
|
+
"type": "string"
|
13
|
+
}
|
14
|
+
},
|
15
|
+
"options": {
|
16
|
+
"title": "Optionen",
|
17
|
+
"type": "object",
|
18
|
+
"properties": {
|
19
|
+
"showSearch": {
|
20
|
+
"title": "Suche anzeigen",
|
21
|
+
"type": "boolean",
|
22
|
+
"default": false,
|
23
|
+
"Q:options": {
|
24
|
+
"availabilityChecks": [
|
25
|
+
{
|
26
|
+
"type": "ToolEndpoint",
|
27
|
+
"config": {
|
28
|
+
"endpoint": "option-availability/showSearch",
|
29
|
+
"fields": [
|
30
|
+
"options"
|
31
|
+
]
|
32
|
+
}
|
33
|
+
}
|
34
|
+
],
|
35
|
+
"notificationChecks": [
|
36
|
+
{
|
37
|
+
"type": "ToolEndpoint",
|
38
|
+
"config": {
|
39
|
+
"endpoint": "notification/exampleNotification",
|
40
|
+
"fields": [
|
41
|
+
"options"
|
42
|
+
]
|
43
|
+
},
|
44
|
+
"priority": {
|
45
|
+
"type": "medium",
|
46
|
+
"value": 2
|
47
|
+
}
|
48
|
+
}
|
49
|
+
],
|
50
|
+
"dynamicSchema": {
|
51
|
+
"type": "ToolEndpoint",
|
52
|
+
"config": {
|
53
|
+
"endpoint": "dynamic-schema/exampleDynamicSchema",
|
54
|
+
"fields": [
|
55
|
+
"options"
|
56
|
+
]
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
},
|
63
|
+
"required": [
|
64
|
+
"title"
|
65
|
+
]
|
66
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import alias from '@rollup/plugin-alias';
|
2
|
+
import json from '@rollup/plugin-json';
|
3
|
+
import nodeResolve from '@rollup/plugin-node-resolve';
|
4
|
+
import svelte from 'rollup-plugin-svelte';
|
5
|
+
import sveltePreprocess from 'svelte-preprocess';
|
6
|
+
import typescript from '@rollup/plugin-typescript';
|
7
|
+
import { terser } from 'rollup-plugin-terser';
|
8
|
+
|
9
|
+
const backendConfig = {
|
10
|
+
input: 'src/routes/routes.ts',
|
11
|
+
output: {
|
12
|
+
file: 'dist/routes.js',
|
13
|
+
format: 'es',
|
14
|
+
},
|
15
|
+
plugins: [typescript(), json()],
|
16
|
+
external: ['@hapi/boom', 'ajv', 'd3-format', 'joi', 'module', 'path', 'simple-statistics', 'svelte/internal', 'uglify-js', 'url'],
|
17
|
+
};
|
18
|
+
|
19
|
+
const frontendConfig = {
|
20
|
+
input: 'src/components/main.svelte',
|
21
|
+
output: {
|
22
|
+
name: 'window.[tool_name]',
|
23
|
+
file: 'dist/[Tool-name].js',
|
24
|
+
format: 'iife',
|
25
|
+
},
|
26
|
+
plugins: [
|
27
|
+
typescript(),
|
28
|
+
json(),
|
29
|
+
svelte({
|
30
|
+
preprocess: sveltePreprocess(),
|
31
|
+
emitCss: false,
|
32
|
+
compilerOptions: {},
|
33
|
+
}),
|
34
|
+
nodeResolve({ browser: true }),
|
35
|
+
terser(),
|
36
|
+
|
37
|
+
alias({
|
38
|
+
entries: [
|
39
|
+
// If you add a new top-level-folder besides src which you want to use, add it here.
|
40
|
+
{ find: /^@src(\/|$)/, replacement: `${__dirname}/src/` },
|
41
|
+
{ find: /^@cps(\/|$)/, replacement: `${__dirname}/src/components/` },
|
42
|
+
{ find: /^@helpers(\/|$)/, replacement: `${__dirname}/src/helpers/` },
|
43
|
+
],
|
44
|
+
}),
|
45
|
+
],
|
46
|
+
};
|
47
|
+
|
48
|
+
export default [frontendConfig, backendConfig];
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module.exports = {
|
2
|
+
root: true,
|
3
|
+
parser: '@typescript-eslint/parser',
|
4
|
+
extends: [
|
5
|
+
'eslint:recommended',
|
6
|
+
|
7
|
+
// Disables rules from eslint:recommended which are already handled by TypeScript.
|
8
|
+
'plugin:@typescript-eslint/eslint-recommended',
|
9
|
+
|
10
|
+
// Typescript defined rules for linter.
|
11
|
+
'plugin:@typescript-eslint/recommended',
|
12
|
+
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
13
|
+
|
14
|
+
// eslint-plugin-svelte rules.
|
15
|
+
'plugin:@ota-meshi/svelte/recommended',
|
16
|
+
],
|
17
|
+
parserOptions: {
|
18
|
+
ecmaVersion: 2020,
|
19
|
+
sourceType: 'module',
|
20
|
+
tsconfigRootDir: __dirname + '/..',
|
21
|
+
project: ['tsconfig.json'],
|
22
|
+
extraFileExtensions: ['.svelte'],
|
23
|
+
},
|
24
|
+
env: {
|
25
|
+
es6: true,
|
26
|
+
browser: true,
|
27
|
+
},
|
28
|
+
overrides: [
|
29
|
+
{
|
30
|
+
files: ['*.svelte'],
|
31
|
+
parser: 'svelte-eslint-parser',
|
32
|
+
parserOptions: {
|
33
|
+
parser: '@typescript-eslint/parser',
|
34
|
+
},
|
35
|
+
},
|
36
|
+
],
|
37
|
+
settings: {},
|
38
|
+
plugins: ['@ota-meshi/svelte', '@typescript-eslint'],
|
39
|
+
ignorePatterns: ['*.cjs', 'node_modules'],
|
40
|
+
rules: {
|
41
|
+
quotes: [2, 'single'],
|
42
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
43
|
+
'@typescript-eslint/triple-slash-reference': 'off',
|
44
|
+
'@typescript-eslint/restrict-template-expressions': 'off',
|
45
|
+
'@typescript-eslint/explicit-function-return-type': [
|
46
|
+
'error',
|
47
|
+
{
|
48
|
+
allowExpressions: true,
|
49
|
+
},
|
50
|
+
],
|
51
|
+
},
|
52
|
+
};
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import Main from './Main.svelte';
|
2
|
+
import { render } from '@testing-library/svelte';
|
3
|
+
import { create[ToolName]SveltePropertiesFixture } from '@src/helpers/fixture-generators';
|
4
|
+
|
5
|
+
describe('[Tool-name]', () => {
|
6
|
+
it('shows the component correctly', () => {
|
7
|
+
const componentProps = create[ToolName]SveltePropertiesFixture();
|
8
|
+
|
9
|
+
const { container } = render(Main, { props: { componentProps } });
|
10
|
+
|
11
|
+
const el = container.getElementsByClassName('s-q-item')[0];
|
12
|
+
|
13
|
+
expect(el).toBeInstanceOf(HTMLDivElement);
|
14
|
+
});
|
15
|
+
});
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
import type { [ToolName]SvelteProperties } from '@src/interfaces';
|
3
|
+
|
4
|
+
// You must type it expclitly to have no lint errors.
|
5
|
+
export let componentProps: [ToolName]SvelteProperties;
|
6
|
+
|
7
|
+
// Extract const heres.
|
8
|
+
const { config, displayOptions, id } = componentProps;
|
9
|
+
|
10
|
+
// Extract dynamic using let instead of cost.
|
11
|
+
// let { dynProp } = componentProps;
|
12
|
+
|
13
|
+
function shouldShowTitle(): boolean {
|
14
|
+
if (typeof displayOptions.hideTitle === 'boolean') {
|
15
|
+
return !displayOptions.hideTitle;
|
16
|
+
}
|
17
|
+
|
18
|
+
return true;
|
19
|
+
}
|
20
|
+
</script>
|
21
|
+
|
22
|
+
<div {id} class="s-q-item">
|
23
|
+
{#if shouldShowTitle()}
|
24
|
+
<h3 class="s-q-item__title">{config.title}</h3>
|
25
|
+
{/if}
|
26
|
+
|
27
|
+
{#if config.subtitle && config.subtitle !== ''}
|
28
|
+
<div class="s-q-item__subtitle">{config.subtitle}</div>
|
29
|
+
{/if}
|
30
|
+
|
31
|
+
Your first [Tool-name]!
|
32
|
+
</div>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
/**
|
2
|
+
* Put all fixture generators here.
|
3
|
+
* Or if the file gets too big split them up to your liking.
|
4
|
+
*/
|
5
|
+
import type { DisplayOptions, [ToolName]Config, [ToolName]ConfigOptions, [ToolName]SvelteProperties } from '@src/interfaces';
|
6
|
+
|
7
|
+
export function create[ToolName]SveltePropertiesFixture(): [ToolName]SvelteProperties {
|
8
|
+
const displayOptions = createDisplayOptionsFixture();
|
9
|
+
|
10
|
+
return {
|
11
|
+
config: create[ToolName]ConfigFixture(),
|
12
|
+
displayOptions,
|
13
|
+
id: 'id',
|
14
|
+
noInteraction: false,
|
15
|
+
width: 400,
|
16
|
+
};
|
17
|
+
}
|
18
|
+
|
19
|
+
export function create[ToolName]ConfigFixture(): [ToolName]Config {
|
20
|
+
return {
|
21
|
+
options: create[ToolName]ConfigOptionsFixture(),
|
22
|
+
title: 'title',
|
23
|
+
subtitle: 'id',
|
24
|
+
};
|
25
|
+
}
|
26
|
+
|
27
|
+
export function create[ToolName]ConfigOptionsFixture(): [ToolName]ConfigOptions {
|
28
|
+
return {
|
29
|
+
showSearch: true,
|
30
|
+
};
|
31
|
+
}
|
32
|
+
|
33
|
+
export function createDisplayOptionsFixture(override: Partial<DisplayOptions> = {}): DisplayOptions {
|
34
|
+
return {
|
35
|
+
hideTitle: false,
|
36
|
+
...override,
|
37
|
+
};
|
38
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import type { ToolRuntimeConfig } from '../interfaces.js';
|
2
|
+
|
3
|
+
export default function getExactPixelWidth(toolRuntimeConfig: ToolRuntimeConfig): number | undefined {
|
4
|
+
if (!toolRuntimeConfig.size || !Array.isArray(toolRuntimeConfig.size.width)) {
|
5
|
+
return undefined;
|
6
|
+
}
|
7
|
+
|
8
|
+
for (const width of toolRuntimeConfig.size.width) {
|
9
|
+
if (width && width.value && width.comparison === '=' && (!width.unit || width.unit === 'px')) {
|
10
|
+
return width.value;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
return undefined;
|
15
|
+
}
|
@@ -0,0 +1,82 @@
|
|
1
|
+
/**
|
2
|
+
* These interface are the basic setup for your [Tool-name] to run.
|
3
|
+
*/
|
4
|
+
|
5
|
+
/**
|
6
|
+
* What is received by your [Tool-name]'s backend.
|
7
|
+
*/
|
8
|
+
export interface WebPayload {
|
9
|
+
item: [ToolName]Config;
|
10
|
+
itemStateInDb: boolean;
|
11
|
+
toolRuntimeConfig: ToolRuntimeConfig;
|
12
|
+
}
|
13
|
+
|
14
|
+
/**
|
15
|
+
* The total config file.
|
16
|
+
*/
|
17
|
+
export interface [ToolName]Config {
|
18
|
+
options: [ToolName]ConfigOptions;
|
19
|
+
title: string;
|
20
|
+
subtitle: string;
|
21
|
+
}
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Specific options for this Q-item.
|
25
|
+
*/
|
26
|
+
export interface [ToolName]ConfigOptions {
|
27
|
+
showSearch: boolean;
|
28
|
+
}
|
29
|
+
|
30
|
+
export interface DisplayOptions {
|
31
|
+
hideTitle?: boolean;
|
32
|
+
}
|
33
|
+
|
34
|
+
/**
|
35
|
+
* Specific options set for this runtime.
|
36
|
+
*/
|
37
|
+
export interface ToolRuntimeConfig {
|
38
|
+
displayOptions?: DisplayOptions;
|
39
|
+
fileRequestBaseUrl: string;
|
40
|
+
toolBaseUrl: string;
|
41
|
+
id: string;
|
42
|
+
size: {
|
43
|
+
width: Array<{ value: number; unit: string; comparison: '=' | '>' | '<' | '>=' | '<=' }>;
|
44
|
+
};
|
45
|
+
isPure: boolean;
|
46
|
+
requestId: string;
|
47
|
+
markup?: string;
|
48
|
+
noInteraction?: boolean;
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* What is sent to the front-end.
|
53
|
+
*/
|
54
|
+
export interface RenderingInfo {
|
55
|
+
polyfills: string[];
|
56
|
+
stylesheets: Array<{ name: string }>;
|
57
|
+
scripts: Array<{ content: string }>;
|
58
|
+
markup: string;
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Standard interface for availability checks.
|
63
|
+
*/
|
64
|
+
export interface AvailabilityResponseObject {
|
65
|
+
available: boolean;
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* The config that you pass into your main svelte component.
|
70
|
+
* This is the entry point of your interacte Q-item.
|
71
|
+
*/
|
72
|
+
export interface [ToolName]SvelteProperties {
|
73
|
+
config: [ToolName]Config;
|
74
|
+
displayOptions: DisplayOptions;
|
75
|
+
noInteraction: boolean;
|
76
|
+
id: string;
|
77
|
+
width: number | undefined;
|
78
|
+
}
|
79
|
+
|
80
|
+
export interface StyleHashMap {
|
81
|
+
main: string;
|
82
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
// The references is required to register the inert extension onto hapi__hapi so that
|
2
|
+
// the h.file line is registered correctly by typescript.
|
3
|
+
/// <reference path="../node_modules/@types/hapi__inert/index.d.ts"/>
|
4
|
+
|
5
|
+
|
6
|
+
// https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html
|
7
|
+
// https://www.typescriptlang.org/docs/handbook/modules.html
|
8
|
+
// https://www.typescriptlang.org/docs/handbook/declaration-files/templates.html
|
@@ -0,0 +1,49 @@
|
|
1
|
+
/**
|
2
|
+
* Dynamic schemas return options to a field that change depending
|
3
|
+
* other settings. Hence, dynamic options.
|
4
|
+
*
|
5
|
+
* You can write your logic in the handler and return whatever options
|
6
|
+
* are decided.
|
7
|
+
*/
|
8
|
+
import Joi from 'joi';
|
9
|
+
import type { [ToolName]ConfigOptions } from '@src/interfaces';
|
10
|
+
import type { Request, ServerRoute } from '@hapi/hapi';
|
11
|
+
|
12
|
+
const route: ServerRoute = {
|
13
|
+
method: 'POST',
|
14
|
+
path: '/dynamic-schema/exampleDynamicSchema',
|
15
|
+
options: {
|
16
|
+
validate: {
|
17
|
+
payload: Joi.object(),
|
18
|
+
},
|
19
|
+
},
|
20
|
+
handler: function (request: Request): ExampleDynamicSchemeReturnPayload {
|
21
|
+
const payload = request.payload as Payload;
|
22
|
+
const options = payload.item.options;
|
23
|
+
|
24
|
+
return {
|
25
|
+
enum: ['one', 'two', 'three', 'four'],
|
26
|
+
'Q:options': {
|
27
|
+
enum_titles: ['1', '2', '3', '4'],
|
28
|
+
},
|
29
|
+
};
|
30
|
+
},
|
31
|
+
};
|
32
|
+
|
33
|
+
export default route;
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Interfaces.
|
37
|
+
*/
|
38
|
+
interface Payload {
|
39
|
+
item: {
|
40
|
+
options: [ToolName]ConfigOptions;
|
41
|
+
};
|
42
|
+
}
|
43
|
+
|
44
|
+
export interface ExampleDynamicSchemeReturnPayload {
|
45
|
+
enum: string[];
|
46
|
+
'Q:options': {
|
47
|
+
enum_titles: string[];
|
48
|
+
};
|
49
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import Joi from 'joi';
|
2
|
+
import { dirname } from 'path';
|
3
|
+
import { fileURLToPath } from 'url';
|
4
|
+
import type { Request, ServerRoute, ResponseToolkit } from '@hapi/hapi';
|
5
|
+
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
7
|
+
const localesDir = __dirname + '/../../resources/locales/';
|
8
|
+
|
9
|
+
const route: ServerRoute = {
|
10
|
+
path: '/locales/{lng}/translation.json',
|
11
|
+
method: 'GET',
|
12
|
+
options: {
|
13
|
+
description: 'Returns translations for given language',
|
14
|
+
tags: ['api'],
|
15
|
+
validate: {
|
16
|
+
params: {
|
17
|
+
lng: Joi.string().required(),
|
18
|
+
},
|
19
|
+
},
|
20
|
+
},
|
21
|
+
handler: (request: Request, h: ResponseToolkit) => {
|
22
|
+
const params = request.params as Params;
|
23
|
+
return h.file(localesDir + params.lng + '/translation.json').type('application/json');
|
24
|
+
},
|
25
|
+
};
|
26
|
+
|
27
|
+
export default route;
|
28
|
+
|
29
|
+
interface Params {
|
30
|
+
lng: string;
|
31
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import Joi from 'joi';
|
2
|
+
import type { Request } from '@hapi/hapi';
|
3
|
+
import type { [ToolName]ConfigOptions } from '@src/interfaces';
|
4
|
+
|
5
|
+
export default {
|
6
|
+
method: 'POST',
|
7
|
+
path: '/notification/exampleNotification',
|
8
|
+
options: {
|
9
|
+
validate: {
|
10
|
+
options: {
|
11
|
+
allowUnknown: true,
|
12
|
+
},
|
13
|
+
payload: Joi.object().required(),
|
14
|
+
},
|
15
|
+
tags: ['api'],
|
16
|
+
},
|
17
|
+
handler: function (request: Request) {
|
18
|
+
try {
|
19
|
+
const payload = request.payload as Payload;
|
20
|
+
const item = payload.item;
|
21
|
+
|
22
|
+
/** Response is fetched from the locales folder. */
|
23
|
+
return {
|
24
|
+
message: {
|
25
|
+
title: 'notifications.exampleNotification.title',
|
26
|
+
body: 'notifications.exampleNotification.body',
|
27
|
+
},
|
28
|
+
};
|
29
|
+
} catch (err) {
|
30
|
+
console.log('Error processing /notification/exampleNotification', err);
|
31
|
+
}
|
32
|
+
|
33
|
+
return null;
|
34
|
+
},
|
35
|
+
};
|
36
|
+
|
37
|
+
/**
|
38
|
+
* Payload is defined in the schema.json:
|
39
|
+
* showSearch -> notificationChecks -> fields
|
40
|
+
*/
|
41
|
+
interface Payload {
|
42
|
+
item: {
|
43
|
+
options: [ToolName]ConfigOptions;
|
44
|
+
};
|
45
|
+
roles: string[];
|
46
|
+
}
|