tychat-contracts 1.6.53 → 1.6.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/legal-terms/default-legal-term-document.d.ts +23 -0
  2. package/dist/legal-terms/default-legal-term-document.d.ts.map +1 -0
  3. package/dist/legal-terms/default-legal-term-document.js +170 -0
  4. package/dist/legal-terms/index.d.ts +4 -0
  5. package/dist/legal-terms/index.d.ts.map +1 -1
  6. package/dist/legal-terms/index.js +4 -0
  7. package/dist/legal-terms/legal-term-body-format.d.ts +1 -1
  8. package/dist/legal-terms/legal-term-body-format.d.ts.map +1 -1
  9. package/dist/legal-terms/legal-term-body-format.js +1 -1
  10. package/dist/legal-terms/legal-term-document-compile.d.ts +3 -0
  11. package/dist/legal-terms/legal-term-document-compile.d.ts.map +1 -0
  12. package/dist/legal-terms/legal-term-document-compile.js +166 -0
  13. package/dist/legal-terms/legal-term-document-compile.spec.d.ts +2 -0
  14. package/dist/legal-terms/legal-term-document-compile.spec.d.ts.map +1 -0
  15. package/dist/legal-terms/legal-term-document-compile.spec.js +49 -0
  16. package/dist/legal-terms/legal-term-document.dto.d.ts +21 -0
  17. package/dist/legal-terms/legal-term-document.dto.d.ts.map +1 -0
  18. package/dist/legal-terms/legal-term-document.dto.js +127 -0
  19. package/dist/legal-terms/legal-term-document.types.d.ts +30 -0
  20. package/dist/legal-terms/legal-term-document.types.d.ts.map +1 -0
  21. package/dist/legal-terms/legal-term-document.types.js +14 -0
  22. package/dist/legal-terms/legal-term-preview.dto.d.ts +2 -0
  23. package/dist/legal-terms/legal-term-preview.dto.d.ts.map +1 -1
  24. package/dist/legal-terms/legal-term-preview.dto.js +14 -1
  25. package/dist/legal-terms/legal-term-template.dto.d.ts +4 -1
  26. package/dist/legal-terms/legal-term-template.dto.d.ts.map +1 -1
  27. package/dist/legal-terms/legal-term-template.dto.js +25 -6
  28. package/package.json +1 -1
  29. package/src/legal-terms/default-legal-term-document.ts +170 -0
  30. package/src/legal-terms/index.ts +4 -0
  31. package/src/legal-terms/legal-term-body-format.ts +1 -1
  32. package/src/legal-terms/legal-term-document-compile.spec.ts +53 -0
  33. package/src/legal-terms/legal-term-document-compile.ts +192 -0
  34. package/src/legal-terms/legal-term-document.dto.ts +100 -0
  35. package/src/legal-terms/legal-term-document.types.ts +42 -0
  36. package/src/legal-terms/legal-term-preview.dto.ts +13 -1
  37. package/src/legal-terms/legal-term-template.dto.ts +23 -7
