@redneckz/wildless-cms-uni-blocks 0.14.20 → 0.14.21

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 (119) hide show
  1. package/bin/migration-scripts/0.14.21.js +33 -0
  2. package/bin/migration-scripts/0.14.7.js +1 -4
  3. package/bundle/blocks.schema.json +1 -1
  4. package/bundle/bundle.umd.js +7 -6
  5. package/bundle/bundle.umd.min.js +1 -1
  6. package/bundle/components/Footer/SocialMedia.d.ts +3 -1
  7. package/bundle/content-page-repository/transformAttachmentLink.d.ts +3 -0
  8. package/bundle/content-page-repository/transformContentPage.d.ts +3 -2
  9. package/bundle/ui-kit/List/ListContent.d.ts +0 -1
  10. package/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.js +1 -1
  11. package/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.js.map +1 -1
  12. package/dist/components/Footer/Footer.js +1 -1
  13. package/dist/components/Footer/Footer.js.map +1 -1
  14. package/dist/components/Footer/SocialMedia.d.ts +3 -1
  15. package/dist/components/Footer/SocialMedia.js +4 -3
  16. package/dist/components/Footer/SocialMedia.js.map +1 -1
  17. package/dist/content-page-repository/transformAttachmentLink.d.ts +3 -0
  18. package/dist/content-page-repository/transformAttachmentLink.js +33 -0
  19. package/dist/content-page-repository/transformAttachmentLink.js.map +1 -0
  20. package/dist/content-page-repository/transformContentPage.d.ts +3 -2
  21. package/dist/content-page-repository/transformContentPage.js +7 -1
  22. package/dist/content-page-repository/transformContentPage.js.map +1 -1
  23. package/dist/content-page-repository/transformDocument.js +1 -1
  24. package/dist/content-page-repository/transformDocument.js.map +1 -1
  25. package/dist/content-page-repository/transformImg.js +1 -1
  26. package/dist/content-page-repository/transformImg.js.map +1 -1
  27. package/dist/ui-kit/List/ListContent.d.ts +0 -1
  28. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.js +1 -1
  29. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.js.map +1 -1
  30. package/lib/components/Footer/Footer.js +1 -1
  31. package/lib/components/Footer/Footer.js.map +1 -1
  32. package/lib/components/Footer/SocialMedia.d.ts +3 -1
  33. package/lib/components/Footer/SocialMedia.js +4 -3
  34. package/lib/components/Footer/SocialMedia.js.map +1 -1
  35. package/lib/content-page-repository/transformAttachmentLink.d.ts +3 -0
  36. package/lib/content-page-repository/transformAttachmentLink.js +27 -0
  37. package/lib/content-page-repository/transformAttachmentLink.js.map +1 -0
  38. package/lib/content-page-repository/transformContentPage.d.ts +3 -2
  39. package/lib/content-page-repository/transformContentPage.js +6 -0
  40. package/lib/content-page-repository/transformContentPage.js.map +1 -1
  41. package/lib/content-page-repository/transformDocument.js +1 -1
  42. package/lib/content-page-repository/transformDocument.js.map +1 -1
  43. package/lib/content-page-repository/transformImg.js +1 -1
  44. package/lib/content-page-repository/transformImg.js.map +1 -1
  45. package/lib/ui-kit/List/ListContent.d.ts +0 -1
  46. package/mobile/bundle/bundle.umd.js +6 -5
  47. package/mobile/bundle/bundle.umd.min.js +1 -1
  48. package/mobile/bundle/components/Footer/SocialMedia.d.ts +3 -1
  49. package/mobile/bundle/content-page-repository/transformAttachmentLink.d.ts +3 -0
  50. package/mobile/bundle/content-page-repository/transformContentPage.d.ts +3 -2
  51. package/mobile/bundle/ui-kit/List/ListContent.d.ts +0 -1
  52. package/mobile/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.js +1 -1
  53. package/mobile/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.js.map +1 -1
  54. package/mobile/dist/components/Footer/SocialMedia.d.ts +3 -1
  55. package/mobile/dist/components/Footer/SocialMedia.js +4 -3
  56. package/mobile/dist/components/Footer/SocialMedia.js.map +1 -1
  57. package/mobile/dist/content-page-repository/transformAttachmentLink.d.ts +3 -0
  58. package/mobile/dist/content-page-repository/transformAttachmentLink.js +33 -0
  59. package/mobile/dist/content-page-repository/transformAttachmentLink.js.map +1 -0
  60. package/mobile/dist/content-page-repository/transformContentPage.d.ts +3 -2
  61. package/mobile/dist/content-page-repository/transformContentPage.js +7 -1
  62. package/mobile/dist/content-page-repository/transformContentPage.js.map +1 -1
  63. package/mobile/dist/content-page-repository/transformDocument.js +1 -1
  64. package/mobile/dist/content-page-repository/transformDocument.js.map +1 -1
  65. package/mobile/dist/content-page-repository/transformImg.js +1 -1
  66. package/mobile/dist/content-page-repository/transformImg.js.map +1 -1
  67. package/mobile/dist/ui-kit/List/ListContent.d.ts +0 -1
  68. package/mobile/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.js +1 -1
  69. package/mobile/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.js.map +1 -1
  70. package/mobile/lib/components/Footer/SocialMedia.d.ts +3 -1
  71. package/mobile/lib/components/Footer/SocialMedia.js +4 -3
  72. package/mobile/lib/components/Footer/SocialMedia.js.map +1 -1
  73. package/mobile/lib/content-page-repository/transformAttachmentLink.d.ts +3 -0
  74. package/mobile/lib/content-page-repository/transformAttachmentLink.js +27 -0
  75. package/mobile/lib/content-page-repository/transformAttachmentLink.js.map +1 -0
  76. package/mobile/lib/content-page-repository/transformContentPage.d.ts +3 -2
  77. package/mobile/lib/content-page-repository/transformContentPage.js +6 -0
  78. package/mobile/lib/content-page-repository/transformContentPage.js.map +1 -1
  79. package/mobile/lib/content-page-repository/transformDocument.js +1 -1
  80. package/mobile/lib/content-page-repository/transformDocument.js.map +1 -1
  81. package/mobile/lib/content-page-repository/transformImg.js +1 -1
  82. package/mobile/lib/content-page-repository/transformImg.js.map +1 -1
  83. package/mobile/lib/ui-kit/List/ListContent.d.ts +0 -1
  84. package/mobile/src/components/Bonus/Bonus.ui.json +3 -0
  85. package/mobile/src/components/BusinessBlock/BusinessBlock.ui.json +3 -0
  86. package/mobile/src/components/ButtonsBlock/ButtonsBlock.ui.json +3 -0
  87. package/mobile/src/components/Calculator/Calculator.ui.json +3 -0
  88. package/mobile/src/components/CarouselProductCard/CarouselProductCard.ui.json +3 -0
  89. package/mobile/src/components/CarouselRecommendationCard/CarouselRecommendationCard.tsx +3 -1
  90. package/mobile/src/components/CarouselTariffsCard/CarouselTariffsCard.ui.json +3 -0
  91. package/mobile/src/components/Footer/SocialMedia.tsx +8 -5
  92. package/mobile/src/components/ProductGallery/ProductGallery.ui.json +3 -0
  93. package/mobile/src/components/RepresentativeOfficeInfo/RepresentativeOfficeInfo.ui.json +3 -0
  94. package/mobile/src/components/StepsBlock/StepsBlock.ui.json +6 -0
  95. package/mobile/src/components/TariffsTable/TariffsTable.ui.json +3 -0
  96. package/mobile/src/content-page-repository/transformAttachmentLink.ts +38 -0
  97. package/mobile/src/content-page-repository/transformContentPage.ts +13 -4
  98. package/mobile/src/content-page-repository/transformDocument.ts +1 -1
  99. package/mobile/src/content-page-repository/transformImg.ts +1 -1
  100. package/mobile/src/ui-kit/List/ListContent.ts +0 -1
  101. package/package.json +1 -1
  102. package/src/components/Bonus/Bonus.ui.json +3 -0
  103. package/src/components/BusinessBlock/BusinessBlock.ui.json +3 -0
  104. package/src/components/ButtonsBlock/ButtonsBlock.ui.json +3 -0
  105. package/src/components/Calculator/Calculator.ui.json +3 -0
  106. package/src/components/CarouselProductCard/CarouselProductCard.ui.json +3 -0
  107. package/src/components/CarouselRecommendationCard/CarouselRecommendationCard.tsx +3 -1
  108. package/src/components/CarouselTariffsCard/CarouselTariffsCard.ui.json +3 -0
  109. package/src/components/Footer/Footer.tsx +3 -1
  110. package/src/components/Footer/SocialMedia.tsx +8 -5
  111. package/src/components/ProductGallery/ProductGallery.ui.json +3 -0
  112. package/src/components/RepresentativeOfficeInfo/RepresentativeOfficeInfo.ui.json +3 -0
  113. package/src/components/StepsBlock/StepsBlock.ui.json +6 -0
  114. package/src/components/TariffsTable/TariffsTable.ui.json +3 -0
  115. package/src/content-page-repository/transformAttachmentLink.ts +38 -0
  116. package/src/content-page-repository/transformContentPage.ts +13 -4
  117. package/src/content-page-repository/transformDocument.ts +1 -1
  118. package/src/content-page-repository/transformImg.ts +1 -1
  119. package/src/ui-kit/List/ListContent.ts +0 -1
