ampless 1.0.0-alpha.43 → 1.0.0-alpha.45

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.d.ts CHANGED
@@ -862,6 +862,16 @@ interface PluginPackageManifest {
862
862
  description?: LocalizedString;
863
863
  /** Optional docs / repo URL. */
864
864
  homepage?: string;
865
+ /**
866
+ * Subpath (relative to the plugin's package.json) of the editor
867
+ * module to auto-wire. `update-ampless` reads this to regenerate
868
+ * `app/(admin)/admin/_editor-bootstrap.tsx`. Absent = no editor
869
+ * extension (= plugin doesn't ship a tiptap Node).
870
+ *
871
+ * The referenced module must export `editorExtension` as a named
872
+ * symbol of type tiptap Extension.
873
+ */
874
+ editorExports?: string;
865
875
  }
866
876
  /**
867
877
  * Secret field types for `settings.secret`. Restricted to `text` /
@@ -989,6 +999,21 @@ interface TiptapRenderNode {
989
999
  }[];
990
1000
  text?: string;
991
1001
  }
1002
+ /**
1003
+ * Adapter that converts a single tiptap node back to its markdown form.
1004
+ * Plugins that ship an embed node (e.g. amplessYoutube → bare YouTube URL)
1005
+ * export a map from nodeType to adapter from their `./editor` module
1006
+ * (named export `tiptapNodeToMarkdown`); `update-ampless` wires the map
1007
+ * into `installAdminTiptapNodeMarkdown` so the admin's
1008
+ * `tiptap → markdown` format switch can losslessly serialise the embed
1009
+ * (the round-trip back to tiptap goes through markdown's bare-URL paste
1010
+ * rule + `extractSingleUrl` in the runtime).
1011
+ *
1012
+ * Return `null` (or simply omit the nodeType from the map) to fall
1013
+ * through to the runtime's default markdown switch.
1014
+ */
1015
+ type TiptapNodeToMarkdown = (node: TiptapRenderNode) => string | null;
1016
+ type TiptapNodeMarkdownAdapters = Readonly<Record<string, TiptapNodeToMarkdown>>;
992
1017
  /**
993
1018
  * Match object passed to a `contentFields` `markdown-url` renderer. The
994
1019
  * runtime walks the markdown body via `marked.lexer`, tests the trimmed
@@ -1876,4 +1901,4 @@ declare function pickDefaultEntrypoint(files: readonly {
1876
1901
 
1877
1902
  declare const VERSION = "0.0.1";
1878
1903
 
1879
- export { type AmplessEvent, type AmplessPlugin, type AuthContext, type BundleExtractResult, type CacheConfig, type CacheStrategy, type Config, type ContentEventPayload, type ContentEventType, type ContentFieldRenderer, type ContentFormat, type ContentTypeDefinition, type CreatePostInput, DEFAULT_ENTRYPOINT, type DateFormat, type EventPayloadOf, type EventType, type ExtractedFile, type FieldDefinition, type FieldType, type HistoryConfig, type ImageDisplay, type KvItem, type KvStore, type LinkListItem, type ListOptions, type ListPostHistoryOptions, type LocalizedString, MAX_BUNDLE_BYTES, type MarkdownEmbedMatch, type Media, type MediaEventPayload, type MediaEventType, type MediaMetadata, type MediaProcessingDefaults, type OgImageConfig, type OgImageFont, type OgImageRenderContext, PLUGIN_KEY_PATTERN, type Page, type PluginBooleanField, type PluginCapability, type PluginCodeField, type PluginEventHandler, type PluginHookResult, type PluginJsonField, type PluginMetadata, type PluginNumberField, type PluginPackageManifest, type PluginPublicRenderContext, type PluginRepeatableField, type PluginRepeatableSubField, type PluginRuntimeContext, type PluginSecretField, type PluginSelectField, type PluginSettingField, type PluginSettingsManifest, type PluginTextField, type PluginTextareaField, type PluginUninstallContext, type PluginUrlField, type Post, type PostIndexEventPayload, type PostIndexEventType, type PostMetadata, type PostRevision, type PostRevisionConnection, type PostStatus, type PostsProvider, type PublicBodyDescriptor, type PublicHeadDescriptor, type PublicPostBodyDescriptor, type PublicPostHtmlDescriptor, type PublicPostHtmlPosition, type PublicPostScriptDescriptor, type Role, SITE_CONFIG_PK, type ScriptStrategy, type SiteSettingsEventPayload, type SiteSettingsEventType, type StaticPostBody, type StaticPostFileMeta, type StreamEventName, TEXT_EXTENSIONS, type ThemeColorField, type ThemeField, type ThemeFieldType, type ThemeFontFamilyField, type ThemeImageField, type ThemeLengthField, type ThemeLinkListField, type ThemeManifest, type ThemeModule, type ThemeRouteContext, type ThemeSelectField, type ThemeTextField, type TiptapRenderNode, type TrustLevel, type TrustedPluginRuntimeContext, VERSION, type ValidationIssue, bundlePrefix, createPost, decodeAwsJson, defineConfig, definePlugin, defineSchema, defineTheme, defineThemeModule, deletePost, deleteSiteSetting, detectContentEvents, encodeAwsJson, escapeXml, extractFirstImageUrl, findAbsolutePathRefs, flattenSettings, formatColorPair, formatDate, formatPublicAssetUrl, getKvStore, getPost, getPostById, getSiteSetting, hasKvStore, hasPostsProvider, isTagListUrl, isValidPluginKey, listPostHistory, listPosts, listSiteSettings, mimeTypeFor, parseColorPair, parseLinkList, pickDefaultEntrypoint, resolveLocalized, resolvePluginSettings, resolveThemeValues, setKvStore, setPostsProvider, setSiteSetting, stringifyLinkList, stripCommonPrefix, themeSettingKey, unflattenSettings, updatePost, validateBundle, validateBundlePath, validatePluginSettingValue, validatePublicAssetKey, validateThemeValue };
1904
+ export { type AmplessEvent, type AmplessPlugin, type AuthContext, type BundleExtractResult, type CacheConfig, type CacheStrategy, type Config, type ContentEventPayload, type ContentEventType, type ContentFieldRenderer, type ContentFormat, type ContentTypeDefinition, type CreatePostInput, DEFAULT_ENTRYPOINT, type DateFormat, type EventPayloadOf, type EventType, type ExtractedFile, type FieldDefinition, type FieldType, type HistoryConfig, type ImageDisplay, type KvItem, type KvStore, type LinkListItem, type ListOptions, type ListPostHistoryOptions, type LocalizedString, MAX_BUNDLE_BYTES, type MarkdownEmbedMatch, type Media, type MediaEventPayload, type MediaEventType, type MediaMetadata, type MediaProcessingDefaults, type OgImageConfig, type OgImageFont, type OgImageRenderContext, PLUGIN_KEY_PATTERN, type Page, type PluginBooleanField, type PluginCapability, type PluginCodeField, type PluginEventHandler, type PluginHookResult, type PluginJsonField, type PluginMetadata, type PluginNumberField, type PluginPackageManifest, type PluginPublicRenderContext, type PluginRepeatableField, type PluginRepeatableSubField, type PluginRuntimeContext, type PluginSecretField, type PluginSelectField, type PluginSettingField, type PluginSettingsManifest, type PluginTextField, type PluginTextareaField, type PluginUninstallContext, type PluginUrlField, type Post, type PostIndexEventPayload, type PostIndexEventType, type PostMetadata, type PostRevision, type PostRevisionConnection, type PostStatus, type PostsProvider, type PublicBodyDescriptor, type PublicHeadDescriptor, type PublicPostBodyDescriptor, type PublicPostHtmlDescriptor, type PublicPostHtmlPosition, type PublicPostScriptDescriptor, type Role, SITE_CONFIG_PK, type ScriptStrategy, type SiteSettingsEventPayload, type SiteSettingsEventType, type StaticPostBody, type StaticPostFileMeta, type StreamEventName, TEXT_EXTENSIONS, type ThemeColorField, type ThemeField, type ThemeFieldType, type ThemeFontFamilyField, type ThemeImageField, type ThemeLengthField, type ThemeLinkListField, type ThemeManifest, type ThemeModule, type ThemeRouteContext, type ThemeSelectField, type ThemeTextField, type TiptapNodeMarkdownAdapters, type TiptapNodeToMarkdown, type TiptapRenderNode, type TrustLevel, type TrustedPluginRuntimeContext, VERSION, type ValidationIssue, bundlePrefix, createPost, decodeAwsJson, defineConfig, definePlugin, defineSchema, defineTheme, defineThemeModule, deletePost, deleteSiteSetting, detectContentEvents, encodeAwsJson, escapeXml, extractFirstImageUrl, findAbsolutePathRefs, flattenSettings, formatColorPair, formatDate, formatPublicAssetUrl, getKvStore, getPost, getPostById, getSiteSetting, hasKvStore, hasPostsProvider, isTagListUrl, isValidPluginKey, listPostHistory, listPosts, listSiteSettings, mimeTypeFor, parseColorPair, parseLinkList, pickDefaultEntrypoint, resolveLocalized, resolvePluginSettings, resolveThemeValues, setKvStore, setPostsProvider, setSiteSetting, stringifyLinkList, stripCommonPrefix, themeSettingKey, unflattenSettings, updatePost, validateBundle, validateBundlePath, validatePluginSettingValue, validatePublicAssetKey, validateThemeValue };
@@ -777,25 +777,67 @@ runtime は `src` のホスト allowlist を強制しない。CSP はサイト
777
777
 
778
778
  ## 6d. Admin エディタ拡張の配線 (Phase 7)
779
779
 
780
- admin エディタに tiptap Node 拡張を提供するプラグインは、別途 `./editor` subpath の client-side エントリを出荷する。テンプレート側で `_editor-bootstrap.tsx` から配線する:
780
+ admin エディタに tiptap Node 拡張を提供するプラグインは、別途 `./editor` subpath の client-side エントリを出荷する。
781
+ `app/(admin)/admin/_editor-bootstrap.tsx` は `npm run update-ampless` によって**自動生成**される — 手動で編集してはならない。
782
+
783
+ ### プラグイン著者向け
784
+
785
+ `package.json#amplessPlugin` に `editorExports` を宣言する:
786
+
787
+ ```jsonc
788
+ // packages/plugin-youtube/package.json
789
+ "amplessPlugin": {
790
+ "apiVersion": 1,
791
+ "name": "youtube",
792
+ "trustLevel": "trusted",
793
+ "capabilities": ["contentFields"],
794
+ "editorExports": "./editor" // ← editor module のある subpath
795
+ }
796
+ ```
797
+
798
+ その subpath から `editorExtension` を named export する:
799
+
800
+ ```ts
801
+ // packages/plugin-youtube/src/editor.tsx
802
+ export const editorExtension = AmplessYoutubeNode // tiptap Node または Extension
803
+ ```
804
+
805
+ `package.json#exports` にも同 subpath を宣言すること(codegen がこれを検証する — 未宣言の場合は warning を出してそのプラグインをスキップする):
806
+
807
+ ```jsonc
808
+ "exports": {
809
+ ".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" },
810
+ "./editor": { "import": "./dist/editor.js", "types": "./dist/editor.d.ts" }
811
+ }
812
+ ```
813
+
814
+ ### プラグインユーザー(サイトエンジニア)向け
815
+
816
+ 1. `npm i @ampless/plugin-youtube@alpha` — plugin を dependency として追加する。
817
+ 2. `cms.config.ts` に登録してサーバーサイド renderer を有効化する。
818
+ 3. `npm run update-ampless` — インストール済み plugin の manifest から `_editor-bootstrap.tsx` を自動再生成する。
819
+
820
+ 生成されたファイルはリポジトリにコミットされ、以下のような内容になる:
781
821
 
782
822
  ```tsx
783
- // templates/_shared/app/(admin)/admin/_editor-bootstrap.tsx
823
+ // app/(admin)/admin/_editor-bootstrap.tsx (AUTO-GENERATED — 編集不可)
784
824
  'use client'
825
+ // AUTO-GENERATED by `npm run update-ampless`. Do not edit — your changes
826
+ // will be overwritten on the next run.
785
827
  import { installAdminEditorExtensions } from '@ampless/admin/editor'
786
- import { youtubeEditor } from '@ampless/plugin-youtube/editor'
787
- import { tweetEditor } from '@ampless/plugin-x-embed/editor'
828
+ import { editorExtension as __ampless_plugin_x_embed_editor } from '@ampless/plugin-x-embed/editor'
829
+ import { editorExtension as __ampless_plugin_youtube_editor } from '@ampless/plugin-youtube/editor'
788
830
 
789
831
  export function EditorBootstrap({ children }: { children: React.ReactNode }) {
790
832
  installAdminEditorExtensions([
791
- youtubeEditor.extension,
792
- tweetEditor.extension,
833
+ __ampless_plugin_x_embed_editor,
834
+ __ampless_plugin_youtube_editor,
793
835
  ])
794
836
  return <>{children}</>
795
837
  }
796
838
  ```
797
839
 
798
- その上で layout に渡す:
840
+ このファイルは admin layout に渡される(テンプレートに既に組み込まれているので追加の作業は不要):
799
841
 
800
842
  ```tsx
801
843
  // templates/_shared/app/(admin)/admin/layout.tsx
@@ -806,9 +848,16 @@ export default createAdminLayout(admin, { editorBootstrap: EditorBootstrap })
806
848
 
807
849
  `installAdminEditorExtensions` は idempotent で、render 時に client component 内で呼ばれる。admin の `<TiptapEditor>` は毎回 render 時に登録済みリストを built-in extensions の末尾に spread する。
808
850
 
851
+ ### active source と完全無効化
852
+
853
+ **エディタ配線の active source は `package.json#dependencies`**(= `node_modules`)であり、`cms.config.ts` ではない。
854
+
855
+ - plugin を `cms.config.ts` から外しても `package.json` に dep が残っていれば、editor の paste rule は**有効のまま**になる。editor は tiptap document にそのノード型を挿入できるが、公開 renderer はレンダリングしない(不整合状態 — 避けること)。
856
+ - 完全に無効化するには: `cms.config.ts` から削除 **かつ** `npm uninstall @ampless/plugin-...` を実行し、`npm run update-ampless` で bootstrap ファイルを再生成する。
857
+
809
858
  ### エディタプレビューのパイプライン
810
859
 
811
- admin の edit / new post フォームは preview ペインを `<iframe sandbox="allow-scripts">` で表示する。`srcDoc` はテンプレート側 preview Route Handler が返す HTML。テンプレート scaffold は handler を `app/(admin)/admin/preview/route.tsx` に同梱する:
860
+ admin の edit / new post フォームは preview ペインを `<iframe sandbox="allow-scripts allow-same-origin">` で表示する。`srcDoc` はテンプレート側 preview Route Handler が返す HTML。テンプレート scaffold は handler を `app/(admin)/admin/preview/route.tsx` に同梱する:
812
861
 
813
862
  ```tsx
814
863
  // templates/_shared/app/(admin)/admin/preview/route.tsx
@@ -862,7 +911,9 @@ export default createEditPostPage(admin, { previewEndpoint: '/cms/admin/preview'
862
911
 
863
912
  Server Action ではなく Route Handler を採用した理由: `'use server'` モジュール内部で `react-dom/server` 由来の rendering を行うと、Next.js 15+ が edit-post page の compile に失敗する。build 時に Client Component から Server Action モジュール経由で import graph を辿るため、その経路上で `react-dom/server` に到達した時点で「You're importing a component that imports react-dom/server」チェックが発火する。Route Handler に切り出すことで rendering を import graph から完全に切り離せる — `<PostForm>` は plain な HTTP endpoint を fetch するだけで、bundler は form から handler 側へ踏み込まない。さらに handler 自身が `admin.isEditor()` を明示的にチェックすることで、将来 `(admin)` route-group gate が誤設定された場合の安全側のフェールセーフになる。`react-dom/server` の import 自体を dynamic にしているのは Next.js 16 の Turbopack が、Route Handler を含む app router build 経路で reach できる top-level の `react-dom/server` static import を一律で flag するため。request 時に解決することで build-time import-graph walker から外しつつ、runtime では同じ Node.js subpath からロードする。
864
913
 
865
- iframe `sandbox="allow-scripts"` は `allow-same-origin` を含まないので、preview の中身は opaque origin で動作する → widget script は admin の DOM に触れない。トレードオフ: widget が自身の origin storage にアクセスできない場合に正しく動かない可能性がある。Phase 7 時点の dogfood では YouTube iframe / x.com widgets.js とも opaque origin で動作することを確認済み。将来 non-opaque origin が必要な widget が出てきた場合、escape hatch は別 subdomain preview route + 適切な CSP sandbox flag を緩めるのは取らない。
914
+ **Preview iframe sandbox — v1 trust boundary 拡張:** iframe は `sandbox="allow-scripts allow-same-origin"` を使う。`srcDoc` とともに使用すると iframe は admin の origin を継承し、サードパーティ embed widget(YouTube SDK、x.com `widgets.js`)が動作できるようになる opaque-origin(`allow-scripts` のみ)の iframe では動作を拒否する(非 HttpOnly storage / cache へのアクセスと real-origin requests が必要なため)。同時に same-origin により preview スクリプトは admin auth state / HttpOnly storage / DOM へのアクセスと authenticated same-origin XHR / fetch の発行が可能になる。
915
+
916
+ これは単なる sandbox 緩和ではなく、**v1 の明示的な設計判断**です: **ampless v1 は admin preview content / plugin script を全部 trusted とみなす**。エンジニアは npm install 前に plugin を審査するし(カスタマイズベース CMS モデル)、body content はこのサイトの trusted editor が作成する。`<PostHistoryPanel>` では別の editor が作成した過去 revision(revision author ≠ preview viewer)をプレビューするケースも通常発生するが、v1 ではそれも明示的に trust ring 内と位置づける。より安全な代替案(別 origin preview route + CSP / COEP / COOP)は v2.0+ でリアルなプラグインマーケットプレイスが必要になった場合に再検討する。
866
917
 
867
918
  ---
868
919
 
@@ -1026,26 +1026,72 @@ middleware. This is documented in each plugin's README.
1026
1026
  ## 6d. Admin editor extension wiring (Phase 7)
1027
1027
 
1028
1028
  Plugins that contribute tiptap Node extensions to the admin editor
1029
- ship a separate client-side entry under the `./editor` subpath. The
1030
- template wires it up in `_editor-bootstrap.tsx`:
1029
+ ship a separate client-side entry under the `./editor` subpath.
1030
+ `app/(admin)/admin/_editor-bootstrap.tsx` is **auto-generated** by
1031
+ `npm run update-ampless` — you should not edit it by hand.
1032
+
1033
+ ### For plugin authors
1034
+
1035
+ Declare `editorExports` in `package.json#amplessPlugin`:
1036
+
1037
+ ```jsonc
1038
+ // packages/plugin-youtube/package.json
1039
+ "amplessPlugin": {
1040
+ "apiVersion": 1,
1041
+ "name": "youtube",
1042
+ "trustLevel": "trusted",
1043
+ "capabilities": ["contentFields"],
1044
+ "editorExports": "./editor" // ← subpath where the editor module lives
1045
+ }
1046
+ ```
1047
+
1048
+ Export `editorExtension` as a named symbol from that subpath:
1049
+
1050
+ ```ts
1051
+ // packages/plugin-youtube/src/editor.tsx
1052
+ export const editorExtension = AmplessYoutubeNode // tiptap Node or Extension
1053
+ ```
1054
+
1055
+ The subpath must be declared in `package.json#exports` as well (the
1056
+ codegen validates this — a missing `exports` entry triggers a warning
1057
+ and the plugin is skipped):
1058
+
1059
+ ```jsonc
1060
+ "exports": {
1061
+ ".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" },
1062
+ "./editor": { "import": "./dist/editor.js", "types": "./dist/editor.d.ts" }
1063
+ }
1064
+ ```
1065
+
1066
+ ### For plugin users (site engineers)
1067
+
1068
+ 1. `npm i @ampless/plugin-youtube@alpha` — add the plugin as a dependency.
1069
+ 2. Register it in `cms.config.ts` for the server-side renderer.
1070
+ 3. `npm run update-ampless` — regenerates `_editor-bootstrap.tsx`
1071
+ automatically from the installed plugin manifests.
1072
+
1073
+ The generated file is committed to your repo and looks like:
1031
1074
 
1032
1075
  ```tsx
1033
- // templates/_shared/app/(admin)/admin/_editor-bootstrap.tsx
1076
+ // app/(admin)/admin/_editor-bootstrap.tsx (AUTO-GENERATED — do not edit)
1034
1077
  'use client'
1078
+ // AUTO-GENERATED by `npm run update-ampless`. Do not edit — your changes
1079
+ // will be overwritten on the next run.
1035
1080
  import { installAdminEditorExtensions } from '@ampless/admin/editor'
1036
- import { youtubeEditor } from '@ampless/plugin-youtube/editor'
1037
- import { tweetEditor } from '@ampless/plugin-x-embed/editor'
1081
+ import { editorExtension as __ampless_plugin_x_embed_editor } from '@ampless/plugin-x-embed/editor'
1082
+ import { editorExtension as __ampless_plugin_youtube_editor } from '@ampless/plugin-youtube/editor'
1038
1083
 
1039
1084
  export function EditorBootstrap({ children }: { children: React.ReactNode }) {
1040
1085
  installAdminEditorExtensions([
1041
- youtubeEditor.extension,
1042
- tweetEditor.extension,
1086
+ __ampless_plugin_x_embed_editor,
1087
+ __ampless_plugin_youtube_editor,
1043
1088
  ])
1044
1089
  return <>{children}</>
1045
1090
  }
1046
1091
  ```
1047
1092
 
1048
- Then thread it into the layout:
1093
+ The file is then wired into the admin layout (already in the template — no
1094
+ extra work required):
1049
1095
 
1050
1096
  ```tsx
1051
1097
  // templates/_shared/app/(admin)/admin/layout.tsx
@@ -1058,10 +1104,23 @@ export default createAdminLayout(admin, { editorBootstrap: EditorBootstrap })
1058
1104
  inside a client component. The admin's `<TiptapEditor>` spreads the
1059
1105
  registered list onto its built-in extensions on every render.
1060
1106
 
1107
+ ### Active source and full disable
1108
+
1109
+ **The active source for editor wiring is `package.json#dependencies`**
1110
+ (= `node_modules`), not `cms.config.ts`. This means:
1111
+
1112
+ - Removing a plugin from `cms.config.ts` but keeping it in
1113
+ `package.json` leaves the editor paste rule active. The editor can
1114
+ still insert the node type into the tiptap document, but the public
1115
+ renderer won't render it (inconsistent state — avoid).
1116
+ - To fully disable a plugin's editor extension: remove it from
1117
+ `cms.config.ts` **and** run `npm uninstall @ampless/plugin-...`,
1118
+ then `npm run update-ampless` to regenerate the bootstrap file.
1119
+
1061
1120
  ### Editor preview pipeline
1062
1121
 
1063
1122
  The admin's edit / new post forms render the preview pane in an
1064
- `<iframe sandbox="allow-scripts">` whose `srcDoc` is the HTML returned
1123
+ `<iframe sandbox="allow-scripts allow-same-origin">` whose `srcDoc` is the HTML returned
1065
1124
  by the template's preview Route Handler. The template scaffold ships
1066
1125
  the handler at `app/(admin)/admin/preview/route.tsx`:
1067
1126
 
@@ -1136,14 +1195,24 @@ included; deferring it to request time keeps the module outside the
1136
1195
  build-time import-graph walker while still loading it from the same
1137
1196
  Node.js subpath at runtime.
1138
1197
 
1139
- The iframe's `sandbox="allow-scripts"` (without `allow-same-origin`)
1140
- keeps preview content in an opaque origin so widget scripts cannot
1141
- reach the admin's DOM. The trade-off is that some widgets may misbehave
1142
- when they can't access their own origin's storage; the YouTube iframe
1143
- embed and x.com widgets.js both work under these constraints in
1144
- dogfood as of Phase 7. If a future widget needs a non-opaque preview
1145
- origin, the escape hatch is a separate preview route on a different
1146
- subdomain with appropriate CSP not relaxing the sandbox flag.
1198
+ **Preview iframe sandbox v1 trust boundary expansion:** The iframe uses
1199
+ `sandbox="allow-scripts allow-same-origin"`. With `srcDoc`, this gives
1200
+ the iframe the admin's origin, which 3rd-party embed widgets (YouTube SDK,
1201
+ x.com `widgets.js`) require they refuse to initialise in an opaque-origin
1202
+ (`allow-scripts`-only) iframe because they need access to non-HttpOnly
1203
+ storage / cache and real-origin requests. Same-origin also gives the
1204
+ preview script access to the admin's auth state / non-HttpOnly storage /
1205
+ DOM and lets it issue authenticated same-origin XHR / fetch.
1206
+
1207
+ This is an explicit v1 design decision, not a no-op sandbox relax:
1208
+ **ampless v1 treats admin preview content / plugin script as trusted**.
1209
+ The engineer audits plugins before npm-installing them (customization-based
1210
+ CMS model), and body content is produced by trusted editors of this site.
1211
+ `<PostHistoryPanel>` can also surface a past revision authored by a
1212
+ different editor (revision author ≠ preview viewer) — v1 explicitly puts
1213
+ both inside the trust ring. The safer alternative — separate-origin preview
1214
+ route + CSP / COEP / COOP — is parked for v2.0+ if/when a real plugin
1215
+ marketplace lands.
1147
1216
 
1148
1217
  ---
1149
1218
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ampless",
3
- "version": "1.0.0-alpha.43",
3
+ "version": "1.0.0-alpha.45",
4
4
  "description": "Serverless CMS for AWS Amplify",
5
5
  "license": "MIT",
6
6
  "type": "module",