jvetrau-ds 0.2.17 → 0.2.19

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 (36) hide show
  1. package/components/embed-viewer/embed-viewer.cjs +98 -4
  2. package/components/embed-viewer/embed-viewer.cjs.map +1 -1
  3. package/components/embed-viewer/embed-viewer.d.ts +5 -1
  4. package/components/embed-viewer/embed-viewer.js +93 -4
  5. package/components/embed-viewer/embed-viewer.js.map +1 -1
  6. package/components/embed-viewer/open-graph.cjs +61 -0
  7. package/components/embed-viewer/open-graph.cjs.map +1 -0
  8. package/components/embed-viewer/open-graph.d.ts +5 -0
  9. package/components/embed-viewer/open-graph.js +59 -0
  10. package/components/embed-viewer/open-graph.js.map +1 -0
  11. package/components/embed-viewer/providers/figma.cjs +50 -0
  12. package/components/embed-viewer/providers/figma.cjs.map +1 -0
  13. package/components/embed-viewer/providers/figma.d.ts +5 -0
  14. package/components/embed-viewer/providers/figma.js +47 -0
  15. package/components/embed-viewer/providers/figma.js.map +1 -0
  16. package/components/embed-viewer/providers/google.cjs +84 -0
  17. package/components/embed-viewer/providers/google.cjs.map +1 -0
  18. package/components/embed-viewer/providers/google.d.ts +6 -0
  19. package/components/embed-viewer/providers/google.js +81 -0
  20. package/components/embed-viewer/providers/google.js.map +1 -0
  21. package/components/embed-viewer/providers/miro.cjs +43 -0
  22. package/components/embed-viewer/providers/miro.cjs.map +1 -0
  23. package/components/embed-viewer/providers/miro.d.ts +5 -0
  24. package/components/embed-viewer/providers/miro.js +40 -0
  25. package/components/embed-viewer/providers/miro.js.map +1 -0
  26. package/components/embed-viewer/providers/typeform.cjs +28 -0
  27. package/components/embed-viewer/providers/typeform.cjs.map +1 -0
  28. package/components/embed-viewer/providers/typeform.d.ts +5 -0
  29. package/components/embed-viewer/providers/typeform.js +25 -0
  30. package/components/embed-viewer/providers/typeform.js.map +1 -0
  31. package/components/embed-viewer/resolver.cjs +74 -0
  32. package/components/embed-viewer/resolver.cjs.map +1 -0
  33. package/components/embed-viewer/resolver.d.ts +15 -0
  34. package/components/embed-viewer/resolver.js +72 -0
  35. package/components/embed-viewer/resolver.js.map +1 -0
  36. package/package.json +1 -1
@@ -1,14 +1,35 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
4
5
  require('./embed-viewer.css');
6
+ var ActionGroup = require('../action-group');
7
+ var Button = require('../button');
5
8
  var classnames = require('../helpers/classnames');
9
+ var openGraph = require('./open-graph');
10
+ var resolver = require('./resolver');
6
11
 
12
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
+
14
+ var ActionGroup__default = /*#__PURE__*/_interopDefault(ActionGroup);
15
+ var Button__default = /*#__PURE__*/_interopDefault(Button);
16
+
17
+ function openUrl(url) {
18
+ window.open(
19
+ url,
20
+ "_blank",
21
+ "noopener,noreferrer"
22
+ );
23
+ }
7
24
  const EmbedViewer = ({
8
25
  src,
26
+ embedSrc,
9
27
  iframeTitle,
10
28
  description,
11
- actions,
29
+ showTemplateAction = false,
30
+ showOpenAction = false,
31
+ onChangeLink,
32
+ customActions,
12
33
  className = "",
13
34
  ...props
14
35
  }) => {
@@ -17,6 +38,42 @@ const EmbedViewer = ({
17
38
  className,
18
39
  {}
19
40
  );
41
+ const resolvedResource = resolver.resolveEmbedResource({
42
+ src,
43
+ embedSrc
44
+ });
45
+ const [
46
+ previewImageUrl,
47
+ setPreviewImageUrl
48
+ ] = react.useState(
49
+ null
50
+ );
51
+ react.useEffect(() => {
52
+ setPreviewImageUrl(null);
53
+ if (resolvedResource.embedUrl || !resolvedResource.sourceUrl) {
54
+ return;
55
+ }
56
+ const controller = new AbortController();
57
+ void openGraph.resolveOpenGraphImage(
58
+ resolvedResource.sourceUrl,
59
+ controller.signal
60
+ ).then((imageUrl) => {
61
+ if (!controller.signal.aborted) {
62
+ setPreviewImageUrl(
63
+ imageUrl
64
+ );
65
+ }
66
+ });
67
+ return () => {
68
+ controller.abort();
69
+ };
70
+ }, [
71
+ resolvedResource.embedUrl,
72
+ resolvedResource.sourceUrl
73
+ ]);
74
+ const templateActionUrl = showTemplateAction && resolvedResource.sourceUrl ? resolvedResource.copyUrl ?? resolvedResource.sourceUrl : null;
75
+ const openActionUrl = showOpenAction && resolvedResource.sourceUrl ? resolvedResource.sourceUrl : null;
76
+ const hasActions = templateActionUrl !== null || openActionUrl !== null || onChangeLink !== void 0 || Boolean(customActions);
20
77
  return /* @__PURE__ */ jsxRuntime.jsxs(
21
78
  "div",
22
79
  {
@@ -24,15 +81,52 @@ const EmbedViewer = ({
24
81
  ...props,
25
82
  children: [
26
83
  description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "embed-viewer__description", children: description }),
27
- /* @__PURE__ */ jsxRuntime.jsx(
84
+ resolvedResource.embedUrl && /* @__PURE__ */ jsxRuntime.jsx(
28
85
  "iframe",
29
86
  {
30
87
  className: "embed-viewer__frame",
31
- src,
88
+ src: resolvedResource.embedUrl,
32
89
  title: iframeTitle
33
90
  }
34
91
  ),
35
- actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "embed-viewer__actions", children: actions })
92
+ !resolvedResource.embedUrl && previewImageUrl && /* @__PURE__ */ jsxRuntime.jsx(
93
+ "img",
94
+ {
95
+ className: "embed-viewer__preview",
96
+ src: previewImageUrl,
97
+ alt: ""
98
+ }
99
+ ),
100
+ hasActions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "embed-viewer__actions", children: /* @__PURE__ */ jsxRuntime.jsxs(ActionGroup__default.default, { children: [
101
+ templateActionUrl && /* @__PURE__ */ jsxRuntime.jsx(
102
+ Button__default.default,
103
+ {
104
+ onClick: () => openUrl(
105
+ templateActionUrl
106
+ ),
107
+ children: "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0448\u0430\u0431\u043B\u043E\u043D"
108
+ }
109
+ ),
110
+ openActionUrl && /* @__PURE__ */ jsxRuntime.jsx(
111
+ Button__default.default,
112
+ {
113
+ rank: "link",
114
+ onClick: () => openUrl(
115
+ openActionUrl
116
+ ),
117
+ children: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0432\u043E \u0432\u0435\u0441\u044C \u044D\u043A\u0440\u0430\u043D"
118
+ }
119
+ ),
120
+ onChangeLink && /* @__PURE__ */ jsxRuntime.jsx(
121
+ Button__default.default,
122
+ {
123
+ rank: "link",
124
+ onClick: onChangeLink,
125
+ children: "\u041F\u043E\u043C\u0435\u043D\u044F\u0442\u044C \u0441\u0441\u044B\u043B\u043A\u0443"
126
+ }
127
+ ),
128
+ customActions
129
+ ] }) })
36
130
  ]
37
131
  }
38
132
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/embed-viewer/embed-viewer.tsx"],"names":["classnames","jsxs","jsx"],"mappings":";;;;;;AAgBA,MAAM,cAEF,CAAC;AAAA,EACH,GAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,OAAA,GAAUA,qBAAA;AAAA,IACd,cAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,uBACEC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,OAAA;AAAA,MACV,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,WAAA,oBACCC,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,wBAGFA,cAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,qBAAA;AAAA,YACV,GAAA;AAAA,YACA,KAAA,EAAO;AAAA;AAAA,SACT;AAAA,QAEC,OAAA,oBACCA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBACZ,QAAA,EAAA,OAAA,EACH;AAAA;AAAA;AAAA,GAEJ;AAEJ,CAAA;AAEA,IAAO,oBAAA,GAAQ","file":"embed-viewer.cjs","sourcesContent":["import React from 'react';\n\nimport './embed-viewer.css';\nimport { classnames } from '../helpers/classnames';\n\nexport interface EmbedViewerProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n src: string;\n iframeTitle: string;\n description?: React.ReactNode;\n actions?: React.ReactNode;\n}\n\nconst EmbedViewer: React.FC<\n EmbedViewerProps\n> = ({\n src,\n iframeTitle,\n description,\n actions,\n className = '',\n ...props\n}) => {\n const classes = classnames(\n 'embed-viewer',\n className,\n {},\n );\n\n return (\n <div\n className={classes}\n {...props}\n >\n {description && (\n <div className=\"embed-viewer__description\">\n {description}\n </div>\n )}\n\n <iframe\n className=\"embed-viewer__frame\"\n src={src}\n title={iframeTitle}\n />\n\n {actions && (\n <div className=\"embed-viewer__actions\">\n {actions}\n </div>\n )}\n </div>\n );\n};\n\nexport default EmbedViewer;\n"]}
1
+ {"version":3,"sources":["../../../src/components/embed-viewer/embed-viewer.tsx"],"names":["classnames","resolveEmbedResource","useState","useEffect","resolveOpenGraphImage","jsxs","jsx","ActionGroup","Button"],"mappings":"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","file":"embed-viewer.cjs","sourcesContent":["import React, {\n useEffect,\n useState,\n} from 'react';\n\nimport './embed-viewer.css';\nimport ActionGroup from '../action-group';\nimport Button from '../button';\nimport { classnames } from '../helpers/classnames';\nimport {\n resolveOpenGraphImage,\n} from './open-graph';\nimport {\n resolveEmbedResource,\n} from './resolver';\n\nexport interface EmbedViewerProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n src: string;\n embedSrc?: string;\n iframeTitle: string;\n description?: React.ReactNode;\n showTemplateAction?: boolean;\n showOpenAction?: boolean;\n onChangeLink?: () => void;\n customActions?: React.ReactNode;\n}\n\nfunction openUrl(url: string) {\n window.open(\n url,\n '_blank',\n 'noopener,noreferrer',\n );\n}\n\nconst EmbedViewer: React.FC<\n EmbedViewerProps\n> = ({\n src,\n embedSrc,\n iframeTitle,\n description,\n showTemplateAction = false,\n showOpenAction = false,\n onChangeLink,\n customActions,\n className = '',\n ...props\n}) => {\n const classes = classnames(\n 'embed-viewer',\n className,\n {},\n );\n\n const resolvedResource =\n resolveEmbedResource({\n src,\n embedSrc,\n });\n\n const [\n previewImageUrl,\n setPreviewImageUrl,\n ] = useState<string | null>(\n null,\n );\n\n useEffect(() => {\n setPreviewImageUrl(null);\n\n if (\n resolvedResource.embedUrl ||\n !resolvedResource.sourceUrl\n ) {\n return;\n }\n\n const controller =\n new AbortController();\n\n void resolveOpenGraphImage(\n resolvedResource.sourceUrl,\n controller.signal,\n ).then((imageUrl) => {\n if (\n !controller.signal.aborted\n ) {\n setPreviewImageUrl(\n imageUrl,\n );\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [\n resolvedResource.embedUrl,\n resolvedResource.sourceUrl,\n ]);\n\n const templateActionUrl =\n showTemplateAction &&\n resolvedResource.sourceUrl\n ? (\n resolvedResource.copyUrl ??\n resolvedResource.sourceUrl\n )\n : null;\n\n const openActionUrl =\n showOpenAction &&\n resolvedResource.sourceUrl\n ? resolvedResource.sourceUrl\n : null;\n\n const hasActions =\n templateActionUrl !== null ||\n openActionUrl !== null ||\n onChangeLink !== undefined ||\n Boolean(customActions);\n\n return (\n <div\n className={classes}\n {...props}\n >\n {description && (\n <div className=\"embed-viewer__description\">\n {description}\n </div>\n )}\n\n {resolvedResource.embedUrl && (\n <iframe\n className=\"embed-viewer__frame\"\n src={\n resolvedResource.embedUrl\n }\n title={iframeTitle}\n />\n )}\n\n {!resolvedResource.embedUrl &&\n previewImageUrl && (\n <img\n className=\"embed-viewer__preview\"\n src={previewImageUrl}\n alt=\"\"\n />\n )}\n\n {hasActions && (\n <div className=\"embed-viewer__actions\">\n <ActionGroup>\n {templateActionUrl && (\n <Button\n onClick={() =>\n openUrl(\n templateActionUrl,\n )\n }\n >\n Скопировать шаблон\n </Button>\n )}\n\n {openActionUrl && (\n <Button\n rank=\"link\"\n onClick={() =>\n openUrl(\n openActionUrl,\n )\n }\n >\n Открыть во весь экран\n </Button>\n )}\n\n {onChangeLink && (\n <Button\n rank=\"link\"\n onClick={\n onChangeLink\n }\n >\n Поменять ссылку\n </Button>\n )}\n\n {customActions}\n </ActionGroup>\n </div>\n )}\n </div>\n );\n};\n\nexport default EmbedViewer;\n"]}
@@ -2,9 +2,13 @@ import React from 'react';
2
2
  import './embed-viewer.css';
3
3
  export interface EmbedViewerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
4
4
  src: string;
5
+ embedSrc?: string;
5
6
  iframeTitle: string;
6
7
  description?: React.ReactNode;
7
- actions?: React.ReactNode;
8
+ showTemplateAction?: boolean;
9
+ showOpenAction?: boolean;
10
+ onChangeLink?: () => void;
11
+ customActions?: React.ReactNode;
8
12
  }
9
13
  declare const EmbedViewer: React.FC<EmbedViewerProps>;
10
14
  export default EmbedViewer;
@@ -1,12 +1,28 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect } from 'react';
2
3
  import './embed-viewer.css';
