@cenk1cenk2/md-printer 3.2.24 → 3.4.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/README.md +213 -57
- package/dist/_virtual/{_@oxc-project_runtime@0.156.0 → _@oxc-project_runtime@0.157.0}/helpers/esm/decorate.mjs +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.156.0 → _@oxc-project_runtime@0.157.0}/helpers/esm/decorateMetadata.mjs +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.156.0 → _@oxc-project_runtime@0.157.0}/helpers/esm/decorateParam.mjs +1 -1
- package/dist/commands/index.mjs +3 -1
- package/dist/components/Localized.svelte +18 -0
- package/dist/components/SignatureBlock.svelte +8 -46
- package/dist/components/Translate.svelte +15 -0
- package/dist/components/extension.ts +8 -0
- package/dist/components/index.ts +3 -0
- package/dist/constants/attachment.constants.mjs +7 -0
- package/dist/constants/index.mjs +3 -2
- package/dist/constants/template.constants.mjs +26 -2
- package/dist/interfaces/attachment.interface.mjs +1 -0
- package/dist/modules/md-printer/md-printer.handler.mjs +4 -2
- package/dist/modules/md-printer/md-printer.module.mjs +1 -1
- package/dist/modules/md-printer/md-printer.schema.mjs +12 -1
- package/dist/services/i18n.service.mjs +6 -4
- package/dist/services/index.mjs +2 -1
- package/dist/services/markdown.service.mjs +1 -1
- package/dist/services/pdf/pdf.service.mjs +124 -0
- package/dist/services/printer.module.mjs +3 -1
- package/dist/services/printer.service.mjs +55 -11
- package/dist/services/renderer/browser.service.mjs +3 -3
- package/dist/services/renderer/renderer.service.mjs +3 -3
- package/dist/services/session/preview.service.mjs +2 -2
- package/dist/services/session/session.service.mjs +11 -11
- package/dist/services/signature/adapters/a-trust.adapter.mjs +2 -2
- package/dist/services/signature/signature.service.mjs +2 -2
- package/dist/services/template/assets.mjs +1 -1
- package/dist/services/template/render.entry.ts +6 -2
- package/dist/services/template/svelte.plugin.mjs +12 -7
- package/dist/services/template/template.schema.mjs +27 -0
- package/dist/services/template/template.service.mjs +123 -26
- package/oclif.manifest.json +16 -2
- package/package.json +14 -24
- package/templates/default/Template.svelte +0 -83
- package/templates/default/settings.json +0 -7
- package/templates/invoice/Template.svelte +0 -247
- package/templates/invoice/components/Client.svelte +0 -42
- package/templates/invoice/components/Company.svelte +0 -41
- package/templates/invoice/components/Items.svelte +0 -66
- package/templates/invoice/components/Notes.svelte +0 -21
- package/templates/invoice/components/Payment.svelte +0 -25
- package/templates/invoice/components/Signature.svelte +0 -34
- package/templates/invoice/components/Totals.svelte +0 -47
- package/templates/invoice/i18n/de.yaml +0 -30
- package/templates/invoice/i18n/en.yaml +0 -30
- package/templates/invoice/round.js +0 -2
- package/templates/invoice/settings.json +0 -11
- package/templates/kilic.dev/Template.svelte +0 -102
- package/templates/kilic.dev/settings.json +0 -7
- package/templates/mail/Template.svelte +0 -166
- package/templates/mail/settings.json +0 -7
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "../../services/index.mjs";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
3
3
|
import { BrowserService } from "../../services/renderer/browser.service.mjs";
|
|
4
4
|
import { PrinterService } from "../../services/printer.service.mjs";
|
|
5
5
|
import { PreviewService } from "../../services/session/preview.service.mjs";
|
|
6
6
|
import { SessionService } from "../../services/session/session.service.mjs";
|
|
7
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
7
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
8
8
|
import { Injectable } from "@nestjs/common";
|
|
9
9
|
import { mkdir } from "fs/promises";
|
|
10
10
|
import { dirname } from "path";
|
|
@@ -34,6 +34,8 @@ let MdPrinterHandler = class MdPrinterHandler {
|
|
|
34
34
|
outputFiletype: flags["output-filetype"],
|
|
35
35
|
stdout: flags.stdout,
|
|
36
36
|
template: flags.template,
|
|
37
|
+
templateType: flags["template-type"],
|
|
38
|
+
templateDirectory: flags["template-directory"],
|
|
37
39
|
title: flags.title,
|
|
38
40
|
language: flags.language,
|
|
39
41
|
continuous: flags.continuous,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MdPrinterHandler } from "./md-printer.handler.mjs";
|
|
2
2
|
import { PrinterModule } from "../../services/printer.module.mjs";
|
|
3
3
|
import "../../services/index.mjs";
|
|
4
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
4
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
5
5
|
import { Module } from "@nestjs/common";
|
|
6
6
|
import { CommandContext, LogLevels, LoggerModule, LogoModule } from "@cenk1cenk2/oclif-common";
|
|
7
7
|
// src/modules/md-printer/md-printer.module.ts
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { InputFileType, OutputFileType } from "../../constants/file.constants.mjs";
|
|
2
2
|
import { PreviewHost } from "../../constants/preview.constants.mjs";
|
|
3
3
|
import { SignatureProvider } from "../../constants/signature.constants.mjs";
|
|
4
|
+
import "../../constants/template.constants.mjs";
|
|
4
5
|
import { z } from "zod";
|
|
5
6
|
// src/modules/md-printer/md-printer.schema.ts
|
|
6
7
|
const MdPrinterSchema = z.object({
|
|
@@ -9,7 +10,9 @@ const MdPrinterSchema = z.object({
|
|
|
9
10
|
["input-filetype"]: z.enum(InputFileType).optional().describe("Input file type. Detected from the file extension, markdown for stdin and unknown extensions."),
|
|
10
11
|
["output-filetype"]: z.enum(OutputFileType).optional().describe("Output file type, defaults to pdf. Overwrites the one defined in front-matter."),
|
|
11
12
|
stdout: z.boolean().default(false).describe("Write the output to stdout instead of a file."),
|
|
12
|
-
template: z.string().optional().describe("Built-in template name or path to a template directory, defaults to \"default\". Overwrites the one defined in front-matter."),
|
|
13
|
+
template: z.string().optional().describe("Built-in template name or path to a template directory, defaults to \"default\", read as --template-type when given. Overwrites the one defined in front-matter."),
|
|
14
|
+
["template-type"]: z.string().optional().describe("How to read --template, one of builtin, package or directory, like the type of the object form in front-matter."),
|
|
15
|
+
["template-directory"]: z.string().optional().describe("Directory inside the package to use as the template, only valid with --template-type package."),
|
|
13
16
|
title: z.string().optional().describe("Document title. Overwrites the one defined in front-matter or the template."),
|
|
14
17
|
language: z.string().optional().describe("Language for template translations. Overwrites the one defined in front-matter and template settings."),
|
|
15
18
|
browser: z.string().optional().describe("Browser executable used for printing. Discovered automatically when omitted (Brave, Chrome, Chromium, Edge)."),
|
|
@@ -35,6 +38,14 @@ const MdPrinterSchema = z.object({
|
|
|
35
38
|
code: "custom",
|
|
36
39
|
message: "Reading from --stdin takes only the output file argument."
|
|
37
40
|
});
|
|
41
|
+
if (flags["template-type"] && !flags.template) ctx.addIssue({
|
|
42
|
+
code: "custom",
|
|
43
|
+
message: "--template-type needs --template to read."
|
|
44
|
+
});
|
|
45
|
+
if (flags["template-directory"] !== void 0 && flags["template-type"] !== "package") ctx.addIssue({
|
|
46
|
+
code: "custom",
|
|
47
|
+
message: "--template-directory is only valid with --template-type package."
|
|
48
|
+
});
|
|
38
49
|
if (flags.stdout && flags.preview) ctx.addIssue({
|
|
39
50
|
code: "custom",
|
|
40
51
|
message: "Writing to stdout is not supported with --preview."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { I18N_ACCEPTED_TYPES } from "../constants/template.constants.mjs";
|
|
2
|
-
import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
3
|
+
import __decorate from "../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
4
4
|
import { Injectable } from "@nestjs/common";
|
|
5
5
|
import { readdir } from "fs/promises";
|
|
6
6
|
import { basename, extname, join } from "path";
|
|
@@ -14,14 +14,16 @@ let I18nService = class I18nService {
|
|
|
14
14
|
this.fs = fs;
|
|
15
15
|
this.parser = parser;
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
/** Loads the folders in order, a key of a later folder replacing the same key of an earlier one while nested keys merge. */
|
|
18
|
+
async load(directories, options) {
|
|
18
19
|
const instance = i18next.createInstance();
|
|
19
20
|
await instance.init({
|
|
20
21
|
lng: options.language,
|
|
21
22
|
fallbackLng: options.fallback ?? options.language ?? "en",
|
|
22
|
-
resources:
|
|
23
|
+
resources: {},
|
|
23
24
|
interpolation: { escapeValue: false }
|
|
24
25
|
});
|
|
26
|
+
for (const directory of directories.filter((directory) => this.fs.exists(directory))) for (const [language, { translation }] of Object.entries(await this.resources(directory))) instance.addResourceBundle(language, "translation", translation, true, true);
|
|
25
27
|
return instance.getFixedT(options.language);
|
|
26
28
|
}
|
|
27
29
|
async resources(directory) {
|
package/dist/services/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { I18nService } from "./i18n.service.mjs";
|
|
2
2
|
import { MarkdownService } from "./markdown.service.mjs";
|
|
3
|
+
import { PdfService } from "./pdf/pdf.service.mjs";
|
|
3
4
|
import { PrinterModule } from "./printer.module.mjs";
|
|
4
5
|
import { PrinterService } from "./printer.service.mjs";
|
|
5
6
|
import { IncompleteSignatureError, SignatureVerificationError, parseSignedData } from "./signature/cms.mjs";
|
|
@@ -12,4 +13,4 @@ import { PreviewService } from "./session/preview.service.mjs";
|
|
|
12
13
|
import { SessionService } from "./session/session.service.mjs";
|
|
13
14
|
import "./signature/index.mjs";
|
|
14
15
|
import { TemplateService } from "./template/template.service.mjs";
|
|
15
|
-
export { ATrustAdapter, BrowserService, I18nService, IncompleteSignatureError, MarkdownService, PreviewService, PrinterModule, PrinterService, RendererService, SessionService, SignatureAdapter, SignatureService, SignatureVerificationError, TemplateService, parseSignedData };
|
|
16
|
+
export { ATrustAdapter, BrowserService, I18nService, IncompleteSignatureError, MarkdownService, PdfService, PreviewService, PrinterModule, PrinterService, RendererService, SessionService, SignatureAdapter, SignatureService, SignatureVerificationError, TemplateService, parseSignedData };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DIRECTIVE_TAG, PAGE_BREAK_CLASS } from "../constants/template.constants.mjs";
|
|
2
|
-
import __decorate from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorate from "../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
3
3
|
import { Injectable } from "@nestjs/common";
|
|
4
4
|
import { toHtml } from "hast-util-to-html";
|
|
5
5
|
import { all } from "lowlight";
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { resolveConfined } from "../template/assets.mjs";
|
|
2
|
+
import "../../constants/attachment.constants.mjs";
|
|
3
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
4
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
5
|
+
import { Injectable } from "@nestjs/common";
|
|
6
|
+
import { readFile } from "fs/promises";
|
|
7
|
+
import { resolve } from "path";
|
|
8
|
+
import { LoggerService } from "@cenk1cenk2/oclif-common";
|
|
9
|
+
import * as mupdf from "mupdf";
|
|
10
|
+
// src/services/pdf/pdf.service.ts
|
|
11
|
+
var _PdfService;
|
|
12
|
+
let PdfService = class PdfService {
|
|
13
|
+
static {
|
|
14
|
+
_PdfService = this;
|
|
15
|
+
}
|
|
16
|
+
logger;
|
|
17
|
+
static IMAGE_MAX_DIMENSION = 2e3;
|
|
18
|
+
static JPEG_QUALITY = 75;
|
|
19
|
+
constructor(logger) {
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
this.logger.setup(this.constructor.name);
|
|
22
|
+
}
|
|
23
|
+
async process(pdf, options) {
|
|
24
|
+
if (!options.attachments.length && !options.compress) return {
|
|
25
|
+
pdf,
|
|
26
|
+
assets: []
|
|
27
|
+
};
|
|
28
|
+
const document = new mupdf.PDFDocument(pdf);
|
|
29
|
+
const pages = document.countPages();
|
|
30
|
+
const assets = [];
|
|
31
|
+
const loaded = await Promise.all(options.attachments.map(async (attachment) => {
|
|
32
|
+
const { content, path } = await this.load(attachment.file, options.directory);
|
|
33
|
+
if (path) assets.push(path);
|
|
34
|
+
return {
|
|
35
|
+
attachment,
|
|
36
|
+
document: this.open(attachment.file, content),
|
|
37
|
+
anchor: this.anchor(attachment, pages)
|
|
38
|
+
};
|
|
39
|
+
}));
|
|
40
|
+
for (const { attachment, document: source, anchor } of loaded.map((item, index) => ({
|
|
41
|
+
...item,
|
|
42
|
+
index
|
|
43
|
+
})).sort((a, b) => b.anchor - a.anchor || b.index - a.index)) {
|
|
44
|
+
if (attachment.compress && !options.compress) this.compress(source);
|
|
45
|
+
for (let page = 0; page < source.countPages(); page++) document.graftPage(anchor + page, source, page);
|
|
46
|
+
this.logger.debug("Attached %s with %d pages at page %d.", attachment.file, source.countPages(), anchor + 1);
|
|
47
|
+
}
|
|
48
|
+
if (options.compress) this.compress(document);
|
|
49
|
+
const output = Buffer.from(document.saveToBuffer(options.compress ? "garbage=compact,compress,compress-fonts" : "garbage=compact,compress").asUint8Array());
|
|
50
|
+
this.logger.debug("Processed PDF: %d bytes to %d bytes.", pdf.length, output.length);
|
|
51
|
+
return {
|
|
52
|
+
pdf: output,
|
|
53
|
+
assets
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
anchor(attachment, pages) {
|
|
57
|
+
if (attachment.position === "before") return 0;
|
|
58
|
+
if (typeof attachment.position !== "number") return pages;
|
|
59
|
+
if (attachment.position > pages + 1) throw new Error(`Attachment ${attachment.file} is placed at page ${attachment.position}, but the document has ${pages} pages.`);
|
|
60
|
+
return attachment.position - 1;
|
|
61
|
+
}
|
|
62
|
+
async load(file, directory) {
|
|
63
|
+
if (/^https?:\/\//.test(file)) {
|
|
64
|
+
const response = await fetch(file);
|
|
65
|
+
if (!response.ok) throw new Error(`Attachment can not be fetched: ${file}, ${response.status} ${response.statusText}`);
|
|
66
|
+
return { content: new Uint8Array(await response.arrayBuffer()) };
|
|
67
|
+
}
|
|
68
|
+
const path = await resolveConfined(resolve(directory, file), directory);
|
|
69
|
+
if (!path) throw new Error(`Attachment does not exist or is outside of the input directory: ${file}`);
|
|
70
|
+
return {
|
|
71
|
+
content: await readFile(path),
|
|
72
|
+
path
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
open(file, content) {
|
|
76
|
+
if (Buffer.from(content.subarray(0, 5)).toString() !== "%PDF-") throw new Error(`Attachment is not a PDF: ${file}`);
|
|
77
|
+
return new mupdf.PDFDocument(content);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Re-encodes the images of a document as JPEG, scaled down to fit a printed page, whenever that makes them smaller.
|
|
81
|
+
* Soft masks, stencil masks and images below 8 bits per component keep their lossless encoding.
|
|
82
|
+
*/
|
|
83
|
+
compress(document) {
|
|
84
|
+
const images = [];
|
|
85
|
+
const masks = /* @__PURE__ */ new Set();
|
|
86
|
+
for (let number = 1; number < document.countObjects(); number++) {
|
|
87
|
+
const object = document.newIndirect(number);
|
|
88
|
+
if (!object.isStream()) continue;
|
|
89
|
+
const subtype = object.get("Subtype");
|
|
90
|
+
if (!subtype.isName() || subtype.asName() !== "Image") continue;
|
|
91
|
+
const mask = object.get("SMask");
|
|
92
|
+
if (mask.isIndirect()) masks.add(mask.asIndirect());
|
|
93
|
+
images.push(object);
|
|
94
|
+
}
|
|
95
|
+
for (const object of images) {
|
|
96
|
+
if (masks.has(object.asIndirect()) || object.get("ImageMask").valueOf() === true) continue;
|
|
97
|
+
const image = document.loadImage(object);
|
|
98
|
+
if (image.getBitsPerComponent() < 8) continue;
|
|
99
|
+
let pixmap = image.toPixmap();
|
|
100
|
+
if (pixmap.getAlpha()) continue;
|
|
101
|
+
if (!pixmap.getColorSpace().isGray() && !pixmap.getColorSpace().isRGB()) pixmap = pixmap.convertToColorSpace(mupdf.ColorSpace.DeviceRGB);
|
|
102
|
+
const [width, height] = [pixmap.getWidth(), pixmap.getHeight()];
|
|
103
|
+
const scale = Math.min(1, _PdfService.IMAGE_MAX_DIMENSION / Math.max(width, height));
|
|
104
|
+
if (scale < 1) pixmap = pixmap.warp([
|
|
105
|
+
[0, 0],
|
|
106
|
+
[width, 0],
|
|
107
|
+
[width, height],
|
|
108
|
+
[0, height]
|
|
109
|
+
], Math.round(width * scale), Math.round(height * scale));
|
|
110
|
+
const jpeg = pixmap.asJPEG(_PdfService.JPEG_QUALITY);
|
|
111
|
+
if (jpeg.length >= object.readRawStream().length) continue;
|
|
112
|
+
object.writeRawStream(jpeg);
|
|
113
|
+
object.put("Filter", document.newName("DCTDecode"));
|
|
114
|
+
object.delete("DecodeParms");
|
|
115
|
+
object.delete("Decode");
|
|
116
|
+
object.put("Width", pixmap.getWidth());
|
|
117
|
+
object.put("Height", pixmap.getHeight());
|
|
118
|
+
object.put("BitsPerComponent", 8);
|
|
119
|
+
object.put("ColorSpace", document.newName(pixmap.getColorSpace().isGray() ? "DeviceGray" : "DeviceRGB"));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
PdfService = _PdfService = __decorate([Injectable(), __decorateMetadata("design:paramtypes", [typeof LoggerService === "undefined" ? Object : LoggerService])], PdfService);
|
|
124
|
+
export { PdfService };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { I18nService } from "./i18n.service.mjs";
|
|
2
2
|
import { MarkdownService } from "./markdown.service.mjs";
|
|
3
|
+
import { PdfService } from "./pdf/pdf.service.mjs";
|
|
3
4
|
import { PrinterService } from "./printer.service.mjs";
|
|
4
5
|
import { BrowserService } from "./renderer/browser.service.mjs";
|
|
5
6
|
import { RendererService } from "./renderer/renderer.service.mjs";
|
|
@@ -9,7 +10,7 @@ import { ATrustAdapter } from "./signature/adapters/a-trust.adapter.mjs";
|
|
|
9
10
|
import { SignatureService } from "./signature/signature.service.mjs";
|
|
10
11
|
import { TemplateService } from "./template/template.service.mjs";
|
|
11
12
|
import { PRINTER_MODULE_OPTIONS } from "../constants/template.constants.mjs";
|
|
12
|
-
import __decorate from "../_virtual/_@oxc-project_runtime@0.
|
|
13
|
+
import __decorate from "../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
13
14
|
import { ConfigurableModuleBuilder, Module } from "@nestjs/common";
|
|
14
15
|
import { FilesystemModule, JsonParser, ParserModule, YamlParser } from "@cenk1cenk2/oclif-common";
|
|
15
16
|
// src/services/printer.module.ts
|
|
@@ -22,6 +23,7 @@ PrinterModule = __decorate([Module({
|
|
|
22
23
|
TemplateService,
|
|
23
24
|
BrowserService,
|
|
24
25
|
RendererService,
|
|
26
|
+
PdfService,
|
|
25
27
|
ATrustAdapter,
|
|
26
28
|
SignatureService,
|
|
27
29
|
PrinterService,
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { I18nService } from "./i18n.service.mjs";
|
|
2
2
|
import { MarkdownService } from "./markdown.service.mjs";
|
|
3
|
+
import { PdfService } from "./pdf/pdf.service.mjs";
|
|
3
4
|
import { RendererService } from "./renderer/renderer.service.mjs";
|
|
4
5
|
import { SignatureVerificationError } from "./signature/cms.mjs";
|
|
5
6
|
import { SignatureService } from "./signature/signature.service.mjs";
|
|
6
7
|
import { inlineHtml } from "./template/assets.mjs";
|
|
8
|
+
import { TemplateSourceSchema, issues } from "./template/template.schema.mjs";
|
|
7
9
|
import { TemplateService } from "./template/template.service.mjs";
|
|
10
|
+
import { AttachmentPosition } from "../constants/attachment.constants.mjs";
|
|
8
11
|
import { DEFAULT_PDF_OPTIONS } from "../constants/template.constants.mjs";
|
|
9
12
|
import { OutputFileType } from "../constants/file.constants.mjs";
|
|
10
|
-
import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.
|
|
11
|
-
import __decorate from "../_virtual/_@oxc-project_runtime@0.
|
|
13
|
+
import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
14
|
+
import __decorate from "../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
12
15
|
import { Injectable } from "@nestjs/common";
|
|
13
|
-
import { basename, dirname, extname,
|
|
16
|
+
import { basename, dirname, extname, resolve } from "path";
|
|
14
17
|
import { ConfigService, FileSystemService, LoggerService } from "@cenk1cenk2/oclif-common";
|
|
15
18
|
import { cloneDeep, mergeWith, uniq } from "es-toolkit";
|
|
16
19
|
import { parse } from "yaml";
|
|
@@ -23,8 +26,9 @@ let PrinterService = class PrinterService {
|
|
|
23
26
|
markdown;
|
|
24
27
|
template;
|
|
25
28
|
renderer;
|
|
29
|
+
pdf;
|
|
26
30
|
signature;
|
|
27
|
-
constructor(fs, logger, config, i18n, markdown, template, renderer, signature) {
|
|
31
|
+
constructor(fs, logger, config, i18n, markdown, template, renderer, pdf, signature) {
|
|
28
32
|
this.fs = fs;
|
|
29
33
|
this.logger = logger;
|
|
30
34
|
this.config = config;
|
|
@@ -32,6 +36,7 @@ let PrinterService = class PrinterService {
|
|
|
32
36
|
this.markdown = markdown;
|
|
33
37
|
this.template = template;
|
|
34
38
|
this.renderer = renderer;
|
|
39
|
+
this.pdf = pdf;
|
|
35
40
|
this.signature = signature;
|
|
36
41
|
this.logger.setup(this.constructor.name);
|
|
37
42
|
}
|
|
@@ -61,13 +66,14 @@ let PrinterService = class PrinterService {
|
|
|
61
66
|
}
|
|
62
67
|
async options(flags, input) {
|
|
63
68
|
const { data } = input;
|
|
64
|
-
const
|
|
65
|
-
const settings = await this.template.
|
|
69
|
+
const source = this.templateSource(this.templateFlags(flags) ?? data.template) ?? "default";
|
|
70
|
+
const { directory: template, settings, files } = await this.template.resolve(source, input.directory);
|
|
66
71
|
const output = flags.outputFiletype ?? data.outputFiletype ?? "pdf";
|
|
67
72
|
if (!Object.values(OutputFileType).includes(output)) throw new Error(`Output file type is not supported: ${output}, use one of ${Object.values(OutputFileType).join(", ")}.`);
|
|
68
73
|
const dest = flags.stdout ? void 0 : flags.output ?? data.dest ?? (input.file ? `${basename(input.file, extname(input.file))}.${output}` : void 0);
|
|
69
74
|
return {
|
|
70
75
|
template,
|
|
76
|
+
files,
|
|
71
77
|
output,
|
|
72
78
|
dest: dest && resolve(dest),
|
|
73
79
|
title: flags.title ?? data.documentTitle,
|
|
@@ -77,11 +83,13 @@ let PrinterService = class PrinterService {
|
|
|
77
83
|
highlight: settings.highlightStyle ?? "atom-one-dark",
|
|
78
84
|
pdf: this.pdfOptions(settings.pdfOptions, data.pdfOptions),
|
|
79
85
|
i18n: settings.i18n ?? {},
|
|
80
|
-
sign: this.signOptions(flags, settings.sign, data.sign)
|
|
86
|
+
sign: this.signOptions(flags, settings.sign, data.sign),
|
|
87
|
+
attachments: this.attachments(data.attachments),
|
|
88
|
+
compress: data.compress === true
|
|
81
89
|
};
|
|
82
90
|
}
|
|
83
91
|
bundle(options) {
|
|
84
|
-
return this.template.bundle(options.
|
|
92
|
+
return this.template.bundle(options.files);
|
|
85
93
|
}
|
|
86
94
|
/**
|
|
87
95
|
* Resolves the signing time and the visible signature description, which the template renders before the document is signed.
|
|
@@ -98,7 +106,7 @@ let PrinterService = class PrinterService {
|
|
|
98
106
|
const { input, options } = ctx;
|
|
99
107
|
const document = await this.template.render(options.template, bundle, {
|
|
100
108
|
data: input.data,
|
|
101
|
-
t: await this.i18n.load(
|
|
109
|
+
t: await this.i18n.load(options.files.i18n, {
|
|
102
110
|
...options.i18n,
|
|
103
111
|
language: options.language
|
|
104
112
|
}),
|
|
@@ -115,6 +123,7 @@ let PrinterService = class PrinterService {
|
|
|
115
123
|
}
|
|
116
124
|
async output(ctx, document) {
|
|
117
125
|
if (ctx.options.output === "html") {
|
|
126
|
+
if (ctx.options.attachments.length || ctx.options.compress) throw new Error("Attachments and compression are only supported for PDF output.");
|
|
118
127
|
const { content, assets } = await inlineHtml(document.html, ctx.input.directory, { confined: true });
|
|
119
128
|
return {
|
|
120
129
|
content: Buffer.from(content),
|
|
@@ -127,9 +136,14 @@ let PrinterService = class PrinterService {
|
|
|
127
136
|
media: ctx.options.media,
|
|
128
137
|
continuous: ctx.options.continuous
|
|
129
138
|
});
|
|
139
|
+
const processed = await this.pdf.process(pdf, {
|
|
140
|
+
directory: ctx.input.directory,
|
|
141
|
+
attachments: ctx.options.attachments,
|
|
142
|
+
compress: ctx.options.compress
|
|
143
|
+
});
|
|
130
144
|
return {
|
|
131
|
-
content: pdf,
|
|
132
|
-
assets
|
|
145
|
+
content: processed.pdf,
|
|
146
|
+
assets: [...assets, ...processed.assets]
|
|
133
147
|
};
|
|
134
148
|
}
|
|
135
149
|
sign(ctx, pdf) {
|
|
@@ -146,6 +160,35 @@ let PrinterService = class PrinterService {
|
|
|
146
160
|
throw err;
|
|
147
161
|
});
|
|
148
162
|
}
|
|
163
|
+
templateFlags({ template, templateType, templateDirectory }) {
|
|
164
|
+
if (!templateType) return template;
|
|
165
|
+
return {
|
|
166
|
+
type: templateType,
|
|
167
|
+
[templateType === "directory" ? "path" : "name"]: template,
|
|
168
|
+
...templateDirectory !== void 0 && { directory: templateDirectory }
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
templateSource(value) {
|
|
172
|
+
if (value === void 0 || value === null) return;
|
|
173
|
+
if (typeof value === "string") return value;
|
|
174
|
+
const { success, data, error } = TemplateSourceSchema.safeParse(value);
|
|
175
|
+
if (!success) throw new Error(`Template is invalid: ${issues(error)}`);
|
|
176
|
+
return data;
|
|
177
|
+
}
|
|
178
|
+
attachments(value) {
|
|
179
|
+
if (value === void 0 || value === null) return [];
|
|
180
|
+
if (!Array.isArray(value)) throw new Error("Front-matter attachments must be a list of { file, position, compress }.");
|
|
181
|
+
return value.map((attachment, index) => {
|
|
182
|
+
if (typeof attachment?.file !== "string" || !attachment.file) throw new Error(`Attachment ${index + 1} needs a file path or URL.`);
|
|
183
|
+
const position = attachment.position ?? "after";
|
|
184
|
+
if (!Object.values(AttachmentPosition).includes(position) && !(Number.isInteger(position) && position >= 1)) throw new Error(`Attachment ${attachment.file} has an invalid position: ${position}, use ${Object.values(AttachmentPosition).join(", ")} or a page number.`);
|
|
185
|
+
return {
|
|
186
|
+
file: attachment.file,
|
|
187
|
+
position,
|
|
188
|
+
compress: attachment.compress === true
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
}
|
|
149
192
|
signOptions(flags, ...sources) {
|
|
150
193
|
return {
|
|
151
194
|
...Object.assign({}, ...sources),
|
|
@@ -176,6 +219,7 @@ PrinterService = __decorate([Injectable(), __decorateMetadata("design:paramtypes
|
|
|
176
219
|
typeof MarkdownService === "undefined" ? Object : MarkdownService,
|
|
177
220
|
typeof TemplateService === "undefined" ? Object : TemplateService,
|
|
178
221
|
typeof RendererService === "undefined" ? Object : RendererService,
|
|
222
|
+
typeof PdfService === "undefined" ? Object : PdfService,
|
|
179
223
|
typeof SignatureService === "undefined" ? Object : SignatureService
|
|
180
224
|
])], PrinterService);
|
|
181
225
|
export { PrinterService };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { discoverBrowser } from "./browser.mjs";
|
|
2
2
|
import { PRINTER_MODULE_OPTIONS } from "../../constants/template.constants.mjs";
|
|
3
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
4
|
-
import __decorateParam from "../../_virtual/_@oxc-project_runtime@0.
|
|
5
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
4
|
+
import __decorateParam from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateParam.mjs";
|
|
5
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
6
6
|
import { Inject, Injectable } from "@nestjs/common";
|
|
7
7
|
import { LoggerService } from "@cenk1cenk2/oclif-common";
|
|
8
8
|
import puppeteer from "puppeteer-core";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BrowserService } from "./browser.service.mjs";
|
|
2
1
|
import { mimeType, resolveConfined } from "../template/assets.mjs";
|
|
2
|
+
import { BrowserService } from "./browser.service.mjs";
|
|
3
3
|
import { PAGE_BREAK_CLASS } from "../../constants/template.constants.mjs";
|
|
4
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
5
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
4
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
5
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
6
6
|
import { Injectable } from "@nestjs/common";
|
|
7
7
|
import { readFile } from "fs/promises";
|
|
8
8
|
import { resolve } from "path";
|
|
@@ -2,8 +2,8 @@ import { isLoopbackRequest } from "../loopback.mjs";
|
|
|
2
2
|
import { resolveConfined } from "../template/assets.mjs";
|
|
3
3
|
import { TemplateService } from "../template/template.service.mjs";
|
|
4
4
|
import "../../constants/file.constants.mjs";
|
|
5
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
6
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
5
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
6
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
7
7
|
import { Injectable } from "@nestjs/common";
|
|
8
8
|
import { mkdtemp, rm } from "fs/promises";
|
|
9
9
|
import { join } from "path";
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { PrinterService } from "../printer.service.mjs";
|
|
2
2
|
import "../../constants/template.constants.mjs";
|
|
3
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
4
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
4
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
5
5
|
import { Injectable } from "@nestjs/common";
|
|
6
6
|
import { dirname, join, resolve } from "path";
|
|
7
7
|
import { LoggerService } from "@cenk1cenk2/oclif-common";
|
|
8
|
+
import { isEqual } from "es-toolkit";
|
|
8
9
|
import { EventEmitter } from "events";
|
|
9
10
|
import { watch } from "chokidar";
|
|
10
11
|
import { debounce } from "perfect-debounce";
|
|
@@ -53,7 +54,7 @@ let SessionService = class SessionService extends EventEmitter {
|
|
|
53
54
|
const file = resolve(path);
|
|
54
55
|
if (this.ignored.has(file)) return;
|
|
55
56
|
this.logger.debug("Changed: %s", file);
|
|
56
|
-
if (this.modules.has(file) || this.bundle
|
|
57
|
+
if (this.modules.has(file) || this.bundle?.files.components.includes(dirname(file))) this.bundle = void 0;
|
|
57
58
|
this.build();
|
|
58
59
|
}
|
|
59
60
|
async run() {
|
|
@@ -62,18 +63,17 @@ let SessionService = class SessionService extends EventEmitter {
|
|
|
62
63
|
try {
|
|
63
64
|
const input = await this.printer.input(this.flags);
|
|
64
65
|
const options = await this.printer.options(this.flags, input);
|
|
65
|
-
const
|
|
66
|
-
this.modules.
|
|
66
|
+
const { files } = options;
|
|
67
|
+
this.modules = /* @__PURE__ */ new Set([...this.modules, files.template]);
|
|
67
68
|
this.watch([
|
|
68
69
|
input.file,
|
|
69
|
-
template,
|
|
70
|
+
files.template,
|
|
71
|
+
...files.candidates,
|
|
70
72
|
join(options.template, "settings.json"),
|
|
71
|
-
join(options.template, "i18n"),
|
|
72
|
-
join(options.template, "components"),
|
|
73
73
|
options.sign.certificate && resolve(options.sign.certificate)
|
|
74
74
|
]);
|
|
75
|
-
if (this.bundle?.
|
|
76
|
-
|
|
75
|
+
if (!isEqual(this.bundle?.files, files)) this.bundle = {
|
|
76
|
+
files,
|
|
77
77
|
bundle: this.printer.bundle(options)
|
|
78
78
|
};
|
|
79
79
|
const cached = this.bundle;
|
|
@@ -82,7 +82,7 @@ let SessionService = class SessionService extends EventEmitter {
|
|
|
82
82
|
throw err;
|
|
83
83
|
});
|
|
84
84
|
if (this.bundle !== cached) return;
|
|
85
|
-
this.modules = /* @__PURE__ */ new Set([template, ...bundle.modules]);
|
|
85
|
+
this.modules = /* @__PURE__ */ new Set([files.template, ...bundle.modules]);
|
|
86
86
|
this.watch(bundle.modules);
|
|
87
87
|
const ctx = {
|
|
88
88
|
input,
|
|
@@ -4,8 +4,8 @@ import { BrowserService } from "../../renderer/browser.service.mjs";
|
|
|
4
4
|
import { IncompleteSignatureError, parseSignedData } from "../cms.mjs";
|
|
5
5
|
import { SignatureAdapter } from "../signature.adapter.mjs";
|
|
6
6
|
import "../../../constants/signature.constants.mjs";
|
|
7
|
-
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.
|
|
8
|
-
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.
|
|
7
|
+
import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
8
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
9
9
|
import { Injectable } from "@nestjs/common";
|
|
10
10
|
import { readFile } from "fs/promises";
|
|
11
11
|
import { CommandContext, LoggerService } from "@cenk1cenk2/oclif-common";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ATrustAdapter } from "./adapters/a-trust.adapter.mjs";
|
|
2
2
|
import { IncompleteSignatureError, SignatureVerificationError, parseSignedData } from "./cms.mjs";
|
|
3
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
4
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorateMetadata.mjs";
|
|
4
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.157.0/helpers/esm/decorate.mjs";
|
|
5
5
|
import { Injectable } from "@nestjs/common";
|
|
6
6
|
import { readFile } from "fs/promises";
|
|
7
7
|
import { isAbsolute, join } from "path";
|
|
@@ -2,11 +2,11 @@ import { readFile, realpath } from "fs/promises";
|
|
|
2
2
|
import { isAbsolute, relative, sep } from "path";
|
|
3
3
|
import { toHtml } from "hast-util-to-html";
|
|
4
4
|
import { visit } from "unist-util-visit";
|
|
5
|
-
import { fileURLToPath, pathToFileURL } from "url";
|
|
6
5
|
import { fromHtml } from "hast-util-from-html";
|
|
7
6
|
import { transform, transformStyleAttribute } from "lightningcss";
|
|
8
7
|
import mime from "mime";
|
|
9
8
|
import { parseSrcset, stringifySrcset } from "srcset";
|
|
9
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
10
10
|
// src/services/template/assets.ts
|
|
11
11
|
const REFERENCES = {
|
|
12
12
|
img: ["src", "srcSet"],
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import modules from 'md-printer:extension'
|
|
1
2
|
import Template from 'md-printer:template'
|
|
2
3
|
import components from 'md-printer:template-components'
|
|
3
4
|
import { render } from 'svelte/server'
|
|
4
5
|
|
|
6
|
+
import Nodes from '../../components/Nodes.svelte'
|
|
5
7
|
import Document from './Document.svelte'
|
|
6
8
|
import Margin from './Margin.svelte'
|
|
7
|
-
import Nodes from '../../components/Nodes.svelte'
|
|
8
9
|
import type { DocumentShellProps, MarginShellProps, MarkdownNode, RenderedPart, TemplateProps } from '@interfaces'
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
// a CommonJS module also comes with module.exports as the default
|
|
12
|
+
const extension = Object.fromEntries(modules.flatMap((module) => Object.entries(module).filter(([name]) => name !== 'default')))
|
|
13
|
+
|
|
14
|
+
export { components, extension }
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
17
|
* Entry of every template bundle, compiled at runtime together with the template it renders.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dataUri, isInlinableAsset } from "./assets.mjs";
|
|
2
2
|
import "../../constants/template.constants.mjs";
|
|
3
3
|
import { readFile, readdir } from "fs/promises";
|
|
4
|
-
import { basename,
|
|
4
|
+
import { basename, extname, join } from "path";
|
|
5
5
|
import { pathToFileURL } from "url";
|
|
6
6
|
import { existsSync } from "fs";
|
|
7
7
|
import { createRequire } from "module";
|
|
@@ -10,9 +10,10 @@ import { compile, preprocess } from "svelte/compiler";
|
|
|
10
10
|
/**
|
|
11
11
|
* `svelte` resolves to md-printer's copy, since templates can live outside any `node_modules`. `<style lang="postcss">` blocks are collected
|
|
12
12
|
* instead of compiled per component, so the template's stylesheet goes through Tailwind once. `md-printer:template-components` maps the shared
|
|
13
|
-
* components and the template's
|
|
13
|
+
* components and the `*.svelte` files of the template's components directory by name, the template's winning. `md-printer:extension` is the extension module of the
|
|
14
|
+
* template, or an empty module without one.
|
|
14
15
|
*/
|
|
15
|
-
function sveltePlugin({ template, components, root, stylesheets }) {
|
|
16
|
+
function sveltePlugin({ template, components, templateComponents, root, stylesheets, extension }) {
|
|
16
17
|
const require = createRequire(root);
|
|
17
18
|
return {
|
|
18
19
|
name: "md-printer:svelte",
|
|
@@ -20,6 +21,7 @@ function sveltePlugin({ template, components, root, stylesheets }) {
|
|
|
20
21
|
if (id === "md-printer:template") return template;
|
|
21
22
|
if (id === "@cenk1cenk2/md-printer/components") return components;
|
|
22
23
|
if (id === "md-printer:template-components") return `\0${id}`;
|
|
24
|
+
if (id === "md-printer:extension") return `\0${id}`;
|
|
23
25
|
if (id === "svelte" || id.startsWith("svelte/")) return {
|
|
24
26
|
id: pathToFileURL(require.resolve(id)).href,
|
|
25
27
|
external: true
|
|
@@ -28,15 +30,18 @@ function sveltePlugin({ template, components, root, stylesheets }) {
|
|
|
28
30
|
},
|
|
29
31
|
async load(id) {
|
|
30
32
|
if (id === `\0md-printer:template-components`) {
|
|
31
|
-
const
|
|
32
|
-
const files = existsSync(directory) ? (await readdir(directory)).filter((file) => extname(file) === ".svelte").sort() : [];
|
|
33
|
+
const files = (await Promise.all((templateComponents ?? []).map(async (folder) => existsSync(folder) ? (await readdir(folder)).filter((file) => extname(file) === ".svelte").sort().map((file) => join(folder, file)) : []))).flat();
|
|
33
34
|
return [
|
|
34
35
|
`import * as shared from ${JSON.stringify("@cenk1cenk2/md-printer/components")}`,
|
|
35
|
-
...files.map((file, index) => `import $${index} from ${JSON.stringify(
|
|
36
|
-
"const { Markdown, ...builtins } = shared",
|
|
36
|
+
...files.map((file, index) => `import $${index} from ${JSON.stringify(file)}`),
|
|
37
|
+
"const { Markdown, getExtension, ...builtins } = shared",
|
|
37
38
|
`export default { ...builtins, ${files.map((file, index) => `${JSON.stringify(basename(file, ".svelte"))}: $${index}`).join(", ")} }`
|
|
38
39
|
].join("\n");
|
|
39
40
|
}
|
|
41
|
+
if (id === `\0md-printer:extension`) {
|
|
42
|
+
const modules = extension ?? [];
|
|
43
|
+
return [...modules.map((file, index) => `import * as $${index} from ${JSON.stringify(file)}`), `export default [${modules.map((_, index) => `$${index}`).join(", ")}]`].join("\n");
|
|
44
|
+
}
|
|
40
45
|
if (!isInlinableAsset(id)) return null;
|
|
41
46
|
return `export default ${JSON.stringify(dataUri(id, await readFile(id)))}`;
|
|
42
47
|
},
|