@cenk1cenk2/md-printer 2.17.4 → 2.18.1

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.
@@ -0,0 +1,10 @@
1
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/decorate.js
2
+ function __decorate(decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ }
8
+
9
+ //#endregion
10
+ export { __decorate as default };
@@ -0,0 +1,7 @@
1
+ //#region \0@oxc-project+runtime@0.140.0/helpers/esm/decorateMetadata.js
2
+ function __decorateMetadata(k, v) {
3
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4
+ }
5
+
6
+ //#endregion
7
+ export { __decorateMetadata as default };
@@ -1,5 +1,7 @@
1
- import { RequiredTemplateFiles, TEMPLATE_DIRECTORY, TemplateFiles } from "../constants/template.constants.mjs";
1
+ import { DEFAULT_LANGUAGE, I18N_DIRECTORY, RequiredTemplateFiles, TEMPLATE_DIRECTORY, TemplateFiles } from "../constants/template.constants.mjs";
2
2
  import { InputFileType, OutputFileType } from "../constants/file.constants.mjs";
3
+ import { I18nService } from "../services/i18n.service.mjs";
4
+ import "../services/index.mjs";
3
5
  import tailwind from "@tailwindcss/postcss";
4
6
  import { watch } from "chokidar";
5
7
  import graymatter from "gray-matter";
@@ -51,6 +53,10 @@ var MDPrinter = class extends Command {
51
53
  char: "T",
52
54
  description: "Overwrite document title."
53
55
  }),
56
+ language: Flags.string({
57
+ char: "l",
58
+ description: "Language code for template translations. Overwrites the one defined in front-matter and template settings."
59
+ }),
54
60
  browser: Flags.string({
55
61
  char: "b",
56
62
  description: "Browser path that is going to be used for the PDF generation.",
@@ -81,10 +87,18 @@ var MDPrinter = class extends Command {
81
87
  });
82
88
  cs;
83
89
  fs;
90
+ i18n;
84
91
  browser;
92
+ register(cli) {
93
+ return {
94
+ ...cli,
95
+ providers: [...cli.providers ?? [], I18nService]
96
+ };
97
+ }
85
98
  async shouldRunBefore() {
86
99
  this.cs = this.app.get(ConfigService);
87
100
  this.fs = this.app.get(FileSystemService);
101
+ this.i18n = this.app.get(I18nService);
88
102
  await this.app.get(ParserService).register(JsonParser, YamlParser);
89
103
  this.nunjucks.addFilter("markdown_to_html", (markdown) => {
90
104
  return new showdown.Converter().makeHtml(markdown);
@@ -160,6 +174,7 @@ var MDPrinter = class extends Command {
160
174
  this.logger.debug("Tailwind CSS exists for template: %s -> %s", paths["tailwind.css"]);
161
175
  ctx.options.css = await postcss([tailwind({ base: ctx.templates })]).process(await this.fs.read(paths["tailwind.css"]), { from: paths["tailwind.css"] }).then((result) => result.css);
162
176
  }
177
+ await this.applyTranslations(ctx);
163
178
  } }]);
164
179
  }