@@ -1,7 +1,8 @@
1
1
  import { JSX } from '@redneckz/uni-jsx';
2
2
  import { useState } from '@redneckz/uni-jsx/lib/hooks';
3
- import { type Picture } from '../../model/Picture';
4
- import { type ButtonContent } from '../../ui-kit/Button/ButtonContent';
3
+ import type { ButtonVersion } from '../../model/ButtonVersion';
4
+ import type { Picture } from '../../model/Picture';
5
+ import type { ButtonContent } from '../../ui-kit/Button/ButtonContent';
5
6
  import { renderButtonsSection } from '../../ui-kit/Button/renderButtonsSection';
6
7
  import { Text } from '../../ui-kit/Text/Text';
7
8
  import { style } from '../../utils/style';
@@ -12,25 +13,27 @@ export interface SocialMediaProps {
12
13
  media?: ButtonContent[];
13
14
  showButtonText?: boolean;
14
15
  stretched?: boolean;
16
+ version?: ButtonVersion;
15
17
  }
16
18
 
17
19
  export const SocialMedia = JSX<SocialMediaProps>(
18
- ({ className = '', media, showButtonText, stretched, children }) => {
20
+ ({ className = '', media, showButtonText, stretched, version = 'white', children }) => {
19
21
  const [hasText, setHasText] = useState<boolean | undefined>();
20
22
  const buttons: ButtonContent[] | undefined = media?.map((_) => {
21
23
  const { href, icon, text } = _;
22
24
  const { iconMapped } = findIconByHref(href);
23
25
  const iconCustom = getFilteredIcon(icon) ?? iconMapped;
24
- const buttonText = showButtonText ? { text } : {};
26
+ const buttonText = showButtonText ? { text } : { text: '' };
25
27
 
26
28
  if (!hasText && text) {
27
29
  setHasText(true);
28
30
  }
29
31
 
30
32
  return {
33
+ ..._,
31
34
  ...buttonText,
32
35
  icon: { ...iconCustom, iconVersion: 'color' },
33
- version: 'white',
36
+ version,
34
37
  };
35
38
  });
36
39
 
@@ -15,6 +15,9 @@
15
15
  },
16
16
  "buttons": {
17
17
  "items": {
18
+ "href": {
19
+ "ui:field": "attachmentHref"
20
+ },
18
21
  "icon": {
19
22
  "ui:field": "icon"
20
23
  },
@@ -4,6 +4,9 @@
4
4
  "ui:widget": "html"
5
5
  },
6
6
  "button": {
7
+ "href": {
8
+ "ui:field": "attachmentHref"
9
+ },
7
10
  "icon": {
8
11
  "ui:field": "icon"
9
12
  },
@@ -2,6 +2,9 @@
2
2
  "content": {
3
3
  "buttons": {
4
4
  "items": {
5
+ "href": {
6
+ "ui:field": "attachmentHref"
7
+ },
5
8
  "icon": {
6
9
  "ui:field": "icon"
7
10
  },
@@ -16,6 +19,9 @@
16
19
  "ui:field": "icon"
17
20
  },
18
21
  "button": {
22
+ "href": {
23
+ "ui:field": "attachmentHref"
24
+ },
19
25
  "icon": {
20
26
  "ui:field": "icon"
21
27
  },
@@ -16,6 +16,9 @@
16
16
  },
17
17
  "buttons": {
18
18
  "items": {
19
+ "href": {
20
+ "ui:field": "attachmentHref"
21
+ },
19
22
  "icon": {
20
23
  "ui:field": "icon"
21
24
  },
@@ -0,0 +1,38 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import util from 'util';
4
+ import type { LinkProps } from '../model/LinkProps';
5
+ import type { TransformationOptions } from './TransformationOptions';
6
+ import { ATTACHMENT_PREFIX } from './transformContentPage';
7
+
8
+ const copyFile = util.promisify(fs.copyFile);
9
+
10
+ export async function transformAttachmentLink(
11
+ link: LinkProps,
12
+ pagePath: string,
13
+ options: TransformationOptions,
14
+ ): Promise<LinkProps> {
15
+ if (!link?.href) {
16
+ return link;
17
+ }
18
+
19
+ const { contentDir, publicDir } = options;
20
+ const input = link.href.replace(ATTACHMENT_PREFIX, '');
21
+ const docRelativePath = path.relative(contentDir, input);
22
+ const output = path.join(publicDir, docRelativePath);
23
+
24
+ try {
25
+ await copyFile(input, output);
26
+ } catch (e) {
27
+ console.info(`No "${input}" attachment found on page: "${pagePath}"`);
28
+
29
+ return link;
30
+ }
31
+
32
+ const href = path.join('/', docRelativePath);
33
+
34
+ return {
35
+ ...link,
36
+ href,
37
+ };
38
+ }
@@ -2,11 +2,13 @@ import { fileResolver, resolveRef } from '@redneckz/json-ref';
2
2
  import { type JSONNode } from '@redneckz/json-ref/lib/JSONNode';
3
3
  import fs from 'fs';
4
4
  import util from 'util';
5
- import { type Attachment } from '../model/Attachment';
6
- import { type ContentPageDef } from '../model/ContentPageDef';
7
- import { type Picture } from '../model/Picture';
5
+ import type { Attachment } from '../model/Attachment';
6
+ import type { ContentPageDef } from '../model/ContentPageDef';
7
+ import type { LinkProps } from '../model/LinkProps';
8
+ import type { Picture } from '../model/Picture';
8
9
  import { mapJSON } from './mapJSON';
9
- import { type TransformationOptions } from './TransformationOptions';
10
+ import type { TransformationOptions } from './TransformationOptions';
11
+ import { transformAttachmentLink } from './transformAttachmentLink';
10
12
  import { transformDocument } from './transformDocument';
11
13
  import { transformHTML } from './transformHTML';
12
14
  import { transformMarkdown } from './transformMarkdown';
@@ -17,6 +19,8 @@ const writeFile = util.promisify(fs.writeFile);
17
19
 
18
20
  const OUTPUT_SUFFIX = '.static';
19
21
 
22
+ export const ATTACHMENT_PREFIX = 'file://';
23
+
20
24
  const DOCUMENT_EXT_LIST = [
21
25
  '.txt',
22
26
  '.doc',
@@ -42,6 +46,8 @@ export async function transformContentPage(
42
46
  return await transformMarkdown(value as string);
43
47
  } else if (isHTML(key, value)) {
44
48
  return await transformHTML(value as string);
49
+ } else if (isAttachmentLink(value)) {
50
+ return await transformAttachmentLink(value, pagePath, options);
45
51
  } else if (isDocumentRef(value)) {
46
52
  return await transformDocument(value, pagePath, options);
47
53
  } else if (isPicture(value)) {
@@ -67,6 +73,9 @@ const isMarkdown = (key: string, value: any): value is string =>
67
73
  const isHTML = (key: string, value: any): value is string =>
68
74
  isString(value) && key?.endsWith('__html');
69
75
 
76
+ const isAttachmentLink = (_: any): _ is LinkProps =>
77
+ isLocalPath(_?.href) && _.href.startsWith(ATTACHMENT_PREFIX);
78
+
70
79
  const isDocumentRef = (_: any): _ is Attachment =>
71
80
  isLocalPath(_?.src) && DOCUMENT_EXT_LIST.some((ext) => _.src.toLowerCase().endsWith(ext));
72
81
 
@@ -17,7 +17,7 @@ export async function transformDocument(
17
17
  }
18
18
 
19
19
  const { contentDir, publicDir } = options;
20
- const input = path.join(path.dirname(pagePath), attachment.src);
20
+ const input = attachment.src;
21
21
  const docRelativePath = path.relative(contentDir, input);
22
22
  const output = path.join(publicDir, docRelativePath);
23
23
  const inputFileSize = (await stat(input)).size;
@@ -37,7 +37,7 @@ export function transformImg(
37
37
  return src || '';
38
38
  }
39
39
 
40
- const input = path.join(path.dirname(pagePath), src);
40
+ const input = src;
41
41
  const output = computeImgOutputPath(input, options);
42
42
 
43
43
  const { cache = defaultTransformationCache } = options;
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * @title Размер пунктов списка
3
- * @default M
4
3
  * @enumNames ["Очень маленький", "Маленький", "Средний", "Большой"]
5
4
  */
6
5
  export type ListItemSize = 'XS' | 'S' | 'M' | 'L';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redneckz/wildless-cms-uni-blocks",
3
- "version": "0.14.20",
3
+ "version": "0.14.21",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "author": "ЦК",
@@ -12,6 +12,9 @@
12
12
  },
13
13
  "buttons": {
14
14
  "items": {
15
+ "href": {
16
+ "ui:field": "attachmentHref"
17
+ },
15
18
  "icon": {
16
19
  "ui:field": "icon"
17
20
  },
@@ -6,6 +6,9 @@
6
6
  "ui:field": "picture"
7
7
  },
8
8
  "button": {
9
+ "href": {
10
+ "ui:field": "attachmentHref"
11
+ },
9
12
  "icon": {
10
13
  "ui:field": "icon"
11
14
  },
@@ -2,6 +2,9 @@
2
2
  "content": {
3
3
  "buttons": {
4
4
  "items": {
5
+ "href": {
6
+ "ui:field": "attachmentHref"
7
+ },
5
8
  "icon": {
6
9
  "ui:field": "icon"
7
10
  },
@@ -24,6 +24,9 @@
24
24
  },
25
25
  "buttons": {
26
26
  "items": {
27
+ "href": {
28
+ "ui:field": "attachmentHref"
29
+ },
27
30
  "icon": {
28
31
  "ui:field": "icon"
29
32
  },
@@ -7,6 +7,9 @@
7
7
  "ui:field": "picture"
8
8
  },
9
9
  "button": {
10
+ "href": {
11
+ "ui:field": "attachmentHref"
12
+ },
10
13
  "icon": {
11
14
  "ui:field": "icon"
12
15
  },
@@ -54,7 +54,9 @@ export const CarouselRecommendationCard = JSX<RecommendationCardProps>(
54
54
  }
55
55
  rightImage={icon?.icon || icon?.src ? <Img image={icon} /> : null}
56
56
  buttons={
57
- socialMedia.length ? <SocialMedia media={socialMedia} showButtonText={true} /> : null
57
+ socialMedia.length ? (
58
+ <SocialMedia media={socialMedia} showButtonText={true} version={rest.version} />
59
+ ) : null
58
60
  }
59
61
  isImageAlwaysOnRight={isImageAlwaysOnRight}
60
62
  >
@@ -4,6 +4,9 @@
4
4
  "items": {
5
5
  "buttons": {
6
6
  "items": {
7
+ "href": {
8
+ "ui:field": "attachmentHref"
9
+ },
7
10
  "icon": {
8
11
  "ui:field": "icon"
9
12
  },
@@ -33,7 +33,9 @@ export const Footer = JSX<FooterProps>(({ className, ...rest }) => {
33
33
  <div className={style(LEFT_COL_WIDTH, 'flex flex-col shrink-0 overflow-hidden space-y-xl')}>
34
34
  <Contacts items={contacts} />
35
35
  <SocialMedia media={socialMedia}>Соцсети</SocialMedia>
36
- <SocialMedia media={mobileApps}>Мобильное приложение</SocialMedia>
36
+ <SocialMedia media={mobileApps} showButtonText={false}>
37
+ Мобильное приложение
38
+ </SocialMedia>
37
39
  </div>
38
40
  <Sitemap className="flex-grow" topItems={topItems} />
39
41
  </div>
@@ -1,7 +1,8 @@
1
1
  import { JSX } from '@redneckz/uni-jsx';
2
2
  import { useState } from '@redneckz/uni-jsx/lib/hooks';
3
- import { type Picture } from '../../model/Picture';
4
- import { type ButtonContent } from '../../ui-kit/Button/ButtonContent';
3
+ import type { ButtonVersion } from '../../model/ButtonVersion';
4
+ import type { Picture } from '../../model/Picture';
5
+ import type { ButtonContent } from '../../ui-kit/Button/ButtonContent';
5
6
  import { renderButtonsSection } from '../../ui-kit/Button/renderButtonsSection';
6
7
  import { Text } from '../../ui-kit/Text/Text';
7
8
  import { style } from '../../utils/style';
@@ -12,25 +13,27 @@ export interface SocialMediaProps {
12
13
  media?: ButtonContent[];
13
14
  showButtonText?: boolean;
14
15
  stretched?: boolean;
16
+ version?: ButtonVersion;
15
17
  }
16
18
 
17
19
  export const SocialMedia = JSX<SocialMediaProps>(
18
- ({ className = '', media, showButtonText, stretched, children }) => {
20
+ ({ className = '', media, showButtonText, stretched, version = 'white', children }) => {
19
21
  const [hasText, setHasText] = useState<boolean | undefined>();
20
22
  const buttons: ButtonContent[] | undefined = media?.map((_) => {
21
23
  const { href, icon, text } = _;
22
24
  const { iconMapped } = findIconByHref(href);
23
25
  const iconCustom = getFilteredIcon(icon) ?? iconMapped;
24
- const buttonText = showButtonText ? { text } : {};
26
+ const buttonText = showButtonText ? { text } : { text: '' };
25
27
 
26
28
  if (!hasText && text) {
27
29
  setHasText(true);
28
30
  }
29
31
 
30
32
  return {
33
+ ..._,
31
34
  ...buttonText,
32
35
  icon: { ...iconCustom, iconVersion: 'color' },
33
- version: 'white',
36
+ version,
34
37
  };
35
38
  });
36
39
 
@@ -15,6 +15,9 @@
15
15
  },
16
16
  "buttons": {
17
17
  "items": {
18
+ "href": {
19
+ "ui:field": "attachmentHref"
20
+ },
18
21
  "icon": {
19
22
  "ui:field": "icon"
20
23
  },
@@ -4,6 +4,9 @@
4
4
  "ui:widget": "html"
5
5
  },
6
6
  "button": {
7
+ "href": {
8
+ "ui:field": "attachmentHref"
9
+ },
7
10
  "icon": {
8
11
  "ui:field": "icon"
9
12
  },
@@ -2,6 +2,9 @@
2
2
  "content": {
3
3
  "buttons": {
4
4
  "items": {
5
+ "href": {
6
+ "ui:field": "attachmentHref"
7
+ },
5
8
  "icon": {
6
9
  "ui:field": "icon"
7
10
  },
@@ -16,6 +19,9 @@
16
19
  "ui:field": "icon"
17
20
  },
18
21
  "button": {
22
+ "href": {
23
+ "ui:field": "attachmentHref"
24
+ },
19
25
  "icon": {
20
26
  "ui:field": "icon"
21
27
  },
@@ -16,6 +16,9 @@
16
16
  },
17
17
  "buttons": {
18
18
  "items": {
19
+ "href": {
20
+ "ui:field": "attachmentHref"
21
+ },
19
22
  "icon": {
20
23
  "ui:field": "icon"
21
24
  },
@@ -0,0 +1,38 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import util from 'util';
4
+ import type { LinkProps } from '../model/LinkProps';
5
+ import type { TransformationOptions } from './TransformationOptions';
6
+ import { ATTACHMENT_PREFIX } from './transformContentPage';
7
+
8
+ const copyFile = util.promisify(fs.copyFile);
9
+
10
+ export async function transformAttachmentLink(
11
+ link: LinkProps,
12
+ pagePath: string,
13
+ options: TransformationOptions,
14
+ ): Promise<LinkProps> {
15
+ if (!link?.href) {
16
+ return link;
17
+ }
18
+
19
+ const { contentDir, publicDir } = options;
20
+ const input = link.href.replace(ATTACHMENT_PREFIX, '');
21
+ const docRelativePath = path.relative(contentDir, input);
22
+ const output = path.join(publicDir, docRelativePath);
23
+
24
+ try {
25
+ await copyFile(input, output);
26
+ } catch (e) {
27
+ console.info(`No "${input}" attachment found on page: "${pagePath}"`);
28
+
29
+ return link;
30
+ }
31
+
32
+ const href = path.join('/', docRelativePath);
33
+
34
+ return {
35
+ ...link,
36
+ href,
37
+ };
38
+ }
@@ -2,11 +2,13 @@ import { fileResolver, resolveRef } from '@redneckz/json-ref';
2
2
  import { type JSONNode } from '@redneckz/json-ref/lib/JSONNode';
3
3
  import fs from 'fs';
4
4
  import util from 'util';
5
- import { type Attachment } from '../model/Attachment';
6
- import { type ContentPageDef } from '../model/ContentPageDef';
7
- import { type Picture } from '../model/Picture';
5
+ import type { Attachment } from '../model/Attachment';
6
+ import type { ContentPageDef } from '../model/ContentPageDef';
7
+ import type { LinkProps } from '../model/LinkProps';
8
+ import type { Picture } from '../model/Picture';
8
9
  import { mapJSON } from './mapJSON';
9
- import { type TransformationOptions } from './TransformationOptions';
10
+ import type { TransformationOptions } from './TransformationOptions';
11
+ import { transformAttachmentLink } from './transformAttachmentLink';
10
12
  import { transformDocument } from './transformDocument';
11
13
  import { transformHTML } from './transformHTML';
12
14
  import { transformMarkdown } from './transformMarkdown';
@@ -17,6 +19,8 @@ const writeFile = util.promisify(fs.writeFile);
17
19
 
18
20
  const OUTPUT_SUFFIX = '.static';
19
21
 
22
+ export const ATTACHMENT_PREFIX = 'file://';
23
+
20
24
  const DOCUMENT_EXT_LIST = [
21
25
  '.txt',
22
26
  '.doc',
@@ -42,6 +46,8 @@ export async function transformContentPage(
42
46
  return await transformMarkdown(value as string);
43
47
  } else if (isHTML(key, value)) {
44
48
  return await transformHTML(value as string);
49
+ } else if (isAttachmentLink(value)) {
50
+ return await transformAttachmentLink(value, pagePath, options);
45
51
  } else if (isDocumentRef(value)) {
46
52
  return await transformDocument(value, pagePath, options);
47
53
  } else if (isPicture(value)) {
@@ -67,6 +73,9 @@ const isMarkdown = (key: string, value: any): value is string =>
67
73
  const isHTML = (key: string, value: any): value is string =>
68
74
  isString(value) && key?.endsWith('__html');
69
75
 
76
+ const isAttachmentLink = (_: any): _ is LinkProps =>
77
+ isLocalPath(_?.href) && _.href.startsWith(ATTACHMENT_PREFIX);
78
+
70
79
  const isDocumentRef = (_: any): _ is Attachment =>
71
80
  isLocalPath(_?.src) && DOCUMENT_EXT_LIST.some((ext) => _.src.toLowerCase().endsWith(ext));
72
81
 
@@ -17,7 +17,7 @@ export async function transformDocument(
17
17
  }
18
18
 
19
19
  const { contentDir, publicDir } = options;
20
- const input = path.join(path.dirname(pagePath), attachment.src);
20
+ const input = attachment.src;
21
21
  const docRelativePath = path.relative(contentDir, input);
22
22
  const output = path.join(publicDir, docRelativePath);
23
23
  const inputFileSize = (await stat(input)).size;
@@ -37,7 +37,7 @@ export function transformImg(
37
37
  return src || '';
38
38
  }
39
39
 
40
- const input = path.join(path.dirname(pagePath), src);
40
+ const input = src;
41
41
  const output = computeImgOutputPath(input, options);
42
42
 
43
43
  const { cache = defaultTransformationCache } = options;
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * @title Размер пунктов списка
3
- * @default M
4
3
  * @enumNames ["Очень маленький", "Маленький", "Средний", "Большой"]
5
4
  */
6
5
  export type ListItemSize = 'XS' | 'S' | 'M' | 'L';