@@ -0,0 +1,23 @@
1
+ import type { LegalTermDocument, LegalTermDocumentBlock } from './legal-term-document.types';
2
+ /** IDs estáveis dos blocos do modelo CFM padrão (restauração no editor). */
3
+ export declare const DEFAULT_LEGAL_TERM_BLOCK_IDS: {
4
+ readonly title: "cfm-title";
5
+ readonly reference: "cfm-reference";
6
+ readonly s1: "cfm-s1-identificacao";
7
+ readonly s2: "cfm-s2-procedimento";
8
+ readonly s3: "cfm-s3-indicacao";
9
+ readonly s4: "cfm-s4-riscos";
10
+ readonly s4Table: "cfm-s4-riscos-table";
11
+ readonly s5: "cfm-s5-beneficios";
12
+ readonly s6: "cfm-s6-alternativas";
13
+ readonly s7: "cfm-s7-orientacoes";
14
+ readonly s8: "cfm-s8-lgpd";
15
+ readonly s9: "cfm-s9-consentimento";
16
+ readonly s10: "cfm-s10-revogacao";
17
+ readonly signatures: "cfm-signatures";
18
+ };
19
+ /** Modelo CFM (TCLE) — texto em português; placeholders suportados pelo backend. */
20
+ export declare function createDefaultCfmLegalTermDocument(): LegalTermDocument;
21
+ /** Mapa id → bloco do seed CFM (para restaurar tópicos padrão). */
22
+ export declare function getDefaultCfmBlocksById(): Map<string, LegalTermDocumentBlock>;
23
+ //# sourceMappingURL=default-legal-term-document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-legal-term-document.d.ts","sourceRoot":"","sources":["../../src/legal-terms/default-legal-term-document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE7F,4EAA4E;AAC5E,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;CAe/B,CAAC;AAMX,oFAAoF;AACpF,wBAAgB,iCAAiC,IAAI,iBAAiB,CA0IrE;AAED,mEAAmE;AACnE,wBAAgB,uBAAuB,IAAI,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAG7E"}
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_LEGAL_TERM_BLOCK_IDS = void 0;
4
+ exports.createDefaultCfmLegalTermDocument = createDefaultCfmLegalTermDocument;
5
+ exports.getDefaultCfmBlocksById = getDefaultCfmBlocksById;
6
+ /** IDs estáveis dos blocos do modelo CFM padrão (restauração no editor). */
7
+ exports.DEFAULT_LEGAL_TERM_BLOCK_IDS = {
8
+ title: 'cfm-title',
9
+ reference: 'cfm-reference',
10
+ s1: 'cfm-s1-identificacao',
11
+ s2: 'cfm-s2-procedimento',
12
+ s3: 'cfm-s3-indicacao',
13
+ s4: 'cfm-s4-riscos',
14
+ s4Table: 'cfm-s4-riscos-table',
15
+ s5: 'cfm-s5-beneficios',
16
+ s6: 'cfm-s6-alternativas',
17
+ s7: 'cfm-s7-orientacoes',
18
+ s8: 'cfm-s8-lgpd',
19
+ s9: 'cfm-s9-consentimento',
20
+ s10: 'cfm-s10-revogacao',
21
+ signatures: 'cfm-signatures',
22
+ };
23
+ function block(partial) {
24
+ return partial;
25
+ }
26
+ /** Modelo CFM (TCLE) — texto em português; placeholders suportados pelo backend. */
27
+ function createDefaultCfmLegalTermDocument() {
28
+ return {
29
+ version: 1,
30
+ blocks: [
31
+ block({
32
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.title,
33
+ type: 'document_title',
34
+ title: 'Termo de consentimento livre e esclarecido',
35
+ titleAlign: 'center',
36
+ titleBold: true,
37
+ }),
38
+ block({
39
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.reference,
40
+ type: 'legal_reference',
41
+ body: 'Conforme Resolução CFM nº 2.217/2018 (Código de Ética Médica)',
42
+ bodyAlign: 'center',
43
+ }),
44
+ block({
45
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s1,
46
+ type: 'section',
47
+ level: 1,
48
+ title: 'Identificação das partes',
49
+ body: [
50
+ 'Paciente: {{ nome_paciente }}',
51
+ 'CPF: {{ cpf_formatado }}',
52
+ 'Data de Nascimento: {{ data_nascimento }}',
53
+ 'Telefone: {{ telefone_paciente }}',
54
+ 'E-mail: {{ email_paciente }}',
55
+ 'Endereço: {{ endereco_paciente }}',
56
+ 'Instituição: (preencher dados da clínica no cadastro)',
57
+ ].join('\n'),
58
+ }),
59
+ block({
60
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s2,
61
+ type: 'section',
62
+ level: 1,
63
+ title: 'Descrição do procedimento',
64
+ body: [
65
+ 'Declaro que fui devidamente informado(a), de forma clara, objetiva e compreensível, acerca da natureza, finalidade, indicação clínica, etapas, duração e métodos envolvidos no procedimento médico descrito abaixo:',
66
+ '{{ procedimentos }}',
67
+ ].join('\n\n'),
68
+ }),
69
+ block({
70
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s3,
71
+ type: 'section',
72
+ level: 1,
73
+ title: 'Indicação e justificativa',
74
+ body: 'O procedimento foi indicado com base em avaliação clínica individualizada, considerando meu histórico de saúde, sintomas apresentados e exames complementares, visando o melhor resultado terapêutico possível.',
75
+ }),
76
+ block({
77
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s4,
78
+ type: 'section',
79
+ level: 1,
80
+ title: 'Riscos e complicações possíveis',
81
+ body: [
82
+ 'Fui informado(a) de que todo procedimento médico envolve riscos inerentes, podendo ocorrer intercorrências imediatas ou tardias, previsíveis ou não, incluindo, mas não se limitando a:',
83
+ ].join('\n'),
84
+ }),
85
+ block({
86
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s4Table,
87
+ type: 'table_side_effects',
88
+ body: '',
89
+ }),
90
+ block({
91
+ id: 'cfm-s4-riscos-after',
92
+ type: 'paragraph',
93
+ body: 'Estou ciente de que não há garantia absoluta de resultados, podendo ser necessária a realização de procedimentos adicionais.',
94
+ }),
95
+ block({
96
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s5,
97
+ type: 'section',
98
+ level: 1,
99
+ title: 'Benefícios esperados',
100
+ body: 'Fui informado(a) sobre os benefícios esperados, incluindo melhora clínica, controle de sintomas e/ou prevenção de agravamentos, respeitando as limitações individuais de resposta ao tratamento.',
101
+ }),
102
+ block({
103
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s6,
104
+ type: 'section',
105
+ level: 1,
106
+ title: 'Alternativas terapêuticas',
107
+ body: 'Foram apresentadas e discutidas alternativas ao procedimento proposto, incluindo tratamentos conservadores, outras técnicas disponíveis e a possibilidade de não realização do procedimento, estando ciente das consequências dessa decisão.',
108
+ }),
109
+ block({
110
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s7,
111
+ type: 'section',
112
+ level: 1,
113
+ title: 'Orientações pré e pós-procedimento',
114
+ body: 'Recebi orientações detalhadas quanto aos cuidados necessários antes e após o procedimento, incluindo restrições, uso de medicamentos, sinais de alerta e acompanhamento médico.',
115
+ }),
116
+ block({
117
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s8,
118
+ type: 'section',
119
+ level: 1,
120
+ title: 'Confidencialidade e proteção de dados',
121
+ body: 'Autorizo o tratamento dos meus dados pessoais e sensíveis para fins médicos, assistenciais e administrativos, conforme a Lei Geral de Proteção de Dados (Lei nº 13.709/2018 - LGPD).',
122
+ }),
123
+ block({
124
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s9,
125
+ type: 'section',
126
+ level: 1,
127
+ title: 'Declaração de consentimento',
128
+ body: [
129
+ 'Declaro que:',
130
+ 'Recebi todas as informações necessárias de forma clara e adequada;',
131
+ 'Tive oportunidade de realizar perguntas e obtive respostas satisfatórias;',
132
+ 'Estou ciente dos riscos, benefícios e alternativas;',
133
+ 'Não fui submetido(a) a qualquer tipo de pressão ou indução;',
134
+ 'Autorizo, de forma livre e esclarecida, a realização do procedimento descrito.',
135
+ ].join('\n'),
136
+ }),
137
+ block({
138
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.s10,
139
+ type: 'section',
140
+ level: 1,
141
+ title: 'Direito de revogação',
142
+ body: 'Estou ciente de que posso revogar este consentimento a qualquer momento antes da realização do procedimento, sem prejuízo ao meu atendimento médico.',
143
+ }),
144
+ block({
145
+ id: exports.DEFAULT_LEGAL_TERM_BLOCK_IDS.signatures,
146
+ type: 'signature_footer',
147
+ body: [
148
+ 'Local: (cidade da clínica)',
149
+ 'Data: {{ data_hora }}',
150
+ '',
151
+ '______________________________',
152
+ 'Paciente',
153
+ '',
154
+ '______________________________',
155
+ 'Responsável Legal',
156
+ '',
157
+ '______________________________',
158
+ 'Médico Responsável',
159
+ '',
160
+ 'Documento gerado eletronicamente. Assinatura válida conforme legislação vigente.',
161
+ ].join('\n'),
162
+ }),
163
+ ],
164
+ };
165
+ }
166
+ /** Mapa id → bloco do seed CFM (para restaurar tópicos padrão). */
167
+ function getDefaultCfmBlocksById() {
168
+ const doc = createDefaultCfmLegalTermDocument();
169
+ return new Map(doc.blocks.map((b) => [b.id, { ...b }]));
170
+ }
@@ -1,4 +1,8 @@
1
1
  export * from './legal-term-body-format';
