create-ampless 1.0.0-alpha.137 → 1.0.0-alpha.139
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -2230,7 +2230,7 @@ async function regenerateEditorBootstrap(destDir, projectPkg) {
|
|
|
2230
2230
|
lines.push("// editor extension, add / remove the corresponding @ampless/plugin-...");
|
|
2231
2231
|
lines.push("// entry in your project's package.json (and register it in cms.config.ts");
|
|
2232
2232
|
lines.push("// for runtime).", "");
|
|
2233
|
-
lines.push("import { installAdminEditorExtensions, installAdminTiptapNodeMarkdown } from '@ampless/admin/editor'");
|
|
2233
|
+
lines.push("import { installAdminEditorExtensions, installAdminTiptapNodeMarkdown, installAdminTiptapNodeHtml } from '@ampless/admin/editor'");
|
|
2234
2234
|
const identifiers = [];
|
|
2235
2235
|
const seen = /* @__PURE__ */ new Map();
|
|
2236
2236
|
for (const p3 of installedPlugins) {
|
|
@@ -2251,6 +2251,7 @@ async function regenerateEditorBootstrap(destDir, projectPkg) {
|
|
|
2251
2251
|
if (identifiers.length === 0) {
|
|
2252
2252
|
lines.push(" installAdminEditorExtensions([])");
|
|
2253
2253
|
lines.push(" installAdminTiptapNodeMarkdown([])");
|
|
2254
|
+
lines.push(" installAdminTiptapNodeHtml([])");
|
|
2254
2255
|
} else {
|
|
2255
2256
|
lines.push(" installAdminEditorExtensions([");
|
|
2256
2257
|
for (const id of identifiers) lines.push(` ${id}.editorExtension,`);
|
|
@@ -2258,6 +2259,9 @@ async function regenerateEditorBootstrap(destDir, projectPkg) {
|
|
|
2258
2259
|
lines.push(" installAdminTiptapNodeMarkdown([");
|
|
2259
2260
|
for (const id of identifiers) lines.push(` ${id}.tiptapNodeToMarkdown ?? {},`);
|
|
2260
2261
|
lines.push(" ])");
|
|
2262
|
+
lines.push(" installAdminTiptapNodeHtml([");
|
|
2263
|
+
for (const id of identifiers) lines.push(` ${id}.tiptapNodeToHtml ?? {},`);
|
|
2264
|
+
lines.push(" ])");
|
|
2261
2265
|
}
|
|
2262
2266
|
lines.push(" return <>{children}</>");
|
|
2263
2267
|
lines.push("}");
|
|
@@ -848,6 +848,113 @@ export default createAdminLayout(admin, { editorBootstrap: EditorBootstrap })
|
|
|
848
848
|
|
|
849
849
|
`installAdminEditorExtensions` は idempotent で、render 時に client component 内で呼ばれる。admin の `<TiptapEditor>` は毎回 render 時に登録済みリストを built-in extensions の末尾に spread する。
|
|
850
850
|
|
|
851
|
+
`update-ampless` が生成する `_editor-bootstrap.tsx` は extensions、markdown アダプター、html アダプターの3つの install 呼び出しを含む:
|
|
852
|
+
|
|
853
|
+
```tsx
|
|
854
|
+
// app/(admin)/admin/_editor-bootstrap.tsx (AUTO-GENERATED — 編集不可)
|
|
855
|
+
'use client'
|
|
856
|
+
// AUTO-GENERATED by `npm run update-ampless`. Do not edit ...
|
|
857
|
+
import { installAdminEditorExtensions, installAdminTiptapNodeMarkdown, installAdminTiptapNodeHtml } from '@ampless/admin/editor'
|
|
858
|
+
import * as __ampless_plugin_x_embed_editor from '@ampless/plugin-x-embed/editor'
|
|
859
|
+
import * as __ampless_plugin_youtube_editor from '@ampless/plugin-youtube/editor'
|
|
860
|
+
|
|
861
|
+
export function EditorBootstrap({ children }: { children: React.ReactNode }) {
|
|
862
|
+
installAdminEditorExtensions([
|
|
863
|
+
__ampless_plugin_x_embed_editor.editorExtension,
|
|
864
|
+
__ampless_plugin_youtube_editor.editorExtension,
|
|
865
|
+
])
|
|
866
|
+
installAdminTiptapNodeMarkdown([
|
|
867
|
+
__ampless_plugin_x_embed_editor.tiptapNodeToMarkdown ?? {},
|
|
868
|
+
__ampless_plugin_youtube_editor.tiptapNodeToMarkdown ?? {},
|
|
869
|
+
])
|
|
870
|
+
installAdminTiptapNodeHtml([
|
|
871
|
+
__ampless_plugin_x_embed_editor.tiptapNodeToHtml ?? {},
|
|
872
|
+
__ampless_plugin_youtube_editor.tiptapNodeToHtml ?? {},
|
|
873
|
+
])
|
|
874
|
+
return <>{children}</>
|
|
875
|
+
}
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
### フォーマット切り替えの可逆アダプター(`tiptapNodeToMarkdown` + `tiptapNodeToHtml`)
|
|
879
|
+
|
|
880
|
+
operator が admin UI でポストのフォーマットを切り替える場合(例: `tiptap → markdown`、`tiptap → html`)、admin はボディコンテンツを変換する必要がある。通常の prose node は tiptap の built-in レンダラーで処理されるが、**atom node**(`amplessYoutube` のような embed ブロック)は子要素を持たず、children が空のまま fallthrough し、embed が無音で消えてしまう。
|
|
881
|
+
|
|
882
|
+
2 つのアダプターで両方向を修正する:
|
|
883
|
+
|
|
884
|
+
| アダプター | 方向 | 出力 |
|
|
885
|
+
| --------------------- | --------------------------------- | ---- |
|
|
886
|
+
| `tiptapNodeToMarkdown`| `tiptap → markdown` | bare URL 行(例: `https://youtu.be/<id>`) |
|
|
887
|
+
| `tiptapNodeToHtml` | `tiptap → html`、`markdown → html`| 正規プレースホルダー div |
|
|
888
|
+
|
|
889
|
+
フォーマット切替で扱う 3 種類の正規 body 表現:
|
|
890
|
+
|
|
891
|
+
| フォーマット | 正規形 |
|
|
892
|
+
| ------------ | ------ |
|
|
893
|
+
| tiptap | `{ type: 'amplessYoutube', attrs: { videoId, start } }` Node |
|
|
894
|
+
| markdown | bare `https://youtu.be/<id>` URL 行 |
|
|
895
|
+
| html | `<div data-ampless-youtube data-video-id="<id>" …>…</div>` |
|
|
896
|
+
|
|
897
|
+
プレースホルダー div は **admin format-switch 相互運用専用**の正規 HTML 形式: `Node.renderHTML` が emit し、`Node.parseHTML` の `tag: 'div[data-ampless-*]'` rule が復元することで、admin での `tiptap ↔ markdown ↔ html` 切替が embed を保ったまま round-trip できる。
|
|
898
|
+
|
|
899
|
+
**`format: 'html'` の公開描画ではプレースホルダー展開を行わない。** 公開描画はフォーマット別に分岐: tiptap 投稿は React walker が `contentFields.tiptap` registry を参照(= `amplessYoutube` Node を実際の iframe に変換)、markdown 投稿は markdown walker が `contentFields.markdownUrl` を参照(= bare URL paragraph を実際の iframe に変換)、html 投稿は `htmlPassthroughBlock` で raw HTML をそのまま出力する。**プレースホルダー div を含む html-format 投稿は公開ページでリテラル div として表示される。** `publicHtmlForPost` は `beforeContent` / `afterContent` slot のみ提供する capability であり、body を変換しない。
|
|
900
|
+
|
|
901
|
+
embed を公開ページで実際に描画させたい場合は、投稿を `tiptap` または `markdown` 形式で保存する(= format-switch round-trip で embed Node / bare URL line に戻り、対応する公開 walker が iframe を emit する)。`html` 形式は **engineer が完全制御で書く raw HTML** として扱われる前提で、プレースホルダーは format-switch round-trip の artefact であって描画可能な embed reference ではない。`data-ampless-*` プレースホルダーを public html walker で iframe に展開する将来 capability は本セクション末尾の follow-up note を参照。
|
|
902
|
+
|
|
903
|
+
#### アダプターの契約
|
|
904
|
+
|
|
905
|
+
両アダプターは同じシグネチャを持つ:
|
|
906
|
+
|
|
907
|
+
```ts
|
|
908
|
+
(node: TiptapRenderNode) => string | null
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
**文字列**(空文字 `''` も含む)を返すと、その出力を使う。**`null`** を返すとデフォルトの switch へ fallthrough する(対応しない node や video id が欠損している場合などに使う)。
|
|
912
|
+
|
|
913
|
+
```ts
|
|
914
|
+
import type { TiptapNodeMarkdownAdapters, TiptapNodeHtmlAdapters } from 'ampless'
|
|
915
|
+
|
|
916
|
+
export const tiptapNodeToMarkdown: TiptapNodeMarkdownAdapters = {
|
|
917
|
+
amplessYoutube: (node) => {
|
|
918
|
+
const videoId = String(node.attrs?.videoId ?? '').trim()
|
|
919
|
+
if (!videoId) return null
|
|
920
|
+
return `https://youtu.be/${videoId}`
|
|
921
|
+
},
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
export const tiptapNodeToHtml: TiptapNodeHtmlAdapters = {
|
|
925
|
+
amplessYoutube: (node) => {
|
|
926
|
+
const videoId = String(node.attrs?.videoId ?? '').trim()
|
|
927
|
+
if (!videoId) return null
|
|
928
|
+
const attrs = placeholderAttrs(node.attrs ?? {})
|
|
929
|
+
return `<div ${attrsToHtmlString(attrs)}><span>YouTube: ${escapeAttr(videoId)}</span></div>`
|
|
930
|
+
},
|
|
931
|
+
}
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
#### 配線
|
|
935
|
+
|
|
936
|
+
`update-ampless` が各プラグインの `./editor` モジュールから `tiptapNodeToMarkdown` と `tiptapNodeToHtml` の named export を読み取り、両方の install に自動で配線する。**手動での配線は不要。** プラグインがいずれかのマップを export しない場合、生成ファイルの `?? {}` fallback が no-op になる。
|
|
937
|
+
|
|
938
|
+
#### `markdown → html` 2-hop
|
|
939
|
+
|
|
940
|
+
`markdown → html` の方向は `tiptapNodeToHtml` アダプターを 2-hop 経由で再利用する:
|
|
941
|
+
|
|
942
|
+
1. `markdownToHtml(body)` — marked が markdown を HTML に変換。bare URL 行は `<p><a href="URL">URL</a></p>` になる。
|
|
943
|
+
2. `generateJSON(html, extensions)` — tiptap が HTML を parse。プラグインの `Node.parseHTML` `tag: 'p'` rule が bare URL の paragraph を embed Node に昇格する。
|
|
944
|
+
3. `tiptapToHtml(doc, { nodeAdapters })` — html アダプターが embed Node をプレースホルダー div に serialize する。
|
|
945
|
+
|
|
946
|
+
プラグインは `tiptap → html` アダプターを 1 つ export するだけでよく、`markdown → html` の方向は tiptap の parse rule を通して自動的に再利用される。**重複ロジックは不要。**
|
|
947
|
+
|
|
948
|
+
#### Follow-up: public html walker(未実装)
|
|
949
|
+
|
|
950
|
+
`format: 'html'` 投稿で、保存されたプレースホルダー div を公開ページで実 iframe として描画するためには、将来の capability で保存された html body を render 時に walk し、`data-ampless-*` flag を見て登録済プラグインの React renderer(= tiptap 投稿で `contentFields.tiptap` が使うのと同じ renderer)に置換する仕組みが必要。スケッチ:
|
|
951
|
+
|
|
952
|
+
- 新 plugin capability `contentFields.html`: プレースホルダー flag attribute(例: `data-ampless-youtube`)を key にし、parse 済 div の attribute set から React node を返す。
|
|
953
|
+
- Runtime: `renderBody` の `format: 'html'` ブランチが body を parse、`[data-ampless-*]` div を walk して登録済 renderer の output に置換、残りは raw HTML として emit。
|
|
954
|
+
- Runtime 側の server-side HTML parser(現状なし、`parse5` / `htmlparser2` 等の小さなパーサーを選定する必要あり)。
|
|
955
|
+
|
|
956
|
+
本 PR の scope 外(別 proposal として track)。当面は html-format 投稿のプレースホルダーは raw HTML として扱われ、公開ページで iframe 表示したい著者は `tiptap` か `markdown` で保存する。
|
|
957
|
+
|
|
851
958
|
### markdown → tiptap の復元
|
|
852
959
|
|
|
853
960
|
editor Node が markdown へ bare URL line として serialise される場合、逆方向の復元は paste rule ではなく `Node.parseHTML()` で扱う必要がある。admin の `markdown → tiptap` format switch は、まず markdown を HTML に変換する。GFM autolink により bare URL line は `<p><a href="https://...">https://...</a></p>` になり、その HTML を tiptap が document として parse する。paste rule は user paste / typing event 用なので、この HTML parse 経路では発火しない。
|
|
@@ -1104,6 +1104,163 @@ export default createAdminLayout(admin, { editorBootstrap: EditorBootstrap })
|
|
|
1104
1104
|
inside a client component. The admin's `<TiptapEditor>` spreads the
|
|
1105
1105
|
registered list onto its built-in extensions on every render.
|
|
1106
1106
|
|
|
1107
|
+
The `_editor-bootstrap.tsx` generated by `update-ampless` wires three
|
|
1108
|
+
install calls — extensions, markdown adapters, and html adapters:
|
|
1109
|
+
|
|
1110
|
+
```tsx
|
|
1111
|
+
// app/(admin)/admin/_editor-bootstrap.tsx (AUTO-GENERATED — do not edit)
|
|
1112
|
+
'use client'
|
|
1113
|
+
// AUTO-GENERATED by `npm run update-ampless`. Do not edit ...
|
|
1114
|
+
import { installAdminEditorExtensions, installAdminTiptapNodeMarkdown, installAdminTiptapNodeHtml } from '@ampless/admin/editor'
|
|
1115
|
+
import * as __ampless_plugin_x_embed_editor from '@ampless/plugin-x-embed/editor'
|
|
1116
|
+
import * as __ampless_plugin_youtube_editor from '@ampless/plugin-youtube/editor'
|
|
1117
|
+
|
|
1118
|
+
export function EditorBootstrap({ children }: { children: React.ReactNode }) {
|
|
1119
|
+
installAdminEditorExtensions([
|
|
1120
|
+
__ampless_plugin_x_embed_editor.editorExtension,
|
|
1121
|
+
__ampless_plugin_youtube_editor.editorExtension,
|
|
1122
|
+
])
|
|
1123
|
+
installAdminTiptapNodeMarkdown([
|
|
1124
|
+
__ampless_plugin_x_embed_editor.tiptapNodeToMarkdown ?? {},
|
|
1125
|
+
__ampless_plugin_youtube_editor.tiptapNodeToMarkdown ?? {},
|
|
1126
|
+
])
|
|
1127
|
+
installAdminTiptapNodeHtml([
|
|
1128
|
+
__ampless_plugin_x_embed_editor.tiptapNodeToHtml ?? {},
|
|
1129
|
+
__ampless_plugin_youtube_editor.tiptapNodeToHtml ?? {},
|
|
1130
|
+
])
|
|
1131
|
+
return <>{children}</>
|
|
1132
|
+
}
|
|
1133
|
+
```
|
|
1134
|
+
|
|
1135
|
+
### Lossless format-switch adapters (`tiptapNodeToMarkdown` + `tiptapNodeToHtml`)
|
|
1136
|
+
|
|
1137
|
+
When the operator switches the post format in the admin UI (e.g. `tiptap →
|
|
1138
|
+
markdown` or `tiptap → html`), the admin must convert the body content. For
|
|
1139
|
+
standard prose nodes tiptap's built-in renderers handle this, but **atom
|
|
1140
|
+
nodes** (embed blocks like `amplessYoutube`) have no children — they fall
|
|
1141
|
+
through with empty output, silently dropping the embed.
|
|
1142
|
+
|
|
1143
|
+
Two adapters fix both directions:
|
|
1144
|
+
|
|
1145
|
+
| Adapter | Direction | Output |
|
|
1146
|
+
| --------------------- | --------------------------------- | ------ |
|
|
1147
|
+
| `tiptapNodeToMarkdown`| `tiptap → markdown` | bare URL line (e.g. `https://youtu.be/<id>`) |
|
|
1148
|
+
| `tiptapNodeToHtml` | `tiptap → html`, `markdown → html`| canonical placeholder div |
|
|
1149
|
+
|
|
1150
|
+
The three canonical body representations across format-switch are:
|
|
1151
|
+
|
|
1152
|
+
| Format | Canonical form |
|
|
1153
|
+
| -------- | -------------- |
|
|
1154
|
+
| tiptap | `{ type: 'amplessYoutube', attrs: { videoId, start } }` Node |
|
|
1155
|
+
| markdown | bare `https://youtu.be/<id>` URL line |
|
|
1156
|
+
| html | `<div data-ampless-youtube data-video-id="<id>" …>…</div>` |
|
|
1157
|
+
|
|
1158
|
+
The placeholder div is the canonical HTML form for **admin format-switch
|
|
1159
|
+
interop only**: it is what `Node.renderHTML` emits, and what
|
|
1160
|
+
`Node.parseHTML`'s `tag: 'div[data-ampless-*]'` rule restores from, so
|
|
1161
|
+
that switching `tiptap ↔ markdown ↔ html` in the admin preserves embeds
|
|
1162
|
+
losslessly.
|
|
1163
|
+
|
|
1164
|
+
**Public render of `format: 'html'` posts does NOT expand the
|
|
1165
|
+
placeholder.** Public render paths are format-specific: tiptap posts go
|
|
1166
|
+
through the React walker that consults the `contentFields.tiptap`
|
|
1167
|
+
registry (= real iframe for `amplessYoutube` Nodes); markdown posts go
|
|
1168
|
+
through the markdown walker that consults `contentFields.markdownUrl`
|
|
1169
|
+
(= real iframe for bare URL paragraphs); html posts pass through as raw
|
|
1170
|
+
HTML (`htmlPassthroughBlock`). For an html-format post that contains a
|
|
1171
|
+
placeholder div, the public page shows the literal placeholder, not an
|
|
1172
|
+
iframe — `publicHtmlForPost` only emits `beforeContent` / `afterContent`
|
|
1173
|
+
slots and does not transform the body.
|
|
1174
|
+
|
|
1175
|
+
If you want the embed to render publicly, save the post as `tiptap` or
|
|
1176
|
+
`markdown` (= the format-switch round-trip restores the embed Node /
|
|
1177
|
+
bare URL line, then the matching public walker emits the iframe). The
|
|
1178
|
+
`html` format is treated as **raw HTML written by an engineer who wants
|
|
1179
|
+
full control** — the placeholder is a format-switch round-trip artefact,
|
|
1180
|
+
not a renderable embed reference. A future capability could add a public
|
|
1181
|
+
html walker that expands `data-ampless-*` placeholders to iframes; see
|
|
1182
|
+
the follow-up note at the end of this section.
|
|
1183
|
+
|
|
1184
|
+
#### Adapter contract
|
|
1185
|
+
|
|
1186
|
+
Both adapters have the same signature:
|
|
1187
|
+
|
|
1188
|
+
```ts
|
|
1189
|
+
(node: TiptapRenderNode) => string | null
|
|
1190
|
+
```
|
|
1191
|
+
|
|
1192
|
+
Return a **string** (including empty string `''`) to use your output.
|
|
1193
|
+
Return **`null`** to fall through to the default switch (useful for nodes
|
|
1194
|
+
you don't handle or for degenerate inputs like a missing video id).
|
|
1195
|
+
|
|
1196
|
+
```ts
|
|
1197
|
+
// packages/plugin-youtube/src/editor.tsx
|
|
1198
|
+
import type { TiptapNodeMarkdownAdapters, TiptapNodeHtmlAdapters } from 'ampless'
|
|
1199
|
+
|
|
1200
|
+
export const tiptapNodeToMarkdown: TiptapNodeMarkdownAdapters = {
|
|
1201
|
+
amplessYoutube: (node) => {
|
|
1202
|
+
const videoId = String(node.attrs?.videoId ?? '').trim()
|
|
1203
|
+
if (!videoId) return null // fall through
|
|
1204
|
+
return `https://youtu.be/${videoId}`
|
|
1205
|
+
},
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
export const tiptapNodeToHtml: TiptapNodeHtmlAdapters = {
|
|
1209
|
+
amplessYoutube: (node) => {
|
|
1210
|
+
const videoId = String(node.attrs?.videoId ?? '').trim()
|
|
1211
|
+
if (!videoId) return null // fall through
|
|
1212
|
+
const attrs = placeholderAttrs(node.attrs ?? {})
|
|
1213
|
+
return `<div ${attrsToHtmlString(attrs)}><span>YouTube: ${escapeAttr(videoId)}</span></div>`
|
|
1214
|
+
},
|
|
1215
|
+
}
|
|
1216
|
+
```
|
|
1217
|
+
|
|
1218
|
+
#### Wiring
|
|
1219
|
+
|
|
1220
|
+
`update-ampless` reads the `tiptapNodeToMarkdown` and `tiptapNodeToHtml`
|
|
1221
|
+
named exports from each plugin's `./editor` module (via namespace import `*
|
|
1222
|
+
as`) and wires them into both installs automatically — **no hand-wiring
|
|
1223
|
+
required**. If your plugin does not export one of the maps, the `?? {}`
|
|
1224
|
+
fallback in the generated file is a no-op.
|
|
1225
|
+
|
|
1226
|
+
#### `markdown → html` 2-hop
|
|
1227
|
+
|
|
1228
|
+
The `markdown → html` direction reuses the `tiptapNodeToHtml` adapter via
|
|
1229
|
+
a 2-hop:
|
|
1230
|
+
|
|
1231
|
+
1. `markdownToHtml(body)` — marked converts the markdown body to HTML. Bare
|
|
1232
|
+
URL lines become `<p><a href="URL">URL</a></p>`.
|
|
1233
|
+
2. `generateJSON(html, extensions)` — tiptap parses the HTML. Your plugin's
|
|
1234
|
+
`Node.parseHTML` `tag: 'p'` rule promotes the bare-URL paragraph to the
|
|
1235
|
+
embed Node.
|
|
1236
|
+
3. `tiptapToHtml(doc, { nodeAdapters })` — the html adapter serialises the
|
|
1237
|
+
embed Node to the placeholder div.
|
|
1238
|
+
|
|
1239
|
+
This means your plugin only needs to export the `tiptap → html` adapter once;
|
|
1240
|
+
the `markdown → html` direction reuses it automatically through tiptap's parse
|
|
1241
|
+
rules. **No duplicate logic is needed.**
|
|
1242
|
+
|
|
1243
|
+
#### Follow-up: public html walker (not implemented)
|
|
1244
|
+
|
|
1245
|
+
To make `format: 'html'` posts render placeholder divs as real iframes
|
|
1246
|
+
on the public page, a future capability would walk the saved html body
|
|
1247
|
+
on render, look up the `data-ampless-*` flag, and replace the placeholder
|
|
1248
|
+
with the registered plugin's React renderer (same renderer that
|
|
1249
|
+
`contentFields.tiptap` already uses for tiptap posts). Sketch:
|
|
1250
|
+
|
|
1251
|
+
- New plugin capability `contentFields.html` keyed on the placeholder
|
|
1252
|
+
flag attribute (e.g. `data-ampless-youtube`), returning a React node
|
|
1253
|
+
from the parsed div's attribute set.
|
|
1254
|
+
- Runtime: `renderBody` for `format: 'html'` parses the body, walks
|
|
1255
|
+
`[data-ampless-*]` divs, replaces each with the registered renderer's
|
|
1256
|
+
output, and emits the rest as raw HTML.
|
|
1257
|
+
- Server-side HTML parsing in runtime (currently absent — would need
|
|
1258
|
+
to pick a small parser like `parse5` or `htmlparser2`).
|
|
1259
|
+
|
|
1260
|
+
Out of scope for the current PR (tracked as a separate proposal). For
|
|
1261
|
+
now, html-format posts treat placeholders as raw HTML and authors who
|
|
1262
|
+
want public iframes should save as `tiptap` or `markdown`.
|
|
1263
|
+
|
|
1107
1264
|
### Markdown to tiptap restoration
|
|
1108
1265
|
|
|
1109
1266
|
If an editor Node serializes to markdown as a bare URL line, the reverse
|
|
@@ -26,21 +26,21 @@
|
|
|
26
26
|
"@tiptap/pm": "^3.23.6",
|
|
27
27
|
"@tiptap/react": "^3.23.6",
|
|
28
28
|
"@tiptap/starter-kit": "^3.23.6",
|
|
29
|
-
"@ampless/plugin-analytics-ga4": "^0.2.0-alpha.
|
|
30
|
-
"@ampless/plugin-cookie-consent": "^0.1.0-alpha.
|
|
31
|
-
"@ampless/plugin-gtm": "^0.2.0-alpha.
|
|
32
|
-
"@ampless/plugin-og-image": "^0.2.0-alpha.
|
|
33
|
-
"@ampless/plugin-plausible": "^0.2.0-alpha.
|
|
34
|
-
"@ampless/plugin-reading-time": "^0.1.0-alpha.
|
|
35
|
-
"@ampless/plugin-rss": "^0.2.0-alpha.
|
|
36
|
-
"@ampless/plugin-schema-jsonld": "^0.1.1-alpha.
|
|
37
|
-
"@ampless/plugin-seo": "^0.2.0-alpha.
|
|
38
|
-
"@ampless/plugin-webhook": "^0.2.0-alpha.
|
|
39
|
-
"@ampless/admin": "^1.0.0-alpha.
|
|
40
|
-
"@ampless/backend": "^1.0.0-alpha.
|
|
41
|
-
"@ampless/runtime": "^1.0.0-alpha.
|
|
29
|
+
"@ampless/plugin-analytics-ga4": "^0.2.0-alpha.31",
|
|
30
|
+
"@ampless/plugin-cookie-consent": "^0.1.0-alpha.22",
|
|
31
|
+
"@ampless/plugin-gtm": "^0.2.0-alpha.30",
|
|
32
|
+
"@ampless/plugin-og-image": "^0.2.0-alpha.47",
|
|
33
|
+
"@ampless/plugin-plausible": "^0.2.0-alpha.30",
|
|
34
|
+
"@ampless/plugin-reading-time": "^0.1.0-alpha.20",
|
|
35
|
+
"@ampless/plugin-rss": "^0.2.0-alpha.47",
|
|
36
|
+
"@ampless/plugin-schema-jsonld": "^0.1.1-alpha.26",
|
|
37
|
+
"@ampless/plugin-seo": "^0.2.0-alpha.47",
|
|
38
|
+
"@ampless/plugin-webhook": "^0.2.0-alpha.48",
|
|
39
|
+
"@ampless/admin": "^1.0.0-alpha.80",
|
|
40
|
+
"@ampless/backend": "^1.0.0-alpha.69",
|
|
41
|
+
"@ampless/runtime": "^1.0.0-alpha.56",
|
|
42
42
|
"@digital-go-jp/tailwind-theme-plugin": "^0.3.4",
|
|
43
|
-
"ampless": "^1.0.0-alpha.
|
|
43
|
+
"ampless": "^1.0.0-alpha.47",
|
|
44
44
|
"aws-amplify": "^6.17.0",
|
|
45
45
|
"class-variance-authority": "^0.7.1",
|
|
46
46
|
"clsx": "^2.1.1",
|