@pactosigna/records 0.1.1 → 0.1.3

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/dist/cli.js CHANGED
@@ -76,6 +76,52 @@ function readDocuments(rootDir, folderPath, statusFilter = INCLUDED_STATUSES) {
76
76
  // src/pdf/markdown-to-pdfmake.ts
77
77
  import MarkdownIt from "markdown-it";
78
78
  var md = new MarkdownIt();
79
+ var UNICODE_REPLACEMENTS = {
80
+ "\u2264": "<=",
81
+ // ≤
82
+ "\u2265": ">=",
83
+ // ≥
84
+ "\u2260": "!=",
85
+ // ≠
86
+ "\u2248": "~=",
87
+ // ≈
88
+ "\xB1": "+/-",
89
+ // ±
90
+ "\u2014": "--",
91
+ // — (em dash)
92
+ "\u2013": "-",
93
+ // – (en dash)
94
+ "\u2018": "'",
95
+ // ' (left single quote)
96
+ "\u2019": "'",
97
+ // ' (right single quote)
98
+ "\u201C": '"',
99
+ // " (left double quote)
100
+ "\u201D": '"',
101
+ // " (right double quote)
102
+ "\u2026": "...",
103
+ // … (ellipsis)
104
+ "\u2192": "->",
105
+ // →
106
+ "\u2190": "<-",
107
+ // ←
108
+ "\xD7": "x",
109
+ // × (multiplication sign)
110
+ "\xF7": "/",
111
+ // ÷ (division sign)
112
+ "\u221E": "Inf",
113
+ // ∞
114
+ "\u2211": "Sum",
115
+ // ∑
116
+ "\u0394": "Delta",
117
+ // Δ
118
+ "\u03BC": "u"
119
+ // μ (micro)
120
+ };
121
+ var UNICODE_PATTERN = new RegExp("[" + Object.keys(UNICODE_REPLACEMENTS).join("") + "]", "g");
122
+ function sanitizeUnicode(text) {
123
+ return text.replace(UNICODE_PATTERN, (match) => UNICODE_REPLACEMENTS[match] ?? match);
124
+ }
79
125
  function markdownToPdfmake(markdown) {
80
126
  if (!markdown.trim()) return [];
81
127
  const tokens = md.parse(markdown, {});
@@ -125,7 +171,7 @@ function markdownToPdfmake(markdown) {
125
171
  }
126
172
  if (token.type === "fence") {
127
173
  result.push({
128
- text: token.content,
174
+ text: sanitizeUnicode(token.content),
129
175
  style: "code",
130
176
  margin: [0, 4, 0, 4],
131
177
  background: "#F5F5F5"
@@ -163,7 +209,7 @@ function parseInlineContent(token) {
163
209
  italics = false;
164
210
  break;
165
211
  case "code_inline":
166
- fragments.push({ text: child.content, font: "Courier", fontSize: 9 });
212
+ fragments.push({ text: sanitizeUnicode(child.content), font: "Courier", fontSize: 9 });
167
213
  break;
168
214
  case "softbreak":
169
215
  case "hardbreak":
@@ -171,17 +217,17 @@ function parseInlineContent(token) {
171
217
  break;
172
218
  case "text":
173
219
  if (bold || italics) {
174
- const fragment = { text: child.content };
220
+ const fragment = { text: sanitizeUnicode(child.content) };
175
221
  if (bold) fragment.bold = true;
176
222
  if (italics) fragment.italics = true;
177
223
  fragments.push(fragment);
178
224
  } else {
179
- fragments.push(child.content);
225
+ fragments.push(sanitizeUnicode(child.content));
180
226
  }
181
227
  break;
182
228
  default:
183
229
  if (child.content) {
184
- fragments.push(child.content);
230
+ fragments.push(sanitizeUnicode(child.content));
185
231
  }
186
232
  break;
187
233
  }
@@ -275,6 +321,33 @@ function parseTable(tokens, startIndex) {
275
321
  };
276
322
  }
277
323
 
324
+ // src/pdf/logo.ts
325
+ import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
326
+ import { resolve as resolve3 } from "path";
327
+ var DEFAULT_LOGO_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="86 33 112 132" fill="none">
328
+ <path d="M 126.660 39.048 C 118.948 40.342, 108.092 43.909, 100.250 47.726 L 93 51.254 93 79.417 C 93 101.290, 93.337 108.873, 94.508 113.369 C 99.124 131.093, 111.353 144.203, 132.521 154.123 L 141.228 158.203 147.482 155.545 C 164.571 148.282, 177.761 137.330, 183.523 125.620 C 185.450 121.704, 187.687 115.350, 188.496 111.500 C 190.017 104.251, 190.622 77.552, 189.250 78.172 C 188.838 78.359, 186.137 79.754, 183.250 81.273 L 178 84.034 177.976 97.767 C 177.955 109.837, 177.670 112.188, 175.617 117.178 C 174.332 120.302, 171.823 124.699, 170.040 126.950 C 166.118 131.901, 156.845 138.641, 147.912 143.031 L 141.324 146.270 133.165 142.025 C 123.422 136.956, 112.066 126.834, 108.987 120.474 C 104.626 111.464, 104.024 106.777, 104.012 81.694 L 104 57.888 108.468 55.911 C 118.291 51.566, 127.969 49.691, 141 49.610 C 154.549 49.525, 161.523 50.879, 172.184 55.663 L 178 58.273 178.015 67.887 C 178.024 73.174, 178.361 78.008, 178.765 78.629 C 179.273 79.409, 181.073 78.866, 184.588 76.874 L 189.677 73.990 189.588 62.811 L 189.500 51.632 182.359 47.990 C 173.984 43.718, 164.090 40.483, 155 39.044 C 147.525 37.861, 133.720 37.863, 126.660 39.048 M 126.500 55.097 C 124.300 55.590, 119.463 56.951, 115.750 58.122 L 109 60.251 109 85.729 L 109 111.207 113.250 117.047 C 115.588 120.259, 117.838 122.912, 118.250 122.943 C 118.662 122.975, 119 116.984, 119 109.630 L 119 96.261 132.250 95.756 C 142.964 95.347, 146.648 94.801, 151.500 92.903 C 167.650 86.582, 173.814 69.996, 163.666 60.161 C 159.792 56.406, 152.831 54, 145.841 54 L 141 54 141 59 L 141 64 145.435 64 C 153.585 64, 158 66.985, 158 72.495 C 158 74.610, 157.079 76.941, 155.504 78.813 C 151.445 83.637, 146.077 85.209, 131.750 85.768 L 119 86.265 119 76.758 L 119 67.250 122.125 66.625 C 123.844 66.281, 125.644 66, 126.125 66 C 126.606 66, 127 69.600, 127 74 L 127 82 132 82 L 137 82 137 68 L 137 54 133.750 54.100 C 131.963 54.156, 128.700 54.604, 126.500 55.097 M 159.103 93.372 C 143.915 101.453, 141 104.415, 141 111.767 C 141 115.024, 141.605 116.696, 143.455 118.545 C 144.805 119.895, 146.717 120.996, 147.705 120.990 C 148.692 120.985, 151.907 119.860, 154.849 118.490 C 160.989 115.632, 162 115.473, 162 117.364 C 162 118.898, 157.383 122.272, 148.500 127.227 C 142.608 130.513, 142.495 130.658, 142.195 135.287 C 142.028 137.879, 142.122 140, 142.406 140 C 142.689 140, 146.800 137.874, 151.541 135.277 C 166.125 127.286, 171 121.968, 171 114.050 C 171 109.325, 168.324 106, 164.522 106 C 163.159 106, 159.572 107.213, 156.550 108.695 C 153.528 110.177, 150.722 111.055, 150.313 110.647 C 148.679 109.012, 152.158 106.229, 162.820 100.641 L 174 94.781 174 90.391 C 174 87.976, 173.662 86.055, 173.250 86.122 C 172.838 86.189, 166.471 89.451, 159.103 93.372 M 127 115.952 L 127 132.904 131.430 135.952 C 133.867 137.628, 136.117 139, 136.430 139 C 136.744 139, 137 130, 137 119 L 137 99 132 99 L 127 99 127 115.952" fill="#0D2D56" fill-rule="evenodd"/>
329
+ <path d="M 159.103 93.372 C 143.915 101.453, 141 104.415, 141 111.767 C 141 115.024, 141.605 116.696, 143.455 118.545 C 144.805 119.895, 146.717 120.996, 147.705 120.990 C 148.692 120.985, 151.907 119.860, 154.849 118.490 C 160.989 115.632, 162 115.473, 162 117.364 C 162 118.898, 157.383 122.272, 148.500 127.227 C 142.608 130.513, 142.495 130.658, 142.195 135.287 C 142.028 137.879, 142.122 140, 142.406 140 C 142.689 140, 146.800 137.874, 151.541 135.277 C 166.125 127.286, 171 121.968, 171 114.050 C 171 109.325, 168.324 106, 164.522 106 C 163.159 106, 159.572 107.213, 156.550 108.695 C 153.528 110.177, 150.722 111.055, 150.313 110.647 C 148.679 109.012, 152.158 106.229, 162.820 100.641 L 174 94.781 174 90.391 C 174 87.976, 173.662 86.055, 173.250 86.122 C 172.838 86.189, 166.471 89.451, 159.103 93.372 M 127 115.952 L 127 132.904 131.430 135.952 C 133.867 137.628, 136.117 139, 136.430 139 C 136.744 139, 137 130, 137 119 L 137 99 132 99 L 127 99 127 115.952" fill="#73C4B0" fill-rule="evenodd"/>
330
+ </svg>`;
331
+ var HEADER_LOGO_HEIGHT = 30;
332
+ function resolveHeaderLogo(rootDir, customLogoPath) {
333
+ if (customLogoPath) {
334
+ const absPath = resolve3(rootDir, customLogoPath);
335
+ if (existsSync2(absPath)) {
336
+ const ext = absPath.toLowerCase();
337
+ if (ext.endsWith(".png") || ext.endsWith(".jpg") || ext.endsWith(".jpeg")) {
338
+ const data = readFileSync3(absPath);
339
+ const mime = ext.endsWith(".png") ? "image/png" : "image/jpeg";
340
+ const base64 = `data:${mime};base64,${data.toString("base64")}`;
341
+ return { image: base64, height: HEADER_LOGO_HEIGHT };
342
+ }
343
+ }
344
+ }
345
+ return {
346
+ svg: DEFAULT_LOGO_SVG,
347
+ height: HEADER_LOGO_HEIGHT
348
+ };
349
+ }
350
+
278
351
  // src/pdf/layout.ts
279
352
  var HEADER_GRAY = "#F0F0F0";
280
353
  var HEADING_COLOR = "#2C3E50";
@@ -331,8 +404,9 @@ function buildCoverPage(options) {
331
404
  return cover;
332
405
  }
333
406
  function buildDocumentDefinition(options) {
334
- const { recordTitle, recordId, version, date, content = [] } = options;
407
+ const { rootDir, config, recordTitle, recordId, version, date, content = [] } = options;
335
408
  const coverPage = buildCoverPage(options);
409
+ const logo = resolveHeaderLogo(rootDir, config.branding.logo);
336
410
  return {
337
411
  pageSize: "A4",
338
412
  pageMargins: [40, 80, 40, 50],
@@ -355,7 +429,7 @@ function buildDocumentDefinition(options) {
355
429
  widths: [usableWidth * 0.2, "*", usableWidth * 0.25],
356
430
  body: [
357
431
  [
358
- { text: "[LOGO]", fontSize: 8, color: "#999999" },
432
+ logo,
359
433
  {
360
434
  stack: [
361
435
  { text: recordTitle, bold: true, fontSize: 10, alignment: "center" },
@@ -438,6 +512,7 @@ function generateUrs(input) {
438
512
  }
439
513
  return buildDocumentDefinition({
440
514
  config: input.config,
515
+ rootDir: input.rootDir,
441
516
  recordTitle: "User Requirements Specification",
442
517
  recordId: "URS",
443
518
  version: input.version,
@@ -474,6 +549,7 @@ function generatePrs(input) {
474
549
  }
475
550
  return buildDocumentDefinition({
476
551
  config: input.config,
552
+ rootDir: input.rootDir,
477
553
  recordTitle: "Product Requirements Specification",
478
554
  recordId: "PRS",
479
555
  version: input.version,
@@ -510,6 +586,7 @@ function generateSrs(input) {
510
586
  }
511
587
  return buildDocumentDefinition({
512
588
  config: input.config,
589
+ rootDir: input.rootDir,
513
590
  recordTitle: "Software Requirements Specification",
514
591
  recordId: "SRS",
515
592
  version: input.version,
@@ -727,6 +804,7 @@ function generatePta(input) {
727
804
  }
728
805
  return buildDocumentDefinition({
729
806
  config: input.config,
807
+ rootDir: input.rootDir,
730
808
  recordTitle: "Product Traceability Analysis",
731
809
  recordId: "PTA",
732
810
  version: input.version,
@@ -2162,7 +2240,9 @@ var ArchitectureFrontmatterSchema = z62.object({
2162
2240
  author: z62.string().min(1),
2163
2241
  reviewers: z62.array(z62.string()).optional(),
2164
2242
  /** Approver list — required for all regulated document types */
2165
- approvers: z62.array(z62.string()).min(1)
2243
+ approvers: z62.array(z62.string()).min(1),
2244
+ /** SRS requirement IDs this architecture item implements (IEC 62304 §5.3.1) */
2245
+ implements: z62.array(z62.string().min(1)).optional()
2166
2246
  });
2167
2247
  var DetailedDesignFrontmatterSchema = z62.object({
2168
2248
  id: z62.string().min(1),
@@ -2180,7 +2260,9 @@ var DetailedDesignFrontmatterSchema = z62.object({
2180
2260
  author: z62.string().min(1),
2181
2261
  reviewers: z62.array(z62.string()).optional(),
2182
2262
  /** Approver list — required for all regulated document types */
2183
- approvers: z62.array(z62.string()).min(1)
2263
+ approvers: z62.array(z62.string()).min(1),
2264
+ /** SRS requirement IDs this design item implements (IEC 62304 §5.4.2) */
2265
+ implements: z62.array(z62.string().min(1)).optional()
2184
2266
  });
2185
2267
  var AnomalyCategorySchema = z72.enum([
2186
2268
  "bug",
@@ -2398,7 +2480,11 @@ var SoftwareRequirementFrontmatterSchema = z16.object({
2398
2480
  traces_from: z16.array(z16.string()).min(1),
2399
2481
  /** Downstream traceability — IDs of documents this SRS traces to */
2400
2482
  traces_to: z16.array(z16.string()).optional(),
2401
- /** HLD/SDD document ID that implements this requirement */
2483
+ /**
2484
+ * @deprecated Use `implements` on HLD/SDD documents instead.
2485
+ * Architecture documents should declare which requirements they implement (IEC 62304 §5.3.1).
2486
+ * Kept for backwards compatibility — the sync engine does not create links from this field.
2487
+ */
2402
2488
  implemented_in: z16.string().optional()
2403
2489
  });
2404
2490
  var TestProtocolFrontmatterSchema = z17.object({
@@ -4912,8 +4998,8 @@ var FrameworkEvidenceResponseSchema = z38.object({
4912
4998
  });
4913
4999
 
4914
5000
  // src/generators/rmr-generator.ts
4915
- import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
4916
- import { resolve as resolve3 } from "path";
5001
+ import { readFileSync as readFileSync4, existsSync as existsSync3 } from "fs";
5002
+ import { resolve as resolve4 } from "path";
4917
5003
  import { parse as parseYaml2 } from "yaml";
4918
5004
  var HEADER_GRAY3 = "#F0F0F0";
4919
5005
  function isHazard(doc) {
@@ -4924,12 +5010,12 @@ function isRiskEntry(doc) {
4924
5010
  }
4925
5011
  function loadRiskMatrix(rootDir) {
4926
5012
  const candidates = [
4927
- resolve3(rootDir, "risk-matrix.yaml"),
4928
- resolve3(rootDir, "docs/risk/risk-matrix.yaml")
5013
+ resolve4(rootDir, "risk-matrix.yaml"),
5014
+ resolve4(rootDir, "docs/risk/risk-matrix.yaml")
4929
5015
  ];
4930
5016
  for (const candidate of candidates) {
4931
- if (existsSync2(candidate)) {
4932
- const raw = readFileSync3(candidate, "utf-8");
5017
+ if (existsSync3(candidate)) {
5018
+ const raw = readFileSync4(candidate, "utf-8");
4933
5019
  const parsed = parseYaml2(raw);
4934
5020
  const result = RiskMatrixConfigSchema.safeParse(parsed);
4935
5021
  if (result.success) {
@@ -5145,6 +5231,7 @@ function generateRmr(input) {
5145
5231
  }
5146
5232
  return buildDocumentDefinition({
5147
5233
  config: input.config,
5234
+ rootDir: input.rootDir,
5148
5235
  recordTitle: "Risk Management Report",
5149
5236
  recordId: "RMR",
5150
5237
  version: input.version,
@@ -5156,8 +5243,8 @@ function generateRmr(input) {
5156
5243
 
5157
5244
  // src/github/changelog.ts
5158
5245
  import { execFileSync } from "child_process";
5159
- import { resolve as resolve4 } from "path";
5160
- import { readFileSync as readFileSync4 } from "fs";
5246
+ import { resolve as resolve5 } from "path";
5247
+ import { readFileSync as readFileSync5 } from "fs";
5161
5248
  import matter3 from "gray-matter";
5162
5249
  function buildChangelog(rootDir, version, date) {
5163
5250
  let previousTag = null;
@@ -5191,7 +5278,7 @@ function buildChangelog(rootDir, version, date) {
5191
5278
  const descriptions = [];
5192
5279
  for (const file of changedFiles.slice(0, 20)) {
5193
5280
  try {
5194
- const raw = readFileSync4(resolve4(rootDir, file), "utf-8");
5281
+ const raw = readFileSync5(resolve5(rootDir, file), "utf-8");
5195
5282
  const { data } = matter3(raw);
5196
5283
  if (data.id && data.title) {
5197
5284
  descriptions.push(`${data.id}: ${data.title}`);
@@ -5289,10 +5376,10 @@ function getDraftReleaseVersion() {
5289
5376
  // src/github/publish.ts
5290
5377
  import { execFileSync as execFileSync3 } from "child_process";
5291
5378
  import { readdirSync as readdirSync2 } from "fs";
5292
- import { resolve as resolve5 } from "path";
5379
+ import { resolve as resolve6 } from "path";
5293
5380
  function publishDraftRelease(version, outputDir) {
5294
5381
  const tag = `v${version}`;
5295
- const pdfFiles = readdirSync2(outputDir).filter((f) => f.endsWith(".pdf")).map((f) => resolve5(outputDir, f));
5382
+ const pdfFiles = readdirSync2(outputDir).filter((f) => f.endsWith(".pdf")).map((f) => resolve6(outputDir, f));
5296
5383
  if (pdfFiles.length === 0) {
5297
5384
  throw new Error("No PDF files found to upload");
5298
5385
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prs-generator.d.ts","sourceRoot":"","sources":["../../src/generators/prs-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAuC9E;AAED,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"prs-generator.d.ts","sourceRoot":"","sources":["../../src/generators/prs-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAwC9E;AAED,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pta-generator.d.ts","sourceRoot":"","sources":["../../src/generators/pta-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,YAAY,CAAC;CACjD;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,IAAI,EAAE,WAAW,EAAE,CAAC;CACrB;AASD,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,cAAc,EAAE,EACrB,IAAI,EAAE,cAAc,EAAE,EACtB,IAAI,EAAE,cAAc,EAAE,GACrB,kBAAkB,CAgJpB;AASD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAkE9E"}
1
+ {"version":3,"file":"pta-generator.d.ts","sourceRoot":"","sources":["../../src/generators/pta-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,YAAY,CAAC;CACjD;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,IAAI,EAAE,WAAW,EAAE,CAAC;CACrB;AASD,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,cAAc,EAAE,EACrB,IAAI,EAAE,cAAc,EAAE,EACtB,IAAI,EAAE,cAAc,EAAE,GACrB,kBAAkB,CAgJpB;AASD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAmE9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"rmr-generator.d.ts","sourceRoot":"","sources":["../../src/generators/rmr-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAW5D,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AA8ED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAmEzD;AAmHD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CA6D9E"}
1
+ {"version":3,"file":"rmr-generator.d.ts","sourceRoot":"","sources":["../../src/generators/rmr-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAW5D,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,cAAc,EAAE,CAAC;IACnC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AA8ED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAmEzD;AAmHD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CA8D9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"srs-generator.d.ts","sourceRoot":"","sources":["../../src/generators/srs-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAuC9E;AAED,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"srs-generator.d.ts","sourceRoot":"","sources":["../../src/generators/srs-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAwC9E;AAED,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"urs-generator.d.ts","sourceRoot":"","sources":["../../src/generators/urs-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKtD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,eAAe,EAAE,aAAa,EAAE,CAAC;CAClC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAuC9E"}
1
+ {"version":3,"file":"urs-generator.d.ts","sourceRoot":"","sources":["../../src/generators/urs-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAKtD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,eAAe,EAAE,aAAa,EAAE,CAAC;CAClC;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAwC9E"}
package/dist/index.js CHANGED
@@ -74,6 +74,52 @@ function readDocuments(rootDir, folderPath, statusFilter = INCLUDED_STATUSES) {
74
74
  // src/pdf/markdown-to-pdfmake.ts
75
75
  import MarkdownIt from "markdown-it";
76
76
  var md = new MarkdownIt();
77
+ var UNICODE_REPLACEMENTS = {
78
+ "\u2264": "<=",
79
+ // ≤
80
+ "\u2265": ">=",
81
+ // ≥
82
+ "\u2260": "!=",
83
+ // ≠
84
+ "\u2248": "~=",
85
+ // ≈
86
+ "\xB1": "+/-",
87
+ // ±
88
+ "\u2014": "--",
89
+ // — (em dash)
90
+ "\u2013": "-",
91
+ // – (en dash)
92
+ "\u2018": "'",
93
+ // ' (left single quote)
94
+ "\u2019": "'",
95
+ // ' (right single quote)
96
+ "\u201C": '"',
97
+ // " (left double quote)
98
+ "\u201D": '"',
99
+ // " (right double quote)
100
+ "\u2026": "...",
101
+ // … (ellipsis)
102
+ "\u2192": "->",
103
+ // →
104
+ "\u2190": "<-",
105
+ // ←
106
+ "\xD7": "x",
107
+ // × (multiplication sign)
108
+ "\xF7": "/",
109
+ // ÷ (division sign)
110
+ "\u221E": "Inf",
111
+ // ∞
112
+ "\u2211": "Sum",
113
+ // ∑
114
+ "\u0394": "Delta",
115
+ // Δ
116
+ "\u03BC": "u"
117
+ // μ (micro)
118
+ };
119
+ var UNICODE_PATTERN = new RegExp("[" + Object.keys(UNICODE_REPLACEMENTS).join("") + "]", "g");
120
+ function sanitizeUnicode(text) {
121
+ return text.replace(UNICODE_PATTERN, (match) => UNICODE_REPLACEMENTS[match] ?? match);
122
+ }
77
123
  function markdownToPdfmake(markdown) {
78
124
  if (!markdown.trim()) return [];
79
125
  const tokens = md.parse(markdown, {});
@@ -123,7 +169,7 @@ function markdownToPdfmake(markdown) {
123
169
  }
124
170
  if (token.type === "fence") {
125
171
  result.push({
126
- text: token.content,
172
+ text: sanitizeUnicode(token.content),
127
173
  style: "code",
128
174
  margin: [0, 4, 0, 4],
129
175
  background: "#F5F5F5"
@@ -161,7 +207,7 @@ function parseInlineContent(token) {
161
207
  italics = false;
162
208
  break;
163
209
  case "code_inline":
164
- fragments.push({ text: child.content, font: "Courier", fontSize: 9 });
210
+ fragments.push({ text: sanitizeUnicode(child.content), font: "Courier", fontSize: 9 });
165
211
  break;
166
212
  case "softbreak":
167
213
  case "hardbreak":
@@ -169,17 +215,17 @@ function parseInlineContent(token) {
169
215
  break;
170
216
  case "text":
171
217
  if (bold || italics) {
172
- const fragment = { text: child.content };
218
+ const fragment = { text: sanitizeUnicode(child.content) };
173
219
  if (bold) fragment.bold = true;
174
220
  if (italics) fragment.italics = true;
175
221
  fragments.push(fragment);
176
222
  } else {
177
- fragments.push(child.content);
223
+ fragments.push(sanitizeUnicode(child.content));
178
224
  }
179
225
  break;
180
226
  default:
181
227
  if (child.content) {
182
- fragments.push(child.content);
228
+ fragments.push(sanitizeUnicode(child.content));
183
229
  }
184
230
  break;
185
231
  }
@@ -273,6 +319,33 @@ function parseTable(tokens, startIndex) {
273
319
  };
274
320
  }
275
321
 
322
+ // src/pdf/logo.ts
323
+ import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
324
+ import { resolve as resolve3 } from "path";
325
+ var DEFAULT_LOGO_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="86 33 112 132" fill="none">
326
+ <path d="M 126.660 39.048 C 118.948 40.342, 108.092 43.909, 100.250 47.726 L 93 51.254 93 79.417 C 93 101.290, 93.337 108.873, 94.508 113.369 C 99.124 131.093, 111.353 144.203, 132.521 154.123 L 141.228 158.203 147.482 155.545 C 164.571 148.282, 177.761 137.330, 183.523 125.620 C 185.450 121.704, 187.687 115.350, 188.496 111.500 C 190.017 104.251, 190.622 77.552, 189.250 78.172 C 188.838 78.359, 186.137 79.754, 183.250 81.273 L 178 84.034 177.976 97.767 C 177.955 109.837, 177.670 112.188, 175.617 117.178 C 174.332 120.302, 171.823 124.699, 170.040 126.950 C 166.118 131.901, 156.845 138.641, 147.912 143.031 L 141.324 146.270 133.165 142.025 C 123.422 136.956, 112.066 126.834, 108.987 120.474 C 104.626 111.464, 104.024 106.777, 104.012 81.694 L 104 57.888 108.468 55.911 C 118.291 51.566, 127.969 49.691, 141 49.610 C 154.549 49.525, 161.523 50.879, 172.184 55.663 L 178 58.273 178.015 67.887 C 178.024 73.174, 178.361 78.008, 178.765 78.629 C 179.273 79.409, 181.073 78.866, 184.588 76.874 L 189.677 73.990 189.588 62.811 L 189.500 51.632 182.359 47.990 C 173.984 43.718, 164.090 40.483, 155 39.044 C 147.525 37.861, 133.720 37.863, 126.660 39.048 M 126.500 55.097 C 124.300 55.590, 119.463 56.951, 115.750 58.122 L 109 60.251 109 85.729 L 109 111.207 113.250 117.047 C 115.588 120.259, 117.838 122.912, 118.250 122.943 C 118.662 122.975, 119 116.984, 119 109.630 L 119 96.261 132.250 95.756 C 142.964 95.347, 146.648 94.801, 151.500 92.903 C 167.650 86.582, 173.814 69.996, 163.666 60.161 C 159.792 56.406, 152.831 54, 145.841 54 L 141 54 141 59 L 141 64 145.435 64 C 153.585 64, 158 66.985, 158 72.495 C 158 74.610, 157.079 76.941, 155.504 78.813 C 151.445 83.637, 146.077 85.209, 131.750 85.768 L 119 86.265 119 76.758 L 119 67.250 122.125 66.625 C 123.844 66.281, 125.644 66, 126.125 66 C 126.606 66, 127 69.600, 127 74 L 127 82 132 82 L 137 82 137 68 L 137 54 133.750 54.100 C 131.963 54.156, 128.700 54.604, 126.500 55.097 M 159.103 93.372 C 143.915 101.453, 141 104.415, 141 111.767 C 141 115.024, 141.605 116.696, 143.455 118.545 C 144.805 119.895, 146.717 120.996, 147.705 120.990 C 148.692 120.985, 151.907 119.860, 154.849 118.490 C 160.989 115.632, 162 115.473, 162 117.364 C 162 118.898, 157.383 122.272, 148.500 127.227 C 142.608 130.513, 142.495 130.658, 142.195 135.287 C 142.028 137.879, 142.122 140, 142.406 140 C 142.689 140, 146.800 137.874, 151.541 135.277 C 166.125 127.286, 171 121.968, 171 114.050 C 171 109.325, 168.324 106, 164.522 106 C 163.159 106, 159.572 107.213, 156.550 108.695 C 153.528 110.177, 150.722 111.055, 150.313 110.647 C 148.679 109.012, 152.158 106.229, 162.820 100.641 L 174 94.781 174 90.391 C 174 87.976, 173.662 86.055, 173.250 86.122 C 172.838 86.189, 166.471 89.451, 159.103 93.372 M 127 115.952 L 127 132.904 131.430 135.952 C 133.867 137.628, 136.117 139, 136.430 139 C 136.744 139, 137 130, 137 119 L 137 99 132 99 L 127 99 127 115.952" fill="#0D2D56" fill-rule="evenodd"/>
327
+ <path d="M 159.103 93.372 C 143.915 101.453, 141 104.415, 141 111.767 C 141 115.024, 141.605 116.696, 143.455 118.545 C 144.805 119.895, 146.717 120.996, 147.705 120.990 C 148.692 120.985, 151.907 119.860, 154.849 118.490 C 160.989 115.632, 162 115.473, 162 117.364 C 162 118.898, 157.383 122.272, 148.500 127.227 C 142.608 130.513, 142.495 130.658, 142.195 135.287 C 142.028 137.879, 142.122 140, 142.406 140 C 142.689 140, 146.800 137.874, 151.541 135.277 C 166.125 127.286, 171 121.968, 171 114.050 C 171 109.325, 168.324 106, 164.522 106 C 163.159 106, 159.572 107.213, 156.550 108.695 C 153.528 110.177, 150.722 111.055, 150.313 110.647 C 148.679 109.012, 152.158 106.229, 162.820 100.641 L 174 94.781 174 90.391 C 174 87.976, 173.662 86.055, 173.250 86.122 C 172.838 86.189, 166.471 89.451, 159.103 93.372 M 127 115.952 L 127 132.904 131.430 135.952 C 133.867 137.628, 136.117 139, 136.430 139 C 136.744 139, 137 130, 137 119 L 137 99 132 99 L 127 99 127 115.952" fill="#73C4B0" fill-rule="evenodd"/>
328
+ </svg>`;
329
+ var HEADER_LOGO_HEIGHT = 30;
330
+ function resolveHeaderLogo(rootDir, customLogoPath) {
331
+ if (customLogoPath) {
332
+ const absPath = resolve3(rootDir, customLogoPath);
333
+ if (existsSync2(absPath)) {
334
+ const ext = absPath.toLowerCase();
335
+ if (ext.endsWith(".png") || ext.endsWith(".jpg") || ext.endsWith(".jpeg")) {
336
+ const data = readFileSync3(absPath);
337
+ const mime = ext.endsWith(".png") ? "image/png" : "image/jpeg";
338
+ const base64 = `data:${mime};base64,${data.toString("base64")}`;
339
+ return { image: base64, height: HEADER_LOGO_HEIGHT };
340
+ }
341
+ }
342
+ }
343
+ return {
344
+ svg: DEFAULT_LOGO_SVG,
345
+ height: HEADER_LOGO_HEIGHT
346
+ };
347
+ }
348
+
276
349
  // src/pdf/layout.ts
277
350
  var HEADER_GRAY = "#F0F0F0";
278
351
  var HEADING_COLOR = "#2C3E50";
@@ -329,8 +402,9 @@ function buildCoverPage(options) {
329
402
  return cover;
330
403
  }
331
404
  function buildDocumentDefinition(options) {
332
- const { recordTitle, recordId, version, date, content = [] } = options;
405
+ const { rootDir, config, recordTitle, recordId, version, date, content = [] } = options;
333
406
  const coverPage = buildCoverPage(options);
407
+ const logo = resolveHeaderLogo(rootDir, config.branding.logo);
334
408
  return {
335
409
  pageSize: "A4",
336
410
  pageMargins: [40, 80, 40, 50],
@@ -353,7 +427,7 @@ function buildDocumentDefinition(options) {
353
427
  widths: [usableWidth * 0.2, "*", usableWidth * 0.25],
354
428
  body: [
355
429
  [
356
- { text: "[LOGO]", fontSize: 8, color: "#999999" },
430
+ logo,
357
431
  {
358
432
  stack: [
359
433
  { text: recordTitle, bold: true, fontSize: 10, alignment: "center" },
@@ -436,6 +510,7 @@ function generateUrs(input) {
436
510
  }
437
511
  return buildDocumentDefinition({
438
512
  config: input.config,
513
+ rootDir: input.rootDir,
439
514
  recordTitle: "User Requirements Specification",
440
515
  recordId: "URS",
441
516
  version: input.version,
@@ -472,6 +547,7 @@ function generatePrs(input) {
472
547
  }
473
548
  return buildDocumentDefinition({
474
549
  config: input.config,
550
+ rootDir: input.rootDir,
475
551
  recordTitle: "Product Requirements Specification",
476
552
  recordId: "PRS",
477
553
  version: input.version,
@@ -508,6 +584,7 @@ function generateSrs(input) {
508
584
  }
509
585
  return buildDocumentDefinition({
510
586
  config: input.config,
587
+ rootDir: input.rootDir,
511
588
  recordTitle: "Software Requirements Specification",
512
589
  recordId: "SRS",
513
590
  version: input.version,
@@ -725,6 +802,7 @@ function generatePta(input) {
725
802
  }
726
803
  return buildDocumentDefinition({
727
804
  config: input.config,
805
+ rootDir: input.rootDir,
728
806
  recordTitle: "Product Traceability Analysis",
729
807
  recordId: "PTA",
730
808
  version: input.version,
@@ -798,8 +876,8 @@ ${probabilityLabels[labelIndex]}`,
798
876
 
799
877
  // src/generators/rmr-generator.ts
800
878
  import { RiskMatrixConfigSchema } from "@pactosigna/schemas";
801
- import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
802
- import { resolve as resolve3 } from "path";
879
+ import { readFileSync as readFileSync4, existsSync as existsSync3 } from "fs";
880
+ import { resolve as resolve4 } from "path";
803
881
  import { parse as parseYaml2 } from "yaml";
804
882
  var HEADER_GRAY3 = "#F0F0F0";
805
883
  function isHazard(doc) {
@@ -810,12 +888,12 @@ function isRiskEntry(doc) {
810
888
  }
811
889
  function loadRiskMatrix(rootDir) {
812
890
  const candidates = [
813
- resolve3(rootDir, "risk-matrix.yaml"),
814
- resolve3(rootDir, "docs/risk/risk-matrix.yaml")
891
+ resolve4(rootDir, "risk-matrix.yaml"),
892
+ resolve4(rootDir, "docs/risk/risk-matrix.yaml")
815
893
  ];
816
894
  for (const candidate of candidates) {
817
- if (existsSync2(candidate)) {
818
- const raw = readFileSync3(candidate, "utf-8");
895
+ if (existsSync3(candidate)) {
896
+ const raw = readFileSync4(candidate, "utf-8");
819
897
  const parsed = parseYaml2(raw);
820
898
  const result = RiskMatrixConfigSchema.safeParse(parsed);
821
899
  if (result.success) {
@@ -1031,6 +1109,7 @@ function generateRmr(input) {
1031
1109
  }
1032
1110
  return buildDocumentDefinition({
1033
1111
  config: input.config,
1112
+ rootDir: input.rootDir,
1034
1113
  recordTitle: "Risk Management Report",
1035
1114
  recordId: "RMR",
1036
1115
  version: input.version,
@@ -1042,8 +1121,8 @@ function generateRmr(input) {
1042
1121
 
1043
1122
  // src/github/changelog.ts
1044
1123
  import { execFileSync } from "child_process";
1045
- import { resolve as resolve4 } from "path";
1046
- import { readFileSync as readFileSync4 } from "fs";
1124
+ import { resolve as resolve5 } from "path";
1125
+ import { readFileSync as readFileSync5 } from "fs";
1047
1126
  import matter2 from "gray-matter";
1048
1127
  function buildChangelog(rootDir, version, date) {
1049
1128
  let previousTag = null;
@@ -1077,7 +1156,7 @@ function buildChangelog(rootDir, version, date) {
1077
1156
  const descriptions = [];
1078
1157
  for (const file of changedFiles.slice(0, 20)) {
1079
1158
  try {
1080
- const raw = readFileSync4(resolve4(rootDir, file), "utf-8");
1159
+ const raw = readFileSync5(resolve5(rootDir, file), "utf-8");
1081
1160
  const { data } = matter2(raw);
1082
1161
  if (data.id && data.title) {
1083
1162
  descriptions.push(`${data.id}: ${data.title}`);
@@ -7,6 +7,7 @@ export interface RevisionEntry {
7
7
  }
8
8
  export interface LayoutOptions {
9
9
  config: RecordsConfig;
10
+ rootDir: string;
10
11
  recordTitle: string;
11
12
  recordId: string;
12
13
  version: string;
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/pdf/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;CACrB;AAMD,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,EAAE,CA2DhE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,aAAa,GAAG,oBAAoB,CAsFpF"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/pdf/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;CACrB;AAMD,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,EAAE,CA2DhE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,aAAa,GAAG,oBAAoB,CAuFpF"}
@@ -0,0 +1,10 @@
1
+ import type { Content } from 'pdfmake/interfaces';
2
+ /**
3
+ * Resolves the logo to use in the PDF header.
4
+ *
5
+ * Priority:
6
+ * 1. Custom logo path from `branding.logo` in pactosigna.yaml (PNG only)
7
+ * 2. Built-in PactoSigna shield icon (SVG, always available)
8
+ */
9
+ export declare function resolveHeaderLogo(rootDir: string, customLogoPath?: string): Content;
10
+ //# sourceMappingURL=logo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logo.d.ts","sourceRoot":"","sources":["../../src/pdf/logo.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAiBlD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAkBnF"}
@@ -1,4 +1,6 @@
1
1
  import type { Content } from 'pdfmake/interfaces';
2
+ /** Replace Unicode characters unsupported by WinAnsiEncoding with ASCII equivalents. */
3
+ export declare function sanitizeUnicode(text: string): string;
2
4
  /**
3
5
  * Converts a markdown string to an array of pdfmake content nodes.
4
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-to-pdfmake.d.ts","sourceRoot":"","sources":["../../src/pdf/markdown-to-pdfmake.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,oBAAoB,CAAC;AAO/D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA4E7D"}
1
+ {"version":3,"file":"markdown-to-pdfmake.d.ts","sourceRoot":"","sources":["../../src/pdf/markdown-to-pdfmake.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,oBAAoB,CAAC;AAoC/D,wFAAwF;AACxF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA4E7D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pactosigna/records",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "description": "Generate audit-ready regulatory PDF records from PactoSigna-compliant git repositories",
6
6
  "publishConfig": {