create-ampless 1.0.0-alpha.39 → 1.0.0-alpha.42

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
@@ -1747,6 +1747,11 @@ var AMPLESS_MANAGED_APP_PATHS = [
1747
1747
  "app/login",
1748
1748
  "app/site"
1749
1749
  ];
1750
+ var AMPLESS_RETIRED_PATHS = [
1751
+ // Retired in alpha.20+ along with the in-deploy multi-site drop (PR #93).
1752
+ "lib/admin-site.ts",
1753
+ "lib/admin-site-client.ts"
1754
+ ];
1750
1755
  var AMPLESS_PACKAGES = /* @__PURE__ */ new Set([
1751
1756
  "ampless",
1752
1757
  "@ampless/admin",
@@ -1898,7 +1903,7 @@ async function pruneEmptyDirs(root) {
1898
1903
  await rm2(root, { recursive: true, force: true });
1899
1904
  }
1900
1905
  }
1901
- async function findObsoleteAppFiles(destDir, sharedDir) {
1906
+ async function findObsoleteFiles(destDir, sharedDir) {
1902
1907
  const obsolete = [];
1903
1908
  for (const managedPath of AMPLESS_MANAGED_APP_PATHS) {
1904
1909
  const userPath = join3(destDir, managedPath);
@@ -1912,9 +1917,15 @@ async function findObsoleteAppFiles(destDir, sharedDir) {
1912
1917
  }
1913
1918
  }
1914
1919
  }
1920
+ for (const retiredPath of AMPLESS_RETIRED_PATHS) {
1921
+ const userFile = join3(destDir, retiredPath);
1922
+ if (existsSync5(userFile)) {
1923
+ obsolete.push(retiredPath);
1924
+ }
1925
+ }
1915
1926
  return obsolete;
1916
1927
  }
1917
- async function removeObsoleteAppFiles(destDir, paths) {
1928
+ async function removeObsoleteFiles(destDir, paths) {
1918
1929
  for (const rel of paths) {
1919
1930
  const abs = join3(destDir, rel);
1920
1931
  if (existsSync5(abs)) {
@@ -1978,7 +1989,7 @@ async function runUpgradeIn(destDir, sharedDir, opts = {}) {
1978
1989
  const shippedThemes = themeSyncEnabled ? await listShippedThemes(templatesRoot) : [];
1979
1990
  const existingThemes = themeSyncEnabled ? await discoverInstalledThemes(destDir) : [];
1980
1991
  const preservedThemes = existingThemes.filter((t) => !shippedThemes.includes(t));
1981
- const obsoleteFiles = await findObsoleteAppFiles(destDir, sharedDir);
1992
+ const obsoleteFiles = await findObsoleteFiles(destDir, sharedDir);
1982
1993
  log3.info(
1983
1994
  `replace: ${pc3.green(`${replaceNew.length} added`)} / ${pc3.yellow(`${replaceUpdate.length} updated`)}`
1984
1995
  );
@@ -2020,7 +2031,7 @@ async function runUpgradeIn(destDir, sharedDir, opts = {}) {
2020
2031
  await copyWithSubstitution(src, dst, vars);
2021
2032
  }
2022
2033
  const themeResult = themeSyncEnabled ? await syncThemes(destDir, templatesRoot) : { synced: [], preserved: [] };
2023
- await removeObsoleteAppFiles(destDir, obsoleteFiles);
2034
+ await removeObsoleteFiles(destDir, obsoleteFiles);
2024
2035
  const templatePkgRaw = await readFile3(join3(sharedDir, "package.json"), "utf-8");
2025
2036
  const templatePkg = JSON.parse(templatePkgRaw);
2026
2037
  const indent = detectIndent(projectPkgRaw);
@@ -65,7 +65,8 @@ npm run sandbox
65
65
  投稿(Post)が唯一のコンテンツタイプです。各投稿には以下があります:
66
66
 
67
67
  - **Format** — `tiptap`(リッチテキスト)/ `markdown` / `html`(生 HTML、サニタイズなし)/ `static`(HTML/CSS/JS の zip アップロード)
68
- - **No layout** フラグ(`format: 'html'` のときのみ)— 本文をそのまま出力し、Next.js のレイアウトもテーマのクロームも適用しない。URL は `/<slug>` のままで、ルートが `/_/<slug>` にリダイレクトする
68
+ - **No layout** フラグ(`format: 'html'` のときのみ)— 本文をそのまま出力し、Next.js のレイアウトもテーマのクロームも適用しない。URL は `/<slug>` のままで、middleware がリクエストを内部のベア HTML ハンドラーに書き換える
69
+ - **キャッシュ戦略**(`metadata.cache`)— 投稿ごとに `Cache-Control` を上書き: `'auto'`(デフォルト、編集時刻ベースのクールダウン)、`'deep'`(常に長期キャッシュ)、`'hot'`(常に no-store)。詳細は `docs/CONTENT.ja.md`
69
70
  - **Slug** — 公開 URL
70
71
  - **Status** — `draft`(管理者のみ)または `published`
71
72
 
@@ -65,7 +65,8 @@ Promotion/demotion is done in the AWS Cognito console — see [RUNBOOK.md → Pr
65
65
  Posts are the single content type. Each post has:
66
66
 
67
67
  - **Format** — `tiptap` (rich text) / `markdown` / `html` (raw, no sanitization) / `static` (zip-upload of HTML/CSS/JS)
68
- - **No layout** flag (`format: 'html'` only) — render the body verbatim with no Next.js layout and no theme chrome. URL stays `/<slug>`; the route redirects to `/_/<slug>`.
68
+ - **No layout** flag (`format: 'html'` only) — render the body verbatim with no Next.js layout and no theme chrome. URL stays `/<slug>`; middleware rewrites the request to the internal bare-HTML handler.
69
+ - **Cache strategy** (`metadata.cache`) — override the per-post Cache-Control: `'auto'` (default; cooldown by edit time), `'deep'` (always long-cache), or `'hot'` (always no-store). See `docs/CONTENT.md` for details.
69
70
  - **Slug** — the public URL
70
71
  - **Status** — `draft` (admin only) or `published`
71
72
 
@@ -1,17 +1,18 @@
1
1
  import { ampless } from '@/lib/ampless'
2
2
  import { createUnderscoreRouteHandler } from '@ampless/runtime/routes'
3
3
 
4
- // Unified handler for the public `/_/<slug>(/...)` URL family.
5
- // Covers two cases that both bypass the theme's post page:
4
+ // Internal handler for no_layout HTML and static-bundle posts. Reached
5
+ // via middleware rewrite from `/<slug>(/<path>)` never directly.
6
+ // Covers two cases that both bypass the themed post page:
6
7
  //
7
8
  // - `format: 'html'` posts with `metadata.no_layout === true`
8
9
  // → bare HTML response, no Next.js root layout, no theme chrome
9
10
  // - `format: 'static'` posts
10
11
  // → S3 presigned URL redirect for the entrypoint and every bundle file
11
12
  //
12
- // File location uses the literal folder name `r/` (not `_/`) because
13
- // Next.js's App Router excludes any path part starting with `_` from
14
- // route discovery. The middleware rewrites the public `/_/` prefix
15
- // to `/r/` internally; the browser URL stays `/_/<slug>(/...)`.
13
+ // The literal folder is `r/` (not `_/` etc.) because Next.js's App
14
+ // Router excludes any path part starting with `_` from route
15
+ // discovery. The browser URL stays `/<slug>(/<path>)` throughout
16
+ // middleware does the public→internal translation.
16
17
  export const dynamic = 'force-dynamic'
17
18
  export const GET = createUnderscoreRouteHandler(ampless)
@@ -22,15 +22,15 @@
22
22
  "@tiptap/pm": "^3.23.4",
23
23
  "@tiptap/react": "^3.23.4",
24
24
  "@tiptap/starter-kit": "^3.23.4",
25
- "@ampless/plugin-og-image": "^0.2.0-alpha.9",
26
- "@ampless/plugin-rss": "^0.2.0-alpha.9",
27
- "@ampless/plugin-seo": "^0.2.0-alpha.9",
28
- "@ampless/plugin-webhook": "^0.2.0-alpha.9",
29
- "@ampless/admin": "^1.0.0-alpha.26",
30
- "@ampless/backend": "^1.0.0-alpha.19",
31
- "@ampless/runtime": "^1.0.0-alpha.13",
25
+ "@ampless/plugin-og-image": "^0.2.0-alpha.10",
26
+ "@ampless/plugin-rss": "^0.2.0-alpha.10",
27
+ "@ampless/plugin-seo": "^0.2.0-alpha.10",
28
+ "@ampless/plugin-webhook": "^0.2.0-alpha.10",
29
+ "@ampless/admin": "^1.0.0-alpha.27",
30
+ "@ampless/backend": "^1.0.0-alpha.20",
31
+ "@ampless/runtime": "^1.0.0-alpha.14",
32
32
  "@digital-go-jp/tailwind-theme-plugin": "^0.3.4",
33
- "ampless": "^1.0.0-alpha.9",
33
+ "ampless": "^1.0.0-alpha.10",
34
34
  "aws-amplify": "^6.10.0",
35
35
  "class-variance-authority": "^0.7.1",
36
36
  "clsx": "^2.1.1",
@@ -1,18 +1,32 @@
1
1
  // Public-site proxy (Next.js 16 rename of "middleware"). Implementation
2
2
  // moved to `@ampless/runtime` (L1 extraction); this file wires the
3
- // project's `cms.config` into the factory and re-exports the default
4
- // matcher. The runtime export name is still `createAmplessMiddleware`
5
- // for API stability; only the user-side file convention (proxy.ts +
6
- // `export const proxy`) follows Next 16's rename.
3
+ // project's `cms.config` + AppSync endpoint into the factory and
4
+ // re-exports the default matcher. The runtime export name is still
5
+ // `createAmplessMiddleware` for API stability; only the user-side
6
+ // file convention (proxy.ts + `export const proxy`) follows Next 16's
7
+ // rename.
7
8
  //
8
- // See `@ampless/runtime/middleware` for behaviour details:
9
- // `/path` `/site/default/path` rewrite, `?previewTheme=` header
10
- // forwarding.
9
+ // See `@ampless/runtime/middleware` for behaviour details: AppSync
10
+ // flag fetch + Lambda-memory LRU + `/r/<slug>(/<path>)` rewrite for
11
+ // no_layout HTML / static bundles + per-post Cache-Control.
11
12
 
12
13
  import cmsConfig from './cms.config'
14
+ import outputs from './amplify_outputs.json'
13
15
  import { createAmplessMiddleware } from '@ampless/runtime/middleware'
14
16
 
15
- export const proxy = createAmplessMiddleware({ cmsConfig })
17
+ // `amplify_outputs.json` is generated by `npx ampx sandbox` /
18
+ // `npx ampx pipeline-deploy` — the public API key has a 365-day TTL
19
+ // and is rotated monthly by the api-key-renewer Lambda. See
20
+ // RUNBOOK.md §"API key rotation".
21
+ export const proxy = createAmplessMiddleware({
22
+ cmsConfig,
23
+ appsyncUrl: outputs.data.url,
24
+ // The public API key is always present in production deploys (the
25
+ // backend declares `apiKeyAuthorizationMode`). The non-null assertion
26
+ // is honest about the assumption; `ampx sandbox` will surface a clear
27
+ // error long before middleware ever runs if it ever isn't.
28
+ apiKey: outputs.data.api_key!,
29
+ })
16
30
 
17
31
  // Next.js 16's Turbopack requires `config` to be a statically
18
32
  // analysable object literal — referencing an imported variable
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-ampless",
3
- "version": "1.0.0-alpha.39",
3
+ "version": "1.0.0-alpha.42",
4
4
  "description": "Create a new ampless project",
5
5
  "license": "MIT",
6
6
  "type": "module",