@tstdl/base 0.83.27 → 0.84.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.
Files changed (55) hide show
  1. package/application/application.d.ts +1 -1
  2. package/application/application.js +4 -4
  3. package/browser/browser-context-controller.d.ts +32 -0
  4. package/browser/browser-context-controller.js +88 -0
  5. package/browser/browser-controller.d.ts +45 -0
  6. package/browser/browser-controller.js +109 -0
  7. package/browser/browser.service.d.ts +34 -0
  8. package/browser/browser.service.js +107 -0
  9. package/browser/index.d.ts +4 -0
  10. package/browser/index.js +21 -0
  11. package/browser/page-controller.d.ts +54 -0
  12. package/browser/page-controller.js +166 -0
  13. package/browser/pdf-options.d.ts +36 -0
  14. package/browser/pdf-options.js +138 -0
  15. package/browser/utils.d.ts +6 -0
  16. package/browser/utils.js +60 -0
  17. package/core.d.ts +1 -1
  18. package/data-structures/cache.d.ts +11 -0
  19. package/data-structures/cache.js +69 -0
  20. package/data-structures/index.d.ts +1 -0
  21. package/data-structures/index.js +1 -0
  22. package/disposable/async-disposer.d.ts +2 -1
  23. package/error/index.d.ts +1 -0
  24. package/error/index.js +1 -0
  25. package/error/timeout.error.d.ts +5 -0
  26. package/error/timeout.error.js +30 -0
  27. package/examples/browser/basic.d.ts +1 -0
  28. package/examples/browser/basic.js +19 -0
  29. package/examples/mail/basic.js +11 -3
  30. package/examples/pdf/basic.js +33 -7
  31. package/examples/pdf/templates/hello-name.js +10 -2
  32. package/http/client/http-client-request.js +1 -1
  33. package/http/server/node/node-http-server.js +1 -1
  34. package/lock/web/web-lock.js +2 -2
  35. package/package.json +6 -6
  36. package/pdf/pdf.service.d.ts +23 -58
  37. package/pdf/pdf.service.js +33 -203
  38. package/pool/pool.d.ts +1 -0
  39. package/pool/pool.js +6 -0
  40. package/queue/mongo/queue.js +2 -2
  41. package/types.d.ts +3 -0
  42. package/utils/cancellation-token.d.ts +11 -16
  43. package/utils/cancellation-token.js +10 -39
  44. package/utils/index.d.ts +1 -0
  45. package/utils/index.js +1 -0
  46. package/utils/stream/finalize-stream.d.ts +22 -1
  47. package/utils/stream/finalize-stream.js +14 -4
  48. package/utils/stream/readable-stream-from-promise.d.ts +2 -1
  49. package/utils/stream/readable-stream-from-promise.js +3 -2
  50. package/utils/timing.d.ts +7 -1
  51. package/utils/timing.js +23 -3
  52. package/utils/type-guards.d.ts +6 -0
  53. package/utils/type-guards.js +26 -0
  54. package/utils/value-or-provider.d.ts +2 -0
  55. package/utils/value-or-provider.js +30 -0
@@ -1,5 +1,9 @@
1
1
  "use strict";
2
+ var import_node_fs = require("node:fs");
3
+ var import_node_path = require("node:path");
4
+ var import_node_url = require("node:url");
2
5
  var import_application = require("../../application/application.js");
6
+ var import_browser_service = require("../../browser/browser.service.js");
3
7
  var import_container = require("../../container/index.js");
4
8
  var import_core = require("../../core.js");
5
9
  var import_pdf_service = require("../../pdf/pdf.service.js");
