confluence-md-sync 0.8.8 → 0.8.9
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/macros/registry.js +4 -2
- package/dist/macros/xml.d.ts +14 -1
- package/dist/macros/xml.js +20 -1
- package/package.json +1 -1
package/dist/macros/registry.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Markdown } from '../markdown/markdown.js';
|
|
2
2
|
import { unescapeParamValue } from './builder.js';
|
|
3
|
-
import {
|
|
3
|
+
import { stableMacroId, structuredMacro } from './xml.js';
|
|
4
4
|
/**
|
|
5
5
|
* Реестр макросов. Пустой при создании — наполняется плагинами через
|
|
6
6
|
* {@link use} или точечной регистрацией через {@link register}.
|
|
@@ -126,7 +126,9 @@ function processMacroType(storage, macroName, renderer) {
|
|
|
126
126
|
}
|
|
127
127
|
const bodyStart = startIdx + match[0].length;
|
|
128
128
|
const body = storage.substring(bodyStart, endIdx).trim();
|
|
129
|
-
|
|
129
|
+
// Стабильный id от содержимого маркера — иначе он менялся бы на КАЖДЫЙ
|
|
130
|
+
// рендер (см. stableMacroId), ломая content-hash идемпотентность publish.
|
|
131
|
+
const macroId = stableMacroId(`${macroName}\u0000${paramStr}\u0000${body}`);
|
|
130
132
|
const macroXhtml = renderer({ params, body, macroId });
|
|
131
133
|
const before = storage.substring(0, startIdx);
|
|
132
134
|
const after = storage.substring(endIdx + endMarker.length);
|
package/dist/macros/xml.d.ts
CHANGED
|
@@ -2,8 +2,21 @@
|
|
|
2
2
|
import type { MacroParam } from './types.js';
|
|
3
3
|
/** Экранирует строку для XML-атрибутов и текстовых узлов. */
|
|
4
4
|
export declare function escapeXmlAttr(s: string): string;
|
|
5
|
-
/** Генерирует UUID для ac:macro-id. */
|
|
5
|
+
/** Генерирует случайный UUID для ac:macro-id (когда стабильность не нужна). */
|
|
6
6
|
export declare function generateMacroId(): string;
|
|
7
|
+
/**
|
|
8
|
+
* Детерминированный macro-id (UUID-формы) от seed — как правило, от исходного
|
|
9
|
+
* содержимого маркера (имя+параметры+тело). ВАЖНО для идемпотентности
|
|
10
|
+
* content-hash: если id генерировать случайно на каждый рендер (см.
|
|
11
|
+
* {@link generateMacroId}), storage у страницы с любым макросом отличается
|
|
12
|
+
* при каждой публикации, даже когда исходный markdown не менялся — hash
|
|
13
|
+
* никогда не совпадает, и publish принудительно обновляет страницу заново
|
|
14
|
+
* при каждом прогоне (замечено на проде: 1 изменённый файл → 250+ страниц
|
|
15
|
+
* «обновились», потому что ~250 из них содержат макрос details/properties).
|
|
16
|
+
* Стабильный id по содержимому убирает этот псевдо-дрейф: одинаковый маркер
|
|
17
|
+
* даёт одинаковый storage → hash совпадает → UNCHANGED.
|
|
18
|
+
*/
|
|
19
|
+
export declare function stableMacroId(seed: string): string;
|
|
7
20
|
export interface StructuredMacroOptions {
|
|
8
21
|
/**
|
|
9
22
|
* Macro parameters. `undefined` values are skipped. A key rendered as
|
package/dist/macros/xml.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** XML helpers shared by macro renderers. */
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
2
3
|
/** Экранирует строку для XML-атрибутов и текстовых узлов. */
|
|
3
4
|
export function escapeXmlAttr(s) {
|
|
4
5
|
return s.replace(/[<>&"']/g, (c) => {
|
|
@@ -12,7 +13,7 @@ export function escapeXmlAttr(s) {
|
|
|
12
13
|
}
|
|
13
14
|
});
|
|
14
15
|
}
|
|
15
|
-
/** Генерирует UUID для ac:macro-id. */
|
|
16
|
+
/** Генерирует случайный UUID для ac:macro-id (когда стабильность не нужна). */
|
|
16
17
|
export function generateMacroId() {
|
|
17
18
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
18
19
|
const r = (Math.random() * 16) | 0;
|
|
@@ -20,6 +21,24 @@ export function generateMacroId() {
|
|
|
20
21
|
return v.toString(16);
|
|
21
22
|
});
|
|
22
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Детерминированный macro-id (UUID-формы) от seed — как правило, от исходного
|
|
26
|
+
* содержимого маркера (имя+параметры+тело). ВАЖНО для идемпотентности
|
|
27
|
+
* content-hash: если id генерировать случайно на каждый рендер (см.
|
|
28
|
+
* {@link generateMacroId}), storage у страницы с любым макросом отличается
|
|
29
|
+
* при каждой публикации, даже когда исходный markdown не менялся — hash
|
|
30
|
+
* никогда не совпадает, и publish принудительно обновляет страницу заново
|
|
31
|
+
* при каждом прогоне (замечено на проде: 1 изменённый файл → 250+ страниц
|
|
32
|
+
* «обновились», потому что ~250 из них содержат макрос details/properties).
|
|
33
|
+
* Стабильный id по содержимому убирает этот псевдо-дрейф: одинаковый маркер
|
|
34
|
+
* даёт одинаковый storage → hash совпадает → UNCHANGED.
|
|
35
|
+
*/
|
|
36
|
+
export function stableMacroId(seed) {
|
|
37
|
+
const hex = createHash('sha256').update(seed, 'utf-8').digest('hex');
|
|
38
|
+
const bytes = hex.slice(0, 32);
|
|
39
|
+
return (`${bytes.slice(0, 8)}-${bytes.slice(8, 12)}-4${bytes.slice(13, 16)}-` +
|
|
40
|
+
`${'89ab'[parseInt(bytes[16], 16) % 4]}${bytes.slice(17, 20)}-${bytes.slice(20, 32)}`);
|
|
41
|
+
}
|
|
23
42
|
/**
|
|
24
43
|
* Assembles an `<ac:structured-macro>` element. Takes care of parameter
|
|
25
44
|
* escaping, rich vs plain bodies and CDATA safety.
|
package/package.json
CHANGED