165
180
  async shouldRunAfter(ctx) {
@@ -182,6 +197,14 @@ var MDPrinter = class extends Command {
182
197
  await this.runMd2Pdf(ctx);
183
198
  if (this.browser) await this.browser.close();
184
199
  }
200
+ async applyTranslations(ctx) {
201
+ ctx.language = this.flags.language ?? ctx.metadata?.language ?? ctx.options.i18n?.language ?? "en";
202
+ ctx.t = await this.i18n.load(join(ctx.templates, I18N_DIRECTORY), {
203
+ language: ctx.language,
204
+ fallback: ctx.options.i18n?.fallback
205
+ });
206
+ if (ctx.t) this.logger.info("Rendering with language: %s", ctx.language);
207
+ }
185
208
  continuousBrowser(browser) {
186
209
  return new Proxy(browser, { get: (target, property, receiver) => {
187
210
  if (property !== "newPage") {
@@ -242,10 +265,15 @@ var MDPrinter = class extends Command {
242
265
  let output;
243
266
  if (ctx.template) {
244
267
  this.logger.info("Rendering as template.");
245
- output = await convertMdToPdf({ content: this.nunjucks.renderString(ctx.template, {
268
+ const context = {
246
269
  ...ctx.metadata ?? {},
247
270
  content: ctx.content
248
- }) }, options, { browser: this.browser });
271
+ };
272
+ if (ctx.t) {
273
+ context.t = ctx.t;
274
+ context.language = ctx.language;
275
+ }
276
+ output = await convertMdToPdf({ content: this.nunjucks.renderString(ctx.template, context) }, options, { browser: this.browser });
249
277
  } else {
250
278
  this.logger.info("Rendering as plain file.");
251
279
  output = await convertMdToPdf({ content: ctx.content }, options, { browser: this.browser });
@@ -1,4 +1,4 @@
1
- import { RequiredTemplateFiles, TEMPLATE_DIRECTORY, TemplateFiles } from "./template.constants.mjs";
1
+ import { DEFAULT_LANGUAGE, I18N_ACCEPTED_TYPES, I18N_DIRECTORY, RequiredTemplateFiles, TEMPLATE_DIRECTORY, TemplateFiles } from "./template.constants.mjs";
2
2
  import { INPUT_FILE_ACCEPTED_TYPES, InputFileType, OUTPUT_FILE_ACCEPTED_TYPES, OutputFileType } from "./file.constants.mjs";
3
3
 
4
- export { INPUT_FILE_ACCEPTED_TYPES, InputFileType, OUTPUT_FILE_ACCEPTED_TYPES, OutputFileType, RequiredTemplateFiles, TEMPLATE_DIRECTORY, TemplateFiles };
4
+ export { DEFAULT_LANGUAGE, I18N_ACCEPTED_TYPES, I18N_DIRECTORY, INPUT_FILE_ACCEPTED_TYPES, InputFileType, OUTPUT_FILE_ACCEPTED_TYPES, OutputFileType, RequiredTemplateFiles, TEMPLATE_DIRECTORY, TemplateFiles };
@@ -10,6 +10,13 @@ let TemplateFiles = /* @__PURE__ */ function(TemplateFiles) {
10
10
  }({});
11
11
  const RequiredTemplateFiles = ["settings.json"];
12
12
  const TEMPLATE_DIRECTORY = "templates";
13
+ const I18N_DIRECTORY = "i18n";
14
+ const I18N_ACCEPTED_TYPES = [
15
+ ".yaml",
16
+ ".yml",
17
+ ".json"
18
+ ];
19
+ const DEFAULT_LANGUAGE = "en";
13
20
 
14
21
  //#endregion
15
- export { RequiredTemplateFiles, TEMPLATE_DIRECTORY, TemplateFiles };
22
+ export { DEFAULT_LANGUAGE, I18N_ACCEPTED_TYPES, I18N_DIRECTORY, RequiredTemplateFiles, TEMPLATE_DIRECTORY, TemplateFiles };
@@ -0,0 +1,40 @@
1
+ import { DEFAULT_LANGUAGE, I18N_ACCEPTED_TYPES } from "../constants/template.constants.mjs";
2
+ import __decorateMetadata from "../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.mjs";
3
+ import __decorate from "../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.mjs";
4
+ import { basename, extname, join } from "path";
5
+ import { ConfigService, FileSystemService } from "@cenk1cenk2/oclif-common";
6
+ import { Injectable } from "@nestjs/common";
7
+ import i18next from "i18next";
8
+
9
+ //#region src/services/i18n.service.ts
10
+ let I18nService = class I18nService {
11
+ fs;
12
+ cs;
13
+ constructor(fs, cs) {
14
+ this.fs = fs;
15
+ this.cs = cs;
16
+ }
17
+ async load(directory, options) {
18
+ if (!this.fs.exists(directory)) return;
19
+ const instance = i18next.createInstance();
20
+ await instance.init({
21
+ lng: options.language,
22
+ fallbackLng: options.fallback ?? options.language ?? "en",
23
+ resources: await this.resources(directory),
24
+ interpolation: { escapeValue: false }
25
+ });
26
+ return instance.getFixedT(options.language);
27
+ }
28
+ async resources(directory) {
29
+ const files = (await this.fs.extra.readdir(directory)).filter((file) => I18N_ACCEPTED_TYPES.includes(extname(file)));
30
+ const resources = {};
31
+ await Promise.all(files.map(async (file) => {
32
+ resources[basename(file, extname(file))] = { translation: await this.cs.read(join(directory, file)) };
33
+ }));
34
+ return resources;
35
+ }
36
+ };
37
+ I18nService = __decorate([Injectable(), __decorateMetadata("design:paramtypes", [typeof FileSystemService === "undefined" ? Object : FileSystemService, typeof ConfigService === "undefined" ? Object : ConfigService])], I18nService);
38
+
39
+ //#endregion
40
+ export { I18nService };
@@ -0,0 +1,3 @@
1
+ import { I18nService } from "./i18n.service.mjs";
2
+
3
+ export { I18nService };
@@ -117,6 +117,14 @@
117
117
  "multiple": false,
118
118
  "type": "option"
119
119
  },
120
+ "language": {
121
+ "char": "l",
122
+ "description": "Language code for template translations. Overwrites the one defined in front-matter and template settings.",
123
+ "name": "language",
124
+ "hasDynamicHelp": false,
125
+ "multiple": false,
126
+ "type": "option"
127
+ },
120
128
  "browser": {
121
129
  "char": "b",
122
130
  "description": "Browser path that is going to be used for the PDF generation.",
@@ -157,5 +165,5 @@
157
165
  "enableJsonFlag": false
158
166
  }
159
167
  },
160
- "version": "2.17.4"
168
+ "version": "2.18.1"
161
169
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cenk1cenk2/md-printer",
3
- "version": "2.17.4",
3
+ "version": "2.18.1",
4
4
  "description": "A markdown printer.",
5
5
  "module": "dist/index.mjs",
6
6
  "type": "module",
@@ -71,7 +71,8 @@
71
71
  ],
72
72
  "dependencies": {
73
73
  "@cenk1cenk2/oclif-common": "^7.0.12",
74
- "@listr2/manager": "^4.2.1",
74
+ "@listr2/manager": "^4.2.3",
75
+ "@nestjs/common": "11.1.16",
75
76
  "@oclif/core": "^4.8.4",
76
77
  "@oclif/plugin-help": "^6.2.37",
77
78
  "@tailwindcss/forms": "^0.5.11",
@@ -81,7 +82,8 @@
81
82
  "fs-extra": "^11.3.4",
82
83
  "get-port": "^7.1.0",
83
84
  "gray-matter": "^4.0.3",
84
- "listr2": "^10.2.1",
85
+ "i18next": "^26.3.6",
86
+ "listr2": "^11.0.0",
85
87
  "md-to-pdf": "^5.2.5",
86
88
  "nunjucks": "^3.2.4",
87
89
  "postcss": "^8.5.8",
@@ -111,7 +113,7 @@
111
113
  "tpm": "^1.4.14",
112
114
  "ts-node": "^10.9.2",
113
115
  "tsconfig-paths": "^4.2.0",
114
- "tsdown": "^0.22.7",
116
+ "tsdown": "^0.22.8",
115
117
  "typescript": "^6.0.3"
116
118
  },
117
119
  "config": {
@@ -0,0 +1,24 @@
1
+ ---
2
+ meta:
3
+ title: Rechnung
4
+ sections:
5
+ from: VON
6
+ to: AN
7
+ payment: ZAHLUNG
8
+ notes: NOTIZEN
9
+ invoice: RECHNUNG
10
+ signature: UNTERSCHRIFT
11
+ fields:
12
+ date: Datum
13
+ id: Rechnungsnr.
14
+ table:
15
+ description: Beschreibung
16
+ quantity: Menge
17
+ price: Preis
18
+ subtotal: Zwischensumme
19
+ tax: MwSt.
20
+ total: Gesamt
21
+ summary:
22
+ subtotal: Zwischensumme
23
+ tax: MwSt.
24
+ total: Gesamt
@@ -0,0 +1,24 @@
1
+ ---
2
+ meta:
3
+ title: Invoice
4
+ sections:
5
+ from: FROM
6
+ to: TO
7
+ payment: PAYMENT
8
+ notes: NOTES
9
+ invoice: INVOICE
10
+ signature: SIGNATURE
11
+ fields:
12
+ date: Date
13
+ id: Invoice#
14
+ table:
15
+ description: Description
16
+ quantity: Qty
17
+ price: Price
18
+ subtotal: Subtotal
19
+ tax: Tax
20
+ total: Total
21
+ summary:
22
+ subtotal: Subtotal
23
+ tax: Tax
24
+ total: Total
@@ -1,6 +1,10 @@
1
1
  {
2
2
  "body_class": [],
3
3
  "highlight_style": "atom-one-dark",
4
+ "i18n": {
5
+ "language": "en",
6
+ "fallback": "en"
7
+ },
4
8
  "pdf_options": {
5
9
  "format": "A4",
6
10
  "margin": "0mm 0mm 12mm 0mm",
@@ -2,13 +2,13 @@
2
2
  vim: ft=htmldjango
3
3
  -->
4
4
  <!DOCTYPE html>
5
- <html lang="en">
5
+ <html lang="{{ language }}">
6
6
 
7
7
  <head>
8
8
  <meta charset="UTF-8">
9
9
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
10
10
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
- <title>Invoice</title>
11
+ <title>{{ t('meta.title') }}</title>
12
12
  </head>
13
13
 
14
14
  <body>
@@ -17,7 +17,7 @@
17
17
  <img src="https://main.s3.kilic.dev/html/icon.png" alt="logo"
18
18
  class="absolute h-40 top-1/2 left-1/2 -translate-x-1/2 -translate-y-[62%] drop-shadow-lg drop-shadow-gray-900 z-10">
19
19
  <div class="col-span-1 flex flex-col justify-center text-lg font-extrabold text-gray-100">
20
- <p class="text-vertical">FROM</p>
20
+ <p class="text-vertical">{{ t('sections.from') }}</p>
21
21
  </div>
22
22
  <div class="col-start-2 col-span-5 flex flex-col justify-start p-4 pt-10 mr-12">
23
23
  <h1>Cenk Kılıç</h1>
@@ -36,12 +36,12 @@
36
36
  </div>
37
37
  </div>
38
38
  <div class="col-span-6 bg-gray-900 rounded-bl-4xl flex flex-col justify-center text-center">
39
- <p class="p-4 font-bold text-white text-6xl">INVOICE</p>
39
+ <p class="p-4 font-bold text-white text-6xl">{{ t('invoice') }}</p>
40
40
  </div>
41
41
  </section>
42
42
  <section id="client" class="grid grid-cols-12">
43
43
  <div class="col-span-1 flex flex-col justify-center text-lg font-extrabold text-gray-100">
44
- <p class="text-vertical">TO</p>
44
+ <p class="text-vertical">{{ t('sections.to') }}</p>
45
45
  </div>
46
46
  <div class="col-span-5 flex flex-col justify-start p-4">
47
47
  <h2>{{ client.name }}</h2>
@@ -54,12 +54,12 @@
54
54
  <div class="grid grid-rows-2 gap-4 w-full mr-12">
55
55
  <div
56
56
  class="p-2 flex flex-row justify-between items-center rounded-xl bg-gray-50 border border-gray-50! inset-shadow-xs inset-shadow-gray-400">
57
- <p class="font-bold">Date</p>
57
+ <p class="font-bold">{{ t('fields.date') }}</p>
58
58
  <p class="font-semibold">{{ date }}</p>
59
59
  </div>
60
60
  <div
61
61
  class="p-2 flex flex-row justify-between items-center rounded-xl bg-gray-50 border border-gray-50! inset-shadow-xs inset-shadow-gray-400">
62
- <p class="font-bold">Invoice#</p>
62
+ <p class="font-bold">{{ t('fields.id') }}</p>
63
63
  <p class="font-semibold">{{ id }}</p>
64
64
  </div>
65
65
  </div>
@@ -71,22 +71,22 @@
71
71
  <thead class="border-b-1 border-b-gray-900! border-x-2 border-x-gray-900!">
72
72
  <tr>
73
73
  <th scope="col" class="w-md text-center">
74
- Description
74
+ {{ t('table.description') }}
75
75
  </th>
76
76
  <th scope="col" class="w-[10%] text-center">
77
- Qty
77
+ {{ t('table.quantity') }}
78
78
  </th>
79
79
  <th scope="col" class="w-[10%] text-center">
80
- Price
80
+ {{ t('table.price') }}
81
81
  </th>
82
82
  <th scope="col" class="w-[10%] text-center">
83
- Subtotal
83
+ {{ t('table.subtotal') }}
84
84
  </th>
85
85
  <th scope="col" class="w-[10%] text-center">
86
- Tax
86
+ {{ t('table.tax') }}
87
87
  </th>
88
88
  <th scope="col" class="w-[14%] font-semibold text-center">
89
- Total
89
+ {{ t('table.total') }}
90
90
  </th>
91
91
  </tr>
92
92
  </thead>
@@ -123,7 +123,7 @@
123
123
  </section>
124
124
  <section id="payment" class="grid grid-cols-12">
125
125
  <div class="col-span-1 flex flex-col justify-center text-lg font-extrabold text-gray-100 bg-gray-900">
126
- <p class="text-vertical">PAYMENT</p>
126
+ <p class="text-vertical">{{ t('sections.payment') }}</p>
127
127
  </div>
128
128
  <div
129
129
  class="col-span-5 flex flex-col p-4 ml-[-1px] pl-5 justify-center font-semibold bg-gray-700 rounded-r-4xl text-white">
@@ -140,7 +140,7 @@
140
140
  <div
141
141
  class="flex flex-row justify-between font-semibold bg-gray-50 rounded-lg border border-gray-50! inset-shadow-xs inset-shadow-gray-400 py-1 px-2">
142
142
  <p>
143
- Subtotal
143
+ {{ t('summary.subtotal') }}
144
144
  </p>
145
145
  <p>
146
146
  {{ calculated_subtotal | round(2) }}{{ currency }}
@@ -149,7 +149,7 @@
149
149
  <div
150
150
  class="flex flex-row justify-between font-semibold bg-gray-50 rounded-lg border border-gray-50! inset-shadow-xs inset-shadow-gray-400 py-1 px-2">
151
151
  <p>
152
- Tax
152
+ {{ t('summary.tax') }}
153
153
  </p>
154
154
  <p>
155
155
  {% if calculated_tax > 0 %}
@@ -163,7 +163,7 @@
163
163
  <div
164
164
  class="flex flex-row justify-between font-bold rounded-lg text-primary-500 bg-gray-50 border border-gray-50! inset-shadow-xs inset-shadow-gray-400 py-1 px-2">
165
165
  <p>
166
- Total
166
+ {{ t('summary.total') }}
167
167
  </p>
168
168
  <p>
169
169
  {% set calculated_total = calculated_subtotal + calculated_tax %}
@@ -175,7 +175,7 @@
175
175
  </section>
176
176
  <section id="footer" class="grid grid-cols-12">
177
177
  <div class="col-span-1 flex flex-col justify-center text-lg font-extrabold text-gray-100">
178
- <p class="text-vertical">NOTES</p>
178
+ <p class="text-vertical">{{ t('sections.notes') }}</p>
179
179
  </div>
180
180
  <div class="col-span-5 flex flex-col p-4 text-sm leading-tight prose">
181
181
  {{ content | safe }}<br />
@@ -183,7 +183,7 @@
183
183
  <div class="col-span-1"></div>
184
184
  <div
185
185
  class="col-span-5 flex flex-col justify-end text-center m-8 mr-16 p-4 pb-0 border-2 border-gray-50! rounded-xl text-xs text-gray-100 h-36">
186
- <p>SIGNATURE</p>
186
+ <p>{{ t('signature') }}</p>
187
187
  </div>
188
188
  </section>
189
189
  </div>