@ampless/plugin-x-embed 1.0.0-beta.15 → 1.0.0-beta.17

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.
@@ -45,9 +45,43 @@ function hasTweetUrlInMarkdown(md) {
45
45
  return false;
46
46
  }
47
47
 
48
+ // src/adapters.ts
49
+ function placeholderAttrs(attrs) {
50
+ return {
51
+ "data-ampless-tweet": "",
52
+ "data-tweet-id": String(attrs.tweetId ?? ""),
53
+ class: "ampless-tweet-placeholder"
54
+ };
55
+ }
56
+ function escapeAttr(v) {
57
+ return v.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
58
+ }
59
+ function attrsToHtmlString(attrs) {
60
+ return Object.entries(attrs).map(([k, v]) => v === "" ? k : `${k}="${escapeAttr(v)}"`).join(" ");
61
+ }
62
+ var tiptapNodeToMarkdown = {
63
+ amplessTweet: (node) => {
64
+ const tweetId = String(node.attrs?.tweetId ?? "").trim();
65
+ if (!tweetId) return null;
66
+ return `https://x.com/i/status/${tweetId}`;
67
+ }
68
+ };
69
+ var tiptapNodeToHtml = {
70
+ amplessTweet: (node) => {
71
+ const tweetId = String(node.attrs?.tweetId ?? "").trim();
72
+ if (!tweetId) return null;
73
+ const attrs = placeholderAttrs(node.attrs ?? {});
74
+ const url = `https://x.com/i/status/${tweetId}`;
75
+ return `<div ${attrsToHtmlString(attrs)}><a href="${escapeAttr(url)}">${escapeAttr(url)}</a></div>`;
76
+ }
77
+ };
78
+
48
79
  export {
49
80
  TWEET_URL,
50
81
  TweetEmbed,
51
82
  parseTweetUrl,
52
- hasTweetIn
83
+ hasTweetIn,
84
+ placeholderAttrs,
85
+ tiptapNodeToMarkdown,
86
+ tiptapNodeToHtml
53
87
  };
package/dist/editor.d.ts CHANGED
@@ -1,38 +1,6 @@
1
1
  import { Node } from '@tiptap/core';
2
2
  import { TiptapNodeHtmlAdapters, TiptapNodeMarkdownAdapters } from 'ampless';
3
3
 
4
- declare module '@tiptap/core' {
5
- interface Commands<ReturnType> {
6
- amplessTweet: {
7
- /** Insert a tweet embed node with the given tweet id. */
8
- setTweet: (opts: {
9
- tweetId: string;
10
- }) => ReturnType;
11
- /**
12
- * Insert a tweet embed from a URL. Returns false (and does
13
- * nothing) if the URL doesn't match the canonical x.com /
14
- * twitter.com /status/ form.
15
- */
16
- insertTweetFromUrl: (url: string) => ReturnType;
17
- };
18
- }
19
- }
20
- declare const AmplessTweetNode: Node<any, any>;
21
- /**
22
- * Named export consumed by templates' `_editor-bootstrap.tsx`.
23
- */
24
- declare const tweetEditor: {
25
- extension: Node<any, any>;
26
- };
27
- /**
28
- * Canonical named export consumed by the codegen'd
29
- * `_editor-bootstrap.tsx`. Plugins MUST export this symbol from
30
- * their `./editor` module (= the subpath declared in
31
- * `package.json#amplessPlugin.editorExports`) for the
32
- * auto-wiring to find them.
33
- */
34
- declare const editorExtension: Node<any, any>;
35
-
36
4
  /**
37
5
  * tiptap → markdown adapter map. Serialises `amplessTweet` nodes back
38
6
  * to a bare `https://x.com/i/status/<tweetId>` URL line so the admin's
@@ -65,4 +33,36 @@ declare const tiptapNodeToMarkdown: TiptapNodeMarkdownAdapters;
65
33
  */
66
34
  declare const tiptapNodeToHtml: TiptapNodeHtmlAdapters;
67
35
 
36
+ declare module '@tiptap/core' {
37
+ interface Commands<ReturnType> {
38
+ amplessTweet: {
39
+ /** Insert a tweet embed node with the given tweet id. */
40
+ setTweet: (opts: {
41
+ tweetId: string;
42
+ }) => ReturnType;
43
+ /**
44
+ * Insert a tweet embed from a URL. Returns false (and does
45
+ * nothing) if the URL doesn't match the canonical x.com /
46
+ * twitter.com /status/ form.
47
+ */
48
+ insertTweetFromUrl: (url: string) => ReturnType;
49
+ };
50
+ }
51
+ }
52
+ declare const AmplessTweetNode: Node<any, any>;
53
+ /**
54
+ * Named export consumed by templates' `_editor-bootstrap.tsx`.
55
+ */
56
+ declare const tweetEditor: {
57
+ extension: Node<any, any>;
58
+ };
59
+ /**
60
+ * Canonical named export consumed by the codegen'd
61
+ * `_editor-bootstrap.tsx`. Plugins MUST export this symbol from
62
+ * their `./editor` module (= the subpath declared in
63
+ * `package.json#amplessPlugin.editorExports`) for the
64
+ * auto-wiring to find them.
65
+ */
66
+ declare const editorExtension: Node<any, any>;
67
+
68
68
  export { AmplessTweetNode, editorExtension, tiptapNodeToHtml, tiptapNodeToMarkdown, tweetEditor };
