@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,27 @@
|
|
1
|
+
import Boom from '@hapi/boom';
|
2
|
+
import Joi from 'joi';
|
3
|
+
import type { AvailabilityResponseObject, WebPayload } from '@src/interfaces';
|
4
|
+
import type { Request } from 'hapi__hapi';
|
5
|
+
|
6
|
+
export default {
|
7
|
+
method: 'POST',
|
8
|
+
path: '/option-availability/{optionName}',
|
9
|
+
options: {
|
10
|
+
validate: {
|
11
|
+
payload: Joi.object(),
|
12
|
+
},
|
13
|
+
},
|
14
|
+
handler: function (request: Request): AvailabilityResponseObject | Boom.Boom {
|
15
|
+
const payload = request.payload as WebPayload;
|
16
|
+
const item = payload.item;
|
17
|
+
const optionName = request.params.optionName as string;
|
18
|
+
|
19
|
+
if (optionName === 'showSearch') {
|
20
|
+
return {
|
21
|
+
available: true,
|
22
|
+
};
|
23
|
+
}
|
24
|
+
|
25
|
+
return Boom.badRequest();
|
26
|
+
},
|
27
|
+
};
|
@@ -0,0 +1,150 @@
|
|
1
|
+
import Ajv from 'ajv';
|
2
|
+
import Boom from '@hapi/boom';
|
3
|
+
import getExactPixelWidth from '@helpers/toolRuntimeConfig.js';
|
4
|
+
import { readFileSync } from 'fs';
|
5
|
+
import schemaString from '@rs/schema.json';
|
6
|
+
import type { Request, ServerRoute } from '@hapi/hapi';
|
7
|
+
import type {
|
8
|
+
AvailabilityResponseObject,
|
9
|
+
DisplayOptions,
|
10
|
+
[ToolName]Config,
|
11
|
+
[ToolName]ConfigOptions,
|
12
|
+
[ToolName]SvelteProperties,
|
13
|
+
RenderingInfo,
|
14
|
+
StyleHashMap,
|
15
|
+
ToolRuntimeConfig,
|
16
|
+
WebPayload,
|
17
|
+
} from '@src/interfaces';
|
18
|
+
|
19
|
+
const ajv = new Ajv();
|
20
|
+
const validate = ajv.compile(schemaString);
|
21
|
+
|
22
|
+
const route: ServerRoute = {
|
23
|
+
method: 'POST',
|
24
|
+
path: '/rendering-info/web',
|
25
|
+
options: {
|
26
|
+
validate: {
|
27
|
+
options: {
|
28
|
+
allowUnknown: true,
|
29
|
+
},
|
30
|
+
payload: async payload => {
|
31
|
+
const payloadTyped = payload as WebPayload;
|
32
|
+
const item = payloadTyped.item;
|
33
|
+
const toolRuntimeConfig = payloadTyped.toolRuntimeConfig;
|
34
|
+
|
35
|
+
if (typeof payloadTyped !== 'object' || typeof item !== 'object' || typeof toolRuntimeConfig !== 'object') {
|
36
|
+
throw Boom.badRequest('The given payload for this route is not correct.');
|
37
|
+
}
|
38
|
+
|
39
|
+
if (await validate(item)) {
|
40
|
+
return item;
|
41
|
+
} else {
|
42
|
+
throw Boom.badRequest(JSON.stringify(validate.errors));
|
43
|
+
}
|
44
|
+
},
|
45
|
+
},
|
46
|
+
},
|
47
|
+
handler: function (request: Request) {
|
48
|
+
const id = createId(request);
|
49
|
+
let qtableCompiledScript = '';
|
50
|
+
let styleHashMap: StyleHashMap | null = null;
|
51
|
+
|
52
|
+
try {
|
53
|
+
qtableCompiledScript = readFileSync('dist/[Tool-name].js', {
|
54
|
+
encoding: 'utf-8',
|
55
|
+
});
|
56
|
+
} catch (e) {
|
57
|
+
console.log('Failed reading compiled [Tool-name] code - ', e);
|
58
|
+
}
|
59
|
+
|
60
|
+
try {
|
61
|
+
const rawString = readFileSync('dist/styles/hashMap.json', {
|
62
|
+
encoding: 'utf-8',
|
63
|
+
});
|
64
|
+
|
65
|
+
styleHashMap = JSON.parse(rawString) as StyleHashMap;
|
66
|
+
} catch (e) {
|
67
|
+
console.log('Failed reading compiled style hashmap - ', e);
|
68
|
+
}
|
69
|
+
|
70
|
+
const payload = request.orig.payload as WebPayload;
|
71
|
+
|
72
|
+
// Extract table configurations.
|
73
|
+
const config = payload.item;
|
74
|
+
|
75
|
+
const toolRuntimeConfig = payload.toolRuntimeConfig || {};
|
76
|
+
const displayOptions = toolRuntimeConfig.displayOptions || ({} as DisplayOptions);
|
77
|
+
const options = config.options;
|
78
|
+
|
79
|
+
const width = getExactPixelWidth(toolRuntimeConfig);
|
80
|
+
|
81
|
+
const props: [ToolName]SvelteProperties = {
|
82
|
+
config,
|
83
|
+
displayOptions,
|
84
|
+
noInteraction: payload.toolRuntimeConfig.noInteraction || false,
|
85
|
+
id,
|
86
|
+
width,
|
87
|
+
};
|
88
|
+
|
89
|
+
const renderingInfo: RenderingInfo = {
|
90
|
+
polyfills: ['Promise'],
|
91
|
+
stylesheets: [],
|
92
|
+
scripts: [
|
93
|
+
{
|
94
|
+
content: qtableCompiledScript,
|
95
|
+
},
|
96
|
+
{
|
97
|
+
content: `
|
98
|
+
(function () {
|
99
|
+
var target = document.querySelector('#${id}_container');
|
100
|
+
target.innerHTML = "";
|
101
|
+
var props = ${JSON.stringify(props)};
|
102
|
+
new window.[tool_name]({
|
103
|
+
"target": target,
|
104
|
+
"props": {
|
105
|
+
props: props
|
106
|
+
}
|
107
|
+
})
|
108
|
+
})();`,
|
109
|
+
},
|
110
|
+
],
|
111
|
+
|
112
|
+
markup: `<div id="${id}" class="[tool-name]-container" />`,
|
113
|
+
};
|
114
|
+
|
115
|
+
if (styleHashMap !== null) {
|
116
|
+
renderingInfo.stylesheets.push({
|
117
|
+
name: styleHashMap['main'],
|
118
|
+
});
|
119
|
+
}
|
120
|
+
|
121
|
+
return renderingInfo;
|
122
|
+
},
|
123
|
+
};
|
124
|
+
|
125
|
+
/**
|
126
|
+
*
|
127
|
+
* Example of code if you ever need to check if an option is avaible within the
|
128
|
+
* handler.
|
129
|
+
*/
|
130
|
+
// async function areMinibarsAvailable(request: Request, config: QTableConfig): Promise<boolean> {
|
131
|
+
// const response = await request.server.inject({
|
132
|
+
// url: '/option-availability/selectedColumnMinibar',
|
133
|
+
// method: 'POST',
|
134
|
+
// payload: { item: config },
|
135
|
+
// });
|
136
|
+
|
137
|
+
// const result = response.result as AvailabilityResponseObject | undefined;
|
138
|
+
// if (result) {
|
139
|
+
// return result.available;
|
140
|
+
// } else {
|
141
|
+
// console.log('Error receiving result for /option-availability/selectedColumnMinibar', result);
|
142
|
+
// return false;
|
143
|
+
// }
|
144
|
+
// }
|
145
|
+
|
146
|
+
function createId(request: Request): string {
|
147
|
+
return `[tool_name]_${request.query._id}_${Math.floor(Math.random() * 100000)}`.replace(/-/g, '');
|
148
|
+
}
|
149
|
+
|
150
|
+
export default route;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import web from './rendering-info/web';
|
2
|
+
import stylesheet from './stylesheet';
|
3
|
+
import optionAvailability from './option-availability';
|
4
|
+
import dynamicSchemas from './dynamic-schemas/index';
|
5
|
+
import health from './health';
|
6
|
+
import locales from './locales';
|
7
|
+
import exampleNotification from './notifications/exampleNotification';
|
8
|
+
import schema from './schema';
|
9
|
+
|
10
|
+
const allRoutes = [
|
11
|
+
...dynamicSchemas,
|
12
|
+
...schema,
|
13
|
+
exampleNotification,
|
14
|
+
health,
|
15
|
+
locales,
|
16
|
+
optionAvailability,
|
17
|
+
stylesheet,
|
18
|
+
web,
|
19
|
+
];
|
20
|
+
|
21
|
+
export default allRoutes;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import schema from '../../resources/schema.json';
|
2
|
+
import displayOptionsSchema from '../../resources/display-options-schema.json';
|
3
|
+
import type { Request, ResponseToolkit, ServerRoute } from '@hapi/hapi';
|
4
|
+
|
5
|
+
const schemaRoute: ServerRoute = {
|
6
|
+
method: 'GET',
|
7
|
+
path: '/schema.json',
|
8
|
+
handler: function (request: Request, h: ResponseToolkit) {
|
9
|
+
return h.response(schema);
|
10
|
+
},
|
11
|
+
};
|
12
|
+
|
13
|
+
const displayOptionsRoute: ServerRoute = {
|
14
|
+
method: 'GET',
|
15
|
+
path: '/display-options-schema.json',
|
16
|
+
handler: function (request: Request, h: ResponseToolkit) {
|
17
|
+
return h.response(displayOptionsSchema);
|
18
|
+
},
|
19
|
+
};
|
20
|
+
|
21
|
+
export default [schemaRoute, displayOptionsRoute];
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import path from 'path';
|
2
|
+
import { dirname } from 'path';
|
3
|
+
import { fileURLToPath } from 'url';
|
4
|
+
import type { Request, ResponseToolkit, ServerRoute } from '@hapi/hapi';
|
5
|
+
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
7
|
+
|
8
|
+
const route: ServerRoute = {
|
9
|
+
method: 'GET',
|
10
|
+
path: '/stylesheet/{filename}.{hash}.{extension}',
|
11
|
+
options: {
|
12
|
+
files: {
|
13
|
+
relativeTo: path.join(__dirname, '/styles/'),
|
14
|
+
},
|
15
|
+
},
|
16
|
+
handler: function (request: Request, h: ResponseToolkit) {
|
17
|
+
const params = request.params as Params;
|
18
|
+
|
19
|
+
return h
|
20
|
+
.file(`${params.filename}.${params.extension}`)
|
21
|
+
.type('text/css')
|
22
|
+
.header('cache-control', `max-age=${60 * 60 * 24 * 365}, immutable`); // 1 year
|
23
|
+
},
|
24
|
+
};
|
25
|
+
|
26
|
+
export default route;
|
27
|
+
|
28
|
+
interface Params {
|
29
|
+
filename: string;
|
30
|
+
extension: string;
|
31
|
+
}
|
@@ -0,0 +1,101 @@
|
|
1
|
+
const fs = require('fs');
|
2
|
+
const crypto = require('crypto');
|
3
|
+
|
4
|
+
const sass = require('sass');
|
5
|
+
const postcss = require('postcss');
|
6
|
+
const postcssImport = require('postcss-import');
|
7
|
+
const autoprefixer = require('autoprefixer');
|
8
|
+
const cssnano = require('cssnano');
|
9
|
+
|
10
|
+
const stylesDir = __dirname + '/../src/styles/';
|
11
|
+
|
12
|
+
function writeHashmap(hashmapPath, files, fileext) {
|
13
|
+
const hashMap = {};
|
14
|
+
|
15
|
+
files
|
16
|
+
.map((file) => {
|
17
|
+
const hash = crypto.createHash('md5');
|
18
|
+
hash.update(file.content, { encoding: 'utf8' });
|
19
|
+
file.hash = hash.digest('hex');
|
20
|
+
return file;
|
21
|
+
})
|
22
|
+
.map((file) => {
|
23
|
+
hashMap[file.name] = `${file.name}.${file.hash.substring(0, 8)}.${fileext}`;
|
24
|
+
});
|
25
|
+
|
26
|
+
fs.writeFileSync(hashmapPath, JSON.stringify(hashMap));
|
27
|
+
}
|
28
|
+
|
29
|
+
async function compileStylesheet(name) {
|
30
|
+
return new Promise((resolve, reject) => {
|
31
|
+
const filePath = stylesDir + `${name}.scss`;
|
32
|
+
|
33
|
+
const exists = fs.existsSync(filePath);
|
34
|
+
if (!exists) {
|
35
|
+
reject(`stylesheet not found ${filePath}`);
|
36
|
+
process.exit(1);
|
37
|
+
}
|
38
|
+
|
39
|
+
sass.render(
|
40
|
+
{
|
41
|
+
file: filePath,
|
42
|
+
includePaths: ['jspm_packages/github/', 'jspm_packages/npm/'],
|
43
|
+
outputStyle: 'compressed',
|
44
|
+
},
|
45
|
+
(err, sassResult) => {
|
46
|
+
if (err) {
|
47
|
+
reject(err);
|
48
|
+
} else {
|
49
|
+
postcss()
|
50
|
+
.use(postcssImport)
|
51
|
+
.use(autoprefixer)
|
52
|
+
.use(cssnano)
|
53
|
+
.process(sassResult.css, {
|
54
|
+
from: `${stylesDir}${name}.css`,
|
55
|
+
})
|
56
|
+
.then((prefixedResult) => {
|
57
|
+
if (prefixedResult.warnings().length > 0) {
|
58
|
+
console.log(`failed to compile stylesheet ${name}`);
|
59
|
+
process.exit(1);
|
60
|
+
}
|
61
|
+
resolve(prefixedResult.css);
|
62
|
+
});
|
63
|
+
}
|
64
|
+
}
|
65
|
+
);
|
66
|
+
});
|
67
|
+
}
|
68
|
+
|
69
|
+
async function buildStyles() {
|
70
|
+
const basePath = 'dist/styles';
|
71
|
+
const fullPathHashmap = `${basePath}/hashMap.json`;
|
72
|
+
|
73
|
+
// Check if directory exists.
|
74
|
+
if (!fs.existsSync(basePath)) {
|
75
|
+
fs.mkdirSync(basePath);
|
76
|
+
}
|
77
|
+
|
78
|
+
const styleFiles = [
|
79
|
+
{
|
80
|
+
name: 'main',
|
81
|
+
content: await compileStylesheet('main'),
|
82
|
+
},
|
83
|
+
];
|
84
|
+
|
85
|
+
styleFiles.map(file => {
|
86
|
+
const fullPathCss = `${basePath}/${file.name}.css`;
|
87
|
+
fs.writeFileSync(fullPathCss, file.content, { flag: 'w' });
|
88
|
+
});
|
89
|
+
|
90
|
+
writeHashmap(fullPathHashmap, styleFiles, 'css');
|
91
|
+
}
|
92
|
+
|
93
|
+
Promise.all([
|
94
|
+
buildStyles(),
|
95
|
+
]).then(() => {
|
96
|
+
console.log('build complete');
|
97
|
+
})
|
98
|
+
.catch((err) => {
|
99
|
+
console.log(err);
|
100
|
+
process.exit(1);
|
101
|
+
});
|
@@ -0,0 +1,158 @@
|
|
1
|
+
/**
|
2
|
+
* @jest-environment jsdom
|
3
|
+
*/
|
4
|
+
|
5
|
+
// https://github.com/prisma/prisma/issues/8558#issuecomment-1102176746
|
6
|
+
global.setImmediate = global.setImmediate || ((fn: () => unknown, ...args: []) => global.setTimeout(fn, 0, ...args));
|
7
|
+
|
8
|
+
import Hapi from '@hapi/hapi';
|
9
|
+
import Joi from 'joi';
|
10
|
+
import { getAvailabilityResponse, getMarkup, getScripts, getStylesheets } from './helpers';
|
11
|
+
import type { ExampleDynamicSchemeReturnPayload } from '@src/routes/dynamic-schemas/exampleDynamicSchema';
|
12
|
+
import { create[ToolName]ConfigFixture } from '@src/helpers/fixture-generators';
|
13
|
+
|
14
|
+
// We ignore because this will be built before you run the tests.
|
15
|
+
// @ts-ignore
|
16
|
+
import routes from '../dist/routes.js';
|
17
|
+
|
18
|
+
let server: Hapi.Server;
|
19
|
+
|
20
|
+
// Start the server before the tests.
|
21
|
+
beforeAll(async () => {
|
22
|
+
try {
|
23
|
+
server = Hapi.server({
|
24
|
+
port: process.env.PORT || 3000,
|
25
|
+
});
|
26
|
+
server.validator(Joi);
|
27
|
+
server.route(routes);
|
28
|
+
} catch (err) {
|
29
|
+
expect(err).not.toBeDefined();
|
30
|
+
}
|
31
|
+
});
|
32
|
+
|
33
|
+
afterAll(async () => {
|
34
|
+
await server.stop({ timeout: 2000 });
|
35
|
+
|
36
|
+
// @ts-ignore.
|
37
|
+
server = null;
|
38
|
+
});
|
39
|
+
|
40
|
+
describe('basics', () => {
|
41
|
+
it('starts the server', () => {
|
42
|
+
expect(server.info.created).toEqual(expect.any(Number));
|
43
|
+
});
|
44
|
+
|
45
|
+
it('is healthy', async () => {
|
46
|
+
const response = await server.inject('/health');
|
47
|
+
expect(response.payload).toEqual('ok');
|
48
|
+
});
|
49
|
+
});
|
50
|
+
|
51
|
+
describe('rendering-info/web', () => {
|
52
|
+
it('renders the tool', async () => {
|
53
|
+
const config = create[ToolName]ConfigFixture();
|
54
|
+
|
55
|
+
const response = await server.inject({
|
56
|
+
url: '/rendering-info/web?_id=someid',
|
57
|
+
method: 'POST',
|
58
|
+
payload: {
|
59
|
+
item: config,
|
60
|
+
toolRuntimeConfig: {},
|
61
|
+
},
|
62
|
+
});
|
63
|
+
|
64
|
+
expect(response.statusCode).toEqual(200);
|
65
|
+
|
66
|
+
const markup = getMarkup(response.result);
|
67
|
+
const stylesheets = getStylesheets(response.result);
|
68
|
+
const scripts = getScripts(response.result);
|
69
|
+
|
70
|
+
const foundMarkupId = markup.includes('id="[tool_name]_someid_');
|
71
|
+
const foundMarkupClass = markup.includes('class="[tool-name]-container"');
|
72
|
+
expect(foundMarkupId).toBe(true);
|
73
|
+
expect(foundMarkupClass).toBe(true);
|
74
|
+
|
75
|
+
const foundStylesheet = stylesheets[0].name.startsWith('main.');
|
76
|
+
expect(foundStylesheet).toBe(true);
|
77
|
+
|
78
|
+
expect(scripts[0].content).toEqual(expect.any(String));
|
79
|
+
});
|
80
|
+
|
81
|
+
it('returns 400 if no payload given', async () => {
|
82
|
+
const response = await server.inject({
|
83
|
+
url: '/rendering-info/web?_id=someid',
|
84
|
+
method: 'POST',
|
85
|
+
});
|
86
|
+
expect(response.statusCode).toEqual(400);
|
87
|
+
});
|
88
|
+
|
89
|
+
it('returns 400 if no item given in payload', async () => {
|
90
|
+
const response = await server.inject({
|
91
|
+
url: '/rendering-info/web?_id=someid',
|
92
|
+
method: 'POST',
|
93
|
+
payload: {
|
94
|
+
item: {},
|
95
|
+
},
|
96
|
+
});
|
97
|
+
expect(response.statusCode).toEqual(400);
|
98
|
+
});
|
99
|
+
|
100
|
+
it('returns 400 if no toolRuntimeConfig given in payload', async () => {
|
101
|
+
const response = await server.inject({
|
102
|
+
url: '/rendering-info/web?_id=someid',
|
103
|
+
method: 'POST',
|
104
|
+
payload: {
|
105
|
+
toolRuntimeConfig: {},
|
106
|
+
},
|
107
|
+
});
|
108
|
+
expect(response.statusCode).toEqual(400);
|
109
|
+
});
|
110
|
+
|
111
|
+
it('returns 400 if invalid item given', async () => {
|
112
|
+
const response = await server.inject({
|
113
|
+
url: '/rendering-info/web?_id=someid',
|
114
|
+
method: 'POST',
|
115
|
+
payload: {
|
116
|
+
item: { foo: 'bar' },
|
117
|
+
toolRuntimeConfig: {},
|
118
|
+
},
|
119
|
+
});
|
120
|
+
expect(response.statusCode).toEqual(400);
|
121
|
+
});
|
122
|
+
});
|
123
|
+
|
124
|
+
describe('option availability endpoint example', () => {
|
125
|
+
it('returns true for option availability of example', async () => {
|
126
|
+
const request = {
|
127
|
+
method: 'POST',
|
128
|
+
url: '/option-availability/showSearch',
|
129
|
+
payload: {
|
130
|
+
item: {},
|
131
|
+
},
|
132
|
+
};
|
133
|
+
const response = await server.inject(request);
|
134
|
+
|
135
|
+
const available = getAvailabilityResponse(response.result);
|
136
|
+
expect(available).toEqual(true);
|
137
|
+
});
|
138
|
+
|
139
|
+
});
|
140
|
+
|
141
|
+
describe('example dynamic schema endpoint', () => {
|
142
|
+
it('returns correct response for exampleDynamicSchema', async () => {
|
143
|
+
const request = {
|
144
|
+
method: 'POST',
|
145
|
+
url: '/dynamic-schema/exampleDynamicSchema',
|
146
|
+
payload: {
|
147
|
+
item: {}
|
148
|
+
},
|
149
|
+
};
|
150
|
+
|
151
|
+
const response = await server.inject(request);
|
152
|
+
|
153
|
+
const result = response.result as ExampleDynamicSchemeReturnPayload;
|
154
|
+
|
155
|
+
expect(result.enum).toEqual(['one', 'two', 'three', 'four']);
|
156
|
+
expect(result['Q:options'].enum_titles).toEqual(['1', '2', '3', '4']);
|
157
|
+
});
|
158
|
+
});
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import type { AvailabilityResponseObject, RenderingInfo } from '@src/interfaces';
|
2
|
+
|
3
|
+
export function getMarkup(result: object | undefined): string {
|
4
|
+
const casted = result as RenderingInfo;
|
5
|
+
return casted.markup;
|
6
|
+
}
|
7
|
+
|
8
|
+
export function getScripts(result: object | undefined): {content: string}[] {
|
9
|
+
const casted = result as RenderingInfo;
|
10
|
+
return casted.scripts;
|
11
|
+
}
|
12
|
+
|
13
|
+
export function getStylesheets(result: object | undefined): {name: string}[] {
|
14
|
+
const casted = result as RenderingInfo;
|
15
|
+
return casted.stylesheets;
|
16
|
+
}
|
17
|
+
|
18
|
+
export function getAvailabilityResponse(result: object | undefined): boolean {
|
19
|
+
const casted = result as AvailabilityResponseObject;
|
20
|
+
return casted.available;
|
21
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
{
|
2
|
+
"extends": "@tsconfig/svelte/tsconfig.json",
|
3
|
+
"compilerOptions": {
|
4
|
+
"sourceMap": false,
|
5
|
+
"strict": true,
|
6
|
+
"baseUrl": ".",
|
7
|
+
"paths": {
|
8
|
+
"@src/*": [
|
9
|
+
"src/*"
|
10
|
+
],
|
11
|
+
"@cps/*": [
|
12
|
+
"src/components/*"
|
13
|
+
],
|
14
|
+
"@rs/*": [
|
15
|
+
"resources/*"
|
16
|
+
],
|
17
|
+
"@helpers/*": [
|
18
|
+
"src/helpers/*"
|
19
|
+
]
|
20
|
+
},
|
21
|
+
"allowSyntheticDefaultImports": true,
|
22
|
+
"declaration": false,
|
23
|
+
"esModuleInterop": true,
|
24
|
+
"module": "es2020",
|
25
|
+
"moduleResolution": "node",
|
26
|
+
"noImplicitAny": true,
|
27
|
+
"strictNullChecks": true,
|
28
|
+
"target": "ES2015",
|
29
|
+
"resolveJsonModule": true,
|
30
|
+
"types": [
|
31
|
+
"node",
|
32
|
+
"svelte",
|
33
|
+
"jest"
|
34
|
+
],
|
35
|
+
"lib": [
|
36
|
+
"DOM"
|
37
|
+
]
|
38
|
+
},
|
39
|
+
"ts-node": {
|
40
|
+
"esm": true,
|
41
|
+
"experimentalSpecifierResolution": true
|
42
|
+
},
|
43
|
+
"include": [
|
44
|
+
"src",
|
45
|
+
"resources",
|
46
|
+
"tests"
|
47
|
+
]
|
48
|
+
}
|