4
+ import ActionGroup from '../action-group';
5
+ import Button from '../button';
3
6
  import { classnames } from '../helpers/classnames';
7
+ import { resolveOpenGraphImage } from './open-graph';
8
+ import { resolveEmbedResource } from './resolver';
4
9
 
10
+ function openUrl(url) {
11
+ window.open(
12
+ url,
13
+ "_blank",
14
+ "noopener,noreferrer"
15
+ );
16
+ }
5
17
  const EmbedViewer = ({
6
18
  src,
19
+ embedSrc,
7
20
  iframeTitle,
8
21
  description,
9
- actions,
22
+ showTemplateAction = false,
23
+ showOpenAction = false,
24
+ onChangeLink,
25
+ customActions,
10
26
  className = "",
11
27
  ...props
12
28
  }) => {
@@ -15,6 +31,42 @@ const EmbedViewer = ({
15
31
  className,
16
32
  {}
17
33
  );
34
+ const resolvedResource = resolveEmbedResource({
35
+ src,
36
+ embedSrc
37
+ });
38
+ const [
39
+ previewImageUrl,
40
+ setPreviewImageUrl
41
+ ] = useState(
42
+ null
43
+ );
44
+ useEffect(() => {
45
+ setPreviewImageUrl(null);
46
+ if (resolvedResource.embedUrl || !resolvedResource.sourceUrl) {
47
+ return;
48
+ }
49
+ const controller = new AbortController();
50
+ void resolveOpenGraphImage(
51
+ resolvedResource.sourceUrl,
52
+ controller.signal
53
+ ).then((imageUrl) => {
54
+ if (!controller.signal.aborted) {
55
+ setPreviewImageUrl(
56
+ imageUrl
57
+ );
58
+ }
59
+ });
60
+ return () => {
61
+ controller.abort();
62
+ };
63
+ }, [
64
+ resolvedResource.embedUrl,
65
+ resolvedResource.sourceUrl
66
+ ]);
67
+ const templateActionUrl = showTemplateAction && resolvedResource.sourceUrl ? resolvedResource.copyUrl ?? resolvedResource.sourceUrl : null;
68
+ const openActionUrl = showOpenAction && resolvedResource.sourceUrl ? resolvedResource.sourceUrl : null;
69
+ const hasActions = templateActionUrl !== null || openActionUrl !== null || onChangeLink !== void 0 || Boolean(customActions);
18
70
  return /* @__PURE__ */ jsxs(
19
71
  "div",
20
72
  {
@@ -22,15 +74,52 @@ const EmbedViewer = ({
22
74
  ...props,
23
75
  children: [
24
76
  description && /* @__PURE__ */ jsx("div", { className: "embed-viewer__description", children: description }),
25
- /* @__PURE__ */ jsx(
77
+ resolvedResource.embedUrl && /* @__PURE__ */ jsx(
26
78
  "iframe",
27
79
  {
28
80
  className: "embed-viewer__frame",
29
- src,
81
+ src: resolvedResource.embedUrl,
30
82
  title: iframeTitle
31
83
  }
32
84
  ),
33
- actions && /* @__PURE__ */ jsx("div", { className: "embed-viewer__actions", children: actions })
85
+ !resolvedResource.embedUrl && previewImageUrl && /* @__PURE__ */ jsx(
86
+ "img",
87
+ {
88
+ className: "embed-viewer__preview",
89
+ src: previewImageUrl,
90
+ alt: ""
91
+ }
92
+ ),
93
+ hasActions && /* @__PURE__ */ jsx("div", { className: "embed-viewer__actions", children: /* @__PURE__ */ jsxs(ActionGroup, { children: [
94
+ templateActionUrl && /* @__PURE__ */ jsx(
95
+ Button,
96
+ {
97
+ onClick: () => openUrl(
98
+ templateActionUrl
99
+ ),
100
+ children: "\u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0448\u0430\u0431\u043B\u043E\u043D"
101
+ }
102
+ ),
103
+ openActionUrl && /* @__PURE__ */ jsx(
104
+ Button,
105
+ {
106
+ rank: "link",
107
+ onClick: () => openUrl(
108
+ openActionUrl
109
+ ),
110
+ children: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0432\u043E \u0432\u0435\u0441\u044C \u044D\u043A\u0440\u0430\u043D"
111
+ }
112
+ ),
113
+ onChangeLink && /* @__PURE__ */ jsx(
114
+ Button,
115
+ {
116
+ rank: "link",
117
+ onClick: onChangeLink,
118
+ children: "\u041F\u043E\u043C\u0435\u043D\u044F\u0442\u044C \u0441\u0441\u044B\u043B\u043A\u0443"
119
+ }
120
+ ),
121
+ customActions
122
+ ] }) })
34
123
  ]
35
124
  }
36
125
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/embed-viewer/embed-viewer.tsx"],"names":[],"mappings":";;;;AAgBA,MAAM,cAEF,CAAC;AAAA,EACH,GAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,KAAM;AACJ,EAAA,MAAM,OAAA,GAAU,UAAA;AAAA,IACd,cAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAC,GACH;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,OAAA;AAAA,MACV,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,WAAA,oBACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,wBAGF,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,qBAAA;AAAA,YACV,GAAA;AAAA,YACA,KAAA,EAAO;AAAA;AAAA,SACT;AAAA,QAEC,OAAA,oBACC,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,yBACZ,QAAA,EAAA,OAAA,EACH;AAAA;AAAA;AAAA,GAEJ;AAEJ,CAAA;AAEA,IAAO,oBAAA,GAAQ","file":"embed-viewer.js","sourcesContent":["import React from 'react';\n\nimport './embed-viewer.css';\nimport { classnames } from '../helpers/classnames';\n\nexport interface EmbedViewerProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n src: string;\n iframeTitle: string;\n description?: React.ReactNode;\n actions?: React.ReactNode;\n}\n\nconst EmbedViewer: React.FC<\n EmbedViewerProps\n> = ({\n src,\n iframeTitle,\n description,\n actions,\n className = '',\n ...props\n}) => {\n const classes = classnames(\n 'embed-viewer',\n className,\n {},\n );\n\n return (\n <div\n className={classes}\n {...props}\n >\n {description && (\n <div className=\"embed-viewer__description\">\n {description}\n </div>\n )}\n\n <iframe\n className=\"embed-viewer__frame\"\n src={src}\n title={iframeTitle}\n />\n\n {actions && (\n <div className=\"embed-viewer__actions\">\n {actions}\n </div>\n )}\n </div>\n );\n};\n\nexport default EmbedViewer;\n"]}
1
+ {"version":3,"sources":["../../../src/components/embed-viewer/embed-viewer.tsx"],"names":[],"mappings":"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","file":"embed-viewer.js","sourcesContent":["import React, {\n useEffect,\n useState,\n} from 'react';\n\nimport './embed-viewer.css';\nimport ActionGroup from '../action-group';\nimport Button from '../button';\nimport { classnames } from '../helpers/classnames';\nimport {\n resolveOpenGraphImage,\n} from './open-graph';\nimport {\n resolveEmbedResource,\n} from './resolver';\n\nexport interface EmbedViewerProps\n extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n > {\n src: string;\n embedSrc?: string;\n iframeTitle: string;\n description?: React.ReactNode;\n showTemplateAction?: boolean;\n showOpenAction?: boolean;\n onChangeLink?: () => void;\n customActions?: React.ReactNode;\n}\n\nfunction openUrl(url: string) {\n window.open(\n url,\n '_blank',\n 'noopener,noreferrer',\n );\n}\n\nconst EmbedViewer: React.FC<\n EmbedViewerProps\n> = ({\n src,\n embedSrc,\n iframeTitle,\n description,\n showTemplateAction = false,\n showOpenAction = false,\n onChangeLink,\n customActions,\n className = '',\n ...props\n}) => {\n const classes = classnames(\n 'embed-viewer',\n className,\n {},\n );\n\n const resolvedResource =\n resolveEmbedResource({\n src,\n embedSrc,\n });\n\n const [\n previewImageUrl,\n setPreviewImageUrl,\n ] = useState<string | null>(\n null,\n );\n\n useEffect(() => {\n setPreviewImageUrl(null);\n\n if (\n resolvedResource.embedUrl ||\n !resolvedResource.sourceUrl\n ) {\n return;\n }\n\n const controller =\n new AbortController();\n\n void resolveOpenGraphImage(\n resolvedResource.sourceUrl,\n controller.signal,\n ).then((imageUrl) => {\n if (\n !controller.signal.aborted\n ) {\n setPreviewImageUrl(\n imageUrl,\n );\n }\n });\n\n return () => {\n controller.abort();\n };\n }, [\n resolvedResource.embedUrl,\n resolvedResource.sourceUrl,\n ]);\n\n const templateActionUrl =\n showTemplateAction &&\n resolvedResource.sourceUrl\n ? (\n resolvedResource.copyUrl ??\n resolvedResource.sourceUrl\n )\n : null;\n\n const openActionUrl =\n showOpenAction &&\n resolvedResource.sourceUrl\n ? resolvedResource.sourceUrl\n : null;\n\n const hasActions =\n templateActionUrl !== null ||\n openActionUrl !== null ||\n onChangeLink !== undefined ||\n Boolean(customActions);\n\n return (\n <div\n className={classes}\n {...props}\n >\n {description && (\n <div className=\"embed-viewer__description\">\n {description}\n </div>\n )}\n\n {resolvedResource.embedUrl && (\n <iframe\n className=\"embed-viewer__frame\"\n src={\n resolvedResource.embedUrl\n }\n title={iframeTitle}\n />\n )}\n\n {!resolvedResource.embedUrl &&\n previewImageUrl && (\n <img\n className=\"embed-viewer__preview\"\n src={previewImageUrl}\n alt=\"\"\n />\n )}\n\n {hasActions && (\n <div className=\"embed-viewer__actions\">\n <ActionGroup>\n {templateActionUrl && (\n <Button\n onClick={() =>\n openUrl(\n templateActionUrl,\n )\n }\n >\n Скопировать шаблон\n </Button>\n )}\n\n {openActionUrl && (\n <Button\n rank=\"link\"\n onClick={() =>\n openUrl(\n openActionUrl,\n )\n }\n >\n Открыть во весь экран\n </Button>\n )}\n\n {onChangeLink && (\n <Button\n rank=\"link\"\n onClick={\n onChangeLink\n }\n >\n Поменять ссылку\n </Button>\n )}\n\n {customActions}\n </ActionGroup>\n </div>\n )}\n </div>\n );\n};\n\nexport default EmbedViewer;\n"]}
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ const defaultFetchResource = async (url, init) => fetch(
4
+ url,
5
+ init
6
+ );
7
+ function isHtmlResponse(response) {
8
+ const contentType = response.headers.get(
9
+ "content-type"
10
+ );
11
+ return contentType === null || contentType.includes("text/html");
12
+ }
13
+ function parseOpenGraphImage(html, sourceUrl) {
14
+ const document = new DOMParser().parseFromString(
15
+ html,
16
+ "text/html"
17
+ );
18
+ const image = document.head.querySelector(
19
+ 'meta[property="og:image"]'
20
+ );
21
+ const content = image?.getAttribute("content");
22
+ if (!content) {
23
+ return null;
24
+ }
25
+ try {
26
+ const url = new URL(
27
+ content,
28
+ sourceUrl
29
+ );
30
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
31
+ return null;
32
+ }
33
+ return url.toString();
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+ async function resolveOpenGraphImage(sourceUrl, signal, fetchResource = defaultFetchResource) {
39
+ try {
40
+ const response = await fetchResource(
41
+ sourceUrl,
42
+ {
43
+ signal
44
+ }
45
+ );
46
+ if (!response.ok || !isHtmlResponse(response)) {
47
+ return null;
48
+ }
49
+ const html = await response.text();
50
+ return parseOpenGraphImage(
51
+ html,
52
+ sourceUrl
53
+ );
54
+ } catch {
55
+ return null;
56
+ }
57
+ }
58
+
59
+ exports.resolveOpenGraphImage = resolveOpenGraphImage;
60
+ //# sourceMappingURL=open-graph.cjs.map
61
+ //# sourceMappingURL=open-graph.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/embed-viewer/open-graph.ts"],"names":[],"mappings":";;AAOA,MAAM,oBAAA,GACJ,OACE,GAAA,EACA,IAAA,KAEA,KAAA;AAAA,EACE,GAAA;AAAA,EACA;AACF,CAAA;AAEJ,SAAS,eACP,QAAA,EACS;AACT,EAAA,MAAM,WAAA,GACJ,SAAS,OAAA,CAAQ,GAAA;AAAA,IACf;AAAA,GACF;AAEF,EAAA,OACE,WAAA,KAAgB,IAAA,IAChB,WAAA,CAAY,QAAA,CAAS,WAAW,CAAA;AAEpC;AAEA,SAAS,mBAAA,CACP,MACA,SAAA,EACe;AACf,EAAA,MAAM,QAAA,GACJ,IAAI,SAAA,EAAU,CAAE,eAAA;AAAA,IACd,IAAA;AAAA,IACA;AAAA,GACF;AAEF,EAAA,MAAM,KAAA,GACJ,SAAS,IAAA,CAAK,aAAA;AAAA,IACZ;AAAA,GACF;AAEF,EAAA,MAAM,OAAA,GACJ,KAAA,EAAO,YAAA,CAAa,SAAS,CAAA;AAE/B,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,MACJ,IAAI,GAAA;AAAA,MACF,OAAA;AAAA,MACA;AAAA,KACF;AAEF,IAAA,IACE,GAAA,CAAI,QAAA,KAAa,OAAA,IACjB,GAAA,CAAI,aAAa,QAAA,EACjB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAsB,qBAAA,CACpB,SAAA,EACA,MAAA,EACA,aAAA,GACE,oBAAA,EACsB;AACxB,EAAA,IAAI;AACF,IAAA,MAAM,WACJ,MAAM,aAAA;AAAA,MACJ,SAAA;AAAA,MACA;AAAA,QACE;AAAA;AACF,KACF;AAEF,IAAA,IACE,CAAC,QAAA,CAAS,EAAA,IACV,CAAC,cAAA,CAAe,QAAQ,CAAA,EACxB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GACJ,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtB,IAAA,OAAO,mBAAA;AAAA,MACL,IAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"open-graph.cjs","sourcesContent":["type FetchResource = (\n url: string,\n init?: {\n signal?: AbortSignal;\n },\n) => Promise<Response>;\n\nconst defaultFetchResource: FetchResource =\n async (\n url,\n init,\n ) =>\n fetch(\n url,\n init,\n );\n\nfunction isHtmlResponse(\n response: Response,\n): boolean {\n const contentType =\n response.headers.get(\n 'content-type',\n );\n\n return (\n contentType === null ||\n contentType.includes('text/html')\n );\n}\n\nfunction parseOpenGraphImage(\n html: string,\n sourceUrl: string,\n): string | null {\n const document =\n new DOMParser().parseFromString(\n html,\n 'text/html',\n );\n\n const image =\n document.head.querySelector(\n 'meta[property=\"og:image\"]',\n );\n\n const content =\n image?.getAttribute('content');\n\n if (!content) {\n return null;\n }\n\n try {\n const url =\n new URL(\n content,\n sourceUrl,\n );\n\n if (\n url.protocol !== 'http:' &&\n url.protocol !== 'https:'\n ) {\n return null;\n }\n\n return url.toString();\n } catch {\n return null;\n }\n}\n\nexport async function resolveOpenGraphImage(\n sourceUrl: string,\n signal?: AbortSignal,\n fetchResource: FetchResource =\n defaultFetchResource,\n): Promise<string | null> {\n try {\n const response =\n await fetchResource(\n sourceUrl,\n {\n signal,\n },\n );\n\n if (\n !response.ok ||\n !isHtmlResponse(response)\n ) {\n return null;\n }\n\n const html =\n await response.text();\n\n return parseOpenGraphImage(\n html,\n sourceUrl,\n );\n } catch {\n return null;\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ type FetchResource = (url: string, init?: {
2
+ signal?: AbortSignal;
3
+ }) => Promise<Response>;
4
+ export declare function resolveOpenGraphImage(sourceUrl: string, signal?: AbortSignal, fetchResource?: FetchResource): Promise<string | null>;
5
+ export {};
@@ -0,0 +1,59 @@
1
+ const defaultFetchResource = async (url, init) => fetch(
2
+ url,
3
+ init
4
+ );
5
+ function isHtmlResponse(response) {
6
+ const contentType = response.headers.get(
7
+ "content-type"
8
+ );
9
+ return contentType === null || contentType.includes("text/html");
10
+ }
11
+ function parseOpenGraphImage(html, sourceUrl) {
12
+ const document = new DOMParser().parseFromString(
13
+ html,
14
+ "text/html"
15
+ );
16
+ const image = document.head.querySelector(
17
+ 'meta[property="og:image"]'
18
+ );
19
+ const content = image?.getAttribute("content");
20
+ if (!content) {
21
+ return null;
22
+ }
23
+ try {
24
+ const url = new URL(
25
+ content,
26
+ sourceUrl
27
+ );
28
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
29
+ return null;
30
+ }
31
+ return url.toString();
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+ async function resolveOpenGraphImage(sourceUrl, signal, fetchResource = defaultFetchResource) {
37
+ try {
38
+ const response = await fetchResource(
39
+ sourceUrl,
40
+ {
41
+ signal
42
+ }
43
+ );
44
+ if (!response.ok || !isHtmlResponse(response)) {
45
+ return null;
46
+ }
47
+ const html = await response.text();
48
+ return parseOpenGraphImage(
49
+ html,
50
+ sourceUrl
51
+ );
52
+ } catch {
53
+ return null;
54
+ }
55
+ }
56
+
57
+ export { resolveOpenGraphImage };
58
+ //# sourceMappingURL=open-graph.js.map
59
+ //# sourceMappingURL=open-graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/embed-viewer/open-graph.ts"],"names":[],"mappings":"AAOA,MAAM,oBAAA,GACJ,OACE,GAAA,EACA,IAAA,KAEA,KAAA;AAAA,EACE,GAAA;AAAA,EACA;AACF,CAAA;AAEJ,SAAS,eACP,QAAA,EACS;AACT,EAAA,MAAM,WAAA,GACJ,SAAS,OAAA,CAAQ,GAAA;AAAA,IACf;AAAA,GACF;AAEF,EAAA,OACE,WAAA,KAAgB,IAAA,IAChB,WAAA,CAAY,QAAA,CAAS,WAAW,CAAA;AAEpC;AAEA,SAAS,mBAAA,CACP,MACA,SAAA,EACe;AACf,EAAA,MAAM,QAAA,GACJ,IAAI,SAAA,EAAU,CAAE,eAAA;AAAA,IACd,IAAA;AAAA,IACA;AAAA,GACF;AAEF,EAAA,MAAM,KAAA,GACJ,SAAS,IAAA,CAAK,aAAA;AAAA,IACZ;AAAA,GACF;AAEF,EAAA,MAAM,OAAA,GACJ,KAAA,EAAO,YAAA,CAAa,SAAS,CAAA;AAE/B,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,MACJ,IAAI,GAAA;AAAA,MACF,OAAA;AAAA,MACA;AAAA,KACF;AAEF,IAAA,IACE,GAAA,CAAI,QAAA,KAAa,OAAA,IACjB,GAAA,CAAI,aAAa,QAAA,EACjB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,eAAsB,qBAAA,CACpB,SAAA,EACA,MAAA,EACA,aAAA,GACE,oBAAA,EACsB;AACxB,EAAA,IAAI;AACF,IAAA,MAAM,WACJ,MAAM,aAAA;AAAA,MACJ,SAAA;AAAA,MACA;AAAA,QACE;AAAA;AACF,KACF;AAEF,IAAA,IACE,CAAC,QAAA,CAAS,EAAA,IACV,CAAC,cAAA,CAAe,QAAQ,CAAA,EACxB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GACJ,MAAM,QAAA,CAAS,IAAA,EAAK;AAEtB,IAAA,OAAO,mBAAA;AAAA,MACL,IAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"open-graph.js","sourcesContent":["type FetchResource = (\n url: string,\n init?: {\n signal?: AbortSignal;\n },\n) => Promise<Response>;\n\nconst defaultFetchResource: FetchResource =\n async (\n url,\n init,\n ) =>\n fetch(\n url,\n init,\n );\n\nfunction isHtmlResponse(\n response: Response,\n): boolean {\n const contentType =\n response.headers.get(\n 'content-type',\n );\n\n return (\n contentType === null ||\n contentType.includes('text/html')\n );\n}\n\nfunction parseOpenGraphImage(\n html: string,\n sourceUrl: string,\n): string | null {\n const document =\n new DOMParser().parseFromString(\n html,\n 'text/html',\n );\n\n const image =\n document.head.querySelector(\n 'meta[property=\"og:image\"]',\n );\n\n const content =\n image?.getAttribute('content');\n\n if (!content) {\n return null;\n }\n\n try {\n const url =\n new URL(\n content,\n sourceUrl,\n );\n\n if (\n url.protocol !== 'http:' &&\n url.protocol !== 'https:'\n ) {\n return null;\n }\n\n return url.toString();\n } catch {\n return null;\n }\n}\n\nexport async function resolveOpenGraphImage(\n sourceUrl: string,\n signal?: AbortSignal,\n fetchResource: FetchResource =\n defaultFetchResource,\n): Promise<string | null> {\n try {\n const response =\n await fetchResource(\n sourceUrl,\n {\n signal,\n },\n );\n\n if (\n !response.ok ||\n !isHtmlResponse(response)\n ) {\n return null;\n }\n\n const html =\n await response.text();\n\n return parseOpenGraphImage(\n html,\n sourceUrl,\n );\n } catch {\n return null;\n }\n}\n"]}
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ const FIGMA_HOSTNAMES = /* @__PURE__ */ new Set([
4
+ "figma.com",
5
+ "www.figma.com"
6
+ ]);
7
+ const FIGMA_RESOURCE_TYPES = /* @__PURE__ */ new Set([
8
+ "board",
9
+ "deck",
10
+ "design",
11
+ "proto",
12
+ "slides"
13
+ ]);
14
+ function isFigmaHostname(hostname) {
15
+ return FIGMA_HOSTNAMES.has(
16
+ hostname
17
+ );
18
+ }
19
+ function isFigmaResourceType(value) {
20
+ return FIGMA_RESOURCE_TYPES.has(
21
+ value
22
+ );
23
+ }
24
+ function resolveFigmaResource(url) {
25
+ if (!isFigmaHostname(
26
+ url.hostname
27
+ )) {
28
+ return null;
29
+ }
30
+ const segments = url.pathname.split("/").filter(Boolean);
31
+ if (segments.length < 2 || !isFigmaResourceType(
32
+ segments[0]
33
+ ) || !segments[1]) {
34
+ return null;
35
+ }
36
+ const embedUrl = new URL(url.toString());
37
+ embedUrl.hostname = "embed.figma.com";
38
+ embedUrl.searchParams.set(
39
+ "embed-host",
40
+ "jvetrau-ds"
41
+ );
42
+ return {
43
+ embedUrl: embedUrl.toString()
44
+ };
45
+ }
46
+
47
+ exports.isFigmaHostname = isFigmaHostname;
48
+ exports.resolveFigmaResource = resolveFigmaResource;
49
+ //# sourceMappingURL=figma.cjs.map
50
+ //# sourceMappingURL=figma.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/embed-viewer/providers/figma.ts"],"names":[],"mappings":";;AAWA,MAAM,eAAA,uBACA,GAAA,CAAI;AAAA,EACN,WAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEH,MAAM,oBAAA,uBACA,GAAA,CAAuB;AAAA,EACzB,OAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEI,SAAS,gBACd,QAAA,EACS;AACT,EAAA,OAAO,eAAA,CAAgB,GAAA;AAAA,IACrB;AAAA,GACF;AACF;AAEA,SAAS,oBACP,KAAA,EAC4B;AAC5B,EAAA,OAAO,oBAAA,CAAqB,GAAA;AAAA,IAC1B;AAAA,GACF;AACF;AAEO,SAAS,qBACd,GAAA,EAC2B;AAC3B,EAAA,IACE,CAAC,eAAA;AAAA,IACC,GAAA,CAAI;AAAA,GACN,EACA;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WACJ,GAAA,CAAI,QAAA,CACD,MAAM,GAAG,CAAA,CACT,OAAO,OAAO,CAAA;AAEnB,EAAA,IACE,QAAA,CAAS,MAAA,GAAS,CAAA,IAClB,CAAC,mBAAA;AAAA,IACC,SAAS,CAAC;AAAA,GACZ,IACA,CAAC,QAAA,CAAS,CAAC,CAAA,EACX;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAA,GACJ,IAAI,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA;AAExB,EAAA,QAAA,CAAS,QAAA,GACP,iBAAA;AAEF,EAAA,QAAA,CAAS,YAAA,CAAa,GAAA;AAAA,IACpB,YAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EACE,SAAS,QAAA;AAAS,GACtB;AACF","file":"figma.cjs","sourcesContent":["export interface FigmaEmbedResource {\n embedUrl: string;\n}\n\ntype FigmaResourceType =\n | 'board'\n | 'deck'\n | 'design'\n | 'proto'\n | 'slides';\n\nconst FIGMA_HOSTNAMES =\n new Set([\n 'figma.com',\n 'www.figma.com',\n ]);\n\nconst FIGMA_RESOURCE_TYPES =\n new Set<FigmaResourceType>([\n 'board',\n 'deck',\n 'design',\n 'proto',\n 'slides',\n ]);\n\nexport function isFigmaHostname(\n hostname: string,\n): boolean {\n return FIGMA_HOSTNAMES.has(\n hostname,\n );\n}\n\nfunction isFigmaResourceType(\n value: string,\n): value is FigmaResourceType {\n return FIGMA_RESOURCE_TYPES.has(\n value as FigmaResourceType,\n );\n}\n\nexport function resolveFigmaResource(\n url: URL,\n): FigmaEmbedResource | null {\n if (\n !isFigmaHostname(\n url.hostname,\n )\n ) {\n return null;\n }\n\n const segments =\n url.pathname\n .split('/')\n .filter(Boolean);\n\n if (\n segments.length < 2 ||\n !isFigmaResourceType(\n segments[0],\n ) ||\n !segments[1]\n ) {\n return null;\n }\n\n const embedUrl =\n new URL(url.toString());\n\n embedUrl.hostname =\n 'embed.figma.com';\n\n embedUrl.searchParams.set(\n 'embed-host',\n 'jvetrau-ds',\n );\n\n return {\n embedUrl:\n embedUrl.toString(),\n };\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export interface FigmaEmbedResource {
2
+ embedUrl: string;
3
+ }
4
+ export declare function isFigmaHostname(hostname: string): boolean;
5
+ export declare function resolveFigmaResource(url: URL): FigmaEmbedResource | null;
@@ -0,0 +1,47 @@
1
+ const FIGMA_HOSTNAMES = /* @__PURE__ */ new Set([
2
+ "figma.com",
3
+ "www.figma.com"
4
+ ]);
5
+ const FIGMA_RESOURCE_TYPES = /* @__PURE__ */ new Set([
6
+ "board",
7
+ "deck",
8
+ "design",
9
+ "proto",
10
+ "slides"
11
+ ]);
12
+ function isFigmaHostname(hostname) {
13
+ return FIGMA_HOSTNAMES.has(
14
+ hostname
15
+ );
16
+ }
17
+ function isFigmaResourceType(value) {
18
+ return FIGMA_RESOURCE_TYPES.has(
19
+ value
20
+ );
21
+ }
22
+ function resolveFigmaResource(url) {
23
+ if (!isFigmaHostname(
24
+ url.hostname
25
+ )) {
26
+ return null;
27
+ }
28
+ const segments = url.pathname.split("/").filter(Boolean);
29
+ if (segments.length < 2 || !isFigmaResourceType(
30
+ segments[0]
31
+ ) || !segments[1]) {
32
+ return null;
33
+ }
34
+ const embedUrl = new URL(url.toString());
35
+ embedUrl.hostname = "embed.figma.com";
36
+ embedUrl.searchParams.set(
37
+ "embed-host",
38
+ "jvetrau-ds"
39
+ );
40
+ return {
41
+ embedUrl: embedUrl.toString()
42
+ };
43
+ }
44
+
45
+ export { isFigmaHostname, resolveFigmaResource };
46
+ //# sourceMappingURL=figma.js.map
47
+ //# sourceMappingURL=figma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/embed-viewer/providers/figma.ts"],"names":[],"mappings":"AAWA,MAAM,eAAA,uBACA,GAAA,CAAI;AAAA,EACN,WAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEH,MAAM,oBAAA,uBACA,GAAA,CAAuB;AAAA,EACzB,OAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEI,SAAS,gBACd,QAAA,EACS;AACT,EAAA,OAAO,eAAA,CAAgB,GAAA;AAAA,IACrB;AAAA,GACF;AACF;AAEA,SAAS,oBACP,KAAA,EAC4B;AAC5B,EAAA,OAAO,oBAAA,CAAqB,GAAA;AAAA,IAC1B;AAAA,GACF;AACF;AAEO,SAAS,qBACd,GAAA,EAC2B;AAC3B,EAAA,IACE,CAAC,eAAA;AAAA,IACC,GAAA,CAAI;AAAA,GACN,EACA;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WACJ,GAAA,CAAI,QAAA,CACD,MAAM,GAAG,CAAA,CACT,OAAO,OAAO,CAAA;AAEnB,EAAA,IACE,QAAA,CAAS,MAAA,GAAS,CAAA,IAClB,CAAC,mBAAA;AAAA,IACC,SAAS,CAAC;AAAA,GACZ,IACA,CAAC,QAAA,CAAS,CAAC,CAAA,EACX;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAA,GACJ,IAAI,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA;AAExB,EAAA,QAAA,CAAS,QAAA,GACP,iBAAA;AAEF,EAAA,QAAA,CAAS,YAAA,CAAa,GAAA;AAAA,IACpB,YAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EACE,SAAS,QAAA;AAAS,GACtB;AACF","file":"figma.js","sourcesContent":["export interface FigmaEmbedResource {\n embedUrl: string;\n}\n\ntype FigmaResourceType =\n | 'board'\n | 'deck'\n | 'design'\n | 'proto'\n | 'slides';\n\nconst FIGMA_HOSTNAMES =\n new Set([\n 'figma.com',\n 'www.figma.com',\n ]);\n\nconst FIGMA_RESOURCE_TYPES =\n new Set<FigmaResourceType>([\n 'board',\n 'deck',\n 'design',\n 'proto',\n 'slides',\n ]);\n\nexport function isFigmaHostname(\n hostname: string,\n): boolean {\n return FIGMA_HOSTNAMES.has(\n hostname,\n );\n}\n\nfunction isFigmaResourceType(\n value: string,\n): value is FigmaResourceType {\n return FIGMA_RESOURCE_TYPES.has(\n value as FigmaResourceType,\n );\n}\n\nexport function resolveFigmaResource(\n url: URL,\n): FigmaEmbedResource | null {\n if (\n !isFigmaHostname(\n url.hostname,\n )\n ) {\n return null;\n }\n\n const segments =\n url.pathname\n .split('/')\n .filter(Boolean);\n\n if (\n segments.length < 2 ||\n !isFigmaResourceType(\n segments[0],\n ) ||\n !segments[1]\n ) {\n return null;\n }\n\n const embedUrl =\n new URL(url.toString());\n\n embedUrl.hostname =\n 'embed.figma.com';\n\n embedUrl.searchParams.set(\n 'embed-host',\n 'jvetrau-ds',\n );\n\n return {\n embedUrl:\n embedUrl.toString(),\n };\n}\n"]}
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+
3
+ const GOOGLE_HOSTNAME = "docs.google.com";
4
+ const GOOGLE_RESOURCE_TYPES = /* @__PURE__ */ new Set([
5
+ "document",
6
+ "presentation",
7
+ "spreadsheets"
8
+ ]);
9
+ function isGoogleHostname(hostname) {
10
+ return hostname === GOOGLE_HOSTNAME;
11
+ }
12
+ function isGoogleResourceType(value) {
13
+ return GOOGLE_RESOURCE_TYPES.has(
14
+ value
15
+ );
16
+ }
17
+ function getSheetsGid(url) {
18
+ const queryGid = url.searchParams.get("gid");
19
+ if (queryGid) {
20
+ return queryGid;
21
+ }
22
+ const hash = url.hash.startsWith("#") ? url.hash.slice(1) : url.hash;
23
+ if (!hash) {
24
+ return null;
25
+ }
26
+ return new URLSearchParams(
27
+ hash
28
+ ).get("gid");
29
+ }
30
+ function createGoogleActionUrl({
31
+ resourceType,
32
+ resourceId,
33
+ action,
34
+ gid
35
+ }) {
36
+ const url = new URL(
37
+ `https://${GOOGLE_HOSTNAME}/${resourceType}/d/${resourceId}/${action}`
38
+ );
39
+ if (resourceType === "spreadsheets" && gid) {
40
+ url.searchParams.set(
41
+ "gid",
42
+ gid
43
+ );
44
+ }
45
+ return url.toString();
46
+ }
47
+ function resolveGoogleResource(url) {
48
+ if (!isGoogleHostname(
49
+ url.hostname
50
+ )) {
51
+ return null;
52
+ }
53
+ const segments = url.pathname.split("/").filter(Boolean);
54
+ if (segments.length < 4 || !isGoogleResourceType(
55
+ segments[0]
56
+ ) || segments[1] !== "d") {
57
+ return null;
58
+ }
59
+ const resourceType = segments[0];
60
+ const resourceId = segments[2];
61
+ if (!resourceId) {
62
+ return null;
63
+ }
64
+ const gid = resourceType === "spreadsheets" ? getSheetsGid(url) : null;
65
+ return {
66
+ embedUrl: createGoogleActionUrl({
67
+ resourceType,
68
+ resourceId,
69
+ action: "preview",
70
+ gid
71
+ }),
72
+ copyUrl: createGoogleActionUrl({
73
+ resourceType,
74
+ resourceId,
75
+ action: "copy",
76
+ gid
77
+ })
78
+ };
79
+ }
80
+
81
+ exports.isGoogleHostname = isGoogleHostname;
82
+ exports.resolveGoogleResource = resolveGoogleResource;
83
+ //# sourceMappingURL=google.cjs.map
84
+ //# sourceMappingURL=google.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/embed-viewer/providers/google.ts"],"names":[],"mappings":";;AAUA,MAAM,eAAA,GACJ,iBAAA;AAEF,MAAM,qBAAA,uBACA,GAAA,CAAwB;AAAA,EAC1B,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEI,SAAS,iBACd,QAAA,EACS;AACT,EAAA,OAAO,QAAA,KAAa,eAAA;AACtB;AAEA,SAAS,qBACP,KAAA,EAC6B;AAC7B,EAAA,OAAO,qBAAA,CAAsB,GAAA;AAAA,IAC3B;AAAA,GACF;AACF;AAEA,SAAS,aACP,GAAA,EACe;AACf,EAAA,MAAM,QAAA,GACJ,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA;AAE5B,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GACJ,GAAA,CAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GACnB,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAChB,GAAA,CAAI,IAAA;AAEV,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAI,eAAA;AAAA,IACT;AAAA,GACF,CAAE,IAAI,KAAK,CAAA;AACb;AAEA,SAAS,qBAAA,CAAsB;AAAA,EAC7B,YAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAKW;AACT,EAAA,MAAM,MAAM,IAAI,GAAA;AAAA,IACd,WAAW,eAAe,CAAA,CAAA,EAAI,YAAY,CAAA,GAAA,EAAM,UAAU,IAAI,MAAM,CAAA;AAAA,GACtE;AAEA,EAAA,IACE,YAAA,KAAiB,kBACjB,GAAA,EACA;AACA,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA;AAAA,MACf,KAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAI,QAAA,EAAS;AACtB;AAEO,SAAS,sBACd,GAAA,EAC4B;AAC5B,EAAA,IACE,CAAC,gBAAA;AAAA,IACC,GAAA,CAAI;AAAA,GACN,EACA;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WACJ,GAAA,CAAI,QAAA,CACD,MAAM,GAAG,CAAA,CACT,OAAO,OAAO,CAAA;AAEnB,EAAA,IACE,QAAA,CAAS,MAAA,GAAS,CAAA,IAClB,CAAC,oBAAA;AAAA,IACC,SAAS,CAAC;AAAA,GACZ,IACA,QAAA,CAAS,CAAC,CAAA,KAAM,GAAA,EAChB;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAA,GACJ,SAAS,CAAC,CAAA;AAEZ,EAAA,MAAM,UAAA,GACJ,SAAS,CAAC,CAAA;AAEZ,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,GAAA,GACJ,YAAA,KAAiB,cAAA,GACb,YAAA,CAAa,GAAG,CAAA,GAChB,IAAA;AAEN,EAAA,OAAO;AAAA,IACL,UACE,qBAAA,CAAsB;AAAA,MACpB,YAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA,EAAQ,SAAA;AAAA,MACR;AAAA,KACD,CAAA;AAAA,IACH,SACE,qBAAA,CAAsB;AAAA,MACpB,YAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA,EAAQ,MAAA;AAAA,MACR;AAAA,KACD;AAAA,GACL;AACF","file":"google.cjs","sourcesContent":["export interface GoogleEmbedResource {\n embedUrl: string;\n copyUrl: string;\n}\n\ntype GoogleResourceType =\n | 'document'\n | 'presentation'\n | 'spreadsheets';\n\nconst GOOGLE_HOSTNAME =\n 'docs.google.com';\n\nconst GOOGLE_RESOURCE_TYPES =\n new Set<GoogleResourceType>([\n 'document',\n 'presentation',\n 'spreadsheets',\n ]);\n\nexport function isGoogleHostname(\n hostname: string,\n): boolean {\n return hostname === GOOGLE_HOSTNAME;\n}\n\nfunction isGoogleResourceType(\n value: string,\n): value is GoogleResourceType {\n return GOOGLE_RESOURCE_TYPES.has(\n value as GoogleResourceType,\n );\n}\n\nfunction getSheetsGid(\n url: URL,\n): string | null {\n const queryGid =\n url.searchParams.get('gid');\n\n if (queryGid) {\n return queryGid;\n }\n\n const hash =\n url.hash.startsWith('#')\n ? url.hash.slice(1)\n : url.hash;\n\n if (!hash) {\n return null;\n }\n\n return new URLSearchParams(\n hash,\n ).get('gid');\n}\n\nfunction createGoogleActionUrl({\n resourceType,\n resourceId,\n action,\n gid,\n}: {\n resourceType: GoogleResourceType;\n resourceId: string;\n action: 'copy' | 'preview';\n gid: string | null;\n}): string {\n const url = new URL(\n `https://${GOOGLE_HOSTNAME}/${resourceType}/d/${resourceId}/${action}`,\n );\n\n if (\n resourceType === 'spreadsheets' &&\n gid\n ) {\n url.searchParams.set(\n 'gid',\n gid,\n );\n }\n\n return url.toString();\n}\n\nexport function resolveGoogleResource(\n url: URL,\n): GoogleEmbedResource | null {\n if (\n !isGoogleHostname(\n url.hostname,\n )\n ) {\n return null;\n }\n\n const segments =\n url.pathname\n .split('/')\n .filter(Boolean);\n\n if (\n segments.length < 4 ||\n !isGoogleResourceType(\n segments[0],\n ) ||\n segments[1] !== 'd'\n ) {\n return null;\n }\n\n const resourceType =\n segments[0];\n\n const resourceId =\n segments[2];\n\n if (!resourceId) {\n return null;\n }\n\n const gid =\n resourceType === 'spreadsheets'\n ? getSheetsGid(url)\n : null;\n\n return {\n embedUrl:\n createGoogleActionUrl({\n resourceType,\n resourceId,\n action: 'preview',\n gid,\n }),\n copyUrl:\n createGoogleActionUrl({\n resourceType,\n resourceId,\n action: 'copy',\n gid,\n }),\n };\n}\n"]}
@@ -0,0 +1,6 @@
1
+ export interface GoogleEmbedResource {
2
+ embedUrl: string;
3
+ copyUrl: string;
4
+ }
5
+ export declare function isGoogleHostname(hostname: string): boolean;
6
+ export declare function resolveGoogleResource(url: URL): GoogleEmbedResource | null;
@@ -0,0 +1,81 @@
1
+ const GOOGLE_HOSTNAME = "docs.google.com";
2
+ const GOOGLE_RESOURCE_TYPES = /* @__PURE__ */ new Set([
3
+ "document",
4
+ "presentation",
5
+ "spreadsheets"
6
+ ]);
7
+ function isGoogleHostname(hostname) {
8
+ return hostname === GOOGLE_HOSTNAME;
9
+ }
10
+ function isGoogleResourceType(value) {
11
+ return GOOGLE_RESOURCE_TYPES.has(
12
+ value
13
+ );
14
+ }
15
+ function getSheetsGid(url) {
16
+ const queryGid = url.searchParams.get("gid");
17
+ if (queryGid) {
18
+ return queryGid;
19
+ }
20
+ const hash = url.hash.startsWith("#") ? url.hash.slice(1) : url.hash;
21
+ if (!hash) {
22
+ return null;
23
+ }
24
+ return new URLSearchParams(
25
+ hash
26
+ ).get("gid");
27
+ }
28
+ function createGoogleActionUrl({
29
+ resourceType,
30
+ resourceId,
31
+ action,
32
+ gid
33
+ }) {
34
+ const url = new URL(
35
+ `https://${GOOGLE_HOSTNAME}/${resourceType}/d/${resourceId}/${action}`
36
+ );
37
+ if (resourceType === "spreadsheets" && gid) {
38
+ url.searchParams.set(
39
+ "gid",
40
+ gid
41
+ );
42
+ }
43
+ return url.toString();
44
+ }
45
+ function resolveGoogleResource(url) {
46
+ if (!isGoogleHostname(
47
+ url.hostname
48
+ )) {
49
+ return null;
50
+ }
51
+ const segments = url.pathname.split("/").filter(Boolean);
52
+ if (segments.length < 4 || !isGoogleResourceType(
53
+ segments[0]
54
+ ) || segments[1] !== "d") {
55
+ return null;
56
+ }
57
+ const resourceType = segments[0];
58
+ const resourceId = segments[2];
59
+ if (!resourceId) {
60
+ return null;
61
+ }
62
+ const gid = resourceType === "spreadsheets" ? getSheetsGid(url) : null;
63
+ return {
64
+ embedUrl: createGoogleActionUrl({
65
+ resourceType,
66
+ resourceId,
67
+ action: "preview",
68
+ gid
69
+ }),
70
+ copyUrl: createGoogleActionUrl({
71
+ resourceType,
72
+ resourceId,
73
+ action: "copy",
74
+ gid
75
+ })
76
+ };
77
+ }
78
+
79
+ export { isGoogleHostname, resolveGoogleResource };
80
+ //# sourceMappingURL=google.js.map
81
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/embed-viewer/providers/google.ts"],"names":[],"mappings":"AAUA,MAAM,eAAA,GACJ,iBAAA;AAEF,MAAM,qBAAA,uBACA,GAAA,CAAwB;AAAA,EAC1B,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEI,SAAS,iBACd,QAAA,EACS;AACT,EAAA,OAAO,QAAA,KAAa,eAAA;AACtB;AAEA,SAAS,qBACP,KAAA,EAC6B;AAC7B,EAAA,OAAO,qBAAA,CAAsB,GAAA;AAAA,IAC3B;AAAA,GACF;AACF;AAEA,SAAS,aACP,GAAA,EACe;AACf,EAAA,MAAM,QAAA,GACJ,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA;AAE5B,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GACJ,GAAA,CAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GACnB,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAChB,GAAA,CAAI,IAAA;AAEV,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAI,eAAA;AAAA,IACT;AAAA,GACF,CAAE,IAAI,KAAK,CAAA;AACb;AAEA,SAAS,qBAAA,CAAsB;AAAA,EAC7B,YAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAKW;AACT,EAAA,MAAM,MAAM,IAAI,GAAA;AAAA,IACd,WAAW,eAAe,CAAA,CAAA,EAAI,YAAY,CAAA,GAAA,EAAM,UAAU,IAAI,MAAM,CAAA;AAAA,GACtE;AAEA,EAAA,IACE,YAAA,KAAiB,kBACjB,GAAA,EACA;AACA,IAAA,GAAA,CAAI,YAAA,CAAa,GAAA;AAAA,MACf,KAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAI,QAAA,EAAS;AACtB;AAEO,SAAS,sBACd,GAAA,EAC4B;AAC5B,EAAA,IACE,CAAC,gBAAA;AAAA,IACC,GAAA,CAAI;AAAA,GACN,EACA;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WACJ,GAAA,CAAI,QAAA,CACD,MAAM,GAAG,CAAA,CACT,OAAO,OAAO,CAAA;AAEnB,EAAA,IACE,QAAA,CAAS,MAAA,GAAS,CAAA,IAClB,CAAC,oBAAA;AAAA,IACC,SAAS,CAAC;AAAA,GACZ,IACA,QAAA,CAAS,CAAC,CAAA,KAAM,GAAA,EAChB;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAA,GACJ,SAAS,CAAC,CAAA;AAEZ,EAAA,MAAM,UAAA,GACJ,SAAS,CAAC,CAAA;AAEZ,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,GAAA,GACJ,YAAA,KAAiB,cAAA,GACb,YAAA,CAAa,GAAG,CAAA,GAChB,IAAA;AAEN,EAAA,OAAO;AAAA,IACL,UACE,qBAAA,CAAsB;AAAA,MACpB,YAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA,EAAQ,SAAA;AAAA,MACR;AAAA,KACD,CAAA;AAAA,IACH,SACE,qBAAA,CAAsB;AAAA,MACpB,YAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA,EAAQ,MAAA;AAAA,MACR;AAAA,KACD;AAAA,GACL;AACF","file":"google.js","sourcesContent":["export interface GoogleEmbedResource {\n embedUrl: string;\n copyUrl: string;\n}\n\ntype GoogleResourceType =\n | 'document'\n | 'presentation'\n | 'spreadsheets';\n\nconst GOOGLE_HOSTNAME =\n 'docs.google.com';\n\nconst GOOGLE_RESOURCE_TYPES =\n new Set<GoogleResourceType>([\n 'document',\n 'presentation',\n 'spreadsheets',\n ]);\n\nexport function isGoogleHostname(\n hostname: string,\n): boolean {\n return hostname === GOOGLE_HOSTNAME;\n}\n\nfunction isGoogleResourceType(\n value: string,\n): value is GoogleResourceType {\n return GOOGLE_RESOURCE_TYPES.has(\n value as GoogleResourceType,\n );\n}\n\nfunction getSheetsGid(\n url: URL,\n): string | null {\n const queryGid =\n url.searchParams.get('gid');\n\n if (queryGid) {\n return queryGid;\n }\n\n const hash =\n url.hash.startsWith('#')\n ? url.hash.slice(1)\n : url.hash;\n\n if (!hash) {\n return null;\n }\n\n return new URLSearchParams(\n hash,\n ).get('gid');\n}\n\nfunction createGoogleActionUrl({\n resourceType,\n resourceId,\n action,\n gid,\n}: {\n resourceType: GoogleResourceType;\n resourceId: string;\n action: 'copy' | 'preview';\n gid: string | null;\n}): string {\n const url = new URL(\n `https://${GOOGLE_HOSTNAME}/${resourceType}/d/${resourceId}/${action}`,\n );\n\n if (\n resourceType === 'spreadsheets' &&\n gid\n ) {\n url.searchParams.set(\n 'gid',\n gid,\n );\n }\n\n return url.toString();\n}\n\nexport function resolveGoogleResource(\n url: URL,\n): GoogleEmbedResource | null {\n if (\n !isGoogleHostname(\n url.hostname,\n )\n ) {\n return null;\n }\n\n const segments =\n url.pathname\n .split('/')\n .filter(Boolean);\n\n if (\n segments.length < 4 ||\n !isGoogleResourceType(\n segments[0],\n ) ||\n segments[1] !== 'd'\n ) {\n return null;\n }\n\n const resourceType =\n segments[0];\n\n const resourceId =\n segments[2];\n\n if (!resourceId) {\n return null;\n }\n\n const gid =\n resourceType === 'spreadsheets'\n ? getSheetsGid(url)\n : null;\n\n return {\n embedUrl:\n createGoogleActionUrl({\n resourceType,\n resourceId,\n action: 'preview',\n gid,\n }),\n copyUrl:\n createGoogleActionUrl({\n resourceType,\n resourceId,\n action: 'copy',\n gid,\n }),\n };\n}\n"]}
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ const MIRO_HOSTNAMES = /* @__PURE__ */ new Set([
4
+ "miro.com",
5
+ "www.miro.com"
6
+ ]);
7
+ function isMiroHostname(hostname) {
8
+ return MIRO_HOSTNAMES.has(
9
+ hostname
10
+ );
11
+ }
12
+ function resolveMiroResource(url) {
13
+ if (!isMiroHostname(
14
+ url.hostname
15
+ )) {
16
+ return null;
17
+ }
18
+ const match = url.pathname.match(
19
+ /^\/app\/board\/([^/]+)\/?$/
20
+ );
21
+ if (!match) {
22
+ return null;
23
+ }
24
+ const boardId = match[1];
25
+ if (!boardId) {
26
+ return null;
27
+ }
28
+ const embedUrl = new URL(
29
+ `https://miro.com/app/live-embed/${boardId}/`
30
+ );
31
+ embedUrl.searchParams.set(
32
+ "autoplay",
33
+ "true"
34
+ );
35
+ return {
36
+ embedUrl: embedUrl.toString()
37
+ };
38
+ }
39
+
40
+ exports.isMiroHostname = isMiroHostname;
41
+ exports.resolveMiroResource = resolveMiroResource;
42
+ //# sourceMappingURL=miro.cjs.map
43
+ //# sourceMappingURL=miro.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/embed-viewer/providers/miro.ts"],"names":[],"mappings":";;AAIA,MAAM,cAAA,uBACA,GAAA,CAAI;AAAA,EACN,UAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEI,SAAS,eACd,QAAA,EACS;AACT,EAAA,OAAO,cAAA,CAAe,GAAA;AAAA,IACpB;AAAA,GACF;AACF;AAEO,SAAS,oBACd,GAAA,EAC0B;AAC1B,EAAA,IACE,CAAC,cAAA;AAAA,IACC,GAAA,CAAI;AAAA,GACN,EACA;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GACJ,IAAI,QAAA,CAAS,KAAA;AAAA,IACX;AAAA,GACF;AAEF,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GACJ,MAAM,CAAC,CAAA;AAET,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WACJ,IAAI,GAAA;AAAA,IACF,mCAAmC,OAAO,CAAA,CAAA;AAAA,GAC5C;AAEF,EAAA,QAAA,CAAS,YAAA,CAAa,GAAA;AAAA,IACpB,UAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EACE,SAAS,QAAA;AAAS,GACtB;AACF","file":"miro.cjs","sourcesContent":["export interface MiroEmbedResource {\n embedUrl: string;\n}\n\nconst MIRO_HOSTNAMES =\n new Set([\n 'miro.com',\n 'www.miro.com',\n ]);\n\nexport function isMiroHostname(\n hostname: string,\n): boolean {\n return MIRO_HOSTNAMES.has(\n hostname,\n );\n}\n\nexport function resolveMiroResource(\n url: URL,\n): MiroEmbedResource | null {\n if (\n !isMiroHostname(\n url.hostname,\n )\n ) {\n return null;\n }\n\n const match =\n url.pathname.match(\n /^\\/app\\/board\\/([^/]+)\\/?$/,\n );\n\n if (!match) {\n return null;\n }\n\n const boardId =\n match[1];\n\n if (!boardId) {\n return null;\n }\n\n const embedUrl =\n new URL(\n `https://miro.com/app/live-embed/${boardId}/`,\n );\n\n embedUrl.searchParams.set(\n 'autoplay',\n 'true',\n );\n\n return {\n embedUrl:\n embedUrl.toString(),\n };\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export interface MiroEmbedResource {
2
+ embedUrl: string;
3
+ }
4
+ export declare function isMiroHostname(hostname: string): boolean;
5
+ export declare function resolveMiroResource(url: URL): MiroEmbedResource | null;
@@ -0,0 +1,40 @@
1
+ const MIRO_HOSTNAMES = /* @__PURE__ */ new Set([
2
+ "miro.com",
3
+ "www.miro.com"
4
+ ]);
5
+ function isMiroHostname(hostname) {
6
+ return MIRO_HOSTNAMES.has(
7
+ hostname
8
+ );
9
+ }
10
+ function resolveMiroResource(url) {
11
+ if (!isMiroHostname(
12
+ url.hostname
13
+ )) {
14
+ return null;
15
+ }
16
+ const match = url.pathname.match(
17
+ /^\/app\/board\/([^/]+)\/?$/
18
+ );
19
+ if (!match) {
20
+ return null;
21
+ }
22
+ const boardId = match[1];
23
+ if (!boardId) {
24
+ return null;
25
+ }
26
+ const embedUrl = new URL(
27
+ `https://miro.com/app/live-embed/${boardId}/`
28
+ );
29
+ embedUrl.searchParams.set(
30
+ "autoplay",
31
+ "true"
32
+ );
33
+ return {
34
+ embedUrl: embedUrl.toString()
35
+ };
36
+ }
37
+
38
+ export { isMiroHostname, resolveMiroResource };
39
+ //# sourceMappingURL=miro.js.map
40
+ //# sourceMappingURL=miro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/embed-viewer/providers/miro.ts"],"names":[],"mappings":"AAIA,MAAM,cAAA,uBACA,GAAA,CAAI;AAAA,EACN,UAAA;AAAA,EACA;AACF,CAAC,CAAA;AAEI,SAAS,eACd,QAAA,EACS;AACT,EAAA,OAAO,cAAA,CAAe,GAAA;AAAA,IACpB;AAAA,GACF;AACF;AAEO,SAAS,oBACd,GAAA,EAC0B;AAC1B,EAAA,IACE,CAAC,cAAA;AAAA,IACC,GAAA,CAAI;AAAA,GACN,EACA;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GACJ,IAAI,QAAA,CAAS,KAAA;AAAA,IACX;AAAA,GACF;AAEF,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GACJ,MAAM,CAAC,CAAA;AAET,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WACJ,IAAI,GAAA;AAAA,IACF,mCAAmC,OAAO,CAAA,CAAA;AAAA,GAC5C;AAEF,EAAA,QAAA,CAAS,YAAA,CAAa,GAAA;AAAA,IACpB,UAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EACE,SAAS,QAAA;AAAS,GACtB;AACF","file":"miro.js","sourcesContent":["export interface MiroEmbedResource {\n embedUrl: string;\n}\n\nconst MIRO_HOSTNAMES =\n new Set([\n 'miro.com',\n 'www.miro.com',\n ]);\n\nexport function isMiroHostname(\n hostname: string,\n): boolean {\n return MIRO_HOSTNAMES.has(\n hostname,\n );\n}\n\nexport function resolveMiroResource(\n url: URL,\n): MiroEmbedResource | null {\n if (\n !isMiroHostname(\n url.hostname,\n )\n ) {\n return null;\n }\n\n const match =\n url.pathname.match(\n /^\\/app\\/board\\/([^/]+)\\/?$/,\n );\n\n if (!match) {\n return null;\n }\n\n const boardId =\n match[1];\n\n if (!boardId) {\n return null;\n }\n\n const embedUrl =\n new URL(\n `https://miro.com/app/live-embed/${boardId}/`,\n );\n\n embedUrl.searchParams.set(\n 'autoplay',\n 'true',\n );\n\n return {\n embedUrl:\n embedUrl.toString(),\n };\n}\n"]}
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ function isTypeformHostname(hostname) {
4
+ return hostname === "typeform.com" || hostname.endsWith(
5
+ ".typeform.com"
6
+ );
7
+ }
8
+ function resolveTypeformResource(url) {
9
+ if (!isTypeformHostname(
10
+ url.hostname
11
+ )) {
12
+ return null;
13
+ }
14
+ const match = url.pathname.match(
15
+ /^\/to\/([^/]+)\/?$/
16
+ );
17
+ if (!match || !match[1]) {
18
+ return null;
19
+ }
20
+ return {
21
+ embedUrl: url.toString()
22
+ };
23
+ }
24
+
25
+ exports.isTypeformHostname = isTypeformHostname;
26
+ exports.resolveTypeformResource = resolveTypeformResource;
27
+ //# sourceMappingURL=typeform.cjs.map
28
+ //# sourceMappingURL=typeform.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/embed-viewer/providers/typeform.ts"],"names":[],"mappings":";;AAIO,SAAS,mBACd,QAAA,EACS;AACT,EAAA,OACE,QAAA,KAAa,kBACb,QAAA,CAAS,QAAA;AAAA,IACP;AAAA,GACF;AAEJ;AAEO,SAAS,wBACd,GAAA,EAC8B;AAC9B,EAAA,IACE,CAAC,kBAAA;AAAA,IACC,GAAA,CAAI;AAAA,GACN,EACA;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GACJ,IAAI,QAAA,CAAS,KAAA;AAAA,IACX;AAAA,GACF;AAEF,EAAA,IACE,CAAC,KAAA,IACD,CAAC,KAAA,CAAM,CAAC,CAAA,EACR;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EACE,IAAI,QAAA;AAAS,GACjB;AACF","file":"typeform.cjs","sourcesContent":["export interface TypeformEmbedResource {\n embedUrl: string;\n}\n\nexport function isTypeformHostname(\n hostname: string,\n): boolean {\n return (\n hostname === 'typeform.com' ||\n hostname.endsWith(\n '.typeform.com',\n )\n );\n}\n\nexport function resolveTypeformResource(\n url: URL,\n): TypeformEmbedResource | null {\n if (\n !isTypeformHostname(\n url.hostname,\n )\n ) {\n return null;\n }\n\n const match =\n url.pathname.match(\n /^\\/to\\/([^/]+)\\/?$/,\n );\n\n if (\n !match ||\n !match[1]\n ) {\n return null;\n }\n\n return {\n embedUrl:\n url.toString(),\n };\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export interface TypeformEmbedResource {
2
+ embedUrl: string;
3
+ }
4
+ export declare function isTypeformHostname(hostname: string): boolean;
5
+ export declare function resolveTypeformResource(url: URL): TypeformEmbedResource | null;
@@ -0,0 +1,25 @@
1
+ function isTypeformHostname(hostname) {
2
+ return hostname === "typeform.com" || hostname.endsWith(
3
+ ".typeform.com"
4
+ );
5
+ }
6
+ function resolveTypeformResource(url) {
7
+ if (!isTypeformHostname(
8
+ url.hostname
9
+ )) {
10
+ return null;
11
+ }
12
+ const match = url.pathname.match(
13
+ /^\/to\/([^/]+)\/?$/
14
+ );
15
+ if (!match || !match[1]) {
16
+ return null;
17
+ }
18
+ return {
19
+ embedUrl: url.toString()
20
+ };
21
+ }
22
+
23
+ export { isTypeformHostname, resolveTypeformResource };
24
+ //# sourceMappingURL=typeform.js.map
25
+ //# sourceMappingURL=typeform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/embed-viewer/providers/typeform.ts"],"names":[],"mappings":"AAIO,SAAS,mBACd,QAAA,EACS;AACT,EAAA,OACE,QAAA,KAAa,kBACb,QAAA,CAAS,QAAA;AAAA,IACP;AAAA,GACF;AAEJ;AAEO,SAAS,wBACd,GAAA,EAC8B;AAC9B,EAAA,IACE,CAAC,kBAAA;AAAA,IACC,GAAA,CAAI;AAAA,GACN,EACA;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GACJ,IAAI,QAAA,CAAS,KAAA;AAAA,IACX;AAAA,GACF;AAEF,EAAA,IACE,CAAC,KAAA,IACD,CAAC,KAAA,CAAM,CAAC,CAAA,EACR;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,QAAA,EACE,IAAI,QAAA;AAAS,GACjB;AACF","file":"typeform.js","sourcesContent":["export interface TypeformEmbedResource {\n embedUrl: string;\n}\n\nexport function isTypeformHostname(\n hostname: string,\n): boolean {\n return (\n hostname === 'typeform.com' ||\n hostname.endsWith(\n '.typeform.com',\n )\n );\n}\n\nexport function resolveTypeformResource(\n url: URL,\n): TypeformEmbedResource | null {\n if (\n !isTypeformHostname(\n url.hostname,\n )\n ) {\n return null;\n }\n\n const match =\n url.pathname.match(\n /^\\/to\\/([^/]+)\\/?$/,\n );\n\n if (\n !match ||\n !match[1]\n ) {\n return null;\n }\n\n return {\n embedUrl:\n url.toString(),\n };\n}\n"]}
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ var figma = require('./providers/figma');
4
+ var google = require('./providers/google');
5
+ var miro = require('./providers/miro');
6
+ var typeform = require('./providers/typeform');
7
+
8
+ function parseHttpUrl(value) {
9
+ try {
10
+ const url = new URL(value);
11
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
12
+ return null;
13
+ }
14
+ return url;
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+ function createEmptyResource() {
20
+ return {
21
+ sourceUrl: null,
22
+ embedUrl: null,
23
+ previewImageUrl: null,
24
+ copyUrl: null,
25
+ capabilities: {
26
+ embed: false,
27
+ open: false
28
+ }
29
+ };
30
+ }
31
+ function isKnownProviderHostname(hostname) {
32
+ return google.isGoogleHostname(hostname) || miro.isMiroHostname(hostname) || figma.isFigmaHostname(hostname) || typeform.isTypeformHostname(hostname);
33
+ }
34
+ function resolveEmbedResource({
35
+ src,
36
+ embedSrc
37
+ }) {
38
+ const sourceUrl = parseHttpUrl(src);
39
+ if (!sourceUrl) {
40
+ return createEmptyResource();
41
+ }
42
+ const googleResource = google.resolveGoogleResource(
43
+ sourceUrl
44
+ );
45
+ const miroResource = miro.resolveMiroResource(
46
+ sourceUrl
47
+ );
48
+ const figmaResource = figma.resolveFigmaResource(
49
+ sourceUrl
50
+ );
51
+ const typeformResource = typeform.resolveTypeformResource(
52
+ sourceUrl
53
+ );
54
+ const providerEmbedUrl = googleResource?.embedUrl ?? miroResource?.embedUrl ?? figmaResource?.embedUrl ?? typeformResource?.embedUrl ?? null;
55
+ const explicitEmbedUrl = embedSrc ? parseHttpUrl(embedSrc) : null;
56
+ const genericEmbedUrl = isKnownProviderHostname(
57
+ sourceUrl.hostname
58
+ ) ? null : sourceUrl.toString();
59
+ const resolvedEmbedUrl = explicitEmbedUrl?.toString() ?? providerEmbedUrl ?? genericEmbedUrl;
60
+ return {
61
+ sourceUrl: sourceUrl.toString(),
62
+ embedUrl: resolvedEmbedUrl,
63
+ previewImageUrl: null,
64
+ copyUrl: googleResource?.copyUrl ?? null,
65
+ capabilities: {
66
+ embed: resolvedEmbedUrl !== null,
67
+ open: true
68
+ }
69
+ };
70
+ }
71
+
72
+ exports.resolveEmbedResource = resolveEmbedResource;
73
+ //# sourceMappingURL=resolver.cjs.map
74
+ //# sourceMappingURL=resolver.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/embed-viewer/resolver.ts"],"names":["isGoogleHostname","isMiroHostname","isFigmaHostname","isTypeformHostname","resolveGoogleResource","resolveMiroResource","resolveFigmaResource","resolveTypeformResource"],"mappings":";;;;;;;AAiCA,SAAS,aACP,KAAA,EACY;AACZ,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GACJ,IAAI,GAAA,CAAI,KAAK,CAAA;AAEf,IAAA,IACE,GAAA,CAAI,QAAA,KAAa,OAAA,IACjB,GAAA,CAAI,aAAa,QAAA,EACjB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,mBAAA,GAA6C;AACpD,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,IAAA;AAAA,IACX,QAAA,EAAU,IAAA;AAAA,IACV,eAAA,EAAiB,IAAA;AAAA,IACjB,OAAA,EAAS,IAAA;AAAA,IACT,YAAA,EAAc;AAAA,MACZ,KAAA,EAAO,KAAA;AAAA,MACP,IAAA,EAAM;AAAA;AACR,GACF;AACF;AAEA,SAAS,wBACP,QAAA,EACS;AACT,EAAA,OACEA,uBAAA,CAAiB,QAAQ,CAAA,IACzBC,mBAAA,CAAe,QAAQ,KACvBC,qBAAA,CAAgB,QAAQ,CAAA,IACxBC,2BAAA,CAAmB,QAAQ,CAAA;AAE/B;AAEO,SAAS,oBAAA,CAAqB;AAAA,EACnC,GAAA;AAAA,EACA;AACF,CAAA,EAAuD;AACrD,EAAA,MAAM,SAAA,GACJ,aAAa,GAAG,CAAA;AAElB,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAO,mBAAA,EAAoB;AAAA,EAC7B;AAEA,EAAA,MAAM,cAAA,GACJC,4BAAA;AAAA,IACE;AAAA,GACF;AAEF,EAAA,MAAM,YAAA,GACJC,wBAAA;AAAA,IACE;AAAA,GACF;AAEF,EAAA,MAAM,aAAA,GACJC,0BAAA;AAAA,IACE;AAAA,GACF;AAEF,EAAA,MAAM,gBAAA,GACJC,gCAAA;AAAA,IACE;AAAA,GACF;AAEF,EAAA,MAAM,gBAAA,GACJ,gBAAgB,QAAA,IAChB,YAAA,EAAc,YACd,aAAA,EAAe,QAAA,IACf,kBAAkB,QAAA,IAClB,IAAA;AAEF,EAAA,MAAM,gBAAA,GACJ,QAAA,GACI,YAAA,CAAa,QAAQ,CAAA,GACrB,IAAA;AAEN,EAAA,MAAM,eAAA,GACJ,uBAAA;AAAA,IACE,SAAA,CAAU;AAAA,GACZ,GACI,IAAA,GACA,SAAA,CAAU,QAAA,EAAS;AAEzB,EAAA,MAAM,gBAAA,GACJ,gBAAA,EAAkB,QAAA,EAAS,IAC3B,gBAAA,IACA,eAAA;AAEF,EAAA,OAAO;AAAA,IACL,SAAA,EACE,UAAU,QAAA,EAAS;AAAA,IACrB,QAAA,EACE,gBAAA;AAAA,IACF,eAAA,EAAiB,IAAA;AAAA,IACjB,OAAA,EACE,gBAAgB,OAAA,IAChB,IAAA;AAAA,IACF,YAAA,EAAc;AAAA,MACZ,OACE,gBAAA,KAAqB,IAAA;AAAA,MACvB,IAAA,EAAM;AAAA;AACR,GACF;AACF","file":"resolver.cjs","sourcesContent":["import {\n isFigmaHostname,\n resolveFigmaResource,\n} from './providers/figma';\nimport {\n isGoogleHostname,\n resolveGoogleResource,\n} from './providers/google';\nimport {\n isMiroHostname,\n resolveMiroResource,\n} from './providers/miro';\nimport {\n isTypeformHostname,\n resolveTypeformResource,\n} from './providers/typeform';\n\nexport interface ResolvedEmbedResource {\n sourceUrl: string | null;\n embedUrl: string | null;\n previewImageUrl: string | null;\n copyUrl: string | null;\n capabilities: {\n embed: boolean;\n open: boolean;\n };\n}\n\nexport interface ResolveEmbedResourceOptions {\n src: string;\n embedSrc?: string;\n}\n\nfunction parseHttpUrl(\n value: string,\n): URL | null {\n try {\n const url =\n new URL(value);\n\n if (\n url.protocol !== 'http:' &&\n url.protocol !== 'https:'\n ) {\n return null;\n }\n\n return url;\n } catch {\n return null;\n }\n}\n\nfunction createEmptyResource(): ResolvedEmbedResource {\n return {\n sourceUrl: null,\n embedUrl: null,\n previewImageUrl: null,\n copyUrl: null,\n capabilities: {\n embed: false,\n open: false,\n },\n };\n}\n\nfunction isKnownProviderHostname(\n hostname: string,\n): boolean {\n return (\n isGoogleHostname(hostname) ||\n isMiroHostname(hostname) ||\n isFigmaHostname(hostname) ||\n isTypeformHostname(hostname)\n );\n}\n\nexport function resolveEmbedResource({\n src,\n embedSrc,\n}: ResolveEmbedResourceOptions): ResolvedEmbedResource {\n const sourceUrl =\n parseHttpUrl(src);\n\n if (!sourceUrl) {\n return createEmptyResource();\n }\n\n const googleResource =\n resolveGoogleResource(\n sourceUrl,\n );\n\n const miroResource =\n resolveMiroResource(\n sourceUrl,\n );\n\n const figmaResource =\n resolveFigmaResource(\n sourceUrl,\n );\n\n const typeformResource =\n resolveTypeformResource(\n sourceUrl,\n );\n\n const providerEmbedUrl =\n googleResource?.embedUrl ??\n miroResource?.embedUrl ??\n figmaResource?.embedUrl ??\n typeformResource?.embedUrl ??\n null;\n\n const explicitEmbedUrl =\n embedSrc\n ? parseHttpUrl(embedSrc)\n : null;\n\n const genericEmbedUrl =\n isKnownProviderHostname(\n sourceUrl.hostname,\n )\n ? null\n : sourceUrl.toString();\n\n const resolvedEmbedUrl =\n explicitEmbedUrl?.toString() ??\n providerEmbedUrl ??\n genericEmbedUrl;\n\n return {\n sourceUrl:\n sourceUrl.toString(),\n embedUrl:\n resolvedEmbedUrl,\n previewImageUrl: null,\n copyUrl:\n googleResource?.copyUrl ??\n null,\n capabilities: {\n embed:\n resolvedEmbedUrl !== null,\n open: true,\n },\n };\n}\n"]}
@@ -0,0 +1,15 @@
1
+ export interface ResolvedEmbedResource {
2
+ sourceUrl: string | null;
3
+ embedUrl: string | null;
4
+ previewImageUrl: string | null;
5
+ copyUrl: string | null;
6
+ capabilities: {
7
+ embed: boolean;
8
+ open: boolean;
9
+ };
10
+ }
11
+ export interface ResolveEmbedResourceOptions {
12
+ src: string;
13
+ embedSrc?: string;
14
+ }
15
+ export declare function resolveEmbedResource({ src, embedSrc, }: ResolveEmbedResourceOptions): ResolvedEmbedResource;
@@ -0,0 +1,72 @@
1
+ import { resolveFigmaResource, isFigmaHostname } from './providers/figma';
2
+ import { resolveGoogleResource, isGoogleHostname } from './providers/google';
3
+ import { resolveMiroResource, isMiroHostname } from './providers/miro';
4
+ import { resolveTypeformResource, isTypeformHostname } from './providers/typeform';
5
+
6
+ function parseHttpUrl(value) {
7
+ try {
8
+ const url = new URL(value);
9
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
10
+ return null;
11
+ }
12
+ return url;
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+ function createEmptyResource() {
18
+ return {
19
+ sourceUrl: null,
20
+ embedUrl: null,
21
+ previewImageUrl: null,
22
+ copyUrl: null,
23
+ capabilities: {
24
+ embed: false,
25
+ open: false
26
+ }
27
+ };
28
+ }
29
+ function isKnownProviderHostname(hostname) {
30
+ return isGoogleHostname(hostname) || isMiroHostname(hostname) || isFigmaHostname(hostname) || isTypeformHostname(hostname);
31
+ }
32
+ function resolveEmbedResource({
33
+ src,
34
+ embedSrc
35
+ }) {
36
+ const sourceUrl = parseHttpUrl(src);
37
+ if (!sourceUrl) {
38
+ return createEmptyResource();
39
+ }
40
+ const googleResource = resolveGoogleResource(
41
+ sourceUrl
42
+ );
43
+ const miroResource = resolveMiroResource(
44
+ sourceUrl
45
+ );
46
+ const figmaResource = resolveFigmaResource(
47
+ sourceUrl
48
+ );
49
+ const typeformResource = resolveTypeformResource(
50
+ sourceUrl
51
+ );
52
+ const providerEmbedUrl = googleResource?.embedUrl ?? miroResource?.embedUrl ?? figmaResource?.embedUrl ?? typeformResource?.embedUrl ?? null;
53
+ const explicitEmbedUrl = embedSrc ? parseHttpUrl(embedSrc) : null;
54
+ const genericEmbedUrl = isKnownProviderHostname(
55
+ sourceUrl.hostname
56
+ ) ? null : sourceUrl.toString();
57
+ const resolvedEmbedUrl = explicitEmbedUrl?.toString() ?? providerEmbedUrl ?? genericEmbedUrl;
58
+ return {
59
+ sourceUrl: sourceUrl.toString(),
60
+ embedUrl: resolvedEmbedUrl,
61
+ previewImageUrl: null,
62
+ copyUrl: googleResource?.copyUrl ?? null,
63
+ capabilities: {
64
+ embed: resolvedEmbedUrl !== null,
65
+ open: true
66
+ }
67
+ };
68
+ }
69
+
70
+ export { resolveEmbedResource };
71
+ //# sourceMappingURL=resolver.js.map
72
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/embed-viewer/resolver.ts"],"names":[],"mappings":";;;;;AAiCA,SAAS,aACP,KAAA,EACY;AACZ,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GACJ,IAAI,GAAA,CAAI,KAAK,CAAA;AAEf,IAAA,IACE,GAAA,CAAI,QAAA,KAAa,OAAA,IACjB,GAAA,CAAI,aAAa,QAAA,EACjB;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,mBAAA,GAA6C;AACpD,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,IAAA;AAAA,IACX,QAAA,EAAU,IAAA;AAAA,IACV,eAAA,EAAiB,IAAA;AAAA,IACjB,OAAA,EAAS,IAAA;AAAA,IACT,YAAA,EAAc;AAAA,MACZ,KAAA,EAAO,KAAA;AAAA,MACP,IAAA,EAAM;AAAA;AACR,GACF;AACF;AAEA,SAAS,wBACP,QAAA,EACS;AACT,EAAA,OACE,gBAAA,CAAiB,QAAQ,CAAA,IACzB,cAAA,CAAe,QAAQ,KACvB,eAAA,CAAgB,QAAQ,CAAA,IACxB,kBAAA,CAAmB,QAAQ,CAAA;AAE/B;AAEO,SAAS,oBAAA,CAAqB;AAAA,EACnC,GAAA;AAAA,EACA;AACF,CAAA,EAAuD;AACrD,EAAA,MAAM,SAAA,GACJ,aAAa,GAAG,CAAA;AAElB,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAO,mBAAA,EAAoB;AAAA,EAC7B;AAEA,EAAA,MAAM,cAAA,GACJ,qBAAA;AAAA,IACE;AAAA,GACF;AAEF,EAAA,MAAM,YAAA,GACJ,mBAAA;AAAA,IACE;AAAA,GACF;AAEF,EAAA,MAAM,aAAA,GACJ,oBAAA;AAAA,IACE;AAAA,GACF;AAEF,EAAA,MAAM,gBAAA,GACJ,uBAAA;AAAA,IACE;AAAA,GACF;AAEF,EAAA,MAAM,gBAAA,GACJ,gBAAgB,QAAA,IAChB,YAAA,EAAc,YACd,aAAA,EAAe,QAAA,IACf,kBAAkB,QAAA,IAClB,IAAA;AAEF,EAAA,MAAM,gBAAA,GACJ,QAAA,GACI,YAAA,CAAa,QAAQ,CAAA,GACrB,IAAA;AAEN,EAAA,MAAM,eAAA,GACJ,uBAAA;AAAA,IACE,SAAA,CAAU;AAAA,GACZ,GACI,IAAA,GACA,SAAA,CAAU,QAAA,EAAS;AAEzB,EAAA,MAAM,gBAAA,GACJ,gBAAA,EAAkB,QAAA,EAAS,IAC3B,gBAAA,IACA,eAAA;AAEF,EAAA,OAAO;AAAA,IACL,SAAA,EACE,UAAU,QAAA,EAAS;AAAA,IACrB,QAAA,EACE,gBAAA;AAAA,IACF,eAAA,EAAiB,IAAA;AAAA,IACjB,OAAA,EACE,gBAAgB,OAAA,IAChB,IAAA;AAAA,IACF,YAAA,EAAc;AAAA,MACZ,OACE,gBAAA,KAAqB,IAAA;AAAA,MACvB,IAAA,EAAM;AAAA;AACR,GACF;AACF","file":"resolver.js","sourcesContent":["import {\n isFigmaHostname,\n resolveFigmaResource,\n} from './providers/figma';\nimport {\n isGoogleHostname,\n resolveGoogleResource,\n} from './providers/google';\nimport {\n isMiroHostname,\n resolveMiroResource,\n} from './providers/miro';\nimport {\n isTypeformHostname,\n resolveTypeformResource,\n} from './providers/typeform';\n\nexport interface ResolvedEmbedResource {\n sourceUrl: string | null;\n embedUrl: string | null;\n previewImageUrl: string | null;\n copyUrl: string | null;\n capabilities: {\n embed: boolean;\n open: boolean;\n };\n}\n\nexport interface ResolveEmbedResourceOptions {\n src: string;\n embedSrc?: string;\n}\n\nfunction parseHttpUrl(\n value: string,\n): URL | null {\n try {\n const url =\n new URL(value);\n\n if (\n url.protocol !== 'http:' &&\n url.protocol !== 'https:'\n ) {\n return null;\n }\n\n return url;\n } catch {\n return null;\n }\n}\n\nfunction createEmptyResource(): ResolvedEmbedResource {\n return {\n sourceUrl: null,\n embedUrl: null,\n previewImageUrl: null,\n copyUrl: null,\n capabilities: {\n embed: false,\n open: false,\n },\n };\n}\n\nfunction isKnownProviderHostname(\n hostname: string,\n): boolean {\n return (\n isGoogleHostname(hostname) ||\n isMiroHostname(hostname) ||\n isFigmaHostname(hostname) ||\n isTypeformHostname(hostname)\n );\n}\n\nexport function resolveEmbedResource({\n src,\n embedSrc,\n}: ResolveEmbedResourceOptions): ResolvedEmbedResource {\n const sourceUrl =\n parseHttpUrl(src);\n\n if (!sourceUrl) {\n return createEmptyResource();\n }\n\n const googleResource =\n resolveGoogleResource(\n sourceUrl,\n );\n\n const miroResource =\n resolveMiroResource(\n sourceUrl,\n );\n\n const figmaResource =\n resolveFigmaResource(\n sourceUrl,\n );\n\n const typeformResource =\n resolveTypeformResource(\n sourceUrl,\n );\n\n const providerEmbedUrl =\n googleResource?.embedUrl ??\n miroResource?.embedUrl ??\n figmaResource?.embedUrl ??\n typeformResource?.embedUrl ??\n null;\n\n const explicitEmbedUrl =\n embedSrc\n ? parseHttpUrl(embedSrc)\n : null;\n\n const genericEmbedUrl =\n isKnownProviderHostname(\n sourceUrl.hostname,\n )\n ? null\n : sourceUrl.toString();\n\n const resolvedEmbedUrl =\n explicitEmbedUrl?.toString() ??\n providerEmbedUrl ??\n genericEmbedUrl;\n\n return {\n sourceUrl:\n sourceUrl.toString(),\n embedUrl:\n resolvedEmbedUrl,\n previewImageUrl: null,\n copyUrl:\n googleResource?.copyUrl ??\n null,\n capabilities: {\n embed:\n resolvedEmbedUrl !== null,\n open: true,\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jvetrau-ds",
3
- "version": "0.2.17",
3
+ "version": "0.2.19",
4
4
  "description": "Multi-brand React design system with semantic tokens",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",