@nzz/q-cli 1.8.2 → 1.9.0
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/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 | 
            +
            }
         |