package/dist/editor.js CHANGED
@@ -1,8 +1,11 @@
1
1
  "use client";
2
2
  import {
3
3
  TWEET_URL,
4
- parseTweetUrl
5
- } from "./chunk-ZB3Q7IQG.js";
4
+ parseTweetUrl,
5
+ placeholderAttrs,
6
+ tiptapNodeToHtml,
7
+ tiptapNodeToMarkdown
8
+ } from "./chunk-T6SLPTAE.js";
6
9
 
7
10
  // src/editor.tsx
8
11
  import { Node, mergeAttributes } from "@tiptap/core";
@@ -23,19 +26,6 @@ function getBareUrlLinkHref(el) {
23
26
  if (el.textContent?.trim() !== linkText) return null;
24
27
  return href;
25
28
  }
26
- function placeholderAttrs(attrs) {
27
- return {
28
- "data-ampless-tweet": "",
29
- "data-tweet-id": String(attrs.tweetId ?? ""),
30
- class: "ampless-tweet-placeholder"
31
- };
32
- }
33
- function escapeAttr(v) {
34
- return v.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
35
- }
36
- function attrsToHtmlString(attrs) {
37
- return Object.entries(attrs).map(([k, v]) => v === "" ? k : `${k}="${escapeAttr(v)}"`).join(" ");
38
- }
39
29
  var AmplessTweetNode = Node.create({
40
30
  name: "amplessTweet",
41
31
  group: "block",
@@ -163,22 +153,6 @@ var tweetEditor = {
163
153
  extension: AmplessTweetNode
164
154
  };
165
155
  var editorExtension = AmplessTweetNode;
166
- var tiptapNodeToMarkdown = {
167
- amplessTweet: (node) => {
168
- const tweetId = String(node.attrs?.tweetId ?? "").trim();
169
- if (!tweetId) return null;
170
- return `https://x.com/i/status/${tweetId}`;
171
- }
172
- };
173
- var tiptapNodeToHtml = {
174
- amplessTweet: (node) => {
175
- const tweetId = String(node.attrs?.tweetId ?? "").trim();
176
- if (!tweetId) return null;
177
- const attrs = placeholderAttrs(node.attrs ?? {});
178
- const url = `https://x.com/i/status/${tweetId}`;
179
- return `<div ${attrsToHtmlString(attrs)}><a href="${escapeAttr(url)}">${escapeAttr(url)}</a></div>`;
180
- }
181
- };
182
156
  export {
183
157
  AmplessTweetNode,
184
158
  editorExtension,
package/dist/index.js CHANGED
@@ -2,8 +2,9 @@ import {
2
2
  TWEET_URL,
3
3
  TweetEmbed,
4
4
  hasTweetIn,
5
- parseTweetUrl
6
- } from "./chunk-ZB3Q7IQG.js";
5
+ parseTweetUrl,
6
+ tiptapNodeToMarkdown
7
+ } from "./chunk-T6SLPTAE.js";
7
8
 
8
9
  // src/index.tsx
9
10
  import { definePlugin } from "ampless";
@@ -27,7 +28,7 @@ function xEmbedPlugin(opts = {}) {
27
28
  // Opt into the public html walker so `format: 'html'` posts expand
28
29
  // the canonical placeholder div (emitted by the admin's tiptap→html
29
30
  // switch) into the same `<TweetEmbed>` the tiptap / markdown walkers
30
- // render. Attribute names match `placeholderAttrs()` in ./editor.tsx
31
+ // render. Attribute names match `placeholderAttrs()` in ./adapters.ts
31
32
  // (the canonical definition site). The page-level widgets.js is
32
33
  // injected via `publicPostScript` + the `hasTweetIn` html branch.
33
34
  htmlPlaceholder: {
@@ -55,7 +56,8 @@ function xEmbedPlugin(opts = {}) {
55
56
  async: true
56
57
  }
57
58
  ];
58
- }
59
+ },
60
+ tiptapNodeToMarkdown
59
61
  });
60
62
  }
61
63
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ampless/plugin-x-embed",
3
- "version": "1.0.0-beta.15",
3
+ "version": "1.0.0-beta.17",
4
4
  "description": "x.com (Twitter) embed plugin for ampless — renders tweet URLs inline as blockquotes hydrated by widgets.js",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  "peerDependencies": {
33
33
  "@tiptap/core": "^3",
34
34
  "react": "^18 || ^19",
35
- "ampless": "^1.0.0-beta.54"
35
+ "ampless": "^1.0.0-beta.56"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@tiptap/core": "^3.23.6",