@@ -8,18 +12,40 @@ var import_file_template_provider = require("../../templates/providers/file.temp
8
12
  var import_handlebars_template_renderer = require("../../templates/renderers/handlebars.template-renderer.js");
9
13
  var import_mjml_template_renderer = require("../../templates/renderers/mjml.template-renderer.js");
10
14
  var import_file_template_resolver = require("../../templates/resolvers/file.template-resolver.js");
11
- var import_node_path = require("node:path");
15
+ const import_meta = {};
16
+ let dirname;
17
+ try {
18
+ dirname = (0, import_node_url.fileURLToPath)(new URL(".", import_meta.url));
19
+ } catch {
20
+ dirname = __dirname;
21
+ }
12
22
  (0, import_core.configureTstdl)();
13
23
  (0, import_module.configureTemplates)({
14
24
  templateProvider: import_file_template_provider.FileTemplateProvider,
15
25
  templateResolvers: [import_file_template_resolver.FileTemplateResolver],
16
26
  templateRenderers: [import_mjml_template_renderer.MjmlTemplateRenderer, import_handlebars_template_renderer.HandlebarsTemplateRenderer]
17
27
  });
18
- (0, import_file_template_provider.configureFileTemplateProvider)({ basePath: (0, import_node_path.resolve)(__dirname, "templates") });
19
- (0, import_file_template_resolver.configureFileTemplateResolver)({ basePath: (0, import_node_path.resolve)(__dirname.replace("dist", "source"), "templates") });
20
- async function test() {
28
+ (0, import_file_template_provider.configureFileTemplateProvider)({ basePath: (0, import_node_path.resolve)(dirname, "templates") });
29
+ (0, import_file_template_resolver.configureFileTemplateResolver)({ basePath: (0, import_node_path.resolve)(dirname.replace("dist", "source"), "templates") });
30
+ async function main() {
31
+ const browserService = await import_container.container.resolveAsync(import_browser_service.BrowserService);
21
32
  const pdfService = await import_container.container.resolveAsync(import_pdf_service.PdfService);
22
- const result = await pdfService.renderTemplate("hello-name", { name: "Max Mustermann" });
23
- console.log(`Resulting PDF has ${result.length} bytes.`);
33
+ const [result1, result2] = await Promise.all([
34
+ pdfService.renderTemplate("hello-name", { name: "Max Mustermann" }),
35
+ pdfService.renderUrl("https://google.de")
36
+ ]);
37
+ console.log(`Resulting PDFs have ${result1.length} and ${result2.length} bytes.`);
38
+ (0, import_node_fs.writeFileSync)("/tmp/template.pdf", result1);
39
+ (0, import_node_fs.writeFileSync)("/tmp/page.pdf", result2);
40
+ const browser = await browserService.newBrowser({ headless: false });
41
+ const context = await browser.newContext();
42
+ const page1 = await context.newPage();
43
+ const page2 = await context.newPage();
44
+ await Promise.all([
45
+ page1.navigate("file:///tmp/template.pdf"),
46
+ page2.navigate("file:///tmp/page.pdf")
47
+ ]);
48
+ await page1.waitForClose();
49
+ await page2.waitForClose();
24
50
  }
25
- import_application.Application.run(test);
51
+ import_application.Application.run(main);
@@ -21,17 +21,25 @@ __export(hello_name_exports, {
21
21
  default: () => hello_name_default
22
22
  });
23
23
  module.exports = __toCommonJS(hello_name_exports);
24
+ var import_node_path = require("node:path");
25
+ var import_node_url = require("node:url");
24
26
  var import_pdf_service = require("../../../pdf/pdf.service.js");
25
27
  var import_file_template_resolver = require("../../../templates/resolvers/file.template-resolver.js");
26
28
  var import_string_template_resolver = require("../../../templates/resolvers/string.template-resolver.js");
27
- var import_node_path = require("node:path");
29
+ const import_meta = {};
30
+ let dirname;
31
+ try {
32
+ dirname = (0, import_node_url.fileURLToPath)(new URL(".", import_meta.url));
33
+ } catch {
34
+ dirname = __dirname;
35
+ }
28
36
  function reverse(value) {
29
37
  return value.split("").reverse().join("");
30
38
  }
31
39
  const template = (0, import_pdf_service.pdfTemplate)("hello-name", {
32
40
  body: (0, import_file_template_resolver.fileTemplateField)({
33
41
  renderer: "handlebars",
34
- templateFile: (0, import_node_path.resolve)(__dirname.replace("dist", "source"), "hello-name.hbs"),
42
+ templateFile: (0, import_node_path.resolve)(dirname.replace("dist", "source"), "hello-name.hbs"),
35
43
  options: {
36
44
  partials: {
37
45
  sometext: (0, import_string_template_resolver.stringTemplateField)({
@@ -97,7 +97,7 @@ class HttpClientRequest {
97
97
  * can be used to cancel the request. Throws HttpError
98
98
  */
99
99
  get abortToken() {
100
- return this._abortToken.asReadonly;
100
+ return this._abortToken.asReadonly();
101
101
  }
102
102
  constructor(urlOrObject, method, options = {}) {
103
103
  if ((0, import_type_guards.isString)(urlOrObject)) {
@@ -133,7 +133,7 @@ let NodeHttpServer = class NodeHttpServer2 extends import_http_server.HttpServer
133
133
  }
134
134
  if (connections > 0) {
135
135
  this.logger.info(`Waiting for ${connections} connections to end`);
136
- await (0, import_timing.cancelableTimeout)(250, import_cancellation_token.CancellationToken.fromObservable(close$));
136
+ await (0, import_timing.cancelableTimeout)(250, import_cancellation_token.CancellationToken.from(close$));
137
137
  }
138
138
  }
139
139
  this.untrackConnectedSockets?.();
@@ -55,9 +55,9 @@ let WebLock = class WebLock2 extends import_lock.Lock {
55
55
  releasePromise.resolve();
56
56
  }
57
57
  };
58
- const timeoutToken = (0, import_type_guards.isDefined)(timeout) && timeout > 0 ? import_cancellation_token.CancellationToken.fromObservable((0, import_rxjs.timer)(timeout).pipe((0, import_rxjs.map)(() => true))) : void 0;
58
+ const timeoutToken = (0, import_type_guards.isDefined)(timeout) && timeout > 0 ? import_cancellation_token.CancellationToken.from((0, import_rxjs.timer)(timeout).pipe((0, import_rxjs.map)(() => true))) : void 0;
59
59
  void navigator.locks.request(this.resource, {
60
- signal: (0, import_type_guards.isDefined)(timeoutToken) ? timeoutToken.asAbortSignal : void 0,
60
+ signal: (0, import_type_guards.isDefined)(timeoutToken) ? timeoutToken.asAbortSignal() : void 0,
61
61
  ifAvailable: (0, import_type_guards.isDefined)(timeout) && timeout <= 0
62
62
  }, async (lock) => {
63
63
  if ((0, import_type_guards.isNull)(lock)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.83.27",
3
+ "version": "0.84.0",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -21,7 +21,7 @@
21
21
  "luxon": "^3.3",
22
22
  "reflect-metadata": "^0.1",
23
23
  "rxjs": "^7.8",
24
- "type-fest": "^3.8"
24
+ "type-fest": "^3.9"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/chroma-js": "2.4",
@@ -35,7 +35,7 @@
35
35
  "@typescript-eslint/parser": "5.59",
36
36
  "concurrently": "8.0",
37
37
  "esbuild": "0.17",
38
- "eslint": "8.38",
38
+ "eslint": "8.39",
39
39
  "eslint-import-resolver-typescript": "3.5",
40
40
  "eslint-plugin-import": "2.27",
41
41
  "tsc-alias": "1.8",
@@ -45,7 +45,7 @@
45
45
  "peerDependencies": {
46
46
  "@elastic/elasticsearch": "^8.7",
47
47
  "@koa/router": "^12.0",
48
- "@tstdl/angular": "^0.83",
48
+ "@tstdl/angular": "^0.84",
49
49
  "@zxcvbn-ts/core": "^2.2",
50
50
  "@zxcvbn-ts/language-common": "^2.0",
51
51
  "@zxcvbn-ts/language-de": "^2.1",
@@ -54,13 +54,13 @@
54
54
  "handlebars": "^4.7",
55
55
  "knex": "^2.4",
56
56
  "koa": "^2.14",
57
- "minio": "^7.0",
57
+ "minio": "^7.1",
58
58
  "mjml": "^4.14",
59
59
  "mongodb": "^5.3",
60
60
  "nodemailer": "^6.9",
61
+ "playwright": "^1.33",
61
62
  "preact": "^10.13",
62
63
  "preact-render-to-string": "^6.0",
63
- "puppeteer": "^19.11",
64
64
  "undici": "^5.22",
65
65
  "urlpattern-polyfill": "^8.0"
66
66
  },
@@ -1,48 +1,15 @@
1
- import type { AfterResolve, Injectable } from '../container/index.js';
2
- import { afterResolve, type resolveArgumentType } from '../container/index.js';
3
- import type { AsyncDisposable } from '../disposable/disposable.js';
4
- import { disposeAsync } from '../disposable/disposable.js';
5
- import { Logger } from '../logger/index.js';
1
+ import { BrowserContextController } from '../browser/browser-context-controller.js';
2
+ import type { BrowserControllerArgument } from '../browser/browser-controller.js';
3
+ import { BrowserController } from '../browser/browser-controller.js';
4
+ import { PdfRenderOptions } from '../browser/pdf-options.js';
5
+ import type { Injectable } from '../container/index.js';
6
+ import { resolveArgumentType } from '../container/index.js';
6
7
  import type { TemplateField } from '../templates/index.js';
7
8
  import { Template, TemplateService } from '../templates/index.js';
8
- export declare enum PdfFormat {
9
- Letter = "letter",
10
- Legal = "legal",
11
- Tabloid = "tabloid",
12
- Ledger = "ledger",
13
- A0 = "a0",
14
- A1 = "a1",
15
- A2 = "a2",
16
- A3 = "a3",
17
- A4 = "a4",
18
- A5 = "a5",
19
- A6 = "a6"
20
- }
21
- export declare class PdfMarginObject {
22
- top?: number | string;
23
- bottom?: number | string;
24
- right?: number | string;
25
- left?: number | string;
26
- }
27
- export declare class PdfRenderOptions {
28
- language?: string;
29
- omitDefaultBackground?: boolean;
30
- renderBackground?: boolean;
31
- landscape?: boolean;
32
- format?: PdfFormat;
33
- width?: string | number;
34
- height?: string | number;
35
- scale?: number;
36
- margin?: string | number | PdfMarginObject;
37
- displayHeaderFooter?: boolean;
9
+ export declare class PdfServiceRenderOptions extends PdfRenderOptions {
10
+ browserContext?: BrowserContextController;
11
+ locale?: string;
38
12
  waitForNetworkIdle?: boolean;
39
- headerTemplate?: string;
40
- footerTemplate?: string;
41
- /**
42
- * Timeout for closing render context in case something went wrong.
43
- * @default 60000 (1 minute)
44
- */
45
- timeout?: number;
46
13
  }
47
14
  export type PdfTemplateOptions = PdfRenderOptions;
48
15
  export declare class PdfTemplate<Context extends object = any> extends Template<{
@@ -53,46 +20,45 @@ export declare class PdfTemplate<Context extends object = any> extends Template<
53
20
  options?: PdfTemplateOptions;
54
21
  }
55
22
  export type PdfServiceOptions = {
56
- language?: string;
23
+ locale?: string;
24
+ };
25
+ export type PdfServiceArgument = PdfServiceOptions & {
26
+ browserControllerArgument: BrowserControllerArgument;
57
27
  };
58
- export type PdfServiceArgument = PdfServiceOptions;
59
- export declare class PdfService implements AsyncDisposable, AfterResolve, Injectable<PdfServiceArgument> {
28
+ export declare class PdfService implements Injectable<PdfServiceArgument> {
60
29
  private readonly templateService;
61
- private readonly logger;
62
- private readonly pool;
30
+ private readonly browserController;
31
+ private readonly defaultLocale;
63
32
  readonly [resolveArgumentType]: PdfServiceArgument;
64
- constructor(templateService: TemplateService, logger: Logger, options?: PdfServiceOptions);
65
- [afterResolve](): void;
66
- [disposeAsync](): Promise<void>;
67
- dispose(): Promise<void>;
33
+ constructor(templateService: TemplateService, browserController: BrowserController, options?: PdfServiceOptions);
68
34
  /**
69
35
  * Renders HTML to pdf stream
70
36
  * @param html html to render
71
37
  * @param options render options
72
38
  * @returns pdf stream
73
39
  */
74
- renderHtmlStream(html: string, options?: PdfRenderOptions): ReadableStream<Uint8Array>;
40
+ renderHtmlStream(html: string, options?: PdfServiceRenderOptions): ReadableStream<Uint8Array>;
75
41
  /**
76
42
  * Renders HTML to pdf
77
43
  * @param html html to render
78
44
  * @param options render options
79
45
  * @returns pdf bytes
80
46
  */
81
- renderHtml(html: string, options?: PdfRenderOptions): Promise<Uint8Array>;
47
+ renderHtml(html: string, options?: PdfServiceRenderOptions): Promise<Uint8Array>;
82
48
  /**
83
49
  * Renders an url to pdf stream
84
50
  * @param url url to load and render
85
51
  * @param options render options
86
52
  * @returns pdf stream
87
53
  */
88
- renderUrlStream(url: string, options?: PdfRenderOptions): ReadableStream<Uint8Array>;
54
+ renderUrlStream(url: string, options?: PdfServiceRenderOptions): ReadableStream<Uint8Array>;
89
55
  /**
90
56
  * Renders an url to pdf
91
57
  * @param url url to load and render
92
58
  * @param options render options
93
59
  * @returns pdf bytes
94
60
  */
95
- renderUrl(url: string, options?: PdfRenderOptions): Promise<Uint8Array>;
61
+ renderUrl(url: string, options?: PdfServiceRenderOptions): Promise<Uint8Array>;
96
62
  /**
97
63
  * Renders a template to pdf
98
64
  * @param key template key
@@ -100,7 +66,7 @@ export declare class PdfService implements AsyncDisposable, AfterResolve, Inject
100
66
  * @param options additional options, overwrites options specified in template
101
67
  * @returns pdf bytes
102
68
  */
103
- renderTemplateStream<Context extends object>(keyOrTemplate: string | PdfTemplate<Context>, templateContext?: Context, options?: PdfRenderOptions): ReadableStream<Uint8Array>;
69
+ renderTemplateStream<Context extends object>(keyOrTemplate: string | PdfTemplate<Context>, templateContext?: Context, options?: PdfServiceRenderOptions): ReadableStream<Uint8Array>;
104
70
  /**
105
71
  * Renders a template to pdf
106
72
  * @param key template key
@@ -108,9 +74,8 @@ export declare class PdfService implements AsyncDisposable, AfterResolve, Inject
108
74
  * @param options additional options, overwrites options specified in template
109
75
  * @returns pdf bytes
110
76
  */
111
- renderTemplate(keyOrTemplate: string | PdfTemplate, templateContext?: object, options?: PdfRenderOptions): Promise<Uint8Array>;
77
+ renderTemplate(keyOrTemplate: string | PdfTemplate, templateContext?: object, options?: PdfServiceRenderOptions): Promise<Uint8Array>;
112
78
  private renderStream;
113
- private convertOptions;
114
79
  }
115
80
  export declare function pdfTemplate(name: string, fields: {
116
81
  body: TemplateField;
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,39 +15,25 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var pdf_service_exports = {};
30
20
  __export(pdf_service_exports, {
31
- PdfFormat: () => PdfFormat,
32
- PdfMarginObject: () => PdfMarginObject,
33
- PdfRenderOptions: () => PdfRenderOptions,
34
21
  PdfService: () => PdfService,
22
+ PdfServiceRenderOptions: () => PdfServiceRenderOptions,
35
23
  PdfTemplate: () => PdfTemplate,
36
24
  pdfTemplate: () => pdfTemplate
37
25
  });
38
26
  module.exports = __toCommonJS(pdf_service_exports);
27
+ var import_browser_context_controller = require("../browser/browser-context-controller.js");
28
+ var import_browser_controller = require("../browser/browser-controller.js");
29
+ var import_pdf_options = require("../browser/pdf-options.js");
39
30
  var import_container = require("../container/index.js");
40
- var import_core = require("../core.js");
41
- var import_disposable = require("../disposable/disposable.js");
42
- var import_logger = require("../logger/index.js");
43
- var import_pool = require("../pool/pool.js");
44
31
  var import_schema = require("../schema/index.js");
45
32
  var import_templates = require("../templates/index.js");
46
33
  var import_finalize_stream = require("../utils/stream/finalize-stream.js");
47
- var import_readable_stream_adapter = require("../utils/stream/readable-stream-adapter.js");
48
34
  var import_readable_stream_from_promise = require("../utils/stream/readable-stream-from-promise.js");
49
35
  var import_stream_reader = require("../utils/stream/stream-reader.js");
50
36
  var import_type_guards = require("../utils/type-guards.js");
51
- var import_units = require("../utils/units.js");
52
- var puppeteer = __toESM(require("puppeteer"), 1);
53
37
  var __decorate = function(decorators, target, key, desc) {
54
38
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
55
39
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -69,148 +53,38 @@ var __param = function(paramIndex, decorator) {
69
53
  decorator(target, key, paramIndex);
70
54
  };
71
55
  };
72
- var PdfFormat;
73
- (function(PdfFormat2) {
74
- PdfFormat2["Letter"] = "letter";
75
- PdfFormat2["Legal"] = "legal";
76
- PdfFormat2["Tabloid"] = "tabloid";
77
- PdfFormat2["Ledger"] = "ledger";
78
- PdfFormat2["A0"] = "a0";
79
- PdfFormat2["A1"] = "a1";
80
- PdfFormat2["A2"] = "a2";
81
- PdfFormat2["A3"] = "a3";
82
- PdfFormat2["A4"] = "a4";
83
- PdfFormat2["A5"] = "a5";
84
- PdfFormat2["A6"] = "a6";
85
- })(PdfFormat || (PdfFormat = {}));
86
- class PdfMarginObject {
87
- top;
88
- bottom;
89
- right;
90
- left;
91
- }
92
- __decorate([
93
- (0, import_schema.Optional)([Number, String]),
94
- __metadata("design:type", Object)
95
- ], PdfMarginObject.prototype, "top", void 0);
96
- __decorate([
97
- (0, import_schema.Optional)([Number, String]),
98
- __metadata("design:type", Object)
99
- ], PdfMarginObject.prototype, "bottom", void 0);
100
- __decorate([
101
- (0, import_schema.Optional)([Number, String]),
102
- __metadata("design:type", Object)
103
- ], PdfMarginObject.prototype, "right", void 0);
104
- __decorate([
105
- (0, import_schema.Optional)([Number, String]),
106
- __metadata("design:type", Object)
107
- ], PdfMarginObject.prototype, "left", void 0);
108
- class PdfRenderOptions {
109
- language;
110
- omitDefaultBackground;
111
- renderBackground;
112
- landscape;
113
- format;
114
- width;
115
- height;
116
- scale;
117
- margin;
118
- displayHeaderFooter;
56
+ class PdfServiceRenderOptions extends import_pdf_options.PdfRenderOptions {
57
+ browserContext;
58
+ locale;
119
59
  waitForNetworkIdle;
120
- headerTemplate;
121
- footerTemplate;
122
- /**
123
- * Timeout for closing render context in case something went wrong.
124
- * @default 60000 (1 minute)
125
- */
126
- timeout;
127
60
  }
128
61
  __decorate([
129
62
  (0, import_schema.Optional)(),
130
- __metadata("design:type", String)
131
- ], PdfRenderOptions.prototype, "language", void 0);
63
+ __metadata("design:type", import_browser_context_controller.BrowserContextController)
64
+ ], PdfServiceRenderOptions.prototype, "browserContext", void 0);
132
65
  __decorate([
133
66
  (0, import_schema.Optional)(),
134
- __metadata("design:type", Boolean)
135
- ], PdfRenderOptions.prototype, "omitDefaultBackground", void 0);
136
- __decorate([
137
- (0, import_schema.Optional)(),
138
- __metadata("design:type", Boolean)
139
- ], PdfRenderOptions.prototype, "renderBackground", void 0);
140
- __decorate([
141
- (0, import_schema.Optional)(),
142
- __metadata("design:type", Boolean)
143
- ], PdfRenderOptions.prototype, "landscape", void 0);
144
- __decorate([
145
- (0, import_schema.Optional)(),
146
- (0, import_schema.Enumeration)(PdfFormat),
147
67
  __metadata("design:type", String)
148
- ], PdfRenderOptions.prototype, "format", void 0);
149
- __decorate([
150
- (0, import_schema.Optional)([String, Number]),
151
- __metadata("design:type", Object)
152
- ], PdfRenderOptions.prototype, "width", void 0);
153
- __decorate([
154
- (0, import_schema.Optional)([String, Number]),
155
- __metadata("design:type", Object)
156
- ], PdfRenderOptions.prototype, "height", void 0);
157
- __decorate([
158
- (0, import_schema.Optional)(),
159
- __metadata("design:type", Number)
160
- ], PdfRenderOptions.prototype, "scale", void 0);
161
- __decorate([
162
- (0, import_schema.Optional)([String, Number, PdfMarginObject]),
163
- __metadata("design:type", Object)
164
- ], PdfRenderOptions.prototype, "margin", void 0);
68
+ ], PdfServiceRenderOptions.prototype, "locale", void 0);
165
69
  __decorate([
166
70
  (0, import_schema.Optional)(),
167
71
  __metadata("design:type", Boolean)
168
- ], PdfRenderOptions.prototype, "displayHeaderFooter", void 0);
169
- __decorate([
170
- (0, import_schema.Optional)(),
171
- __metadata("design:type", Boolean)
172
- ], PdfRenderOptions.prototype, "waitForNetworkIdle", void 0);
173
- __decorate([
174
- (0, import_schema.Optional)(),
175
- __metadata("design:type", String)
176
- ], PdfRenderOptions.prototype, "headerTemplate", void 0);
177
- __decorate([
178
- (0, import_schema.Optional)(),
179
- __metadata("design:type", String)
180
- ], PdfRenderOptions.prototype, "footerTemplate", void 0);
181
- __decorate([
182
- (0, import_schema.Optional)(),
183
- __metadata("design:type", Number)
184
- ], PdfRenderOptions.prototype, "timeout", void 0);
72
+ ], PdfServiceRenderOptions.prototype, "waitForNetworkIdle", void 0);
185
73
  class PdfTemplate extends import_templates.Template {
186
74
  }
187
75
  __decorate([
188
76
  (0, import_schema.Optional)(),
189
77
  __metadata("design:type", Object)
190
78
  ], PdfTemplate.prototype, "options", void 0);
79
+ const browserArguments = ["--font-render-hinting=none", "--disable-web-security", "--disable-features=IsolateOrigins", "--disable-site-isolation-trials"];
191
80
  let PdfService = class PdfService2 {
192
81
  templateService;
193
- logger;
194
- pool;
195
- constructor(templateService, logger, options = {}) {
82
+ browserController;
83
+ defaultLocale;
84
+ constructor(templateService, browserController, options = {}) {
196
85
  this.templateService = templateService;
197
- this.logger = logger;
198
- const args = ["--font-render-hinting=none", "--disable-web-security", "--disable-features=IsolateOrigins", "--disable-site-isolation-trials"];
199
- const env = {};
200
- if ((0, import_type_guards.isDefined)(options.language)) {
201
- args.push(`--lang=${options.language}`);
202
- env["LANGUAGE"] = options.language;
203
- }
204
- this.pool = new import_pool.Pool(async () => puppeteer.launch({ headless: true, args, env }), async (browser) => browser.close(), logger);
205
- }
206
- [import_container.afterResolve]() {
207
- import_core.disposer.add(this);
208
- }
209
- async [import_disposable.disposeAsync]() {
210
- return this.dispose();
211
- }
212
- async dispose() {
213
- return this.pool.dispose();
86
+ this.browserController = browserController;
87
+ this.defaultLocale = options.locale;
214
88
  }
215
89
  /**
216
90
  * Renders HTML to pdf stream
@@ -219,7 +93,7 @@ let PdfService = class PdfService2 {
219
93
  * @returns pdf stream
220
94
  */
221
95
  renderHtmlStream(html, options) {
222
- return this.renderStream(async (page) => page.setContent(html, { waitUntil: options?.waitForNetworkIdle == true ? "networkidle2" : "load" }), options);
96
+ return this.renderStream(async (page) => page.setContent(html, { waitUntil: options?.waitForNetworkIdle == true ? "networkidle" : "load" }), options);
223
97
  }
224
98
  /**
225
99
  * Renders HTML to pdf
@@ -238,8 +112,8 @@ let PdfService = class PdfService2 {
238
112
  * @returns pdf stream
239
113
  */
240
114
  renderUrlStream(url, options) {
241
- return this.renderStream(async (page) => {
242
- await page.goto(url, { waitUntil: options?.waitForNetworkIdle == true ? "networkidle2" : "load" });
115
+ return this.renderStream(async (controller) => {
116
+ await controller.navigate(url, { waitUntil: options?.waitForNetworkIdle == true ? "networkidle" : "load" });
243
117
  }, options);
244
118
  }
245
119
  /**
@@ -262,8 +136,8 @@ let PdfService = class PdfService2 {
262
136
  renderTemplateStream(keyOrTemplate, templateContext, options) {
263
137
  return this.renderStream(async (page) => {
264
138
  const { fields: { header, body, footer }, options: optionsFromTemplate } = await this.templateService.render(keyOrTemplate, templateContext);
265
- await page.setContent(body, { ...optionsFromTemplate, headerTemplate: header, footerTemplate: footer, waitUntil: options?.waitForNetworkIdle == true ? "networkidle2" : "load", ...options });
266
- return { ...optionsFromTemplate, headerTemplate: header, footerTemplate: footer, ...options };
139
+ await page.setContent(body, { timeout: options?.timeout, waitUntil: options?.waitForNetworkIdle == true ? "networkidle" : "load" });
140
+ return { ...optionsFromTemplate, headerTemplate: header, footerTemplate: footer };
267
141
  }, options);
268
142
  }
269
143
  /**
@@ -279,67 +153,23 @@ let PdfService = class PdfService2 {
279
153
  }
280
154
  renderStream(handler, options = {}) {
281
155
  return (0, import_readable_stream_from_promise.readableStreamFromPromise)(async () => {
282
- const browser = await this.pool.get();
283
- try {
284
- let page;
285
- try {
286
- page = await browser.newPage();
287
- } catch (error) {
288
- await this.pool.disposeInstance(browser);
289
- throw error;
290
- }
291
- if ((0, import_type_guards.isDefined)(options.language)) {
292
- await page.setExtraHTTPHeaders({ "Accept-Language": options.language });
293
- }
294
- const timeoutRef = setTimeout(() => void page.close().catch((error) => this.logger.error(error)), options.timeout ?? import_units.millisecondsPerMinute);
295
- const optionsFromHandler = await handler(page) ?? {};
296
- const mergedOptions = { ...optionsFromHandler, ...options };
297
- const createPdfOptions = this.convertOptions(mergedOptions);
298
- const pdfStream = await page.createPDFStream(createPdfOptions);
299
- return (0, import_finalize_stream.finalizeStream)((0, import_readable_stream_adapter.getReadableStreamFromIterable)(pdfStream), async () => {
300
- clearTimeout(timeoutRef);
301
- try {
302
- await page.close();
303
- } catch (error) {
304
- this.logger.error(error);
305
- throw error;
306
- } finally {
307
- await this.pool.release(browser);
308
- }
309
- });
310
- } catch (error) {
311
- await this.pool.release(browser);
312
- throw error;
313
- }
156
+ const page = (0, import_type_guards.isDefined)(options.browserContext) ? await options.browserContext.newPage() : await this.browserController.newPage({ locale: options.locale ?? this.defaultLocale });
157
+ const optionsFromHandler = await handler(page);
158
+ const pdfStream = page.renderPdfStream({ ...optionsFromHandler, ...options });
159
+ const close = async () => page.close();
160
+ return (0, import_finalize_stream.finalizeStream)(pdfStream, {
161
+ beforeDone: close,
162
+ beforeCancel: close,
163
+ error: close
164
+ });
314
165
  });
315
166
  }
316
- convertOptions(options) {
317
- const margin = (0, import_type_guards.isUndefined)(options.margin) ? void 0 : (0, import_type_guards.isObject)(options.margin) ? options.margin : {
318
- top: options.margin,
319
- bottom: options.margin,
320
- right: options.margin,
321
- left: options.margin
322
- };
323
- return {
324
- format: options.format ?? "a4",
325
- scale: options.scale,
326
- landscape: options.landscape,
327
- width: options.width,
328
- height: options.height,
329
- omitBackground: options.omitDefaultBackground,
330
- printBackground: options.renderBackground,
331
- margin,
332
- displayHeaderFooter: options.displayHeaderFooter ?? ((0, import_type_guards.isDefined)(options.headerTemplate) || (0, import_type_guards.isDefined)(options.footerTemplate)),
333
- headerTemplate: options.headerTemplate,
334
- footerTemplate: options.footerTemplate
335
- };
336
- }
337
167
  };
338
168
  PdfService = __decorate([
339
169
  (0, import_container.singleton)(),
340
- __param(1, (0, import_container.resolveArg)("PdfService")),
170
+ __param(1, (0, import_container.forwardArg)((argument) => argument?.browserControllerArgument ?? { browserArguments })),
341
171
  __param(2, (0, import_container.injectArg)()),
342
- __metadata("design:paramtypes", [import_templates.TemplateService, import_logger.Logger, Object])
172
+ __metadata("design:paramtypes", [import_templates.TemplateService, import_browser_controller.BrowserController, Object])
343
173
  ], PdfService);
344
174
  function pdfTemplate(name, fields, options) {
345
175
  return {
package/pool/pool.d.ts CHANGED
@@ -34,6 +34,7 @@ export declare class Pool<T extends object> implements AsyncDisposable {
34
34
  private disposed;
35
35
  get length(): number;
36
36
  constructor(factory: PoolInstanceFactory<T>, disposer: PoolInstanceDisposer<T>, logger: Logger, options?: PoolOptions);
37
+ owns(instance: T): boolean;
37
38
  get(): Promise<T>;
38
39
  release(instance: T): Promise<void>;
39
40
  /**
package/pool/pool.js CHANGED
@@ -50,6 +50,9 @@ class Pool {
50
50
  this.placeholderInstances = 0;
51
51
  this.disposed = false;
52
52
  }
53
+ owns(instance) {
54
+ return this.usedInstances.includes(instance) || this.freeInstances.includes(instance);
55
+ }
53
56
  async get() {
54
57
  if (this.disposed) {
55
58
  throw new Error("Pool was disposed.");
@@ -79,6 +82,9 @@ class Pool {
79
82
  return this.get();
80
83
  }
81
84
  async release(instance) {
85
+ if (this.freeInstances.includes(instance)) {
86
+ throw new Error("Instance is free already.");
87
+ }
82
88
  if (!this.usedInstances.has(instance)) {
83
89
  throw new Error("Instance is not from this pool.");
84
90
  }