ampless 1.0.0-beta.57 → 1.0.0-beta.59
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 +66 -1
- package/dist/index.js +50 -0
- package/docs/plugin-author-guide.ja.md +4 -0
- package/docs/plugin-author-guide.md +15 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -337,6 +337,20 @@ type ScriptStrategy = 'afterInteractive' | 'lazyOnload';
|
|
|
337
337
|
* per-post context lands in Phase 4 (`plugin-per-post-rfp.md`).
|
|
338
338
|
*/
|
|
339
339
|
interface PluginPublicRenderContext {
|
|
340
|
+
/**
|
|
341
|
+
* The site's `name` / `url` / `description` block. When the caller
|
|
342
|
+
* wires `@ampless/runtime`'s `createPluginHead(cmsConfig, pluginSettings,
|
|
343
|
+
* siteSettings)` with its third argument (as `createAmpless` does), this
|
|
344
|
+
* is the **effective** site settings — the S3-cached admin
|
|
345
|
+
* `settings.public` override merged over the `cms.config.ts` defaults,
|
|
346
|
+
* the same value the `/<slug>.md` route's canonical line uses — not
|
|
347
|
+
* merely a static passthrough of `cms.config.ts`. It falls back to the
|
|
348
|
+
* `cms.config.ts` block on a site-settings fetch failure, or entirely
|
|
349
|
+
* when the caller omits `siteSettings` (the two-argument
|
|
350
|
+
* `createPluginHead` call, kept for backward compatibility). The type
|
|
351
|
+
* shape (`{ name, url, description? }`) does not change either way —
|
|
352
|
+
* only which value populates it.
|
|
353
|
+
*/
|
|
340
354
|
site: Config['site'];
|
|
341
355
|
/**
|
|
342
356
|
* Resolve a public setting value for the active plugin instance.
|
|
@@ -1987,6 +2001,57 @@ declare function resolvePluginSettings(manifest: PluginSettingsManifest | undefi
|
|
|
1987
2001
|
*/
|
|
1988
2002
|
declare function extractFirstImageUrl(post: Post): string | null;
|
|
1989
2003
|
|
|
2004
|
+
/** How the scan ended. `null` = the fetcher was exhausted cleanly. */
|
|
2005
|
+
type BoundedScanTruncation = 'limit' | 'early' | null;
|
|
2006
|
+
interface BoundedScanResult<T> {
|
|
2007
|
+
items: T[];
|
|
2008
|
+
/**
|
|
2009
|
+
* - `'limit'` — a `limit + 1`th item was actually fetched, so more
|
|
2010
|
+
* items exist beyond the returned `limit`; the extra item is
|
|
2011
|
+
* dropped from `items`.
|
|
2012
|
+
* - `'early'` — one of the safety bounds tripped (`maxPages` reached
|
|
2013
|
+
* or the same `nextToken` came back twice), so the scan may have
|
|
2014
|
+
* stopped with more items unread.
|
|
2015
|
+
* - `null` — the fetcher signalled exhaustion (no `nextToken`) at or
|
|
2016
|
+
* below `limit`.
|
|
2017
|
+
*/
|
|
2018
|
+
truncated: BoundedScanTruncation;
|
|
2019
|
+
}
|
|
2020
|
+
interface BoundedScanOptions {
|
|
2021
|
+
/**
|
|
2022
|
+
* Target item count. The walk collects until it has `limit + 1`
|
|
2023
|
+
* items (the extra confirms there really are more), the fetcher is
|
|
2024
|
+
* exhausted, or a safety bound trips.
|
|
2025
|
+
*/
|
|
2026
|
+
limit: number;
|
|
2027
|
+
/** Max items requested per page (default 50). */
|
|
2028
|
+
pageSizeCap?: number;
|
|
2029
|
+
/** Hard cap on pages walked regardless of items collected (default 21). */
|
|
2030
|
+
maxPages?: number;
|
|
2031
|
+
}
|
|
2032
|
+
interface BoundedScanPage<T> {
|
|
2033
|
+
items: T[];
|
|
2034
|
+
nextToken: string | null;
|
|
2035
|
+
}
|
|
2036
|
+
/**
|
|
2037
|
+
* Walk `fetchPage` pages until we have `limit + 1` items (the extra
|
|
2038
|
+
* item confirms there really are more items beyond `limit` — a present
|
|
2039
|
+
* `nextToken` alone doesn't guarantee that, since a paginated backend
|
|
2040
|
+
* can return a token alongside zero remaining items), the token is
|
|
2041
|
+
* exhausted, or one of the two safety bounds below trips:
|
|
2042
|
+
*
|
|
2043
|
+
* - `maxPages` pages walked without reaching either stop condition
|
|
2044
|
+
* - the same `nextToken` comes back twice (defends against a
|
|
2045
|
+
* misbehaving resolver looping forever)
|
|
2046
|
+
*
|
|
2047
|
+
* Returns at most `limit` items (the confirming `limit + 1`th item is
|
|
2048
|
+
* dropped) alongside how the scan ended.
|
|
2049
|
+
*/
|
|
2050
|
+
declare function collectBounded<T>(fetchPage: (args: {
|
|
2051
|
+
limit: number;
|
|
2052
|
+
nextToken?: string;
|
|
2053
|
+
}) => Promise<BoundedScanPage<T>>, opts: BoundedScanOptions): Promise<BoundedScanResult<T>>;
|
|
2054
|
+
|
|
1990
2055
|
type PostListStatusFilter = 'all' | 'draft' | 'published';
|
|
1991
2056
|
type PostListSort = 'updated-desc' | 'updated-asc' | 'published-desc' | 'published-asc' | 'title-asc' | 'title-desc';
|
|
1992
2057
|
interface PostListFilterOptions {
|
|
@@ -2088,4 +2153,4 @@ declare function pickDefaultEntrypoint(files: readonly {
|
|
|
2088
2153
|
|
|
2089
2154
|
declare const VERSION = "0.0.1";
|
|
2090
2155
|
|
|
2091
|
-
export { type AiConfig, 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 PostListFilterOptions, type PostListSort, type PostListStatusFilter, type PostMetadata, type PostRevision, type PostRevisionConnection, type PostStatus, type PostSummary, 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, type SummaryListOptions, 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 TiptapNodeHtmlAdapters, type TiptapNodeMarkdownAdapters, type TiptapNodeToHtml, type TiptapNodeToMarkdown, type TiptapRenderNode, type TrustLevel, type TrustedPluginRuntimeContext, VERSION, type ValidationIssue, bundlePrefix, collectTags, createPost, decodeAwsJson, defineConfig, definePlugin, defineSchema, defineTheme, defineThemeModule, deletePost, deleteSiteSetting, detectContentEvents, encodeAwsJson, escapeXml, extractFirstImageUrl, filterSortPostSummaries, findAbsolutePathRefs, flattenSettings, formatColorPair, formatDate, formatPublicAssetUrl, getKvStore, getPost, getPostById, getSiteSetting, hasKvStore, hasPostsProvider, isTagListUrl, isValidPluginKey, listPostHistory, listPostSummaries, listPosts, listSiteSettings, mimeTypeFor, parseColorPair, parseLinkList, pickDefaultEntrypoint, resolveLocalized, resolvePluginSettings, resolveThemeValues, setKvStore, setPostsProvider, setSiteSetting, stringifyLinkList, stripCommonPrefix, themeSettingKey, unflattenSettings, updatePost, validateBundle, validateBundlePath, validatePluginSettingValue, validatePublicAssetKey, validateThemeValue };
|
|
2156
|
+
export { type AiConfig, type AmplessEvent, type AmplessPlugin, type AuthContext, type BoundedScanOptions, type BoundedScanPage, type BoundedScanResult, type BoundedScanTruncation, 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 PostListFilterOptions, type PostListSort, type PostListStatusFilter, type PostMetadata, type PostRevision, type PostRevisionConnection, type PostStatus, type PostSummary, 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, type SummaryListOptions, 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 TiptapNodeHtmlAdapters, type TiptapNodeMarkdownAdapters, type TiptapNodeToHtml, type TiptapNodeToMarkdown, type TiptapRenderNode, type TrustLevel, type TrustedPluginRuntimeContext, VERSION, type ValidationIssue, bundlePrefix, collectBounded, collectTags, createPost, decodeAwsJson, defineConfig, definePlugin, defineSchema, defineTheme, defineThemeModule, deletePost, deleteSiteSetting, detectContentEvents, encodeAwsJson, escapeXml, extractFirstImageUrl, filterSortPostSummaries, findAbsolutePathRefs, flattenSettings, formatColorPair, formatDate, formatPublicAssetUrl, getKvStore, getPost, getPostById, getSiteSetting, hasKvStore, hasPostsProvider, isTagListUrl, isValidPluginKey, listPostHistory, listPostSummaries, listPosts, listSiteSettings, mimeTypeFor, parseColorPair, parseLinkList, pickDefaultEntrypoint, resolveLocalized, resolvePluginSettings, resolveThemeValues, setKvStore, setPostsProvider, setSiteSetting, stringifyLinkList, stripCommonPrefix, themeSettingKey, unflattenSettings, updatePost, validateBundle, validateBundlePath, validatePluginSettingValue, validatePublicAssetKey, validateThemeValue };
|
package/dist/index.js
CHANGED
|
@@ -501,6 +501,55 @@ function findHtmlImage(body) {
|
|
|
501
501
|
return m ? m[1] : null;
|
|
502
502
|
}
|
|
503
503
|
|
|
504
|
+
// src/paging.ts
|
|
505
|
+
var DEFAULT_PAGE_SIZE_CAP = 50;
|
|
506
|
+
var DEFAULT_MAX_PAGES = 21;
|
|
507
|
+
function requirePositiveInt(name, value) {
|
|
508
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
509
|
+
throw new TypeError(
|
|
510
|
+
`collectBounded: \`${name}\` must be a finite positive integer, received ${String(value)}`
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
async function collectBounded(fetchPage, opts) {
|
|
515
|
+
const limit = opts.limit;
|
|
516
|
+
const pageSizeCap = opts.pageSizeCap ?? DEFAULT_PAGE_SIZE_CAP;
|
|
517
|
+
const maxPages = opts.maxPages ?? DEFAULT_MAX_PAGES;
|
|
518
|
+
requirePositiveInt("limit", limit);
|
|
519
|
+
requirePositiveInt("pageSizeCap", pageSizeCap);
|
|
520
|
+
requirePositiveInt("maxPages", maxPages);
|
|
521
|
+
const items = [];
|
|
522
|
+
const seenTokens = /* @__PURE__ */ new Set();
|
|
523
|
+
let token;
|
|
524
|
+
let truncated = null;
|
|
525
|
+
for (let page = 0; page < maxPages; page++) {
|
|
526
|
+
const remaining = limit + 1 - items.length;
|
|
527
|
+
const pageLimit = Math.min(pageSizeCap, remaining);
|
|
528
|
+
const res = await fetchPage({ limit: pageLimit, nextToken: token });
|
|
529
|
+
items.push(...res.items);
|
|
530
|
+
if (items.length > limit) {
|
|
531
|
+
truncated = "limit";
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
if (!res.nextToken) {
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
if (seenTokens.has(res.nextToken)) {
|
|
538
|
+
truncated = "early";
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
seenTokens.add(res.nextToken);
|
|
542
|
+
token = res.nextToken;
|
|
543
|
+
if (page === maxPages - 1) {
|
|
544
|
+
truncated = "early";
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return {
|
|
548
|
+
items: truncated === "limit" ? items.slice(0, limit) : items,
|
|
549
|
+
truncated
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
504
553
|
// src/post-list-filter.ts
|
|
505
554
|
function filterSortPostSummaries(rows, options = {}) {
|
|
506
555
|
const query = options.query?.trim().toLowerCase() ?? "";
|
|
@@ -869,6 +918,7 @@ export {
|
|
|
869
918
|
TEXT_EXTENSIONS,
|
|
870
919
|
VERSION,
|
|
871
920
|
bundlePrefix,
|
|
921
|
+
collectBounded,
|
|
872
922
|
collectTags,
|
|
873
923
|
createPost,
|
|
874
924
|
decodeAwsJson,
|
|
@@ -351,6 +351,8 @@ SSR がデッドラインなしでブロックします。ネットワーク呼
|
|
|
351
351
|
|
|
352
352
|
`ctx.setting()` は Phase 2 で追加された admin 管理値アクセッサ — §8 参照。
|
|
353
353
|
|
|
354
|
+
**`ctx.site` は `cms.config.ts` の静的な値そのままではなく、実効 site 設定です。** ホストアプリが `@ampless/runtime` の `createPluginHead(cmsConfig, pluginSettings, siteSettings)` を第 3 引数つきで配線している場合(`createAmpless` は標準でこう配線しており、サイト側のコード変更は不要)、`ctx.site` は admin の `settings.public` override を `cms.config.ts` のデフォルトにマージした値 — `/<slug>.md` ルートの canonical 行が使うのと同じ実効値 — を反映します。site settings の取得に失敗した場合は `cms.config.ts` の値にフォールバックします。型の形(`{ name, url, description? }`)は変わらず、値の意味だけが変わります。`ctx.site.url` から絶対 URL を組み立てるプラグイン(例: `@ampless/plugin-ai-actions` の外部 AI リンク)は、再デプロイなしで admin が編集した site URL の変更を自動的に反映します。
|
|
355
|
+
|
|
354
356
|
---
|
|
355
357
|
|
|
356
358
|
## 6. Descriptor リファレンス
|
|
@@ -1693,6 +1695,8 @@ it('admin が空文字保存した場合は空配列', () => {
|
|
|
1693
1695
|
- [`packages/plugin-webhook`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-webhook) — trusted hook + 外向き HTTP + `secretSettings` (admin 管理の signing secret、Phase 6a)
|
|
1694
1696
|
- [`packages/plugin-og-image`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-og-image) — `ogImage` ルートレンダラ
|
|
1695
1697
|
- [`packages/plugin-schema-jsonld`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-schema-jsonld) — `publicBodyForPost` + `schema` capability、投稿単位 Article JSON-LD。(Phase 4)
|
|
1698
|
+
- [`packages/plugin-reading-time`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-reading-time) — `publicHtmlForPost`、語数推定を本文の前後に `<p>` バッジとして描画。(Phase 6d)
|
|
1699
|
+
- [`packages/plugin-ai-actions`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-ai-actions) — `publicHtmlForPost`、`ctx.site.url`(実効 site 設定)と投稿の `/<slug>.md` URL から「Markdown で表示」+ opt-in の「Claude で開く」/「ChatGPT で開く」リンクを組み立てる。(AI-readable publishing ロードマップ Phase B)
|
|
1696
1700
|
|
|
1697
1701
|
---
|
|
1698
1702
|
|
|
@@ -434,6 +434,19 @@ The `ctx` object carries:
|
|
|
434
434
|
`ctx.setting()` is the Phase 2 admin-managed values accessor — see
|
|
435
435
|
§8.
|
|
436
436
|
|
|
437
|
+
**`ctx.site` is the effective site settings, not a static passthrough of
|
|
438
|
+
`cms.config.ts`.** When the host app wires `@ampless/runtime`'s
|
|
439
|
+
`createPluginHead(cmsConfig, pluginSettings, siteSettings)` with its third
|
|
440
|
+
argument (as `createAmpless` does — this is the standard wiring, no site
|
|
441
|
+
code changes needed), `ctx.site` reflects admin `settings.public`
|
|
442
|
+
overrides merged over the `cms.config.ts` defaults — the same effective
|
|
443
|
+
value the `/<slug>.md` route's canonical line uses. It falls back to the
|
|
444
|
+
`cms.config.ts` block on a site-settings fetch failure. The shape
|
|
445
|
+
(`{ name, url, description? }`) is unchanged; only which value populates
|
|
446
|
+
it. Plugins that build absolute URLs from `ctx.site.url` (e.g.
|
|
447
|
+
`@ampless/plugin-ai-actions`'s external AI links) automatically track
|
|
448
|
+
admin-edited site URL changes without a redeploy.
|
|
449
|
+
|
|
437
450
|
---
|
|
438
451
|
|
|
439
452
|
## 6. Descriptor reference
|
|
@@ -2308,6 +2321,8 @@ Worked examples to crib from:
|
|
|
2308
2321
|
- [`packages/plugin-webhook`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-webhook) — trusted hook with outbound HTTP + `secretSettings` (admin-managed signing secret, Phase 6a).
|
|
2309
2322
|
- [`packages/plugin-og-image`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-og-image) — `ogImage` route renderer.
|
|
2310
2323
|
- [`packages/plugin-schema-jsonld`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-schema-jsonld) — `publicBodyForPost` + `schema` capability; per-post Article JSON-LD. (Phase 4)
|
|
2324
|
+
- [`packages/plugin-reading-time`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-reading-time) — `publicHtmlForPost`; word-count estimate rendered as a `<p>` badge before/after the post body. (Phase 6d)
|
|
2325
|
+
- [`packages/plugin-ai-actions`](https://github.com/heavymoons/ampless/tree/main/packages/plugin-ai-actions) — `publicHtmlForPost`; "View as Markdown" + opt-in "Open in Claude" / "Open in ChatGPT" links built from `ctx.site.url` (effective site settings) and the post's `/<slug>.md` URL. (AI-readable publishing roadmap, Phase B)
|
|
2311
2326
|
|
|
2312
2327
|
---
|
|
2313
2328
|
|