ampless 1.0.0-alpha.31 → 1.0.0-alpha.33
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 +82 -6
- package/docs/plugin-author-guide.ja.md +73 -2
- package/docs/plugin-author-guide.md +98 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -302,7 +302,7 @@ type TrustLevel = 'untrusted' | 'trusted' | 'privileged';
|
|
|
302
302
|
* capability today is harmless, but the runtime won't expose any new
|
|
303
303
|
* surface for it until the matching phase ships.
|
|
304
304
|
*/
|
|
305
|
-
type PluginCapability = 'publicHead' | 'publicBody' | 'metadata' | 'eventHooks' | 'adminSettings' | 'writePublicAsset' | 'schema' | 'publicHtmlForPost' | 'secretSettings' | 'contentFields' | 'adminPage' | 'serverRoute' | 'network' | 'scheduler' | 'storageWrite' | 'privilegedSystem';
|
|
305
|
+
type PluginCapability = 'publicHead' | 'publicBody' | 'metadata' | 'eventHooks' | 'adminSettings' | 'writePublicAsset' | 'schema' | 'publicHtmlForPost' | 'secretSettings' | 'contentFields' | 'adminPage' | 'serverRoute' | 'network' | 'scheduler' | 'storageWrite' | 'privilegedSystem' | 'cspReady';
|
|
306
306
|
/**
|
|
307
307
|
* Loading strategy for `script` / `inlineScript` descriptors.
|
|
308
308
|
*
|
|
@@ -344,6 +344,16 @@ interface PluginPublicRenderContext {
|
|
|
344
344
|
* field's declared shape, so the cast is safe in practice.
|
|
345
345
|
*/
|
|
346
346
|
setting<T = unknown>(key: string): T | undefined;
|
|
347
|
+
/**
|
|
348
|
+
* Request-scoped CSP nonce reservation. Always `undefined` in Phase 1
|
|
349
|
+
* — the runtime does not populate this field yet. Middleware/SSR
|
|
350
|
+
* threading lands with the future CSP RFP. Plugin authors who want to
|
|
351
|
+
* be ready for the future stamping can declare
|
|
352
|
+
* `inlineScript.nonce: 'auto'` today; once the middleware-driven
|
|
353
|
+
* threading PR lands, those descriptors will become candidates for
|
|
354
|
+
* runtime nonce stamping.
|
|
355
|
+
*/
|
|
356
|
+
cspNonce?: string;
|
|
347
357
|
}
|
|
348
358
|
/**
|
|
349
359
|
* Descriptor returned by `publicHead()`. The runtime validates each
|
|
@@ -364,6 +374,15 @@ type PublicHeadDescriptor = {
|
|
|
364
374
|
defer?: boolean;
|
|
365
375
|
/** Allow-listed attributes only (data-*, crossorigin, referrerpolicy, ...). */
|
|
366
376
|
attrs?: Record<string, string | boolean>;
|
|
377
|
+
/**
|
|
378
|
+
* Optional CSP nonce. Same semantics as inlineScript.nonce
|
|
379
|
+
* (`'auto'` is the sentinel for future runtime stamping; any
|
|
380
|
+
* other string is an explicit literal; undefined emits no
|
|
381
|
+
* `nonce` attribute). Phase 1 reservation: runtime accepts
|
|
382
|
+
* but does not propagate. See `inlineScript.nonce` JSDoc for
|
|
383
|
+
* the full description.
|
|
384
|
+
*/
|
|
385
|
+
nonce?: 'auto' | string;
|
|
367
386
|
} | {
|
|
368
387
|
type: 'inlineScript';
|
|
369
388
|
/** Required for duplicate detection and dev warnings. */
|
|
@@ -391,9 +410,25 @@ type PublicHeadDescriptor = {
|
|
|
391
410
|
*/
|
|
392
411
|
scriptType?: 'application/ld+json';
|
|
393
412
|
/**
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
413
|
+
* Optional CSP nonce.
|
|
414
|
+
*
|
|
415
|
+
* - `'auto'`: sentinel reserved for future runtime stamping.
|
|
416
|
+
* When the middleware/SSR CSP nonce threading PR lands, the
|
|
417
|
+
* runtime will read `ctx.cspNonce` from the request scope
|
|
418
|
+
* and stamp the rendered `<script>` tag automatically.
|
|
419
|
+
* - any other `string`: explicit nonce literal (advanced;
|
|
420
|
+
* rarely needed).
|
|
421
|
+
* - `undefined`: no `nonce` attribute emitted (default,
|
|
422
|
+
* backward-compatible with non-CSP sites).
|
|
423
|
+
*
|
|
424
|
+
* Phase 1 reservation: the runtime accepts the field but does
|
|
425
|
+
* not propagate it to the rendered element. Declaring
|
|
426
|
+
* `nonce: 'auto'` today is a forward-compatibility hint and
|
|
427
|
+
* does not change the rendered HTML.
|
|
428
|
+
*
|
|
429
|
+
* Note: TypeScript does not type-widen here — `string` already
|
|
430
|
+
* accepts `'auto'` as a literal. The semantic reservation is
|
|
431
|
+
* documented above.
|
|
397
432
|
*/
|
|
398
433
|
nonce?: string;
|
|
399
434
|
} | {
|
|
@@ -540,7 +575,48 @@ interface PluginMetadata {
|
|
|
540
575
|
types?: Record<string, string>;
|
|
541
576
|
};
|
|
542
577
|
}
|
|
543
|
-
|
|
578
|
+
/**
|
|
579
|
+
* Hook return value reservation (Phase 1: type only, runtime no-op).
|
|
580
|
+
*
|
|
581
|
+
* Today's runtime (after-event SQS Lambdas) ignores the return value
|
|
582
|
+
* entirely. The type is widened so a future PR can land additive
|
|
583
|
+
* directives without breaking plugin authors who publish in the
|
|
584
|
+
* meantime. Likely first use case:
|
|
585
|
+
*
|
|
586
|
+
* - `metrics?: Record<string, number>` — emit observability data
|
|
587
|
+
* without touching CloudWatch SDK directly from the plugin.
|
|
588
|
+
*
|
|
589
|
+
* `cancel` / `post` rewrite-style directives are NOT enabled by this
|
|
590
|
+
* type alone — they would also require `before:*` events to be wired
|
|
591
|
+
* to plugins (currently reserved, see events.ts) and payload shapes
|
|
592
|
+
* to expose mutable bodies. This PR widens the return surface only;
|
|
593
|
+
* richer semantics need follow-on PRs.
|
|
594
|
+
*
|
|
595
|
+
* The `readonly __amplessPluginHookResult?: never` marker is a
|
|
596
|
+
* type-level nominal tag: it prevents `Promise<void | PluginHookResult>`
|
|
597
|
+
* from silently accepting unrelated promise types like
|
|
598
|
+
* `Promise<string>` or `Promise<number>`. Plugin authors do not need
|
|
599
|
+
* to set this field — it is optional and exists only to constrain
|
|
600
|
+
* what the union accepts.
|
|
601
|
+
*/
|
|
602
|
+
interface PluginHookResult {
|
|
603
|
+
readonly __amplessPluginHookResult?: never;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Async event hook handler.
|
|
607
|
+
*
|
|
608
|
+
* The return value is reserved (see `PluginHookResult`). Today's
|
|
609
|
+
* runtime ignores it — returning `undefined` (`Promise<void>`) is
|
|
610
|
+
* the canonical "no-op" and matches existing plugin code without
|
|
611
|
+
* migration. Plugins that explicitly return a `PluginHookResult`
|
|
612
|
+
* object type-check today but do not change runtime behaviour
|
|
613
|
+
* until the matching capability PR lands.
|
|
614
|
+
*
|
|
615
|
+
* Non-PluginHookResult promise types (`Promise<string>`,
|
|
616
|
+
* `Promise<number>`, etc.) are rejected at compile time by the
|
|
617
|
+
* `__amplessPluginHookResult` private marker on `PluginHookResult`.
|
|
618
|
+
*/
|
|
619
|
+
type PluginEventHandler<T extends EventType = EventType> = (event: AmplessEvent<T>, ctx: PluginRuntimeContext) => Promise<void | PluginHookResult>;
|
|
544
620
|
/**
|
|
545
621
|
* Runtime services injected into hook handlers by the Lambda processor.
|
|
546
622
|
* Decoupling plugins from concrete AWS clients lets us swap implementations
|
|
@@ -1475,4 +1551,4 @@ declare function pickDefaultEntrypoint(files: readonly {
|
|
|
1475
1551
|
|
|
1476
1552
|
declare const VERSION = "0.0.1";
|
|
1477
1553
|
|
|
1478
|
-
export { type AmplessEvent, type AmplessPlugin, type AuthContext, type BundleExtractResult, type CacheConfig, type CacheStrategy, type Config, type ContentEventPayload, type ContentEventType, type ContentFormat, type ContentTypeDefinition, type CreatePostInput, DEFAULT_ENTRYPOINT, type DateFormat, type EventPayloadOf, type EventType, type ExtractedFile, type FieldDefinition, type FieldType, type ImageDisplay, type KvItem, type KvStore, type LinkListItem, type ListOptions, type LocalizedString, MAX_BUNDLE_BYTES, 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 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 PluginUrlField, type Post, type PostIndexEventPayload, type PostIndexEventType, type PostMetadata, type PostStatus, type PostsProvider, type PublicBodyDescriptor, type PublicHeadDescriptor, type PublicPostBodyDescriptor, type PublicPostHtmlDescriptor, type PublicPostHtmlPosition, 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 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, listPosts, listSiteSettings, mimeTypeFor, parseColorPair, parseLinkList, pickDefaultEntrypoint, resolveLocalized, resolvePluginSettings, resolveThemeValues, setKvStore, setPostsProvider, setSiteSetting, stringifyLinkList, stripCommonPrefix, themeSettingKey, unflattenSettings, updatePost, validateBundle, validateBundlePath, validatePluginSettingValue, validatePublicAssetKey, validateThemeValue };
|
|
1554
|
+
export { type AmplessEvent, type AmplessPlugin, type AuthContext, type BundleExtractResult, type CacheConfig, type CacheStrategy, type Config, type ContentEventPayload, type ContentEventType, type ContentFormat, type ContentTypeDefinition, type CreatePostInput, DEFAULT_ENTRYPOINT, type DateFormat, type EventPayloadOf, type EventType, type ExtractedFile, type FieldDefinition, type FieldType, type ImageDisplay, type KvItem, type KvStore, type LinkListItem, type ListOptions, type LocalizedString, MAX_BUNDLE_BYTES, 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 PluginUrlField, type Post, type PostIndexEventPayload, type PostIndexEventType, type PostMetadata, type PostStatus, type PostsProvider, type PublicBodyDescriptor, type PublicHeadDescriptor, type PublicPostBodyDescriptor, type PublicPostHtmlDescriptor, type PublicPostHtmlPosition, 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 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, listPosts, listSiteSettings, mimeTypeFor, parseColorPair, parseLinkList, pickDefaultEntrypoint, resolveLocalized, resolvePluginSettings, resolveThemeValues, setKvStore, setPostsProvider, setSiteSetting, stringifyLinkList, stripCommonPrefix, themeSettingKey, unflattenSettings, updatePost, validateBundle, validateBundlePath, validatePluginSettingValue, validatePublicAssetKey, validateThemeValue };
|
|
@@ -441,7 +441,7 @@ runtime は `body` を `sanitize-html` の厳格 allowlist で sanitize し(
|
|
|
441
441
|
- **`attrs` allowlist**: `data-*`、`crossorigin`、`referrerpolicy`、`integrity`、`fetchpriority`、`loading`、`sandbox`、`allow`、`allowfullscreen`。それ以外は dev warn 付きで drop
|
|
442
442
|
- **`inlineScript.id` は必須**。無いとプラグイン同士が似たスニペットを emit したときに dedup できず、dev warning も index 番号を指すだけで原因プラグインを特定できません
|
|
443
443
|
- **id 重複**: 最後の出現が勝ち。dev warning でどの key が重複したか表示されます
|
|
444
|
-
- **CSP nonce**: Phase 1
|
|
444
|
+
- **CSP nonce**: `inlineScript.nonce` と `script.nonce` は型として受け入れられます(`'auto'` は将来の runtime スタンプ用 sentinel。文字列リテラルも可)。Phase 1 予約: runtime はフィールドを受け入れますが描画要素には伝搬しません。詳細は下記の [CSP nonce(Phase 1 予約)](#csp-nonce-phase-1-) を参照。
|
|
445
445
|
- **strategy**: `afterInteractive` は外部 script に `async` を付ける。`lazyOnload` は `defer`。明示的な `async` / `defer` が常に勝ち。`beforeInteractive` は非対応
|
|
446
446
|
|
|
447
447
|
### runtime が描画する形
|
|
@@ -563,11 +563,82 @@ React 19 はさらに、クライアントコンポーネントのレンダー
|
|
|
563
563
|
|
|
564
564
|
投稿単位の見える出力には `publicHtmlForPost` を使ってください(Phase 6d — 上の例と §6 の `PublicPostHtmlDescriptor` 参照)。runtime が post 本文の周囲の固定スロットにサーバーサイド HTML を出すので、hydration と競合しません。
|
|
565
565
|
|
|
566
|
+
|
|
567
|
+
### CSP nonce(Phase 1 予約)
|
|
568
|
+
|
|
569
|
+
CSP(Content Security Policy)は本番公開サイトのほぼ必須要件です。nonce 伝搬を後から追加した場合に既存プラグインが一斉に動かなくなるのを防ぐため、ampless は今のうちに API サーフェスだけ予約しておきます(Phase 1 は完全 no-op)。
|
|
570
|
+
|
|
571
|
+
3 層設計:
|
|
572
|
+
|
|
573
|
+
1. **`ctx.cspNonce?: string`** — `PluginPublicRenderContext` の型に予約済み。今のところ常に `undefined`。runtime はこのフィールドをまだ populate しません。middleware/SSR nonce threading は将来の CSP RFP とともに landing します。
|
|
574
|
+
|
|
575
|
+
2. **`descriptor.nonce: 'auto' | string`** — `inlineScript` と `script` の両 descriptor variant の型で受け入れられます。`'auto'` は将来の runtime スタンプ用 sentinel。その他の文字列は明示的リテラル。`undefined` は `nonce` 属性を emit しない(デフォルト、非 CSP サイトと後方互換)。Phase 1: runtime は受け入れますが伝搬しません。`nonce: 'auto'` を今日宣言することは前方互換性のヒントであり、描画 HTML を変更しません。
|
|
576
|
+
|
|
577
|
+
3. **`'cspReady'` capability** — name-only の declarative バッジ。将来の admin UI / サニティチェックの対象になります。Phase 1 では runtime の cross-check や enforcement は一切なし。
|
|
578
|
+
|
|
579
|
+
**対応方法:**
|
|
580
|
+
|
|
581
|
+
```ts
|
|
582
|
+
// src/index.ts
|
|
583
|
+
definePlugin({
|
|
584
|
+
name: 'my-plugin',
|
|
585
|
+
apiVersion: 1,
|
|
586
|
+
trust_level: 'untrusted',
|
|
587
|
+
capabilities: ['publicHead', 'cspReady'],
|
|
588
|
+
publicHead: () => [{
|
|
589
|
+
type: 'inlineScript',
|
|
590
|
+
id: 'my-snippet',
|
|
591
|
+
body: '...',
|
|
592
|
+
nonce: 'auto', // 前方互換性ヒント。Phase 1 では効果なし
|
|
593
|
+
}],
|
|
594
|
+
})
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
npm 公開のスタンドアロンプラグインの場合は、`package.json#amplessPlugin.capabilities` も合わせて更新してください — static manifest と factory return value が一致しない場合、runtime cross-check が警告を出します:
|
|
598
|
+
|
|
599
|
+
```json
|
|
600
|
+
{
|
|
601
|
+
"amplessPlugin": {
|
|
602
|
+
"apiVersion": 1,
|
|
603
|
+
"name": "my-plugin",
|
|
604
|
+
"trustLevel": "untrusted",
|
|
605
|
+
"capabilities": ["publicHead", "cspReady"]
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
**`'cspReady'` の意味:**
|
|
611
|
+
|
|
612
|
+
- サイト全体の CSP 適合は middleware / レスポンスヘッダー / runtime が制御しない他の inline コンテンツにも依存します。
|
|
613
|
+
- middleware-driven nonce threading PR が landing した後は、`nonce: 'auto'` を持つ plugin-supplied script が runtime nonce スタンプの候補になります。
|
|
614
|
+
- `'cspReady'` は `create-ampless plugin --capabilities` には表示されません — reserved capability であり、scaffold はアクティブな enforcement を示唆しないよう除外しています。
|
|
615
|
+
|
|
566
616
|
---
|
|
567
617
|
|
|
568
618
|
## 7. 非同期イベントフック
|
|
569
619
|
|
|
570
|
-
`hooks` は SQS から到着したイベントを trust_level に対応する processor Lambda が受けて実行します。
|
|
620
|
+
`hooks` は SQS から到着したイベントを trust_level に対応する processor Lambda が受けて実行します。
|
|
621
|
+
|
|
622
|
+
### 戻り値の予約
|
|
623
|
+
|
|
624
|
+
`PluginEventHandler` の戻り値型は `Promise<void | PluginHookResult>`。
|
|
625
|
+
runtime は現状この戻り値を完全に無視する — 既存 plugin が
|
|
626
|
+
`Promise<void>` を返す形は migration 不要で動き続ける。
|
|
627
|
+
`PluginHookResult` は将来の directive (最初の用例として有力:
|
|
628
|
+
`metrics?: Record<string, number>` による observability emission) のた
|
|
629
|
+
めの予約で、今宣言するのは forward-compatibility のヒントとして
|
|
630
|
+
の扱い。注意: rewrite / cancel 系 directive は本 widening だけで
|
|
631
|
+
は有効化されない — `before:*` event の plugin 配線と payload 拡張
|
|
632
|
+
が別 PR で必要。
|
|
633
|
+
|
|
634
|
+
`PluginHookResult` には private な `__amplessPluginHookResult`
|
|
635
|
+
marker が付いており、union が `Promise<string>` / `Promise<number>`
|
|
636
|
+
等の無関係な promise を silently 受け入れないようになっている —
|
|
637
|
+
plugin 作者がこの marker を明示的に設定する必要は無い。
|
|
638
|
+
|
|
639
|
+
### Runtime context
|
|
640
|
+
|
|
641
|
+
runtime context (`ctx`) の中身:
|
|
571
642
|
|
|
572
643
|
```ts
|
|
573
644
|
interface PluginRuntimeContext {
|
|
@@ -540,8 +540,12 @@ a console warning** and never rendered.
|
|
|
540
540
|
index numbers no one can map back to a plugin.
|
|
541
541
|
- **Duplicate `id`**: the last occurrence wins. A dev warning prints
|
|
542
542
|
which key was duplicated.
|
|
543
|
-
- **CSP nonce**:
|
|
544
|
-
|
|
543
|
+
- **CSP nonce**: `inlineScript.nonce` and `script.nonce` are accepted
|
|
544
|
+
by the type (`'auto'` is the sentinel for future runtime stamping;
|
|
545
|
+
any string is an explicit literal). Phase 1 reservation: the runtime
|
|
546
|
+
accepts the field but does not propagate it to the rendered element.
|
|
547
|
+
See [CSP nonce (Phase 1 reservation)](#csp-nonce-phase-1-reservation)
|
|
548
|
+
below.
|
|
545
549
|
- **Strategy**: `afterInteractive` adds `async` to external scripts.
|
|
546
550
|
`lazyOnload` adds `defer`. Explicit `async` / `defer` always
|
|
547
551
|
wins. `beforeInteractive` is not supported.
|
|
@@ -715,12 +719,103 @@ the example above and §6's `PublicPostHtmlDescriptor`). The runtime
|
|
|
715
719
|
emits server-side HTML at fixed slots around the post body, so
|
|
716
720
|
nothing races against hydration.
|
|
717
721
|
|
|
722
|
+
|
|
723
|
+
### CSP nonce (Phase 1 reservation)
|
|
724
|
+
|
|
725
|
+
Content Security Policy (CSP) is a near-mandatory requirement for production
|
|
726
|
+
sites. To avoid breaking every plugin at once when nonce propagation lands,
|
|
727
|
+
ampless reserves the API surface today (Phase 1 no-op) so plugins can opt in
|
|
728
|
+
ahead of time.
|
|
729
|
+
|
|
730
|
+
The 3-layer design:
|
|
731
|
+
|
|
732
|
+
1. **`ctx.cspNonce?: string`** on `PluginPublicRenderContext` — type-reserved
|
|
733
|
+
on the interface; always `undefined` today. The runtime does not populate
|
|
734
|
+
this field yet; reads resolve to `undefined`. Middleware/SSR nonce threading
|
|
735
|
+
lands with the future CSP RFP.
|
|
736
|
+
|
|
737
|
+
2. **`descriptor.nonce: 'auto' | string`** — accepted by the type on both
|
|
738
|
+
`inlineScript` and `script` descriptor variants. `'auto'` is the sentinel
|
|
739
|
+
for future runtime stamping; any other string is an explicit literal;
|
|
740
|
+
`undefined` emits no `nonce` attribute (default, backward-compatible).
|
|
741
|
+
Phase 1: the runtime accepts but does not propagate it. Declaring
|
|
742
|
+
`nonce: 'auto'` today is a forward-compatibility hint and does not change
|
|
743
|
+
the rendered HTML.
|
|
744
|
+
|
|
745
|
+
3. **`'cspReady'` capability** — a name-only declarative badge. Declaring it
|
|
746
|
+
signals intent; future admin UI / sanity checks may surface it. No runtime
|
|
747
|
+
cross-check or enforcement exists in Phase 1.
|
|
748
|
+
|
|
749
|
+
**How to be ready:**
|
|
750
|
+
|
|
751
|
+
```ts
|
|
752
|
+
// src/index.ts
|
|
753
|
+
definePlugin({
|
|
754
|
+
name: 'my-plugin',
|
|
755
|
+
apiVersion: 1,
|
|
756
|
+
trust_level: 'untrusted',
|
|
757
|
+
capabilities: ['publicHead', 'cspReady'],
|
|
758
|
+
publicHead: () => [{
|
|
759
|
+
type: 'inlineScript',
|
|
760
|
+
id: 'my-snippet',
|
|
761
|
+
body: '...',
|
|
762
|
+
nonce: 'auto', // forward-compat hint; no effect in Phase 1
|
|
763
|
+
}],
|
|
764
|
+
})
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
For standalone npm-published plugins, also update `package.json#amplessPlugin.capabilities`
|
|
768
|
+
to match — the runtime cross-check warns on disagreement between the static
|
|
769
|
+
manifest and the factory return value:
|
|
770
|
+
|
|
771
|
+
```json
|
|
772
|
+
{
|
|
773
|
+
"amplessPlugin": {
|
|
774
|
+
"apiVersion": 1,
|
|
775
|
+
"name": "my-plugin",
|
|
776
|
+
"trustLevel": "untrusted",
|
|
777
|
+
"capabilities": ["publicHead", "cspReady"]
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
**What "cspReady" means:**
|
|
783
|
+
|
|
784
|
+
- Site-level CSP compliance depends on middleware / response headers / other
|
|
785
|
+
inline content the runtime does not control.
|
|
786
|
+
- Once the middleware-driven nonce threading PR lands, plugin-supplied scripts
|
|
787
|
+
that carry `nonce: 'auto'` will become candidates for runtime nonce stamping.
|
|
788
|
+
- `'cspReady'` does **not** appear in `create-ampless plugin --capabilities`
|
|
789
|
+
output — it is a reserved capability and the scaffold excludes it to avoid
|
|
790
|
+
implying active enforcement.
|
|
791
|
+
|
|
718
792
|
---
|
|
719
793
|
|
|
720
794
|
## 7. Async event hooks
|
|
721
795
|
|
|
722
796
|
`hooks` runs inside the trust_level-matched processor Lambda when an
|
|
723
|
-
event arrives via SQS.
|
|
797
|
+
event arrives via SQS.
|
|
798
|
+
|
|
799
|
+
### Return value reservation
|
|
800
|
+
|
|
801
|
+
`PluginEventHandler` returns `Promise<void | PluginHookResult>`. The
|
|
802
|
+
runtime currently ignores the return value entirely — existing
|
|
803
|
+
plugins returning `Promise<void>` keep working without migration.
|
|
804
|
+
`PluginHookResult` is reserved for a future directive (likely first:
|
|
805
|
+
`metrics?: Record<string, number>` for observability emission);
|
|
806
|
+
declaring it today is a forward-compatibility hint. Note: rewrite
|
|
807
|
+
or cancel directives are NOT enabled by this widening alone — they
|
|
808
|
+
require additional `before:*` event support and payload extensions
|
|
809
|
+
in separate PRs.
|
|
810
|
+
|
|
811
|
+
`PluginHookResult` carries a private `__amplessPluginHookResult`
|
|
812
|
+
marker so that the union does not silently accept unrelated promise
|
|
813
|
+
types (`Promise<string>` / `Promise<number>` etc.) — plugin authors
|
|
814
|
+
do not need to set this field.
|
|
815
|
+
|
|
816
|
+
### Runtime context
|
|
817
|
+
|
|
818
|
+
The runtime context (`ctx`) carries:
|
|
724
819
|
|
|
725
820
|
```ts
|
|
726
821
|
interface PluginRuntimeContext {
|