Skip to content

Commit c2c5457

Browse files
committed
new transfromers
1 parent e958f67 commit c2c5457

40 files changed

Lines changed: 1219 additions & 22 deletions

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ Currently, the following services are supported out of the box:
103103
- Google Docs (supports formats: docs.google.com/document/d/..., docs.google.com/spreadsheets/d/..., docs.google.com/presentation/d/...)
104104
- PDF (supports embedding PDF files)
105105
- CodePen (supports formats: codepen.io/username/pen/penId, codepen.io/username/full/penId)
106+
- Typeform (supports formats: form.typeform.com/to/FORM_ID, [workspace].typeform.com/to/FORM_ID)
106107

107108
### Contributing New Services
108109

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "link-to-iframe",
3-
"version": "1.0.4",
3+
"version": "1.0.5",
44
"description": "Transform links to embeddable iframes",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/transformers/abstract.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { IframeAttributes, Transformer } from "../types";
2+
3+
/**
4+
* Transformer for Abstract URLs
5+
* Handles formats:
6+
* - https://share.abstract.com/[SHARE_ID]
7+
* - https://app.abstract.com/share/[SHARE_ID]
8+
*/
9+
export const abstractTransformer: Transformer = {
10+
pattern: /https?:\/\/(?:share|app)\.abstract\.com\/(?:share\/)?([a-zA-Z0-9-]+)/i,
11+
12+
transform: (url: string, matches: RegExpExecArray): IframeAttributes | null => {
13+
const shareId = matches[1];
14+
15+
if (!shareId) {
16+
return null;
17+
}
18+
19+
return {
20+
src: `https://app.abstract.com/embed/share/${shareId}`,
21+
width: 800,
22+
height: 600,
23+
frameborder: 0,
24+
allowfullscreen: true,
25+
};
26+
},
27+
};

src/transformers/adobexd.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Transformer, IframeAttributes } from "../types";
2+
3+
/**
4+
* Transformer for Adobe XD prototypes
5+
* Supports formats:
6+
* - xd.adobe.com/view/DESIGN_ID
7+
* - xd.adobe.com/spec/SPEC_ID
8+
*/
9+
export const adobexdTransformer: Transformer = {
10+
patterns: [
11+
// Design view pattern
12+
/(?:https?:\/\/)?(?:www\.)?xd\.adobe\.com\/view\/([a-zA-Z0-9-]+)(?:\/.*)?(?:\?.*)?$/i,
13+
// Spec pattern
14+
/(?:https?:\/\/)?(?:www\.)?xd\.adobe\.com\/spec\/([a-zA-Z0-9-]+)(?:\/.*)?(?:\?.*)?$/i,
15+
],
16+
17+
transform: (url: string, matches: RegExpExecArray): IframeAttributes => {
18+
const id = matches[1];
19+
const type = url.includes("/view/") ? "view" : "spec";
20+
21+
return {
22+
src: `https://xd.adobe.com/embed/${type}/${id}`,
23+
width: 800,
24+
height: 600,
25+
frameborder: 0,
26+
allowfullscreen: true,
27+
};
28+
},
29+
};

src/transformers/amplitude.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Transformer, IframeAttributes } from "../types";
2+
3+
/**
4+
* Transformer for Amplitude dashboards and charts
5+
* Supports formats:
6+
* - analytics.amplitude.com/org/PROJECT/dashboard/DASHBOARD_ID
7+
* - analytics.amplitude.com/org/PROJECT/chart/CHART_ID
8+
*/
9+
export const amplitudeTransformer: Transformer = {
10+
pattern: /(?:https?:\/\/)?(?:www\.)?analytics\.amplitude\.com\/([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+)\/(?:dashboard|chart)\/([a-zA-Z0-9_-]+)(?:\?.*)?$/i,
11+
12+
transform: (url: string, matches: RegExpExecArray): IframeAttributes => {
13+
const org = matches[1];
14+
const project = matches[2];
15+
const id = matches[3];
16+
const type = url.includes("/dashboard/") ? "dashboard" : "chart";
17+
18+
return {
19+
src: `https://analytics.amplitude.com/embed/${org}/${project}/${type}/${id}`,
20+
width: 800,
21+
height: 600,
22+
frameborder: 0,
23+
allowfullscreen: true,
24+
};
25+
},
26+
};

src/transformers/asana.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Transformer, IframeAttributes } from "../types";
2+
3+
/**
4+
* Transformer for Asana tasks and projects
5+
* Supports formats:
6+
* - app.asana.com/0/PROJECT_ID/TASK_ID
7+
* - app.asana.com/0/PROJECT_ID
8+
*/
9+
export const asanaTransformer: Transformer = {
10+
pattern: /(?:https?:\/\/)?(?:www\.)?app\.asana\.com\/0\/([0-9]+)(?:\/([0-9]+))?(?:\?.*)?$/i,
11+
12+
transform: (url: string, matches: RegExpExecArray): IframeAttributes => {
13+
const projectId = matches[1];
14+
const taskId = matches[2] || "";
15+
16+
// Build the embed URL
17+
let embedUrl = `https://app.asana.com/embed/${projectId}`;
18+
if (taskId) {
19+
embedUrl += `/${taskId}`;
20+
}
21+
22+
return {
23+
src: embedUrl,
24+
width: 800,
25+
height: 600,
26+
frameborder: 0,
27+
allowfullscreen: true,
28+
};
29+
},
30+
};

