@squiz/render-runtime-lib 1.64.0 → 1.65.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/lib/index.js CHANGED
@@ -81,10 +81,10 @@ var import_cors = __toESM(require("cors"));
81
81
  var import_compression = __toESM(require("compression"));
82
82
  var import_crypto = require("crypto");
83
83
  var import_helmet = __toESM(require("helmet"));
84
- var import_dx_common_lib5 = require("@squiz/dx-common-lib");
84
+ var import_dx_common_lib6 = require("@squiz/dx-common-lib");
85
85
 
86
86
  // src/webserver/routes/routes.ts
87
- var import_runtime5 = require("@tsoa/runtime");
87
+ var import_runtime6 = require("@tsoa/runtime");
88
88
 
89
89
  // src/webserver/controllers/CoreController.ts
90
90
  var import_tsoa = require("tsoa");
@@ -340,17 +340,157 @@ DefinitionController = __decorateClass([
340
340
  __decorateParam(3, (0, import_inversify2.inject)("ComponentRootUrlResolver"))
341
341
  ], DefinitionController);
342
342
 
343
- // src/webserver/controllers/RenderController.ts
343
+ // src/webserver/controllers/DevelopmentController.ts
344
344
  var import_tsoa3 = require("tsoa");
345
345
  var import_inversify_binding_decorators3 = require("inversify-binding-decorators");
346
346
  var import_inversify3 = require("inversify");
347
+ var import_dx_common_lib3 = require("@squiz/dx-common-lib");
348
+ var DevelopmentController = class extends import_tsoa3.Controller {
349
+ constructor(config, manifestService, componentRunnerService) {
350
+ super();
351
+ this.config = config;
352
+ this.manifestService = manifestService;
353
+ this.componentRunnerService = componentRunnerService;
354
+ }
355
+ async getComponents() {
356
+ if (!this.config.enableDevMode) {
357
+ throw new import_dx_common_lib3.ResourceNotFoundError("Route does not exist.");
358
+ }
359
+ const components = await this.manifestService.listAllComponentManifests();
360
+ return components.map((component) => component.getModel());
361
+ }
362
+ async Manifest(namespace, componentName, version) {
363
+ if (!this.config.enableDevMode) {
364
+ throw new import_dx_common_lib3.ResourceNotFoundError("Route does not exist.");
365
+ }
366
+ const manifest = await this.manifestService.loadManifest(namespace, componentName, version);
367
+ return manifest.getModel();
368
+ }
369
+ async getContentSchema(namespace, componentName, version) {
370
+ if (!this.config.enableDevMode) {
371
+ throw new import_dx_common_lib3.ResourceNotFoundError("Route does not exist.");
372
+ }
373
+ const componentManifest = await this.manifestService.loadManifest(namespace, componentName, version);
374
+ const inputSchemas = componentManifest.getInputSchemas();
375
+ const schemaResult = [];
376
+ inputSchemas.forEach((inputSchema) => {
377
+ if (inputSchema.schema && Object.keys(inputSchema.schema).length) {
378
+ schemaResult.push(inputSchema);
379
+ }
380
+ });
381
+ return schemaResult;
382
+ }
383
+ /* Commenting this out for POC, would like to do something like the following: */
384
+ /* TODO: FEAAS-627 Temporary Preview:
385
+ - Bit crude and should be improved but the method is:
386
+ - A preview is created by post of the temp data (env, header, content etc) to the server and stored in the map bellow
387
+ - Post request returns the id for the map
388
+ - Front end opens the get route in the browser using the id thats returned
389
+
390
+ type TemporaryPreviewInput = {
391
+ componentSet: RuntimeComponentSet;
392
+ headers: Headers;
393
+ // content: ContentItemWebModelForCreate
394
+ };
395
+
396
+ temporaryPreviewResultMap: Map<string, { componentResult: FunctionReturnTypes; headers: Headers }> = new Map();
397
+
398
+ @Post('/temp-preview/:namespace/:componentName/:version/:functionName')
399
+ public async TemporaryPreview(
400
+ @Request() req: ExpressRequest,
401
+ @Path() namespace: string,
402
+ @Path() componentName: string,
403
+ @Path() version: string,
404
+ @Path() functionName: string,
405
+ @Body() requestBody?: TemporaryPreviewInput,
406
+ ) {
407
+ const res = (<any>req).res as ExpressResponse;
408
+ // const contentItem: ContentItem = new ContentItem(requestBody); //FIXME: do something like this
409
+ const rootUrl = parseEnvVarForVar('COMPONENT_RENDER_SERVICE_URL').replace(/\/+$/, '');
410
+ const componentManifest = await this.manifestService.loadManifest(namespace, componentName, version);
411
+ // const renderedOutput = await this.doFunctionRender(renderInput);
412
+
413
+ // Form the input from the request body content
414
+ // const input = await this.getContentFromContentService(request);
415
+ // this.assertInputIsValid(input, componentFunction);
416
+ // const resolvedInput = await resolveFormattedTextNodes(
417
+ // input,
418
+ // componentFunction.input,
419
+ // formattedTextToHtmlStringResolvers,
420
+ // { withJoin: '' },
421
+ // );
422
+ // this.assertRenderInputIsValid(resolvedInput, componentFunction);
423
+
424
+ const result = await this.componentRunnerService.executeComponentFunction({
425
+ dxpApiKey: undefined,
426
+ requestId: 'MOCK_ME',
427
+ args: [],
428
+ functionEntryFilePath: await componentManifest.getComponentFunctionEntryFilePath(
429
+ componentManifest.getComponentFunctionByName(functionName),
430
+ ),
431
+ environment: requestBody.componentSet.environment,
432
+ componentFullName: componentName,
433
+ componentFunction: componentManifest.getComponentFunctionByName(functionName),
434
+ componentRootUrl: rootUrl,
435
+ manifest: componentManifest.getModel(),
436
+ runtimeSet: requestBody.componentSet,
437
+ manifestPath: await componentManifest.getManifestPath(),
438
+ previewKey: undefined,
439
+ queryParameters: undefined,
440
+ });
441
+
442
+ //Set the render and headers into temporary memory
443
+ this.temporaryPreviewResultMap.set(req.id, { componentResult: result, headers: requestBody.headers });
444
+ res.send(req.id);
445
+ }
446
+
447
+ @Get('/temp-preview/:id')
448
+ public async getTemporaryPreviewRender(@Request() req: ExpressRequest, @Path() id: string) {
449
+ const res = (<any>req).res as ExpressResponse;
450
+ const temporaryPreview = this.temporaryPreviewResultMap.get(id);
451
+ if (temporaryPreview === undefined) {
452
+ throw new BadRequestError(`Temporary Preview with id ${id}, does not exist`);
453
+ }
454
+ setHeadersOnExpressResponse(temporaryPreview.headers, res);
455
+ res.send(temporaryPreview.componentResult);
456
+ }
457
+ */
458
+ };
459
+ __decorateClass([
460
+ (0, import_tsoa3.Get)("/all")
461
+ ], DevelopmentController.prototype, "getComponents", 1);
462
+ __decorateClass([
463
+ (0, import_tsoa3.Get)("/manifest/:namespace/:componentName/:version"),
464
+ __decorateParam(0, (0, import_tsoa3.Path)()),
465
+ __decorateParam(1, (0, import_tsoa3.Path)()),
466
+ __decorateParam(2, (0, import_tsoa3.Path)())
467
+ ], DevelopmentController.prototype, "Manifest", 1);
468
+ __decorateClass([
469
+ (0, import_tsoa3.Get)("/schemas/:namespace/:componentName/:version"),
470
+ __decorateParam(0, (0, import_tsoa3.Path)()),
471
+ __decorateParam(1, (0, import_tsoa3.Path)()),
472
+ __decorateParam(2, (0, import_tsoa3.Path)())
473
+ ], DevelopmentController.prototype, "getContentSchema", 1);
474
+ DevelopmentController = __decorateClass([
475
+ (0, import_inversify_binding_decorators3.provide)(DevelopmentController),
476
+ (0, import_tsoa3.Route)("/dev"),
477
+ (0, import_tsoa3.Hidden)(),
478
+ __decorateParam(0, (0, import_inversify3.inject)("Config")),
479
+ __decorateParam(1, (0, import_inversify3.inject)("ManifestService")),
480
+ __decorateParam(2, (0, import_inversify3.inject)("ComponentRunnerService"))
481
+ ], DevelopmentController);
482
+
483
+ // src/webserver/controllers/RenderController.ts
484
+ var import_tsoa4 = require("tsoa");
485
+ var import_inversify_binding_decorators4 = require("inversify-binding-decorators");
486
+ var import_inversify4 = require("inversify");
347
487
  var import_query_string = require("query-string");
348
488
  var import_component_lib = require("@squiz/component-lib");
349
- var import_dx_common_lib3 = require("@squiz/dx-common-lib");
489
+ var import_dx_common_lib4 = require("@squiz/dx-common-lib");
350
490
  var import_api = require("@opentelemetry/api");
351
491
  var UPPERCASE_REGEX = /[A-Z]/;
352
492
  var meter = import_api.metrics.getMeter("render-runtime");