2
+ export * from './legal-term-document.types';
3
+ export * from './legal-term-document.dto';
4
+ export * from './legal-term-document-compile';
5
+ export * from './default-legal-term-document';
2
6
  export * from './legal-term-template.dto';
3
7
  export * from './legal-term-preview.dto';
4
8
  export * from './legal-term-dispatch.dto';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/legal-terms/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/legal-terms/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC"}
@@ -15,6 +15,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./legal-term-body-format"), exports);
18
+ __exportStar(require("./legal-term-document.types"), exports);
19
+ __exportStar(require("./legal-term-document.dto"), exports);
20
+ __exportStar(require("./legal-term-document-compile"), exports);
21
+ __exportStar(require("./default-legal-term-document"), exports);
18
22
  __exportStar(require("./legal-term-template.dto"), exports);
19
23
  __exportStar(require("./legal-term-preview.dto"), exports);
20
24
  __exportStar(require("./legal-term-dispatch.dto"), exports);
@@ -1,4 +1,4 @@
1
1
  /** Formato de armazenamento do modelo; conversão para HTML/PDF é determinística por enum. */
2
- export declare const LEGAL_TERM_BODY_FORMATS: readonly ["html", "markdown", "plain_text"];
2
+ export declare const LEGAL_TERM_BODY_FORMATS: readonly ["structured", "html", "markdown", "plain_text"];
3
3
  export type LegalTermBodyFormat = (typeof LEGAL_TERM_BODY_FORMATS)[number];