src/transformers/box.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Transformer, IframeAttributes } from "../types";
2+
3+
/**
4+
* Transformer for Box files and folders
5+
* Supports formats:
6+
* - app.box.com/s/FILE_ID
7+
* - app.box.com/file/FILE_ID
8+
* - app.box.com/folder/FOLDER_ID
9+
*/
10+
export const boxTransformer: Transformer = {
11+
patterns: [
12+
// Shared link pattern
13+
/(?:https?:\/\/)?(?:www\.)?app\.box\.com\/s\/([a-zA-Z0-9]+)(?:\?.*)?$/i,
14+
// File pattern
15+
/(?:https?:\/\/)?(?:www\.)?app\.box\.com\/file\/([0-9]+)(?:\?.*)?$/i,
16+
// Folder pattern
17+
/(?:https?:\/\/)?(?:www\.)?app\.box\.com\/folder\/([0-9]+)(?:\?.*)?$/i,
18+
],
19+
20+
transform: (url: string, matches: RegExpExecArray): IframeAttributes => {
21+
// Check which pattern matched
22+
if (url.includes("/s/")) {
23+
// Shared link
24+
const sharedId = matches[1];
25+
return {
26+
src: `https://app.box.com/embed/s/${sharedId}`,
27+
width: 800,
28+
height: 600,
29+
frameborder: 0,
30+
allowfullscreen: true,
31+
};
32+
} else if (url.includes("/file/")) {
33+
// File
34+
const fileId = matches[1];
35+
return {
36+
src: `https://app.box.com/embed/file/${fileId}`,
37+
width: 800,
38+
height: 600,
39+
frameborder: 0,
40+
allowfullscreen: true,
41+
};
42+
} else {
43+
// Folder
44+
const folderId = matches[1];
45+
return {
46+
src: `https://app.box.com/embed/folder/${folderId}`,
47+
width: 800,
48+
height: 600,
49+
frameborder: 0,
50+
allowfullscreen: true,
51+
};
52+
}
53+
},
54+
};

src/transformers/claap.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Transformer, IframeAttributes } from "../types";
2+
3+
/**
4+
* Transformer for Claap videos
5+
* Supports formats:
6+
* - claap.io/r/VIDEO_ID
7+
* - app.claap.io/r/VIDEO_ID
8+
*/
9+
export const claapTransformer: Transformer = {
10+
pattern: /(?:https?:\/\/)?(?:www\.|app\.)?claap\.io\/r\/([a-zA-Z0-9_-]+)(?:\?.*)?$/i,
11+
12+
transform: (url: string, matches: RegExpExecArray): IframeAttributes => {
13+
const videoId = matches[1];
14+
15+
return {
16+
src: `https://app.claap.io/embed/r/${videoId}`,
17+
width: 800,
18+
height: 600,
19+
frameborder: 0,
20+
allowfullscreen: true,
21+
allow: "fullscreen; picture-in-picture",
22+
};
23+
},
24+
};

src/transformers/clickup.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Transformer, IframeAttributes } from "../types";
2+
3+
/**
4+
* Transformer for ClickUp tasks and documents
5+
* Supports formats:
6+
* - app.clickup.com/t/TASK_ID
7+
* - app.clickup.com/d/DOC_ID
8+
* - app.clickup.com/v/vi/DASHBOARD_ID
9+
*/
10+
export const clickupTransformer: Transformer = {
11+
patterns: [
12+
// Task pattern
13+
/(?:https?:\/\/)?(?:www\.)?app\.clickup\.com\/t\/([a-zA-Z0-9]+)(?:\?.*)?$/i,
14+
// Doc pattern
15+
/(?:https?:\/\/)?(?:www\.)?app\.clickup\.com\/d\/([a-zA-Z0-9]+)(?:\?.*)?$/i,
16+
// Dashboard pattern
17+
/(?:https?:\/\/)?(?:www\.)?app\.clickup\.com\/v\/vi\/([a-zA-Z0-9]+)(?:\?.*)?$/i,
18+
],
19+
20+
transform: (url: string, matches: RegExpExecArray): IframeAttributes => {
21+
const id = matches[1];
22+
let type = "t";
23+
24+
if (url.includes("/d/")) {
25+
type = "d";
26+
} else if (url.includes("/v/vi/")) {
27+
type = "vi";
28+
}
29+
30+
return {
31+
src: `https://app.clickup.com/embed/${type}/${id}`,
32+
width: 800,
33+
height: 600,
34+
frameborder: 0,
35+
allowfullscreen: true,
36+
};
37+
},
38+
};

src/transformers/deepnote.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Transformer, IframeAttributes } from "../types";
2+
3+
/**
4+
* Transformer for Deepnote notebooks
5+
* Supports formats:
6+
* - deepnote.com/workspace/WORKSPACE-ID/PROJECT-NAME-PROJECT-ID
7+
*/
8+
export const deepnoteTransformer: Transformer = {
9+
pattern: /(?:https?:\/\/)?(?:www\.)?deepnote\.com\/workspace\/([a-zA-Z0-9-]+)\/([a-zA-Z0-9-]+)-([a-zA-Z0-9]+)(?:\/.*)?$/i,
10+
11+
transform: (url: string): IframeAttributes => {
12+
return {
13+
src: `${url.replace(/\/edit.*$/, "")}/embed`,
14+
width: 800,
15+
height: 600,
16+
frameborder: 0,
17+
allowfullscreen: true,
18+
};
19+
},
20+
};

0 commit comments

Comments
 (0)