353
- var RenderController = class extends import_tsoa3.Controller {
493
+ var RenderController = class extends import_tsoa4.Controller {
354
494
  constructor(componentSetService, manifestService, componentFunctionService, componentRunnerService, renderInputService, contentItemService, componentPreviewService) {
355
495
  super();
356
496
  this.componentSetService = componentSetService;
@@ -375,7 +515,7 @@ var RenderController = class extends import_tsoa3.Controller {
375
515
  }
376
516
  async getGivenFunctionRendering(expressRequest, namespace, componentName, version, functionName, componentSet, previewKey, contentItemId) {
377
517
  const response = expressRequest.res;
378
- (0, import_dx_common_lib3.assertIsDefined)(response);
518
+ (0, import_dx_common_lib4.assertIsDefined)(response);
379
519
  const { path: path7, query } = expressRequest;
380
520
  if (UPPERCASE_REGEX.test(path7) || componentSet && UPPERCASE_REGEX.test(componentSet)) {
381
521
  const url = (0, import_query_string.stringifyUrl)({
@@ -479,50 +619,50 @@ var RenderController = class extends import_tsoa3.Controller {
479
619
  if (typeof cacheControl !== "string") {
480
620
  cacheControl = void 0;
481
621
  }
482
- response.setHeader("cache-control", (0, import_dx_common_lib3.parseAndSanitiseCacheControlHeader)(cacheControl));
622
+ response.setHeader("cache-control", (0, import_dx_common_lib4.parseAndSanitiseCacheControlHeader)(cacheControl));
483
623
  }
484
624
  };
485
625
  __decorateClass([
486
- (0, import_tsoa3.Get)("/:namespace/:componentName/:version"),
487
- __decorateParam(0, (0, import_tsoa3.Request)()),
488
- __decorateParam(1, (0, import_tsoa3.Path)()),
489
- __decorateParam(2, (0, import_tsoa3.Path)()),
490
- __decorateParam(3, (0, import_tsoa3.Path)()),
491
- __decorateParam(4, (0, import_tsoa3.Query)("_componentSet")),
492
- __decorateParam(5, (0, import_tsoa3.Query)("_previewKey")),
493
- __decorateParam(6, (0, import_tsoa3.Query)("_contentItemId"))
626
+ (0, import_tsoa4.Get)("/:namespace/:componentName/:version"),
627
+ __decorateParam(0, (0, import_tsoa4.Request)()),
628
+ __decorateParam(1, (0, import_tsoa4.Path)()),
629
+ __decorateParam(2, (0, import_tsoa4.Path)()),
630
+ __decorateParam(3, (0, import_tsoa4.Path)()),
631
+ __decorateParam(4, (0, import_tsoa4.Query)("_componentSet")),
632
+ __decorateParam(5, (0, import_tsoa4.Query)("_previewKey")),
633
+ __decorateParam(6, (0, import_tsoa4.Query)("_contentItemId"))
494
634
  ], RenderController.prototype, "getDefaultFunctionRendering", 1);
495
635
  __decorateClass([
496
- (0, import_tsoa3.Get)("/:namespace/:componentName/:version/:functionName"),
497
- __decorateParam(0, (0, import_tsoa3.Request)()),
498
- __decorateParam(1, (0, import_tsoa3.Path)()),
499
- __decorateParam(2, (0, import_tsoa3.Path)()),
500
- __decorateParam(3, (0, import_tsoa3.Path)()),
501
- __decorateParam(4, (0, import_tsoa3.Path)()),
502
- __decorateParam(5, (0, import_tsoa3.Query)("_componentSet")),
503
- __decorateParam(6, (0, import_tsoa3.Query)("_previewKey")),
504
- __decorateParam(7, (0, import_tsoa3.Query)("_contentItemId"))
636
+ (0, import_tsoa4.Get)("/:namespace/:componentName/:version/:functionName"),
637
+ __decorateParam(0, (0, import_tsoa4.Request)()),
638
+ __decorateParam(1, (0, import_tsoa4.Path)()),
639
+ __decorateParam(2, (0, import_tsoa4.Path)()),
640
+ __decorateParam(3, (0, import_tsoa4.Path)()),
641
+ __decorateParam(4, (0, import_tsoa4.Path)()),
642
+ __decorateParam(5, (0, import_tsoa4.Query)("_componentSet")),
643
+ __decorateParam(6, (0, import_tsoa4.Query)("_previewKey")),
644
+ __decorateParam(7, (0, import_tsoa4.Query)("_contentItemId"))
505
645
  ], RenderController.prototype, "getGivenFunctionRendering", 1);
506
646
  RenderController = __decorateClass([
507
- (0, import_inversify_binding_decorators3.provide)(RenderController),
508
- (0, import_tsoa3.Route)("/r"),
509
- __decorateParam(0, (0, import_inversify3.inject)("ComponentSetService")),
510
- __decorateParam(1, (0, import_inversify3.inject)("ManifestService")),
511
- __decorateParam(2, (0, import_inversify3.inject)("ComponentFunctionService")),
512
- __decorateParam(3, (0, import_inversify3.inject)("ComponentRunnerService")),
513
- __decorateParam(4, (0, import_inversify3.inject)("RenderInputService")),
514
- __decorateParam(5, (0, import_inversify3.inject)("ContentItemService")),
515
- __decorateParam(6, (0, import_inversify3.inject)("ComponentPreviewService"))
647
+ (0, import_inversify_binding_decorators4.provide)(RenderController),
648
+ (0, import_tsoa4.Route)("/r"),
649
+ __decorateParam(0, (0, import_inversify4.inject)("ComponentSetService")),
650
+ __decorateParam(1, (0, import_inversify4.inject)("ManifestService")),
651
+ __decorateParam(2, (0, import_inversify4.inject)("ComponentFunctionService")),
652
+ __decorateParam(3, (0, import_inversify4.inject)("ComponentRunnerService")),
653
+ __decorateParam(4, (0, import_inversify4.inject)("RenderInputService")),
654
+ __decorateParam(5, (0, import_inversify4.inject)("ContentItemService")),
655
+ __decorateParam(6, (0, import_inversify4.inject)("ComponentPreviewService"))
516
656
  ], RenderController);
517
657
 
518
658
  // src/webserver/controllers/StaticController.ts
519
- var import_tsoa4 = require("tsoa");
520
- var import_inversify_binding_decorators4 = require("inversify-binding-decorators");
521
- var import_dx_common_lib4 = require("@squiz/dx-common-lib");
659
+ var import_tsoa5 = require("tsoa");
660
+ var import_inversify_binding_decorators5 = require("inversify-binding-decorators");
661
+ var import_dx_common_lib5 = require("@squiz/dx-common-lib");
522
662
  var import_path = __toESM(require("path"));
523
- var import_inversify4 = require("inversify");
663
+ var import_inversify5 = require("inversify");
524
664
  var import_assert = __toESM(require("assert"));
525
- var StaticController = class extends import_tsoa4.Controller {
665
+ var StaticController = class extends import_tsoa5.Controller {
526
666
  constructor(manifestService, componentSetService, componentFunctionService) {
527
667
  super();
528
668
  this.manifestService = manifestService;
@@ -531,7 +671,7 @@ var StaticController = class extends import_tsoa4.Controller {
531
671
  }
532
672
  async getPreview(namespace, componentName, version, staticFile, req, _componentSet, _previewKey) {
533
673
  if (_componentSet !== void 0 && _previewKey !== void 0) {
534
- throw new import_dx_common_lib4.BadRequestError("You can not have both _componentSet and _previewKey");
674
+ throw new import_dx_common_lib5.BadRequestError("You can not have both _componentSet and _previewKey");
535
675
  }
536
676
  const manifest = await this.manifestService.loadManifest(namespace, componentName, version);
537
677
  const manifestModel = manifest.getModel();
@@ -560,7 +700,7 @@ var StaticController = class extends import_tsoa4.Controller {
560
700
  if (req.next) {
561
701
  if (e?.code == "ENOENT") {
562
702
  req.next(
563
- new import_dx_common_lib4.ResourceNotFoundError(
703
+ new import_dx_common_lib5.ResourceNotFoundError(
564
704
  `could not find ${e?.path.substr(
565
705
  e?.path.indexOf(componentStaticFileRoot) + componentStaticFileRoot.length
566
706
  )}`
@@ -579,20 +719,20 @@ var StaticController = class extends import_tsoa4.Controller {
579
719
  });
580
720
  });
581
721
  } else {
582
- throw new import_dx_common_lib4.ResourceNotFoundError(`${componentName} ${version} doesn't expose any static resources`);
722
+ throw new import_dx_common_lib5.ResourceNotFoundError(`${componentName} ${version} doesn't expose any static resources`);
583
723
  }
584
724
  }
585
725
  setResponseHeaders(headers, response) {
586
726
  setHeadersOnExpressResponse(headers, response);
587
727
  let cacheControl = response.getHeader("cache-control");
588
728
  if (typeof cacheControl != "string") {
589
- cacheControl = import_dx_common_lib4.DEFAULT_CACHE_CONTROL_HEADER;
729
+ cacheControl = import_dx_common_lib5.DEFAULT_CACHE_CONTROL_HEADER;
590
730
  }
591
- let cacheControlObj = (0, import_dx_common_lib4.parseCacheControl)(cacheControl);
592
- cacheControlObj = (0, import_dx_common_lib4.applyDefaultRulesToCacheControlObject)(cacheControlObj);
731
+ let cacheControlObj = (0, import_dx_common_lib5.parseCacheControl)(cacheControl);
732
+ cacheControlObj = (0, import_dx_common_lib5.applyDefaultRulesToCacheControlObject)(cacheControlObj);
593
733
  cacheControlObj.immutable = true;
594
734
  cacheControlObj["max-age"] = 604800;
595
- response.setHeader("cache-control", (0, import_dx_common_lib4.cacheControlToString)(cacheControlObj));
735
+ response.setHeader("cache-control", (0, import_dx_common_lib5.cacheControlToString)(cacheControlObj));
596
736
  }
597
737
  async getHeadersForInputType(_componentSet, _previewKey, manifest) {
598
738
  if (_componentSet) {
@@ -605,13 +745,13 @@ var StaticController = class extends import_tsoa4.Controller {
605
745
  const headers = functionPreview?.headers ? functionPreview.headers : {};
606
746
  return headers;
607
747
  }
608
- throw new import_dx_common_lib4.BadRequestError(`neither componentSet or previewKey set`);
748
+ throw new import_dx_common_lib5.BadRequestError(`neither componentSet or previewKey set`);
609
749
  }
610
750
  async getValidatedSet(_componentSet, manifest) {
611
751
  const set = await this.componentSetService.getComponentSet(_componentSet);
612
752
  const isCompVersionInSet = this.componentSetService.componentVersionInSet(manifest, set.webPath);
613
753
  if (!isCompVersionInSet) {
614
- throw new import_dx_common_lib4.ResourceNotFoundError(`${manifest.getName()} ${manifest.getVersion()} not in set ${set.webPath}`);
754
+ throw new import_dx_common_lib5.ResourceNotFoundError(`${manifest.getName()} ${manifest.getVersion()} not in set ${set.webPath}`);
615
755
  }
616
756
  return set;
617
757
  }
@@ -630,33 +770,34 @@ var StaticController = class extends import_tsoa4.Controller {
630
770
  }
631
771
  };
632
772
  __decorateClass([
633
- (0, import_tsoa4.Get)("/:namespace/:componentName/:version/:staticFile*"),
634
- __decorateParam(0, (0, import_tsoa4.Path)()),
635
- __decorateParam(1, (0, import_tsoa4.Path)()),
636
- __decorateParam(2, (0, import_tsoa4.Path)()),
637
- __decorateParam(3, (0, import_tsoa4.Path)()),
638
- __decorateParam(4, (0, import_tsoa4.Request)()),
639
- __decorateParam(5, (0, import_tsoa4.Query)()),
640
- __decorateParam(6, (0, import_tsoa4.Query)())
773
+ (0, import_tsoa5.Get)("/:namespace/:componentName/:version/:staticFile*"),
774
+ __decorateParam(0, (0, import_tsoa5.Path)()),
775
+ __decorateParam(1, (0, import_tsoa5.Path)()),
776
+ __decorateParam(2, (0, import_tsoa5.Path)()),
777
+ __decorateParam(3, (0, import_tsoa5.Path)()),
778
+ __decorateParam(4, (0, import_tsoa5.Request)()),
779
+ __decorateParam(5, (0, import_tsoa5.Query)()),
780
+ __decorateParam(6, (0, import_tsoa5.Query)())
641
781
  ], StaticController.prototype, "getPreview", 1);
642
782
  StaticController = __decorateClass([
643
- (0, import_inversify_binding_decorators4.provide)(StaticController),
644
- (0, import_tsoa4.Route)("/s"),
645
- __decorateParam(0, (0, import_inversify4.inject)("ManifestService")),
646
- __decorateParam(1, (0, import_inversify4.inject)("ComponentSetService")),
647
- __decorateParam(2, (0, import_inversify4.inject)("ComponentFunctionService"))
783
+ (0, import_inversify_binding_decorators5.provide)(StaticController),
784
+ (0, import_tsoa5.Route)("/s"),
785
+ __decorateParam(0, (0, import_inversify5.inject)("ManifestService")),
786
+ __decorateParam(1, (0, import_inversify5.inject)("ComponentSetService")),
787
+ __decorateParam(2, (0, import_inversify5.inject)("ComponentFunctionService"))
648
788
  ], StaticController);
649
789
 
650
790
  // src/ioc.ts
651
- var import_inversify5 = require("inversify");
652
- var import_inversify_binding_decorators5 = require("inversify-binding-decorators");
653
- var import_tsoa5 = require("tsoa");
654
- (0, import_inversify5.decorate)((0, import_inversify5.injectable)(), import_tsoa5.Controller);
791
+ var import_inversify6 = require("inversify");
792
+ var import_inversify_binding_decorators6 = require("inversify-binding-decorators");
793
+ var import_tsoa6 = require("tsoa");
794
+ (0, import_inversify6.decorate)((0, import_inversify6.injectable)(), import_tsoa6.Controller);
655
795
  var iocContainer;
656
- var initIocContainer = (services) => {
657
- const container = new import_inversify5.Container();
658
- container.load((0, import_inversify_binding_decorators5.buildProviderModule)());
659
- container.bind("sandbox").toConstantValue(services.sandbox);
796
+ var initIocContainer = (services, config) => {
797
+ const container = new import_inversify6.Container();
798
+ container.load((0, import_inversify_binding_decorators6.buildProviderModule)());
799
+ container.bind("Config").toConstantValue(config);
800
+ container.bind("Sandbox").toConstantValue(services.sandbox);
660
801
  container.bind("Logger").toConstantValue(services.logger);
661
802
  container.bind("ComponentFunctionService").toConstantValue(services.componentFunctionService);
662
803
  container.bind("ComponentRunnerService").toConstantValue(services.componentRunnerService);
@@ -1106,15 +1247,25 @@ var models = {
1106
1247
  "queryParameters": { "dataType": "nestedObjectLiteral", "nestedProperties": {}, "additionalProperties": { "ref": "QueryParameterValueType" } }
1107
1248
  },
1108
1249
  "additionalProperties": { "dataType": "any" }
1250
+ },
1251
+ // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
1252
+ "ComponentManifest": {
1253
+ "dataType": "refAlias",
1254
+ "type": { "ref": "MANIFEST_MODELS.v1.ComponentManifest", "validators": {} }
1255
+ },
1256
+ // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
1257
+ "ComponentSchema": {
1258
+ "dataType": "refAlias",
1259
+ "type": { "dataType": "nestedObjectLiteral", "nestedProperties": { "schema": { "dataType": "object", "required": true }, "name": { "dataType": "string", "required": true } }, "validators": {} }
1109
1260
  }
1110
1261
  // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
1111
1262
  };
1112
- var validationService = new import_runtime5.ValidationService(models);
1263
+ var validationService = new import_runtime6.ValidationService(models);
1113
1264
  function RegisterRoutes(app) {
1114
1265
  app.get(
1115
1266
  "/schemas/:version.json",
1116
- ...(0, import_runtime5.fetchMiddlewares)(CoreController),
1117
- ...(0, import_runtime5.fetchMiddlewares)(CoreController.prototype.getSchemaVersion),
1267
+ ...(0, import_runtime6.fetchMiddlewares)(CoreController),
1268
+ ...(0, import_runtime6.fetchMiddlewares)(CoreController.prototype.getSchemaVersion),
1118
1269
  async function CoreController_getSchemaVersion(request, response, next) {
1119
1270
  const args = {
1120
1271
  version: { "in": "path", "name": "version", "required": true, "dataType": "string" }
@@ -1136,8 +1287,8 @@ function RegisterRoutes(app) {
1136
1287
  );
1137
1288
  app.get(
1138
1289
  "/health",
1139
- ...(0, import_runtime5.fetchMiddlewares)(CoreController),
1140
- ...(0, import_runtime5.fetchMiddlewares)(CoreController.prototype.getHealthInfo),
1290
+ ...(0, import_runtime6.fetchMiddlewares)(CoreController),
1291
+ ...(0, import_runtime6.fetchMiddlewares)(CoreController.prototype.getHealthInfo),
1141
1292
  async function CoreController_getHealthInfo(request, response, next) {
1142
1293
  const args = {};
1143
1294
  let validatedArgs = [];
@@ -1157,8 +1308,8 @@ function RegisterRoutes(app) {
1157
1308
  );
1158
1309
  app.get(
1159
1310
  "/",
1160
- ...(0, import_runtime5.fetchMiddlewares)(CoreController),
1161
- ...(0, import_runtime5.fetchMiddlewares)(CoreController.prototype.getComponents),
1311
+ ...(0, import_runtime6.fetchMiddlewares)(CoreController),
1312
+ ...(0, import_runtime6.fetchMiddlewares)(CoreController.prototype.getComponents),
1162
1313
  async function CoreController_getComponents(request, response, next) {
1163
1314
  const args = {
1164
1315
  req: { "in": "request", "name": "req", "required": true, "dataType": "object" }
@@ -1180,8 +1331,8 @@ function RegisterRoutes(app) {
1180
1331
  );
1181
1332
  app.get(
1182
1333
  "/d/:namespace/:componentName/:version/manifest.json",
1183
- ...(0, import_runtime5.fetchMiddlewares)(DefinitionController),
1184
- ...(0, import_runtime5.fetchMiddlewares)(DefinitionController.prototype.getComponentVersionManifest),
1334
+ ...(0, import_runtime6.fetchMiddlewares)(DefinitionController),
1335
+ ...(0, import_runtime6.fetchMiddlewares)(DefinitionController.prototype.getComponentVersionManifest),
1185
1336
  async function DefinitionController_getComponentVersionManifest(request, response, next) {
1186
1337
  const args = {
1187
1338
  namespace: { "in": "path", "name": "namespace", "required": true, "dataType": "string" },
@@ -1208,8 +1359,8 @@ function RegisterRoutes(app) {
1208
1359
  );
1209
1360
  app.get(
1210
1361
  "/d/:namespace/:componentName/:version",
1211
- ...(0, import_runtime5.fetchMiddlewares)(DefinitionController),
1212
- ...(0, import_runtime5.fetchMiddlewares)(DefinitionController.prototype.getDefaultFunctionDefinition),
1362
+ ...(0, import_runtime6.fetchMiddlewares)(DefinitionController),
1363
+ ...(0, import_runtime6.fetchMiddlewares)(DefinitionController.prototype.getDefaultFunctionDefinition),
1213
1364
  async function DefinitionController_getDefaultFunctionDefinition(request, response, next) {
1214
1365
  const args = {
1215
1366
  namespace: { "in": "path", "name": "namespace", "required": true, "dataType": "string" },
@@ -1236,8 +1387,8 @@ function RegisterRoutes(app) {
1236
1387
  );
1237
1388
  app.get(
1238
1389
  "/d/:namespace/:componentName/:version/:functionName",
1239
- ...(0, import_runtime5.fetchMiddlewares)(DefinitionController),
1240
- ...(0, import_runtime5.fetchMiddlewares)(DefinitionController.prototype.getGivenFunctionDefinition),
1390
+ ...(0, import_runtime6.fetchMiddlewares)(DefinitionController),
1391
+ ...(0, import_runtime6.fetchMiddlewares)(DefinitionController.prototype.getGivenFunctionDefinition),
1241
1392
  async function DefinitionController_getGivenFunctionDefinition(request, response, next) {
1242
1393
  const args = {
1243
1394
  namespace: { "in": "path", "name": "namespace", "required": true, "dataType": "string" },
@@ -1263,10 +1414,81 @@ function RegisterRoutes(app) {
1263
1414
  }
1264
1415
  }
1265
1416
  );
1417
+ app.get(
1418
+ "/dev/all",
1419
+ ...(0, import_runtime6.fetchMiddlewares)(DevelopmentController),
1420
+ ...(0, import_runtime6.fetchMiddlewares)(DevelopmentController.prototype.getComponents),
1421
+ async function DevelopmentController_getComponents(request, response, next) {
1422
+ const args = {};
1423
+ let validatedArgs = [];
1424
+ try {
1425
+ validatedArgs = getValidatedArgs(args, request, response);
1426
+ const container = typeof iocContainer === "function" ? iocContainer(request) : iocContainer;
1427
+ const controller = await container.get(DevelopmentController);
1428
+ if (typeof controller["setStatus"] === "function") {
1429
+ controller.setStatus(void 0);
1430
+ }
1431
+ const promise = controller.getComponents.apply(controller, validatedArgs);
1432
+ promiseHandler(controller, promise, response, void 0, next);
1433
+ } catch (err) {
1434
+ return next(err);
1435
+ }
1436
+ }
1437
+ );
1438
+ app.get(
1439
+ "/dev/manifest/:namespace/:componentName/:version",
1440
+ ...(0, import_runtime6.fetchMiddlewares)(DevelopmentController),
1441
+ ...(0, import_runtime6.fetchMiddlewares)(DevelopmentController.prototype.Manifest),
1442
+ async function DevelopmentController_Manifest(request, response, next) {
1443
+ const args = {
1444
+ namespace: { "in": "path", "name": "namespace", "required": true, "dataType": "string" },
1445
+ componentName: { "in": "path", "name": "componentName", "required": true, "dataType": "string" },
1446
+ version: { "in": "path", "name": "version", "required": true, "dataType": "string" }
1447
+ };
1448
+ let validatedArgs = [];
1449
+ try {
1450
+ validatedArgs = getValidatedArgs(args, request, response);
1451
+ const container = typeof iocContainer === "function" ? iocContainer(request) : iocContainer;
1452
+ const controller = await container.get(DevelopmentController);
1453
+ if (typeof controller["setStatus"] === "function") {
1454
+ controller.setStatus(void 0);
1455
+ }
1456
+ const promise = controller.Manifest.apply(controller, validatedArgs);
1457
+ promiseHandler(controller, promise, response, void 0, next);
1458
+ } catch (err) {
1459
+ return next(err);
1460
+ }
1461
+ }
1462
+ );
1463
+ app.get(
1464
+ "/dev/schemas/:namespace/:componentName/:version",
1465
+ ...(0, import_runtime6.fetchMiddlewares)(DevelopmentController),
1466
+ ...(0, import_runtime6.fetchMiddlewares)(DevelopmentController.prototype.getContentSchema),
1467
+ async function DevelopmentController_getContentSchema(request, response, next) {
1468
+ const args = {
1469
+ namespace: { "in": "path", "name": "namespace", "required": true, "dataType": "string" },
1470
+ componentName: { "in": "path", "name": "componentName", "required": true, "dataType": "string" },
1471
+ version: { "in": "path", "name": "version", "required": true, "dataType": "string" }
1472
+ };
1473
+ let validatedArgs = [];
1474
+ try {
1475
+ validatedArgs = getValidatedArgs(args, request, response);
1476
+ const container = typeof iocContainer === "function" ? iocContainer(request) : iocContainer;
1477
+ const controller = await container.get(DevelopmentController);
1478
+ if (typeof controller["setStatus"] === "function") {
1479
+ controller.setStatus(void 0);
1480
+ }
1481
+ const promise = controller.getContentSchema.apply(controller, validatedArgs);
1482
+ promiseHandler(controller, promise, response, void 0, next);
1483
+ } catch (err) {
1484
+ return next(err);
1485
+ }
1486
+ }
1487
+ );
1266
1488
  app.get(
1267
1489
  "/r/:namespace/:componentName/:version",
1268
- ...(0, import_runtime5.fetchMiddlewares)(RenderController),
1269
- ...(0, import_runtime5.fetchMiddlewares)(RenderController.prototype.getDefaultFunctionRendering),
1490
+ ...(0, import_runtime6.fetchMiddlewares)(RenderController),
1491
+ ...(0, import_runtime6.fetchMiddlewares)(RenderController.prototype.getDefaultFunctionRendering),
1270
1492
  async function RenderController_getDefaultFunctionRendering(request, response, next) {
1271
1493
  const args = {
1272
1494
  expressRequest: { "in": "request", "name": "expressRequest", "required": true, "dataType": "object" },
@@ -1294,8 +1516,8 @@ function RegisterRoutes(app) {
1294
1516
  );
1295
1517
  app.get(
1296
1518
  "/r/:namespace/:componentName/:version/:functionName",
1297
- ...(0, import_runtime5.fetchMiddlewares)(RenderController),
1298
- ...(0, import_runtime5.fetchMiddlewares)(RenderController.prototype.getGivenFunctionRendering),
1519
+ ...(0, import_runtime6.fetchMiddlewares)(RenderController),
1520
+ ...(0, import_runtime6.fetchMiddlewares)(RenderController.prototype.getGivenFunctionRendering),
1299
1521
  async function RenderController_getGivenFunctionRendering(request, response, next) {
1300
1522
  const args = {
1301
1523
  expressRequest: { "in": "request", "name": "expressRequest", "required": true, "dataType": "object" },
@@ -1324,8 +1546,8 @@ function RegisterRoutes(app) {
1324
1546
  );
1325
1547
  app.get(
1326
1548
  "/s/:namespace/:componentName/:version/:staticFile*",
1327
- ...(0, import_runtime5.fetchMiddlewares)(StaticController),
1328
- ...(0, import_runtime5.fetchMiddlewares)(StaticController.prototype.getPreview),
1549
+ ...(0, import_runtime6.fetchMiddlewares)(StaticController),
1550
+ ...(0, import_runtime6.fetchMiddlewares)(StaticController.prototype.getPreview),
1329
1551
  async function StaticController_getPreview(request, response, next) {
1330
1552
  const args = {
1331
1553
  namespace: { "in": "path", "name": "namespace", "required": true, "dataType": "string" },
@@ -1419,7 +1641,7 @@ function RegisterRoutes(app) {
1419
1641
  }
1420
1642
  });
1421
1643
  if (Object.keys(fieldErrors).length > 0) {
1422
- throw new import_runtime5.ValidateError(fieldErrors, "");
1644
+ throw new import_runtime6.ValidateError(fieldErrors, "");
1423
1645
  }
1424
1646
  return values;
1425
1647
  }
@@ -1428,8 +1650,8 @@ function RegisterRoutes(app) {
1428
1650
  // src/webserver/app.ts
1429
1651
  var import_path2 = __toESM(require("path"));
1430
1652
  var import_swagger_ui_express = __toESM(require("swagger-ui-express"));
1431
- function setupApp(services) {
1432
- initIocContainer(services);
1653
+ function setupApp(services, config = {}) {
1654
+ initIocContainer(services, config);
1433
1655
  const app = (0, import_express.default)();
1434
1656
  app.request.services = services;
1435
1657
  app.options("*", (0, import_cors.default)({ credentials: true }));
@@ -1466,6 +1688,11 @@ function setupApp(services) {
1466
1688
  next();
1467
1689
  });
1468
1690
  app.use((req, res, next) => {
1691
+ req.accepts("json");
1692
+ if (["POST", "PUT", "PATCH"].includes(req.method) && req.header("content-type") !== "application/json") {
1693
+ next(new import_dx_common_lib6.BadRequestError("content-type must be application/json"));
1694
+ return;
1695
+ }
1469
1696
  const id = (0, import_crypto.randomUUID)();
1470
1697
  req.log = services.logger.child({ req_id: id, area: "application", path: req.path });
1471
1698
  req.id = id;
@@ -1484,7 +1711,7 @@ function setupApp(services) {
1484
1711
  })
1485
1712
  );
1486
1713
  RegisterRoutes(app);
1487
- app.use(import_dx_common_lib5.errorMiddleware);
1714
+ app.use(import_dx_common_lib6.errorMiddleware);
1488
1715
  return app;
1489
1716
  }
1490
1717
 
@@ -1495,7 +1722,7 @@ var import_component_lib3 = require("@squiz/component-lib");
1495
1722
  var import_path3 = __toESM(require("path"));
1496
1723
  var import_api2 = require("@opentelemetry/api");
1497
1724
  var import_component_lib2 = require("@squiz/component-lib");
1498
- var import_dx_common_lib6 = require("@squiz/dx-common-lib");
1725
+ var import_dx_common_lib7 = require("@squiz/dx-common-lib");
1499
1726
 
1500
1727
  // src/component-runner/ExecuteComponentTask.ts
1501
1728
  var isJobTask = (task) => {
@@ -1565,29 +1792,7 @@ var ComponentRunnerServiceWithWorkers = class {
1565
1792
  });
1566
1793
  return result;
1567
1794
  } catch (e) {
1568
- if (e instanceof import_dx_common_lib6.TimeoutError) {
1569
- const message = `function ${task.componentFunction.name} of component ${task.componentFullName} ${task.manifest.version} ` + WORKER_TIMEOUT_ERROR_MESSAGE;
1570
- await this.componentLogger.error(message, task.requestId).catch((err) => this.logger.error(err));
1571
- throw new import_component_lib2.ComponentError(
1572
- task.requestId,
1573
- new Error(message),
1574
- task.componentFunction.name,
1575
- task.componentFullName,
1576
- task.manifest.version,
1577
- task.runtimeSet.webPath
1578
- );
1579
- } else {
1580
- const componentError = new import_component_lib2.ComponentError(
1581
- task.requestId,
1582
- e,
1583
- task.componentFunction.name,
1584
- task.componentFullName,
1585
- task.manifest.version,
1586
- task.runtimeSet.webPath
1587
- );
1588
- await this.componentLogger.error(componentError.message, task.requestId).catch((err) => this.logger.error(err));
1589
- throw componentError;
1590
- }
1795
+ return await this.handleComponentExecutionError(e, task);
1591
1796
  } finally {
1592
1797
  await this.componentLogger.flush().catch((err) => this.logger.error(err));
1593
1798
  span.end();
@@ -1600,7 +1805,7 @@ var ComponentRunnerServiceWithWorkers = class {
1600
1805
  const result = await this.sandbox.execute(task);
1601
1806
  return result;
1602
1807
  } catch (e) {
1603
- if (e instanceof import_dx_common_lib6.TimeoutError) {
1808
+ if (e instanceof import_dx_common_lib7.TimeoutError) {
1604
1809
  const message = `function ${task.jobFunction.name} of job ${task.jobFullName} ${task.manifest.version} ` + WORKER_TIMEOUT_ERROR_MESSAGE;
1605
1810
  await this.componentLogger.error(message, task.requestId).catch((err) => this.logger.error(err));
1606
1811
  throw new import_component_lib2.JobError(task.requestId, e, task.jobFunction.name, task.jobFullName, task.manifest.version);
@@ -1625,6 +1830,24 @@ var ComponentRunnerServiceWithWorkers = class {
1625
1830
  async healthCheck() {
1626
1831
  return this.sandbox.health();
1627
1832
  }
1833
+ async handleComponentExecutionError(e, task) {
1834
+ const componentError = new import_component_lib2.ComponentError(
1835
+ task.requestId,
1836
+ e,
1837
+ task.componentFunction.name,
1838
+ task.componentFullName,
1839
+ task.manifest.version,
1840
+ task.runtimeSet.webPath
1841
+ );
1842
+ if (e instanceof import_dx_common_lib7.TimeoutError) {
1843
+ componentError.message = this.constructTimeoutErrorMessage(e, task);
1844
+ }
1845
+ await this.componentLogger.error(componentError.message, task.requestId).catch((err) => this.logger.error(err));
1846
+ throw componentError;
1847
+ }
1848
+ constructTimeoutErrorMessage(e, task) {
1849
+ return `function ${task.componentFunction.name} of component ${task.componentFullName} ${task.manifest.version} ` + WORKER_TIMEOUT_ERROR_MESSAGE;
1850
+ }
1628
1851
  };
1629
1852
 
1630
1853
  // src/PreviewComponentService.ts
@@ -1693,7 +1916,7 @@ function cssIncludeTagHtml(file) {
1693
1916
  }
1694
1917
 
1695
1918
  // src/PreviewComponentService.ts
1696
- var import_dx_common_lib7 = require("@squiz/dx-common-lib");
1919
+ var import_dx_common_lib8 = require("@squiz/dx-common-lib");
1697
1920
  var PREVIEW_COMPONENT_SET = "unknown";
1698
1921
  var ComponentPreviewService = class {
1699
1922
  async dressRenderedOutputForPreview(componentManifest, functionDefinition, previewKey, componentOutput) {
@@ -1713,7 +1936,7 @@ var ComponentPreviewService = class {
1713
1936
  async embedComponentIntoWrapper(componentDirectory, wrapper, functionDefinition, componentOutput) {
1714
1937
  const wrapperFilePath = import_path4.default.resolve(componentDirectory, wrapper.path);
1715
1938
  if (await (0, import_fs_extra.pathExists)(wrapperFilePath) === false) {
1716
- throw new import_dx_common_lib7.BadRequestError(`Preview wrapper file "${wrapper.path}" does not exist`);
1939
+ throw new import_dx_common_lib8.BadRequestError(`Preview wrapper file "${wrapper.path}" does not exist`);
1717
1940
  }
1718
1941
  const wrapperContent = await import_promises.default.readFile(wrapperFilePath, {
1719
1942
  encoding: "utf-8"
@@ -1729,17 +1952,17 @@ var ComponentPreviewService = class {
1729
1952
  case "json":
1730
1953
  return componentOutput;
1731
1954
  default:
1732
- return (0, import_dx_common_lib7.never)(type);
1955
+ return (0, import_dx_common_lib8.never)(type);
1733
1956
  }
1734
1957
  }
1735
1958
  };
1736
1959
 
1737
1960
  // src/test/helpers/stack.ts
1738
- var import_dx_common_lib9 = require("@squiz/dx-common-lib");
1961
+ var import_dx_common_lib10 = require("@squiz/dx-common-lib");
1739
1962
 
1740
1963
  // src/RenderInputService.ts
1741
1964
  var import_strict = __toESM(require("assert/strict"));
1742
- var import_dx_common_lib8 = require("@squiz/dx-common-lib");
1965
+ var import_dx_common_lib9 = require("@squiz/dx-common-lib");
1743
1966
  var import_formatted_text_lib = require("@squiz/formatted-text-lib");
1744
1967
  var import_dx_json_schema_lib2 = require("@squiz/dx-json-schema-lib");
1745
1968
  var import_api3 = require("@opentelemetry/api");
@@ -1786,7 +2009,7 @@ var RenderInputService = class {
1786
2009
  case "preview":
1787
2010
  return this.getPreviewRenderInput(request, manifest);
1788
2011
  default:
1789
- return (0, import_dx_common_lib8.never)(renderType);
2012
+ return (0, import_dx_common_lib9.never)(renderType);
1790
2013
  }
1791
2014
  } finally {
1792
2015
  span.end();
@@ -1797,10 +2020,10 @@ var RenderInputService = class {
1797
2020
  getRenderType(request) {
1798
2021
  if (request.previewKey) {
1799
2022
  if (request.contentItemId) {
1800
- throw new import_dx_common_lib8.BadRequestError("You cannot provide a previewKey and a ContentId as input");
2023
+ throw new import_dx_common_lib9.BadRequestError("You cannot provide a previewKey and a ContentId as input");
1801
2024
  }
1802
2025
  if (request.componentSet) {
1803
- throw new import_dx_common_lib8.BadRequestError("You cannot provide a previewKey and a componentSet as input");
2026
+ throw new import_dx_common_lib9.BadRequestError("You cannot provide a previewKey and a componentSet as input");
1804
2027
  }
1805
2028
  return "preview";
1806
2029
  }
@@ -1810,7 +2033,7 @@ var RenderInputService = class {
1810
2033
  }
1811
2034
  return "set-without-content-item";
1812
2035
  }
1813
- throw new import_dx_common_lib8.BadRequestError("invalid input, you must provide either a previewKey or a component set");
2036
+ throw new import_dx_common_lib9.BadRequestError("invalid input, you must provide either a previewKey or a component set");
1814
2037
  }
1815
2038
  async getContentItemAndSetInput(request, manifest) {
1816
2039
  await this.assertComponentVersionInSet(request, manifest);
@@ -1932,13 +2155,13 @@ var RenderInputService = class {
1932
2155
  const queryParameters = {};
1933
2156
  for (const parameter of Object.keys(componentFunction.queryParameters)) {
1934
2157
  if (componentFunction.queryParameters[parameter].required && request.expressRequest.query[parameter] === void 0) {
1935
- throw new import_dx_common_lib8.BadRequestError(`Required query parameter '${parameter}' is missing`);
2158
+ throw new import_dx_common_lib9.BadRequestError(`Required query parameter '${parameter}' is missing`);
1936
2159
  }
1937
2160
  if (request.expressRequest.query[parameter] === void 0) {
1938
2161
  continue;
1939
2162
  }
1940
2163
  if (typeof request.expressRequest.query[parameter] !== "string") {
1941
- throw new import_dx_common_lib8.BadRequestError(`Value for query parameter '${parameter}' must be a string`);
2164
+ throw new import_dx_common_lib9.BadRequestError(`Value for query parameter '${parameter}' must be a string`);
1942
2165
  }
1943
2166
  queryParameters[parameter] = request.expressRequest.query[parameter];
1944
2167
  }
@@ -1957,7 +2180,7 @@ var RenderInputService = class {
1957
2180
  this.componentFunctionService.assertInputValidForComponentFunction(input, componentFunction);
1958
2181
  } catch (e) {
1959
2182
  if (e instanceof Error) {
1960
- const error = new import_dx_common_lib8.BadRequestError(e.message);
2183
+ const error = new import_dx_common_lib9.BadRequestError(e.message);
1961
2184
  error.stack = e.stack;
1962
2185
  throw error;
1963
2186
  }
@@ -1969,7 +2192,7 @@ var RenderInputService = class {
1969
2192
  this.componentFunctionService.assertRenderInputValidForComponentFunction(input, componentFunction);
1970
2193
  } catch (e) {
1971
2194
  if (e instanceof Error) {
1972
- const error = new import_dx_common_lib8.BadRequestError(e.message);
2195
+ const error = new import_dx_common_lib9.BadRequestError(e.message);
1973
2196
  error.stack = e.stack;
1974
2197
  throw error;
1975
2198
  }
@@ -1981,7 +2204,7 @@ var RenderInputService = class {
1981
2204
  const set = await this.componentSetService.getComponentSet(request.componentSet);
1982
2205
  const isCompVersionInSet = await this.componentSetService.componentVersionInSet(manifest, set.webPath);
1983
2206
  if (!isCompVersionInSet) {
1984
- throw new import_dx_common_lib8.ResourceNotFoundError(`${request.componentName} ${request.version} not in set ${set.webPath}`);
2207
+ throw new import_dx_common_lib9.ResourceNotFoundError(`${request.componentName} ${request.version} not in set ${set.webPath}`);
1985
2208
  }
1986
2209
  }
1987
2210
  async getInputForPreview(request, manifest) {
@@ -2010,14 +2233,14 @@ var RenderInputService = class {
2010
2233
  }
2011
2234
  async getContentFromContentService(request) {
2012
2235
  if (!this.contentItemService) {
2013
- throw new import_dx_common_lib8.InternalServerError("Content Item service is not configured");
2236
+ throw new import_dx_common_lib9.InternalServerError("Content Item service is not configured");
2014
2237
  }
2015
2238
  if (!request.contentItemId) {
2016
- throw new import_dx_common_lib8.InternalServerError("Content Item id must be defined");
2239
+ throw new import_dx_common_lib9.InternalServerError("Content Item id must be defined");
2017
2240
  }
2018
2241
  const contentInput = await this.contentItemService.getContentItem(request.contentItemId, this.getDxpApiKey());
2019
2242
  if (!contentInput) {
2020
- throw new import_dx_common_lib8.ResourceNotFoundError(`Cannot find content item with ID '${request.contentItemId}'`);
2243
+ throw new import_dx_common_lib9.ResourceNotFoundError(`Cannot find content item with ID '${request.contentItemId}'`);
2021
2244
  }
2022
2245
  return contentInput;
2023
2246
  }
@@ -2057,10 +2280,10 @@ function getTestComponentFolder() {
2057
2280
  const rootDir = (0, import_child_process.execSync)("git rev-parse --show-toplevel", { encoding: "utf-8" }).replace(/\n$/, "");
2058
2281
  return import_path5.default.resolve(rootDir, "test-components");
2059
2282
  }
2060
- function setupTestApp(services = {}) {
2283
+ function setupTestApp(services = {}, config = {}) {
2061
2284
  const dataMount = getTestComponentFolder();
2062
2285
  const componentRootUrlResolver = () => "http://localhost:3000";
2063
- const apiKeyService = new import_dx_common_lib9.DevelopmentApiKeyService();
2286
+ const apiKeyService = new import_dx_common_lib10.DevelopmentApiKeyService();
2064
2287
  const sandbox = services.sandbox || createTestSandbox();
2065
2288
  const componentRunnerService = new ComponentRunnerServiceWithWorkers(sandbox, testLogger, testComponentLogger);
2066
2289
  const componentFunctionService = new import_component_lib3.ComponentFunctionService();
@@ -2075,20 +2298,23 @@ function setupTestApp(services = {}) {
2075
2298
  contentItemService,
2076
2299
  componentRootUrlResolver
2077
2300
  );
2078
- const app = setupApp({
2079
- componentFunctionService,
2080
- componentSetService,
2081
- manifestService,
2082
- componentRunnerService,
2083
- contentItemService,
2084
- renderInputService,
2085
- logger: testLogger,
2086
- apiKeyService,
2087
- componentPreviewService: new ComponentPreviewService(),
2088
- sandbox,
2089
- componentRootUrlResolver,
2090
- ...services
2091
- });
2301
+ const app = setupApp(
2302
+ {
2303
+ componentFunctionService,
2304
+ componentSetService,
2305
+ manifestService,
2306
+ componentRunnerService,
2307
+ contentItemService,
2308
+ renderInputService,
2309
+ logger: testLogger,
2310
+ apiKeyService,
2311
+ componentPreviewService: new ComponentPreviewService(),
2312
+ sandbox,
2313
+ componentRootUrlResolver,
2314
+ ...services
2315
+ },
2316
+ config
2317
+ );
2092
2318
  return { server: import_http.default.createServer(app), app };
2093
2319
  }
2094
2320
  function getTestWebServer(services = {}) {
@@ -2104,8 +2330,8 @@ function getTestWebServer(services = {}) {
2104
2330
  return agent;
2105
2331
  }
2106
2332
  var TestServer = class {
2107
- constructor(services = {}) {
2108
- const { server, app } = setupTestApp(services);
2333
+ constructor(services = {}, config = {}) {
2334
+ const { server, app } = setupTestApp(services, config);
2109
2335
  this.server = server;
2110
2336
  this.server.on("close", async () => {
2111
2337
  for (const service of Object.values(app.request.services)) {
@@ -3313,6 +3539,116 @@ function definitionRouteTests(request, _rootUrl = "http://localhost:3000") {
3313
3539
  });
3314
3540
  }
3315
3541
 
3542
+ // src/webserver/controllers/test/development-route-tests.ts
3543
+ function developmentRouteTests(request, devModeEnabled) {
3544
+ describe(`development routes`, () => {
3545
+ if (devModeEnabled) {
3546
+ describe("all route (dev mode enabled)", () => {
3547
+ it("should return an array of all component manifests", async () => {
3548
+ const response = await request().get("/dev/all");
3549
+ expect(response.statusCode).toEqual(200);
3550
+ expect(response.type).toEqual("application/json");
3551
+ expect(response.body).toEqual(
3552
+ expect.arrayContaining([
3553
+ expect.objectContaining({
3554
+ $schema: "http://localhost:3000/schemas/v1.json#",
3555
+ name: "test-preview-component",
3556
+ version: "1.0.1",
3557
+ mainFunction: "main",
3558
+ displayName: "some-display-name",
3559
+ namespace: "unit-test-components",
3560
+ description: "some-description",
3561
+ functions: expect.any(Array),
3562
+ staticFiles: expect.any(Object),
3563
+ previews: expect.any(Object)
3564
+ })
3565
+ ])
3566
+ );
3567
+ });
3568
+ });
3569
+ describe("manifest route (dev mode enabled)", () => {
3570
+ it("should return the manifest of the requested component", async () => {
3571
+ const response = await request().get("/dev/manifest/unit-test-components/test-preview-component/1.0.1");
3572
+ expect(response.statusCode).toEqual(200);
3573
+ expect(response.type).toEqual("application/json");
3574
+ expect(response.body).toEqual(
3575
+ expect.objectContaining({
3576
+ $schema: "http://localhost:3000/schemas/v1.json#",
3577
+ name: "test-preview-component",
3578
+ version: "1.0.1",
3579
+ mainFunction: "main",
3580
+ displayName: "some-display-name",
3581
+ namespace: "unit-test-components",
3582
+ description: "some-description",
3583
+ functions: expect.any(Array),
3584
+ staticFiles: expect.any(Object),
3585
+ previews: expect.any(Object)
3586
+ })
3587
+ );
3588
+ });
3589
+ });
3590
+ describe("schemas route (dev mode enabled)", () => {
3591
+ it("should return the schemas of the requested component", async () => {
3592
+ const response = await request().get("/dev/schemas/unit-test-components/test-preview-component/1.0.1");
3593
+ expect(response.statusCode).toEqual(200);
3594
+ expect(response.type).toEqual("application/json");
3595
+ expect(response.body).toEqual([
3596
+ {
3597
+ name: "main",
3598
+ schema: {
3599
+ type: "object",
3600
+ properties: {
3601
+ something: {
3602
+ type: "string"
3603
+ }
3604
+ },
3605
+ required: []
3606
+ }
3607
+ },
3608
+ {
3609
+ name: "promise-func",
3610
+ schema: {
3611
+ type: "object",
3612
+ properties: {
3613
+ something: {
3614
+ type: "string"
3615
+ }
3616
+ },
3617
+ required: ["something"]
3618
+ }
3619
+ }
3620
+ ]);
3621
+ });
3622
+ });
3623
+ } else {
3624
+ describe("all route (dev mode disabled)", () => {
3625
+ it("all return a 404 error", async () => {
3626
+ const response = await request().get("/dev/all");
3627
+ expect(response.statusCode).toEqual(404);
3628
+ expect(response.type).toEqual("application/json");
3629
+ expect(response.body).toEqual({ message: "Route does not exist." });
3630
+ });
3631
+ });
3632
+ describe("manifest route (dev mode disabled)", () => {
3633
+ it("should return a 404 error", async () => {
3634
+ const response = await request().get("/dev/manifest/unit-test-components/test-preview-component/1.0.1");
3635
+ expect(response.statusCode).toEqual(404);
3636
+ expect(response.type).toEqual("application/json");
3637
+ expect(response.body).toEqual({ message: "Route does not exist." });
3638
+ });
3639
+ });
3640
+ describe("schemas route (dev mode disabled)", () => {
3641
+ it("should return a 404 error", async () => {
3642
+ const response = await request().get("/dev/schemas/unit-test-components/test-preview-component/1.0.1");
3643
+ expect(response.statusCode).toEqual(404);
3644
+ expect(response.type).toEqual("application/json");
3645
+ expect(response.body).toEqual({ message: "Route does not exist." });
3646
+ });
3647
+ });
3648
+ }
3649
+ });
3650
+ }
3651
+
3316
3652
  // src/webserver/controllers/test/static-route-tests.ts
3317
3653
  function staticRouteTests(request) {
3318
3654
  describe("GET /s/set/unit-test-components/test-static-files/1.0.0/", () => {
@@ -3431,6 +3767,9 @@ function staticRouteTests(request) {
3431
3767
 
3432
3768
  // src/webserver/controllers/test/render-route-tests.ts
3433
3769
  var import_os2 = __toESM(require("os"));
3770
+ function wrapMessageInHtmlComment(message) {
3771
+ return `<!-- ${message} -->`;
3772
+ }
3434
3773
  function renderRouteTests(request, rootUrl) {
3435
3774
  describe("GET /r/unit-test-components/test-component/1.0.10/?_componentSet=set", () => {
3436
3775
  it("should render the test component with html endpoint", async () => {
@@ -3500,12 +3839,12 @@ function renderRouteTests(request, rootUrl) {
3500
3839
  "/r/unit-test-components/test-component/1.0.4/render-json-invalid?_componentSet=set"
3501
3840
  );
3502
3841
  expect(response.statusCode).toEqual(500);
3503
- expect(response.headers["content-type"]).toContain("application/json");
3504
- expect(response.body).toMatchInlineSnapshot(`
3505
- {
3506
- "message": "failed validation: Expected \`3\` (string) in \`#/my-array/0/a-number\` to be of type \`number\`",
3507
- }
3508
- `);
3842
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
3843
+ expect(response.text).toEqual(
3844
+ wrapMessageInHtmlComment(
3845
+ "failed validation: Expected `3` (string) in `#/my-array/0/a-number` to be of type `number`"
3846
+ )
3847
+ );
3509
3848
  }, 2e4);
3510
3849
  it("should validate a complex json against a schema", async () => {
3511
3850
  const response = await request().get(
@@ -3528,13 +3867,13 @@ function renderRouteTests(request, rootUrl) {
3528
3867
  "/r/unit-test-components/test-component/1.0.4/render-json-nested-object-invalid?_componentSet=set"
3529
3868
  );
3530
3869
  expect(response.statusCode).toEqual(500);
3531
- expect(response.headers["content-type"]).toContain("application/json");
3532
- expect(response.body).toMatchInlineSnapshot(`
3533
- {
3534
- "message": "failed validation: Expected \`false\` (string) in \`#/my-object/a-boolean\` to be of type \`boolean\`,
3535
- Expected given value \`N\` in #/my-object/a-nested-object/an-enum\` to be one of \`[Y, E, S]\`",
3536
- }
3537
- `);
3870
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
3871
+ expect(response.text).toEqual(
3872
+ wrapMessageInHtmlComment(
3873
+ `failed validation: Expected \`false\` (string) in \`#/my-object/a-boolean\` to be of type \`boolean\`,
3874
+ Expected given value \`N\` in #/my-object/a-nested-object/an-enum\` to be one of \`[Y, E, S]\``
3875
+ )
3876
+ );
3538
3877
  }, 2e4);
3539
3878
  });
3540
3879
  describe("GET /r/unit-test-components/test-component/1.0.7?_componentSet=set", () => {
@@ -3636,26 +3975,24 @@ function renderRouteTests(request, rootUrl) {
3636
3975
  it("should throw an error if trying to use modules in the js", async () => {
3637
3976
  const response = await request().get("/r/unit-test-components/test-component/1.0.8/module-js?_componentSet=set");
3638
3977
  expect(response.statusCode).toEqual(500);
3639
- expect(response.headers["content-type"]).toContain("application/json");
3640
- expect(response.body).toEqual({ message: "ESM style modules are not supported." });
3978
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
3979
+ expect(response.text).toEqual(wrapMessageInHtmlComment("ESM style modules are not supported."));
3641
3980
  });
3642
3981
  it("should throw an error if the component uploaded does not export a function", async () => {
3643
3982
  const response = await request().get(
3644
3983
  "/r/unit-test-components/test-component/1.0.8/no-module-export?_componentSet=set"
3645
3984
  );
3646
3985
  expect(response.statusCode).toEqual(500);
3647
- expect(response.headers["content-type"]).toContain("application/json");
3648
- expect(response.body).toEqual({ message: "script is not a function" });
3986
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
3987
+ expect(response.text).toEqual(wrapMessageInHtmlComment("script is not a function"));
3649
3988
  });
3650
3989
  it("should throw an error if the component is not async and throws and error object", async () => {
3651
3990
  const response = await request().get(
3652
3991
  "/r/unit-test-components/test-component/1.0.8/no-promise-throws-error?_componentSet=set"
3653
3992
  );
3654
3993
  expect(response.statusCode).toEqual(500);
3655
- expect(response.headers["content-type"]).toContain("application/json");
3656
- expect(response.body).toEqual({
3657
- message: "throw error"
3658
- });
3994
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
3995
+ expect(response.text).toEqual(wrapMessageInHtmlComment("throw error"));
3659
3996
  });
3660
3997
  it("throw an error if the component is not async and throws an arbitrary value", async () => {
3661
3998
  const response = await request().get(
@@ -3663,10 +4000,10 @@ function renderRouteTests(request, rootUrl) {
3663
4000
  );
3664
4001
  expect(response.statusCode).toEqual(500);
3665
4002
  expect(response.headers["cache-control"]).toEqual("no-cache, no-store, max-age=0");
3666
- expect(response.headers["content-type"]).toContain("application/json");
3667
- expect(response.body).toEqual({
3668
- message: "An error occurred with no additional information available"
3669
- });
4003
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4004
+ expect(response.text).toEqual(
4005
+ wrapMessageInHtmlComment("An error occurred with no additional information available")
4006
+ );
3670
4007
  });
3671
4008
  it("throw an error if the component is not async and throws undefined", async () => {
3672
4009
  const response = await request().get(
@@ -3674,10 +4011,10 @@ function renderRouteTests(request, rootUrl) {
3674
4011
  );
3675
4012
  expect(response.statusCode).toEqual(500);
3676
4013
  expect(response.headers["cache-control"]).toEqual("no-cache, no-store, max-age=0");
3677
- expect(response.headers["content-type"]).toContain("application/json");
3678
- expect(response.body).toEqual({
3679
- message: "An error occurred with no additional information available"
3680
- });
4014
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4015
+ expect(response.text).toEqual(
4016
+ wrapMessageInHtmlComment("An error occurred with no additional information available")
4017
+ );
3681
4018
  });
3682
4019
  it("should throw an error if the component is async/returns a promise but rejects", async () => {
3683
4020
  const response = await request().get(
@@ -3685,10 +4022,10 @@ function renderRouteTests(request, rootUrl) {
3685
4022
  );
3686
4023
  expect(response.statusCode).toEqual(500);
3687
4024
  expect(response.headers["cache-control"]).toEqual("no-cache, no-store, max-age=0");
3688
- expect(response.headers["content-type"]).toContain("application/json");
3689
- expect(response.body).toEqual({
3690
- message: "An error occurred with no additional information available"
3691
- });
4025
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4026
+ expect(response.text).toEqual(
4027
+ wrapMessageInHtmlComment("An error occurred with no additional information available")
4028
+ );
3692
4029
  });
3693
4030
  it("should throw an error if the component is async/returns a promise and throws and error object", async () => {
3694
4031
  const response = await request().get(
@@ -3696,10 +4033,8 @@ function renderRouteTests(request, rootUrl) {
3696
4033
  );
3697
4034
  expect(response.statusCode).toEqual(500);
3698
4035
  expect(response.headers["cache-control"]).toEqual("no-cache, no-store, max-age=0");
3699
- expect(response.headers["content-type"]).toContain("application/json");
3700
- expect(response.body).toEqual({
3701
- message: "throws error"
3702
- });
4036
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4037
+ expect(response.text).toEqual(wrapMessageInHtmlComment("throws error"));
3703
4038
  });
3704
4039
  it("throw an error if the component is async/returns a promise and throws an arbitrary value", async () => {
3705
4040
  const response = await request().get(
@@ -3707,10 +4042,10 @@ function renderRouteTests(request, rootUrl) {
3707
4042
  );
3708
4043
  expect(response.statusCode).toEqual(500);
3709
4044
  expect(response.headers["cache-control"]).toEqual("no-cache, no-store, max-age=0");
3710
- expect(response.headers["content-type"]).toContain("application/json");
3711
- expect(response.body).toEqual({
3712
- message: "An error occurred with no additional information available"
3713
- });
4045
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4046
+ expect(response.text).toEqual(
4047
+ wrapMessageInHtmlComment("An error occurred with no additional information available")
4048
+ );
3714
4049
  });
3715
4050
  it("throw an error if the component is async/returns a promise and throws undefined", async () => {
3716
4051
  const response = await request().get(
@@ -3718,20 +4053,18 @@ function renderRouteTests(request, rootUrl) {
3718
4053
  );
3719
4054
  expect(response.statusCode).toEqual(500);
3720
4055
  expect(response.headers["cache-control"]).toEqual("no-cache, no-store, max-age=0");
3721
- expect(response.headers["content-type"]).toContain("application/json");
3722
- expect(response.body).toEqual({
3723
- message: "An error occurred with no additional information available"
3724
- });
4056
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4057
+ expect(response.text).toEqual(
4058
+ wrapMessageInHtmlComment("An error occurred with no additional information available")
4059
+ );
3725
4060
  });
3726
4061
  it("throw an error if the component has a syntax error", async () => {
3727
4062
  const response = await request().get(
3728
4063
  "/r/unit-test-components/test-component/1.0.8/syntax-error?_componentSet=set"
3729
4064
  );
3730
4065
  expect(response.statusCode).toEqual(500);
3731
- expect(response.headers["content-type"]).toContain("application/json");
3732
- expect(response.body).toEqual({
3733
- message: "Unexpected token '}'"
3734
- });
4066
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4067
+ expect(response.text).toEqual(wrapMessageInHtmlComment("Unexpected token '}'"));
3735
4068
  });
3736
4069
  });
3737
4070
  describe("GET /r/unit-test-components/test-static-files/1.0.0?_componentSet=set", () => {
@@ -3869,6 +4202,9 @@ function renderRouteTests(request, rootUrl) {
3869
4202
  }
3870
4203
 
3871
4204
  // src/webserver/controllers/test/render-route-sandbox-tests.ts
4205
+ function wrapMessageInHtmlComment2(message) {
4206
+ return `<!-- ${message} -->`;
4207
+ }
3872
4208
  function renderRouteSandboxTests(request) {
3873
4209
  describe("GET /r/unit-test-components/test-malicious-code/...", () => {
3874
4210
  it("should timeout infinite running code", async () => {
@@ -3876,40 +4212,47 @@ function renderRouteSandboxTests(request) {
3876
4212
  "/r/unit-test-components/test-malicious-code/1.0.0/?_componentSet=set&something=hello"
3877
4213
  );
3878
4214
  expect(response.statusCode).toEqual(500);
3879
- expect(response.headers["content-type"]).toContain("application/json");
3880
- expect(response.body).toEqual({
3881
- message: "function while-true of component unit-test-components/test-malicious-code 1.0.0 could not complete with in the allotted time"
3882
- });
4215
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4216
+ expect(response.text).toEqual(
4217
+ wrapMessageInHtmlComment2(
4218
+ "function while-true of component unit-test-components/test-malicious-code 1.0.0 could not complete with in the allotted time"
4219
+ )
4220
+ );
3883
4221
  }, 3e4);
3884
4222
  it("should timeout non terminating code", async () => {
3885
4223
  const response = await request().get(
3886
4224
  "/r/unit-test-components/test-malicious-code/1.3.0/executing-after-return?_componentSet=set"
3887
4225
  );
3888
4226
  expect(response.statusCode).toEqual(500);
3889
- expect(response.headers["content-type"]).toContain("application/json");
3890
- expect(response.body).toEqual({
3891
- message: "function executing-after-return of component unit-test-components/test-malicious-code 1.3.0 could not complete with in the allotted time"
3892
- });
4227
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4228
+ expect(response.text).toEqual(
4229
+ wrapMessageInHtmlComment2(
4230
+ "function executing-after-return of component unit-test-components/test-malicious-code 1.3.0 could not complete with in the allotted time"
4231
+ )
4232
+ );
3893
4233
  }, 3e4);
3894
4234
  it.skip("should not allow starting your own services", async () => {
3895
4235
  const response = await request().get(
3896
4236
  "/r/unit-test-components/test-malicious-code/1.3.0/reverse-shell?_componentSet=set"
3897
4237
  );
4238
+ expect(response.text).toEqual(
4239
+ wrapMessageInHtmlComment2(
4240
+ "function executing-after-return of component unit-test-components/test-malicious-code 1.3.0 could not complete with in the allotted time"
4241
+ )
4242
+ );
3898
4243
  expect(response.statusCode).toEqual(500);
3899
- expect(response.headers["content-type"]).toContain("application/json");
3900
- expect(response.body).toEqual({
3901
- message: "function executing-after-return of component unit-test-components/test-malicious-code 1.3.0 could not complete with in the allotted time"
3902
- });
4244
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
3903
4245
  }, 1e4);
3904
4246
  it.skip("should deny access to fs", async () => {
3905
4247
  const response = await request().get(
3906
4248
  "/r/unit-test-components/test-malicious-code/1.1.0/?_componentSet=set&something=hello"
3907
4249
  );
3908
4250
  expect(response.statusCode).toEqual(500);
3909
- expect(response.headers["content-type"]).toContain("application/json");
4251
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
3910
4252
  expect(response.body).toEqual({
3911
4253
  message: "Cannot find module 'fs'"
3912
4254
  });
4255
+ expect(response.text).toEqual(wrapMessageInHtmlComment2(`"Cannot find module 'fs'`));
3913
4256
  });
3914
4257
  it("should allow access to a subset of node provided modules", async () => {
3915
4258
  const response = await request().get(
@@ -3993,100 +4336,92 @@ function renderRouteSandboxTests(request) {
3993
4336
  "/r/unit-test-components/test-malicious-code/1.2.0/process-exit?_componentSet=set"
3994
4337
  );
3995
4338
  expect(response.statusCode).toEqual(500);
3996
- expect(response.headers["content-type"]).toContain("application/json");
3997
- expect(response.body).toEqual({
3998
- message: "process.exit is not a function"
3999
- });
4339
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4340
+ expect(response.text).toEqual(wrapMessageInHtmlComment2("process.exit is not a function"));
4000
4341
  });
4001
4342
  it("should not allow process.binding calls", async () => {
4002
4343
  const response = await request().get(
4003
4344
  "/r/unit-test-components/test-malicious-code/1.2.0/process-binding?_componentSet=set"
4004
4345
  );
4005
4346
  expect(response.statusCode).toEqual(500);
4006
- expect(response.headers["content-type"]).toContain("application/json");
4007
- expect(response.body).toEqual({
4008
- message: "Cannot read properties of undefined (reading 'process')"
4009
- });
4347
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4348
+ expect(response.text).toEqual(
4349
+ wrapMessageInHtmlComment2("Cannot read properties of undefined (reading 'process')")
4350
+ );
4010
4351
  });
4011
4352
  it("should not allow process.kill calls", async () => {
4012
4353
  const response = await request().get(
4013
4354
  "/r/unit-test-components/test-malicious-code/1.2.0/process-kill?_componentSet=set"
4014
4355
  );
4015
4356
  expect(response.statusCode).toEqual(500);
4016
- expect(response.headers["content-type"]).toContain("application/json");
4017
- expect(response.body).toEqual({
4018
- message: "process.kill is not a function"
4019
- });
4357
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4358
+ expect(response.text).toEqual(wrapMessageInHtmlComment2("process.kill is not a function"));
4020
4359
  });
4021
4360
  it("should not allow process.abort calls", async () => {
4022
4361
  const response = await request().get(
4023
4362
  "/r/unit-test-components/test-malicious-code/1.2.0/process-abort?_componentSet=set"
4024
4363
  );
4025
4364
  expect(response.statusCode).toEqual(500);
4026
- expect(response.headers["content-type"]).toContain("application/json");
4027
- expect(response.body).toEqual({
4028
- message: "process.abort is not a function"
4029
- });
4365
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4366
+ expect(response.text).toEqual(wrapMessageInHtmlComment2("process.abort is not a function"));
4030
4367
  });
4031
4368
  it.skip("should not allow access to parentPort", async () => {
4032
4369
  const response = await request().get(
4033
4370
  "/r/unit-test-components/test-malicious-code/1.3.0/accessing-parent-port?_componentSet=set"
4034
4371
  );
4035
4372
  expect(response.statusCode).toEqual(500);
4036
- expect(response.headers["content-type"]).toContain("application/json");
4037
- expect(response.body).toEqual({
4038
- message: "Cannot find module 'worker_threads'"
4039
- });
4373
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4374
+ expect(response.text).toEqual(wrapMessageInHtmlComment2("Cannot find module 'worker_threads'"));
4040
4375
  });
4041
4376
  it("should not allow escaping the sandbox through the constructor", async () => {
4042
4377
  const response = await request().get(
4043
4378
  "/r/unit-test-components/test-malicious-code/1.2.0/constructor-escape?_componentSet=set"
4044
4379
  );
4045
4380
  expect(response.statusCode).toEqual(500);
4046
- expect(response.headers["content-type"]).toContain("application/json");
4047
- expect(response.body).toEqual({
4048
- message: "Cannot read properties of undefined (reading 'constructor')"
4049
- });
4381
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4382
+ expect(response.text).toEqual(
4383
+ wrapMessageInHtmlComment2("Cannot read properties of undefined (reading 'constructor')")
4384
+ );
4050
4385
  });
4051
4386
  it("should not allow escaping the sandbox through the constructor and calling exit", async () => {
4052
4387
  const response = await request().get(
4053
4388
  "/r/unit-test-components/test-malicious-code/1.2.0/constructor-escape?_componentSet=set"
4054
4389
  );
4055
4390
  expect(response.statusCode).toEqual(500);
4056
- expect(response.headers["content-type"]).toContain("application/json");
4057
- expect(response.body).toEqual({
4058
- message: "Cannot read properties of undefined (reading 'constructor')"
4059
- });
4391
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4392
+ expect(response.text).toEqual(
4393
+ wrapMessageInHtmlComment2("Cannot read properties of undefined (reading 'constructor')")
4394
+ );
4060
4395
  });
4061
4396
  it("should not allow escaping the sandbox through the constructor and loading restricted modules", async () => {
4062
4397
  const response = await request().get(
4063
4398
  "/r/unit-test-components/test-malicious-code/1.2.0/constructor-fs?_componentSet=set"
4064
4399
  );
4400
+ expect(response.text).toEqual(
4401
+ wrapMessageInHtmlComment2("Cannot read properties of undefined (reading 'constructor')")
4402
+ );
4065
4403
  expect(response.statusCode).toEqual(500);
4066
- expect(response.headers["content-type"]).toContain("application/json");
4067
- expect(response.body).toEqual({
4068
- message: "Cannot read properties of undefined (reading 'constructor')"
4069
- });
4404
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4070
4405
  });
4071
4406
  it("should not allow circumvention of module restrictions", async () => {
4072
4407
  const response = await request().get(
4073
4408
  "/r/unit-test-components/test-malicious-code/1.2.0/circumventing-module-restriction?_componentSet=set"
4074
4409
  );
4075
4410
  expect(response.statusCode).toEqual(500);
4076
- expect(response.headers["content-type"]).toContain("application/json");
4077
- expect(response.body).toEqual({
4078
- message: "Cannot read properties of undefined (reading 'constructor')"
4079
- });
4411
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4412
+ expect(response.text).toEqual(
4413
+ wrapMessageInHtmlComment2("Cannot read properties of undefined (reading 'constructor')")
4414
+ );
4080
4415
  });
4081
4416
  it("should not allow circumvention of module restrictions with mainmodule", async () => {
4082
4417
  const response = await request().get(
4083
4418
  "/r/unit-test-components/test-malicious-code/1.2.0/circumventing-module-restriction-mainmodule?_componentSet=set"
4084
4419
  );
4085
4420
  expect(response.statusCode).toEqual(500);
4086
- expect(response.headers["content-type"]).toContain("application/json");
4087
- expect(response.body).toEqual({
4088
- message: "Cannot read properties of undefined (reading 'require')"
4089
- });
4421
+ expect(response.headers["content-type"]).toContain("text/html; charset=utf-8");
4422
+ expect(response.text).toEqual(
4423
+ wrapMessageInHtmlComment2("Cannot read properties of undefined (reading 'require')")
4424
+ );
4090
4425
  });
4091
4426
  });
4092
4427
  }
@@ -4195,7 +4530,8 @@ var routeTests = {
4195
4530
  static: staticRouteTests,
4196
4531
  render: renderRouteTests,
4197
4532
  renderSandbox: renderRouteSandboxTests,
4198
- preview: previewRouteTests
4533
+ preview: previewRouteTests,
4534
+ development: developmentRouteTests
4199
4535
  };
4200
4536
  // Annotate the CommonJS export names for ESM import in node:
4201
4537
  0 && (module.exports = {