4
4
  //# sourceMappingURL=legal-term-body-format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"legal-term-body-format.d.ts","sourceRoot":"","sources":["../../src/legal-terms/legal-term-body-format.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,eAAO,MAAM,uBAAuB,6CAA8C,CAAC;AAEnF,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"legal-term-body-format.d.ts","sourceRoot":"","sources":["../../src/legal-terms/legal-term-body-format.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,eAAO,MAAM,uBAAuB,2DAA4D,CAAC;AAEjG,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LEGAL_TERM_BODY_FORMATS = void 0;
4
4
  /** Formato de armazenamento do modelo; conversão para HTML/PDF é determinística por enum. */
5
- exports.LEGAL_TERM_BODY_FORMATS = ['html', 'markdown', 'plain_text'];
5
+ exports.LEGAL_TERM_BODY_FORMATS = ['structured', 'html', 'markdown', 'plain_text'];
@@ -0,0 +1,3 @@
1
+ import type { LegalTermDocument } from './legal-term-document.types';
2
+ export declare function compileLegalTermDocumentToHtml(document: LegalTermDocument): string;
3
+ //# sourceMappingURL=legal-term-document-compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legal-term-document-compile.d.ts","sourceRoot":"","sources":["../../src/legal-terms/legal-term-document-compile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAIlB,MAAM,6BAA6B,CAAC;AA2KrC,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAelF"}
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compileLegalTermDocumentToHtml = compileLegalTermDocumentToHtml;
4
+ function escapeHtmlText(s) {
5
+ return s
6
+ .replace(/&/g, '&amp;')
7
+ .replace(/</g, '&lt;')
8
+ .replace(/>/g, '&gt;')
9
+ .replace(/"/g, '&quot;');
10
+ }
11
+ function cssTextStyle(opts, defaults = {}) {
12
+ const align = opts.align ?? defaults.align ?? 'left';
13
+ const bold = opts.bold ?? defaults.bold ?? false;
14
+ const italic = opts.italic ?? defaults.italic ?? false;
15
+ const underline = opts.underline ?? defaults.underline ?? false;
16
+ const parts = [`text-align:${align}`];
17
+ if (bold)
18
+ parts.push('font-weight:700');
19
+ if (italic)
20
+ parts.push('font-style:italic');
21
+ if (underline)
22
+ parts.push('text-decoration:underline');
23
+ return parts.join(';');
24
+ }
25
+ function textToHtmlParagraphs(text, opts = {}) {
26
+ const trimmed = text.trim();
27
+ if (!trimmed)
28
+ return '';
29
+ const style = cssTextStyle(opts, { align: 'left' });
30
+ const lines = trimmed.split(/\r?\n/);
31
+ return lines
32
+ .map((line) => {
33
+ const t = line.trim();
34
+ if (!t)
35
+ return '<br/>';
36
+ return `<p style="margin:0.4em 0;line-height:1.45;${style}">${escapeHtmlText(t)}</p>`;
37
+ })
38
+ .join('');
39
+ }
40
+ function formatSectionNumber(counters, level) {
41
+ if (level === 1)
42
+ return `${counters[0]}.`;
43
+ if (level === 2)
44
+ return `${counters[0]}.${counters[1]}.`;
45
+ return `${counters[0]}.${counters[1]}.${counters[2]}.`;
46
+ }
47
+ function bumpSectionCounters(counters, level) {
48
+ const next = [...counters];
49
+ if (level === 1) {
50
+ next[0] += 1;
51
+ next[1] = 0;
52
+ next[2] = 0;
53
+ }
54
+ else if (level === 2) {
55
+ next[1] += 1;
56
+ next[2] = 0;
57
+ }
58
+ else {
59
+ next[2] += 1;
60
+ }
61
+ return next;
62
+ }
63
+ function compileBlock(block, sectionCounters) {
64
+ let counters = sectionCounters;
65
+ const wrap = (inner, extraStyle = '') => `<div class="legal-term-block" data-block-type="${block.type}" style="margin-bottom:0.75em;${extraStyle}">${inner}</div>`;
66
+ switch (block.type) {
67
+ case 'document_title': {
68
+ const title = (block.title ?? block.body ?? '').trim();
69
+ const style = cssTextStyle({
70
+ align: block.titleAlign,
71
+ bold: block.titleBold,
72
+ italic: block.titleItalic,
73
+ underline: block.titleUnderline,
74
+ }, { align: 'center', bold: true });
75
+ const inner = title
76
+ ? `<h1 style="font-size:1.25em;margin:0 0 0.5em;${style}">${escapeHtmlText(title)}</h1>`
77
+ : '';
78
+ return { html: wrap(inner), counters };
79
+ }
80
+ case 'legal_reference': {
81
+ const ref = (block.body ?? block.title ?? '').trim();
82
+ const inner = ref
83
+ ? textToHtmlParagraphs(ref, {
84
+ align: block.bodyAlign ?? 'center',
85
+ bold: block.bodyBold,
86
+ italic: block.bodyItalic,
87
+ underline: block.bodyUnderline,
88
+ })
89
+ : '';
90
+ return { html: wrap(inner), counters };
91
+ }
92
+ case 'section': {
93
+ const level = block.level === 2 || block.level === 3 ? block.level : 1;
94
+ counters = bumpSectionCounters(counters, level);
95
+ const num = formatSectionNumber(counters, level);
96
+ const title = (block.title ?? '').trim();
97
+ const titleStyle = cssTextStyle({
98
+ align: block.titleAlign,
99
+ bold: block.titleBold,
100
+ italic: block.titleItalic,
101
+ underline: block.titleUnderline,
102
+ }, { align: 'left', bold: true });
103
+ const bodyHtml = textToHtmlParagraphs(block.body ?? '', {
104
+ align: block.bodyAlign,
105
+ bold: block.bodyBold,
106
+ italic: block.bodyItalic,
107
+ underline: block.bodyUnderline,
108
+ });
109
+ const heading = title
110
+ ? `<h2 style="font-size:${level === 1 ? '1.05em' : '1em'};margin:0.75em 0 0.35em;${titleStyle}">${escapeHtmlText(`${num} ${title}`)}</h2>`
111
+ : '';
112
+ return { html: wrap(`${heading}${bodyHtml}`), counters };
113
+ }
114
+ case 'paragraph': {
115
+ return {
116
+ html: wrap(textToHtmlParagraphs(block.body ?? '', {
117
+ align: block.bodyAlign,
118
+ bold: block.bodyBold,
119
+ italic: block.bodyItalic,
120
+ underline: block.bodyUnderline,
121
+ })),
122
+ counters,
123
+ };
124
+ }
125
+ case 'table_side_effects': {
126
+ const intro = textToHtmlParagraphs(block.body ?? '', {
127
+ align: block.bodyAlign,
128
+ bold: block.bodyBold,
129
+ italic: block.bodyItalic,
130
+ underline: block.bodyUnderline,
131
+ });
132
+ const token = '<p>{{ table_side_effects_en_list }}</p>';
133
+ return { html: wrap(`${intro}${token}`), counters };
134
+ }
135
+ case 'signature_footer': {
136
+ return {
137
+ html: wrap(textToHtmlParagraphs(block.body ?? '', {
138
+ align: block.bodyAlign ?? 'left',
139
+ bold: block.bodyBold,
140
+ italic: block.bodyItalic,
141
+ underline: block.bodyUnderline,
142
+ }), 'page-break-inside:avoid;margin-top:1.5em;padding-top:0.5em;border-top:1px solid #ddd'),
143
+ counters,
144
+ };
145
+ }
146
+ default:
147
+ return { html: '', counters };
148
+ }
149
+ }
150
+ function compileLegalTermDocumentToHtml(document) {
151
+ if (!document?.blocks?.length) {
152
+ return '<p></p>';
153
+ }
154
+ let sectionCounters = [0, 0, 0];
155
+ const parts = [
156
+ '<div class="legal-term-document" style="font-family:Roboto,Helvetica,Arial,sans-serif;font-size:11pt;color:#111">',
157
+ ];
158
+ for (const block of document.blocks) {
159
+ const { html, counters } = compileBlock(block, sectionCounters);
160
+ sectionCounters = counters;
161
+ if (html)
162
+ parts.push(html);
163
+ }
164
+ parts.push('</div>');
165
+ return parts.join('').trim() || '<p></p>';
166
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=legal-term-document-compile.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legal-term-document-compile.spec.d.ts","sourceRoot":"","sources":["../../src/legal-terms/legal-term-document-compile.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const legal_term_document_compile_1 = require("./legal-term-document-compile");
4
+ const default_legal_term_document_1 = require("./default-legal-term-document");
5
+ describe('compileLegalTermDocumentToHtml', () => {
6
+ it('returns empty paragraph for no blocks', () => {
7
+ expect((0, legal_term_document_compile_1.compileLegalTermDocumentToHtml)({ version: 1, blocks: [] })).toBe('<p></p>');
8
+ });
9
+ it('numbers sections hierarchically', () => {
10
+ const doc = {
11
+ version: 1,
12
+ blocks: [
13
+ { id: 'a', type: 'section', level: 1, title: 'ONE', body: 'a' },
14
+ { id: 'b', type: 'section', level: 2, title: 'TWO', body: 'b' },
15
+ { id: 'c', type: 'section', level: 3, title: 'THREE', body: 'c' },
16
+ { id: 'd', type: 'section', level: 1, title: 'FOUR', body: 'd' },
17
+ ],
18
+ };
19
+ const html = (0, legal_term_document_compile_1.compileLegalTermDocumentToHtml)(doc);
20
+ expect(html).toContain('1. ONE');
21
+ expect(html).toContain('1.1. TWO');
22
+ expect(html).toContain('1.1.1. THREE');
23
+ expect(html).toContain('2. FOUR');
24
+ });
25
+ it('escapes HTML in body text', () => {
26
+ const doc = {
27
+ version: 1,
28
+ blocks: [{ id: 'x', type: 'paragraph', body: '<script>alert(1)</script>' }],
29
+ };
30
+ const html = (0, legal_term_document_compile_1.compileLegalTermDocumentToHtml)(doc);
31
+ expect(html).not.toContain('<script>');
32
+ expect(html).toContain('&lt;script&gt;');
33
+ });
34
+ it('emits table placeholder token', () => {
35
+ const doc = {
36
+ version: 1,
37
+ blocks: [{ id: 't', type: 'table_side_effects', body: 'intro' }],
38
+ };
39
+ const html = (0, legal_term_document_compile_1.compileLegalTermDocumentToHtml)(doc);
40
+ expect(html).toContain('{{ table_side_effects_en_list }}');
41
+ expect(html).toContain('intro');
42
+ });
43
+ it('compiles default CFM document', () => {
44
+ const html = (0, legal_term_document_compile_1.compileLegalTermDocumentToHtml)((0, default_legal_term_document_1.createDefaultCfmLegalTermDocument)());
45
+ expect(html).toContain('Termo de consentimento livre e esclarecido');
46
+ expect(html).toContain('{{ nome_paciente }}');
47
+ expect(html).toContain('Identificação das partes');
48
+ });
49
+ });
@@ -0,0 +1,21 @@
1
+ import { type LegalTermBlockType, type LegalTermDocument, type LegalTermSectionLevel } from './legal-term-document.types';
2
+ export declare class LegalTermDocumentBlockDto {
3
+ id: string;
4
+ type: LegalTermBlockType;
5
+ level?: LegalTermSectionLevel;
6
+ title?: string;
7
+ body?: string;
8
+ titleAlign?: 'left' | 'center' | 'right';
9
+ titleBold?: boolean;
10
+ titleItalic?: boolean;
11
+ titleUnderline?: boolean;
12
+ bodyAlign?: 'left' | 'center' | 'right';
13
+ bodyBold?: boolean;
14
+ bodyItalic?: boolean;
15
+ bodyUnderline?: boolean;
16
+ }
17
+ export declare class LegalTermDocumentDto implements LegalTermDocument {
18
+ version: 1;
19
+ blocks: LegalTermDocumentBlockDto[];
20
+ }
21
+ //# sourceMappingURL=legal-term-document.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legal-term-document.dto.d.ts","sourceRoot":"","sources":["../../src/legal-terms/legal-term-document.dto.ts"],"names":[],"mappings":"AAcA,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC3B,MAAM,6BAA6B,CAAC;AAErC,qBAAa,yBAAyB;IAKpC,EAAE,EAAE,MAAM,CAAC;IAIX,IAAI,EAAE,kBAAkB,CAAC;IAOzB,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAM9B,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,IAAI,CAAC,EAAE,MAAM,CAAC;IAKd,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAIzC,SAAS,CAAC,EAAE,OAAO,CAAC;IAIpB,WAAW,CAAC,EAAE,OAAO,CAAC;IAItB,cAAc,CAAC,EAAE,OAAO,CAAC;IAKzB,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAIxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAInB,UAAU,CAAC,EAAE,OAAO,CAAC;IAIrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,qBAAa,oBAAqB,YAAW,iBAAiB;IAK5D,OAAO,EAAE,CAAC,CAAC;IAMX,MAAM,EAAE,yBAAyB,EAAE,CAAC;CACrC"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (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
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.LegalTermDocumentDto = exports.LegalTermDocumentBlockDto = void 0;
13
+ const swagger_1 = require("@nestjs/swagger");
14
+ const class_transformer_1 = require("class-transformer");
15
+ const class_validator_1 = require("class-validator");
16
+ const legal_term_document_types_1 = require("./legal-term-document.types");
17
+ class LegalTermDocumentBlockDto {
18
+ id;
19
+ type;
20
+ level;
21
+ title;
22
+ body;
23
+ titleAlign;
24
+ titleBold;
25
+ titleItalic;
26
+ titleUnderline;
27
+ bodyAlign;
28
+ bodyBold;
29
+ bodyItalic;
30
+ bodyUnderline;
31
+ }
32
+ exports.LegalTermDocumentBlockDto = LegalTermDocumentBlockDto;
33
+ __decorate([
34
+ (0, swagger_1.ApiProperty)({ description: 'Identificador estável do bloco (UUID ou id preset CFM)' }),
35
+ (0, class_validator_1.IsString)(),
36
+ (0, class_validator_1.MinLength)(1),
37
+ (0, class_validator_1.MaxLength)(64),
38
+ __metadata("design:type", String)
39
+ ], LegalTermDocumentBlockDto.prototype, "id", void 0);
40
+ __decorate([
41
+ (0, swagger_1.ApiProperty)({ enum: legal_term_document_types_1.LEGAL_TERM_BLOCK_TYPES }),
42
+ (0, class_validator_1.IsIn)([...legal_term_document_types_1.LEGAL_TERM_BLOCK_TYPES]),
43
+ __metadata("design:type", String)
44
+ ], LegalTermDocumentBlockDto.prototype, "type", void 0);
45
+ __decorate([
46
+ (0, swagger_1.ApiPropertyOptional)({ enum: [1, 2, 3] }),
47
+ (0, class_validator_1.IsOptional)(),
48
+ (0, class_validator_1.IsInt)(),
49
+ (0, class_validator_1.Min)(1),
50
+ (0, class_validator_1.Max)(3),
51
+ __metadata("design:type", Number)
52
+ ], LegalTermDocumentBlockDto.prototype, "level", void 0);
53
+ __decorate([
54
+ (0, swagger_1.ApiPropertyOptional)({ maxLength: 500 }),
55
+ (0, class_validator_1.IsOptional)(),
56
+ (0, class_validator_1.IsString)(),
57
+ (0, class_validator_1.MaxLength)(500),
58
+ __metadata("design:type", String)
59
+ ], LegalTermDocumentBlockDto.prototype, "title", void 0);
60
+ __decorate([
61
+ (0, swagger_1.ApiPropertyOptional)({ maxLength: 50_000 }),
62
+ (0, class_validator_1.IsOptional)(),
63
+ (0, class_validator_1.IsString)(),
64
+ (0, class_validator_1.MaxLength)(50_000),
65
+ __metadata("design:type", String)
66
+ ], LegalTermDocumentBlockDto.prototype, "body", void 0);
67
+ __decorate([
68
+ (0, swagger_1.ApiPropertyOptional)({ enum: ['left', 'center', 'right'] }),
69
+ (0, class_validator_1.IsOptional)(),
70
+ (0, class_validator_1.IsIn)(['left', 'center', 'right']),
71
+ __metadata("design:type", String)
72
+ ], LegalTermDocumentBlockDto.prototype, "titleAlign", void 0);
73
+ __decorate([
74
+ (0, swagger_1.ApiPropertyOptional)(),
75
+ (0, class_validator_1.IsOptional)(),
76
+ __metadata("design:type", Boolean)
77
+ ], LegalTermDocumentBlockDto.prototype, "titleBold", void 0);
78
+ __decorate([
79
+ (0, swagger_1.ApiPropertyOptional)(),
80
+ (0, class_validator_1.IsOptional)(),
81
+ __metadata("design:type", Boolean)
82
+ ], LegalTermDocumentBlockDto.prototype, "titleItalic", void 0);
83
+ __decorate([
84
+ (0, swagger_1.ApiPropertyOptional)(),
85
+ (0, class_validator_1.IsOptional)(),
86
+ __metadata("design:type", Boolean)
87
+ ], LegalTermDocumentBlockDto.prototype, "titleUnderline", void 0);
88
+ __decorate([
89
+ (0, swagger_1.ApiPropertyOptional)({ enum: ['left', 'center', 'right'] }),
90
+ (0, class_validator_1.IsOptional)(),
91
+ (0, class_validator_1.IsIn)(['left', 'center', 'right']),
92
+ __metadata("design:type", String)
93
+ ], LegalTermDocumentBlockDto.prototype, "bodyAlign", void 0);
94
+ __decorate([
95
+ (0, swagger_1.ApiPropertyOptional)(),
96
+ (0, class_validator_1.IsOptional)(),
97
+ __metadata("design:type", Boolean)
98
+ ], LegalTermDocumentBlockDto.prototype, "bodyBold", void 0);
99
+ __decorate([
100
+ (0, swagger_1.ApiPropertyOptional)(),
101
+ (0, class_validator_1.IsOptional)(),
102
+ __metadata("design:type", Boolean)
103
+ ], LegalTermDocumentBlockDto.prototype, "bodyItalic", void 0);
104
+ __decorate([
105
+ (0, swagger_1.ApiPropertyOptional)(),
106
+ (0, class_validator_1.IsOptional)(),
107
+ __metadata("design:type", Boolean)
108
+ ], LegalTermDocumentBlockDto.prototype, "bodyUnderline", void 0);
109
+ class LegalTermDocumentDto {
110
+ version;
111
+ blocks;
112
+ }
113
+ exports.LegalTermDocumentDto = LegalTermDocumentDto;
114
+ __decorate([
115
+ (0, swagger_1.ApiProperty)({ enum: [legal_term_document_types_1.LEGAL_TERM_DOCUMENT_VERSION] }),
116
+ (0, class_validator_1.IsInt)(),
117
+ (0, class_validator_1.Min)(1),
118
+ (0, class_validator_1.Max)(1),
119
+ __metadata("design:type", Number)
120
+ ], LegalTermDocumentDto.prototype, "version", void 0);
121
+ __decorate([
122
+ (0, swagger_1.ApiProperty)({ type: [LegalTermDocumentBlockDto] }),
123
+ (0, class_validator_1.IsArray)(),
124
+ (0, class_validator_1.ValidateNested)({ each: true }),
125
+ (0, class_transformer_1.Type)(() => LegalTermDocumentBlockDto),
126
+ __metadata("design:type", Array)
127
+ ], LegalTermDocumentDto.prototype, "blocks", void 0);