create-ampless 0.2.0-alpha.0 → 0.2.0-alpha.10
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/README.md +36 -0
- package/dist/index.js +2098 -48
- package/dist/templates/_shared/amplify/auth/resource.ts +7 -2
- package/dist/templates/_shared/amplify/backend.custom.ts +41 -0
- package/dist/templates/_shared/amplify/backend.ts +10 -2
- package/dist/templates/_shared/amplify/data/resource.custom.ts +33 -0
- package/dist/templates/_shared/amplify/data/resource.ts +23 -15
- package/dist/templates/_shared/amplify/functions/user-admin/handler.ts +4 -0
- package/dist/templates/_shared/amplify/functions/user-admin/resource.ts +6 -0
- package/dist/templates/_shared/amplify/storage/resource.ts +7 -2
- package/dist/templates/_shared/amplify.yml +18 -0
- package/dist/templates/_shared/app/(admin)/admin/users/page.tsx +5 -0
- package/dist/templates/_shared/app/site/[siteId]/[...path]/route.ts +17 -0
- package/dist/templates/_shared/components/i18n-provider.tsx +8 -0
- package/dist/templates/_shared/lib/admin-site.ts +6 -2
- package/dist/templates/_shared/lib/admin.ts +10 -4
- package/dist/templates/_shared/lib/amplify.ts +17 -6
- package/dist/templates/_shared/lib/auth-server.ts +7 -3
- package/dist/templates/_shared/lib/i18n.ts +5 -1
- package/dist/templates/_shared/lib/posts-public.ts +11 -3
- package/dist/templates/_shared/lib/seo.ts +5 -2
- package/dist/templates/_shared/lib/site-settings.ts +4 -1
- package/dist/templates/_shared/lib/storage.ts +5 -2
- package/dist/templates/_shared/lib/theme-active.ts +3 -1
- package/dist/templates/_shared/lib/theme-config.ts +3 -1
- package/dist/templates/_shared/package.json +22 -19
- package/dist/templates/_shared/proxy.ts +33 -0
- package/package.json +3 -2
- package/dist/templates/_shared/middleware.ts +0 -13
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineAuth } from '@aws-amplify/backend'
|
|
2
|
+
import { amplessAuthConfig } from '@ampless/backend'
|
|
2
3
|
import { postConfirmation } from './post-confirmation/resource.js'
|
|
3
4
|
|
|
4
5
|
// Provisions a Cognito User Pool + Identity Pool with the three role
|
|
5
6
|
// groups (ampless-admin, ampless-editor, ampless-reader) and wires in
|
|
6
7
|
// the post-confirmation Lambda that promotes the first confirmed user
|
|
7
8
|
// to ampless-admin.
|
|
8
|
-
|
|
9
|
+
//
|
|
10
|
+
// `defineAuth` must be called from this file directly — Amplify Gen 2's
|
|
11
|
+
// import-path verifier requires it to live at amplify/auth/resource.ts.
|
|
12
|
+
// `amplessAuthConfig` just returns the props object.
|
|
13
|
+
export const auth = defineAuth(amplessAuthConfig({ postConfirmation }))
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { AmplessBackend } from '@ampless/backend'
|
|
2
|
+
|
|
3
|
+
// Custom backend extensions for this project.
|
|
4
|
+
//
|
|
5
|
+
// `amplify/backend.ts` calls `customizeBackend(backend)` right after
|
|
6
|
+
// ampless's baseline wiring. Mutate the passed `backend` instance to
|
|
7
|
+
// add Lambda permissions, attach event sources, register custom CDK
|
|
8
|
+
// constructs, etc.
|
|
9
|
+
//
|
|
10
|
+
// This file is NEVER overwritten by `create-ampless upgrade` —
|
|
11
|
+
// `amplify/backend.ts` is, so keep your customizations here.
|
|
12
|
+
//
|
|
13
|
+
// (Function-export rather than side-effect import on purpose: a
|
|
14
|
+
// top-level `import { backend } from './backend.js'` would create an
|
|
15
|
+
// ESM circular dependency, leaving `backend` in its TDZ at evaluation
|
|
16
|
+
// time. The factory pattern sidesteps that.)
|
|
17
|
+
//
|
|
18
|
+
// Example: granting an existing ampless Lambda extra IAM permissions:
|
|
19
|
+
//
|
|
20
|
+
// import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam'
|
|
21
|
+
//
|
|
22
|
+
// export function customizeBackend(backend: AmplessBackend): void {
|
|
23
|
+
// backend.processorTrusted.resources.lambda.addToRolePolicy(
|
|
24
|
+
// new PolicyStatement({
|
|
25
|
+
// effect: Effect.ALLOW,
|
|
26
|
+
// actions: ['ses:SendEmail'],
|
|
27
|
+
// resources: ['*'],
|
|
28
|
+
// })
|
|
29
|
+
// )
|
|
30
|
+
// }
|
|
31
|
+
//
|
|
32
|
+
// Example: adding your own Lambda function — define it in
|
|
33
|
+
// `amplify/functions/<name>/resource.ts`, import it here, and attach
|
|
34
|
+
// it inside `customizeBackend` via `backend.createStack(...)` or by
|
|
35
|
+
// granting it permissions on existing resources.
|
|
36
|
+
//
|
|
37
|
+
// If you don't need any extensions, leave the body empty.
|
|
38
|
+
|
|
39
|
+
export function customizeBackend(_backend: AmplessBackend): void {
|
|
40
|
+
// No-op by default.
|
|
41
|
+
}
|
|
@@ -8,13 +8,16 @@ import { eventDispatcher } from './events/dispatcher/resource.js'
|
|
|
8
8
|
import { processorTrusted } from './events/processor-trusted/resource.js'
|
|
9
9
|
import { processorUntrusted } from './events/processor-untrusted/resource.js'
|
|
10
10
|
import { apiKeyRenewer } from './functions/api-key-renewer/resource.js'
|
|
11
|
+
import { userAdmin } from './functions/user-admin/resource.js'
|
|
12
|
+
import { customizeBackend } from './backend.custom.js'
|
|
11
13
|
|
|
12
14
|
// `defineAmplessBackend` provisions auth, data, storage, the event
|
|
13
15
|
// system (DynamoDB Streams → SQS-trusted / SQS-untrusted → trust_level
|
|
14
16
|
// Lambdas), the AppSync API key renewer, and every IAM / CORS /
|
|
15
17
|
// password policy override. Add custom CDK constructs / IAM policies
|
|
16
|
-
//
|
|
17
|
-
// returns the same object Amplify Gen 2's
|
|
18
|
+
// in `amplify/backend.custom.ts` by mutating the `backend` instance —
|
|
19
|
+
// `defineAmplessBackend` returns the same object Amplify Gen 2's
|
|
20
|
+
// `defineBackend` does.
|
|
18
21
|
const backend = defineAmplessBackend({
|
|
19
22
|
auth,
|
|
20
23
|
data,
|
|
@@ -24,6 +27,11 @@ const backend = defineAmplessBackend({
|
|
|
24
27
|
processorTrusted,
|
|
25
28
|
processorUntrusted,
|
|
26
29
|
apiKeyRenewer,
|
|
30
|
+
userAdmin,
|
|
27
31
|
})
|
|
28
32
|
|
|
33
|
+
// Run user-defined customizations after baseline wiring. `backend.custom.ts`
|
|
34
|
+
// is never overwritten by `create-ampless upgrade`.
|
|
35
|
+
customizeBackend(backend)
|
|
36
|
+
|
|
29
37
|
export default backend
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Custom data schema models for this project.
|
|
2
|
+
//
|
|
3
|
+
// `amplify/data/resource.ts` calls `customSchemaModels(a)` and spreads
|
|
4
|
+
// the result alongside ampless's built-in models in the same
|
|
5
|
+
// `a.schema({...})` call, which is the only way Amplify Gen 2's
|
|
6
|
+
// `ClientSchema<typeof schema>` inference picks up extra models.
|
|
7
|
+
//
|
|
8
|
+
// This file is NEVER overwritten by `create-ampless upgrade` —
|
|
9
|
+
// `amplify/data/resource.ts` is, so keep your custom models here.
|
|
10
|
+
//
|
|
11
|
+
// Example:
|
|
12
|
+
//
|
|
13
|
+
// export function customSchemaModels(a: any) {
|
|
14
|
+
// return {
|
|
15
|
+
// Bookmark: a
|
|
16
|
+
// .model({
|
|
17
|
+
// siteId: a.string().required(),
|
|
18
|
+
// bookmarkId: a.id().required(),
|
|
19
|
+
// url: a.string().required(),
|
|
20
|
+
// title: a.string(),
|
|
21
|
+
// })
|
|
22
|
+
// .identifier(['siteId', 'bookmarkId'])
|
|
23
|
+
// .authorization((allow: any) => [allow.groups(['ampless-admin', 'ampless-editor'])]),
|
|
24
|
+
// }
|
|
25
|
+
// }
|
|
26
|
+
//
|
|
27
|
+
// `a` is the Amplify Gen 2 schema builder; see Amplify Data docs for
|
|
28
|
+
// the full DSL. Return an empty object if no customizations are needed.
|
|
29
|
+
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
+
export function customSchemaModels(_a: any): Record<string, unknown> {
|
|
32
|
+
return {}
|
|
33
|
+
}
|
|
@@ -1,26 +1,34 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
2
|
+
import { dirname, resolve } from 'node:path'
|
|
1
3
|
import { a, defineData, type ClientSchema } from '@aws-amplify/backend'
|
|
2
4
|
import { amplessSchemaModels, defaultAuthorizationModes } from '@ampless/backend'
|
|
5
|
+
import { userAdmin } from '../functions/user-admin/resource.js'
|
|
6
|
+
import { customSchemaModels } from './resource.custom.js'
|
|
7
|
+
|
|
8
|
+
// AppSync's `a.handler.custom({ entry })` paths are resolved by CDK
|
|
9
|
+
// relative to the file that called `a.handler.custom`. When the call
|
|
10
|
+
// originates inside `@ampless/backend` (via amplessSchemaModels), the
|
|
11
|
+
// CDK synth tries to resolve `./list-published-posts.js` relative to
|
|
12
|
+
// `node_modules/@ampless/backend/dist/index.js` and fails with
|
|
13
|
+
// `UnresolvedEntryPathError`. Anchor the resolver paths at THIS file's
|
|
14
|
+
// directory so the result is unambiguous.
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
3
16
|
|
|
4
17
|
// Ampless's built-in models (Post / Page / Media / Taxonomy / PostTag /
|
|
5
18
|
// KvStore) plus the three public-read custom queries
|
|
6
19
|
// (listPublishedPosts / getPublishedPost / listPostsByTag).
|
|
7
20
|
//
|
|
8
|
-
// Add project-specific models
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// })
|
|
17
|
-
//
|
|
18
|
-
// The three AppSync JS resolvers (`*.js` in this directory) stay
|
|
19
|
-
// user-owned — AppSync resolves `entry: './...'` paths at synth time
|
|
20
|
-
// relative to this file. If you relocate them, pass new paths via
|
|
21
|
-
// `amplessSchemaModels(a, { resolverPaths: { ... } })`.
|
|
21
|
+
// Add project-specific models in `amplify/data/resource.custom.ts` —
|
|
22
|
+
// that file is never overwritten by `create-ampless upgrade`.
|
|
23
|
+
const resolverPaths = {
|
|
24
|
+
listPublishedPosts: resolve(__dirname, 'list-published-posts.js'),
|
|
25
|
+
getPublishedPost: resolve(__dirname, 'get-published-post.js'),
|
|
26
|
+
listPostsByTag: resolve(__dirname, 'list-posts-by-tag.js'),
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
const schema = a.schema({
|
|
23
|
-
...amplessSchemaModels(a),
|
|
30
|
+
...amplessSchemaModels(a, { resolverPaths, userAdminFunction: userAdmin }),
|
|
31
|
+
...customSchemaModels(a),
|
|
24
32
|
})
|
|
25
33
|
|
|
26
34
|
export type Schema = ClientSchema<typeof schema>
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineStorage } from '@aws-amplify/backend'
|
|
2
|
+
import { amplessStorageConfig } from '@ampless/backend'
|
|
2
3
|
|
|
3
4
|
// Provisions the ampless media + plugins bucket with guest read on
|
|
4
5
|
// `public/*` and admin/editor write on the matched prefixes. CORS and
|
|
5
6
|
// the bucket-level public-access policy are applied by
|
|
6
7
|
// defineAmplessBackend.
|
|
7
|
-
|
|
8
|
+
//
|
|
9
|
+
// `defineStorage` must be called from this file directly — Amplify Gen 2's
|
|
10
|
+
// import-path verifier requires it to live at amplify/storage/resource.ts.
|
|
11
|
+
// `amplessStorageConfig` just returns the props object.
|
|
12
|
+
export const storage = defineStorage(amplessStorageConfig())
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
frontend:
|
|
3
|
+
phases:
|
|
4
|
+
preBuild:
|
|
5
|
+
commands:
|
|
6
|
+
- npm install
|
|
7
|
+
build:
|
|
8
|
+
commands:
|
|
9
|
+
- npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
|
|
10
|
+
- npm run build
|
|
11
|
+
artifacts:
|
|
12
|
+
baseDirectory: .next
|
|
13
|
+
files:
|
|
14
|
+
- '**/*'
|
|
15
|
+
cache:
|
|
16
|
+
paths:
|
|
17
|
+
- node_modules/**/*
|
|
18
|
+
- .next/cache/**/*
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ampless } from '@/lib/ampless'
|
|
2
|
+
import { createStaticRouteHandler } from '@ampless/runtime/routes'
|
|
3
|
+
|
|
4
|
+
// Catch-all handler for `format: 'static'` post bundles. Lives here
|
|
5
|
+
// instead of under a dedicated `/static/` prefix so the published URL
|
|
6
|
+
// stays a clean `/<slug>/…`, matching how a developer would host a
|
|
7
|
+
// hand-written landing page locally. The runtime handler enforces
|
|
8
|
+
// `format === 'static'` and 404s for any other post format reaching
|
|
9
|
+
// this route.
|
|
10
|
+
//
|
|
11
|
+
// Routing precedence: Next.js prefers the more specific
|
|
12
|
+
// `[siteId]/[slug]/page.tsx` for single-segment URLs, so the regular
|
|
13
|
+
// theme post dispatcher keeps handling normal posts. This catch-all
|
|
14
|
+
// only fires for multi-segment requests (e.g. `/promo/index.html`,
|
|
15
|
+
// `/promo/assets/style.css`).
|
|
16
|
+
export const dynamic = 'force-dynamic'
|
|
17
|
+
export const GET = createStaticRouteHandler(ampless)
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
1
3
|
// Back-compat shim. I18n provider + hooks moved to `@ampless/admin`
|
|
2
4
|
// (L2 extraction). The component tree mounts the provider inside the
|
|
3
5
|
// admin layout factory; the root layout in `app/layout.tsx` still
|
|
4
6
|
// wraps the public site in this same provider to keep client-side
|
|
5
7
|
// `useT()` calls working from theme-side components too.
|
|
8
|
+
//
|
|
9
|
+
// The `'use client'` directive is needed because the bundled
|
|
10
|
+
// @ampless/admin/components ESM strips per-file 'use client' (tsup
|
|
11
|
+
// default behaviour). This shim re-establishes a client boundary so
|
|
12
|
+
// Next.js doesn't try to evaluate the React hooks inside an RSC
|
|
13
|
+
// server context.
|
|
6
14
|
|
|
7
15
|
export { I18nProvider, useT, useLocale } from '@ampless/admin/components'
|
|
@@ -4,5 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
import { admin } from './admin'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// Arrow wrappers: defer `admin` resolution to call time (avoid TDZ in
|
|
8
|
+
// case of circular import chains touching admin shims).
|
|
9
|
+
export const currentAdminSiteId: typeof admin.currentAdminSiteId =
|
|
10
|
+
(...args) => admin.currentAdminSiteId(...args)
|
|
11
|
+
export const adminSiteOptions: typeof admin.adminSiteOptions =
|
|
12
|
+
(...args) => admin.adminSiteOptions(...args)
|
|
@@ -4,18 +4,24 @@
|
|
|
4
4
|
//
|
|
5
5
|
// L2 architectural change (admin extraction): admin UI now lives in
|
|
6
6
|
// `@ampless/admin`. This module wires the project's
|
|
7
|
-
// `amplify_outputs.json
|
|
8
|
-
//
|
|
7
|
+
// `amplify_outputs.json` and `cms.config` into a single `Admin`
|
|
8
|
+
// instance.
|
|
9
|
+
//
|
|
10
|
+
// NOTE: We intentionally do NOT pass an `ampless` instance to
|
|
11
|
+
// createAdmin. That would import `lib/ampless.ts`, which imports
|
|
12
|
+
// `themes-registry`, which (via theme pages → `lib/i18n.ts`) imports
|
|
13
|
+
// back to this file — a circular chain that crashes with a TDZ
|
|
14
|
+
// ReferenceError on `ampless` at module init. `createAdmin` builds
|
|
15
|
+
// its own internal Ampless when omitted, which is functionally
|
|
16
|
+
// equivalent for admin's needs.
|
|
9
17
|
|
|
10
18
|
import outputs from '../amplify_outputs.json'
|
|
11
19
|
import cmsConfig from '@/cms.config'
|
|
12
20
|
import { createAdmin } from '@ampless/admin'
|
|
13
|
-
import { ampless } from './ampless'
|
|
14
21
|
|
|
15
22
|
export const admin = createAdmin({
|
|
16
23
|
outputs,
|
|
17
24
|
cmsConfig,
|
|
18
|
-
ampless,
|
|
19
25
|
locale: (cmsConfig as { locale?: string }).locale ?? 'en',
|
|
20
26
|
})
|
|
21
27
|
|
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
1
|
+
// Client-side Amplify SDK setup. Imported as a side-effect from
|
|
2
|
+
// `app/providers.tsx` so it runs on every page load (public + admin +
|
|
3
|
+
// login). `<AdminProviders>` (mounted by the admin layout factory)
|
|
4
|
+
// also performs this configuration, but it only runs for routes under
|
|
5
|
+
// the (admin) group; `/login` is a top-level route outside that group
|
|
6
|
+
// and would otherwise hit "Auth UserPool not configured" because no
|
|
7
|
+
// AdminProviders has bootstrapped the SDK yet.
|
|
8
|
+
//
|
|
9
|
+
// `Amplify.configure` is idempotent — calling it once at the root and
|
|
10
|
+
// again inside AdminProviders is harmless.
|
|
11
|
+
|
|
12
|
+
import { Amplify } from 'aws-amplify'
|
|
13
|
+
import outputs from '../amplify_outputs.json'
|
|
14
|
+
|
|
15
|
+
Amplify.configure(outputs, { ssr: true })
|
|
6
16
|
|
|
7
17
|
export function configureAmplify() {
|
|
8
|
-
//
|
|
18
|
+
// module-level side effect above already ran; keep this as a no-op
|
|
19
|
+
// for callers that still import it as a function for back-compat.
|
|
9
20
|
}
|
|
@@ -6,6 +6,10 @@ import { admin } from './admin'
|
|
|
6
6
|
|
|
7
7
|
export type { ServerSession } from '@ampless/admin'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
export const
|
|
11
|
-
|
|
9
|
+
// Arrow wrappers: defer `admin` resolution to call time (avoid TDZ).
|
|
10
|
+
export const getServerSession: typeof admin.getServerSession =
|
|
11
|
+
(...args) => admin.getServerSession(...args)
|
|
12
|
+
export const isAdmin: typeof admin.isAdmin =
|
|
13
|
+
(...args) => admin.isAdmin(...args)
|
|
14
|
+
export const isEditor: typeof admin.isEditor =
|
|
15
|
+
(...args) => admin.isEditor(...args)
|
|
@@ -20,7 +20,11 @@ export function getDictionary(locale: Locale = admin.locale): Dictionary {
|
|
|
20
20
|
return adminGetDictionary(locale)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
// Arrow wrapper: defer `admin` resolution to call time. If a future
|
|
24
|
+
// circular import chain triggers i18n.ts before admin.ts has finished
|
|
25
|
+
// initialising, eager `admin.t` would TDZ; calling the method through
|
|
26
|
+
// a wrapper avoids that.
|
|
27
|
+
export const t: typeof admin.t = (key, vars) => admin.t(key, vars)
|
|
24
28
|
|
|
25
29
|
export function translate(
|
|
26
30
|
_dict: Dictionary,
|
|
@@ -8,9 +8,17 @@
|
|
|
8
8
|
|
|
9
9
|
import { ampless } from './ampless'
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
// Arrow function wrappers (not `.bind(ampless)`) so the `ampless`
|
|
12
|
+
// binding is read at call time, not at module evaluation. Module
|
|
13
|
+
// evaluation can run while `lib/ampless.ts` is still in its TDZ
|
|
14
|
+
// because the themes-registry → theme → shim → ampless dependency
|
|
15
|
+
// chain is circular by construction.
|
|
16
|
+
export const listPublishedPosts: typeof ampless.listPublishedPosts =
|
|
17
|
+
(...args) => ampless.listPublishedPosts(...args)
|
|
18
|
+
export const getPublishedPost: typeof ampless.getPublishedPost =
|
|
19
|
+
(...args) => ampless.getPublishedPost(...args)
|
|
20
|
+
export const listPostsByTag: typeof ampless.listPostsByTag =
|
|
21
|
+
(...args) => ampless.listPostsByTag(...args)
|
|
14
22
|
|
|
15
23
|
export type {
|
|
16
24
|
ListPostsOptions,
|
|
@@ -4,5 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { ampless } from './ampless'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
export const
|
|
7
|
+
// Arrow wrappers: defer `ampless` resolution to call time (avoid TDZ).
|
|
8
|
+
export const postMetadata: typeof ampless.postMetadata =
|
|
9
|
+
(...args) => ampless.postMetadata(...args)
|
|
10
|
+
export const siteMetadata: typeof ampless.siteMetadata =
|
|
11
|
+
(...args) => ampless.siteMetadata(...args)
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
import { ampless } from './ampless'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// Arrow wrapper: defer `ampless` resolution to call time (avoid TDZ in
|
|
7
|
+
// the themes-registry → theme → shim → ampless circular import chain).
|
|
8
|
+
export const loadSiteSettings: typeof ampless.loadSiteSettings =
|
|
9
|
+
(...args) => ampless.loadSiteSettings(...args)
|
|
7
10
|
|
|
8
11
|
export type { EffectiveSiteSettings } from '@ampless/runtime'
|
|
@@ -3,5 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
import { ampless } from './ampless'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
export const
|
|
6
|
+
// Arrow wrappers: defer `ampless` resolution to call time (avoid TDZ).
|
|
7
|
+
export const publicAssetUrl: typeof ampless.publicAssetUrl =
|
|
8
|
+
(...args) => ampless.publicAssetUrl(...args)
|
|
9
|
+
export const isStorageConfigured: typeof ampless.isStorageConfigured =
|
|
10
|
+
(...args) => ampless.isStorageConfigured(...args)
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
import { ampless } from './ampless'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// Arrow wrapper: defer `ampless` resolution to call time (avoid TDZ).
|
|
7
|
+
export const resolveActiveTheme: typeof ampless.resolveActiveTheme =
|
|
8
|
+
(...args) => ampless.resolveActiveTheme(...args)
|
|
7
9
|
|
|
8
10
|
export type { ResolvedTheme } from '@ampless/runtime'
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
import { ampless } from './ampless'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// Arrow wrapper: defer `ampless` resolution to call time (avoid TDZ).
|
|
7
|
+
export const loadThemeConfig: typeof ampless.loadThemeConfig =
|
|
8
|
+
(...args) => ampless.loadThemeConfig(...args)
|
|
7
9
|
|
|
8
10
|
export { renderThemeCss } from '@ampless/runtime'
|
|
9
11
|
|
|
@@ -8,36 +8,39 @@
|
|
|
8
8
|
"build": "next build",
|
|
9
9
|
"start": "next start",
|
|
10
10
|
"lint": "next lint",
|
|
11
|
-
"sandbox": "ampx sandbox"
|
|
11
|
+
"sandbox": "ampx sandbox",
|
|
12
|
+
"sandbox:dev": "ampx sandbox --once && next dev",
|
|
13
|
+
"update-ampless": "npx create-ampless@latest upgrade",
|
|
14
|
+
"copy-theme": "npx create-ampless@latest copy-theme"
|
|
12
15
|
},
|
|
13
16
|
"dependencies": {
|
|
14
17
|
"@aws-amplify/adapter-nextjs": "^1.6.0",
|
|
15
18
|
"@radix-ui/react-dialog": "^1.1.4",
|
|
16
19
|
"@radix-ui/react-label": "^2.1.1",
|
|
17
20
|
"@radix-ui/react-slot": "^1.1.1",
|
|
18
|
-
"@tiptap/extension-image": "^
|
|
19
|
-
"@tiptap/extension-link": "^
|
|
20
|
-
"@tiptap/pm": "^
|
|
21
|
-
"@tiptap/react": "^
|
|
22
|
-
"@tiptap/starter-kit": "^
|
|
23
|
-
"@ampless/plugin-og-image": "^0.2.0-alpha.
|
|
24
|
-
"@ampless/plugin-rss": "^0.2.0-alpha.
|
|
25
|
-
"@ampless/plugin-seo": "^0.2.0-alpha.
|
|
26
|
-
"@ampless/plugin-webhook": "^0.2.0-alpha.
|
|
27
|
-
"@ampless/admin": "^0.2.0-alpha.
|
|
28
|
-
"@ampless/backend": "^0.2.0-alpha.
|
|
29
|
-
"@ampless/runtime": "^0.2.0-alpha.
|
|
21
|
+
"@tiptap/extension-image": "^3.23.4",
|
|
22
|
+
"@tiptap/extension-link": "^3.23.4",
|
|
23
|
+
"@tiptap/pm": "^3.23.4",
|
|
24
|
+
"@tiptap/react": "^3.23.4",
|
|
25
|
+
"@tiptap/starter-kit": "^3.23.4",
|
|
26
|
+
"@ampless/plugin-og-image": "^0.2.0-alpha.3",
|
|
27
|
+
"@ampless/plugin-rss": "^0.2.0-alpha.3",
|
|
28
|
+
"@ampless/plugin-seo": "^0.2.0-alpha.3",
|
|
29
|
+
"@ampless/plugin-webhook": "^0.2.0-alpha.3",
|
|
30
|
+
"@ampless/admin": "^0.2.0-alpha.10",
|
|
31
|
+
"@ampless/backend": "^0.2.0-alpha.4",
|
|
32
|
+
"@ampless/runtime": "^0.2.0-alpha.5",
|
|
30
33
|
"@digital-go-jp/tailwind-theme-plugin": "^0.3.4",
|
|
31
|
-
"ampless": "^0.2.0-alpha.
|
|
34
|
+
"ampless": "^0.2.0-alpha.3",
|
|
32
35
|
"aws-amplify": "^6.10.0",
|
|
33
36
|
"class-variance-authority": "^0.7.1",
|
|
34
37
|
"clsx": "^2.1.1",
|
|
35
|
-
"lucide-react": "^
|
|
36
|
-
"next": "^
|
|
38
|
+
"lucide-react": "^1.16.0",
|
|
39
|
+
"next": "^16.2.6",
|
|
37
40
|
"react": "^19.0.0",
|
|
38
41
|
"react-dom": "^19.0.0",
|
|
39
42
|
"react-image-crop": "^11.0.7",
|
|
40
|
-
"tailwind-merge": "^
|
|
43
|
+
"tailwind-merge": "^3.6.0"
|
|
41
44
|
},
|
|
42
45
|
"devDependencies": {
|
|
43
46
|
"@aws-amplify/backend": "^1.13.0",
|
|
@@ -45,7 +48,7 @@
|
|
|
45
48
|
"@aws-sdk/client-appsync": "^3.717.0",
|
|
46
49
|
"@aws-sdk/client-cognito-identity-provider": "^3.717.0",
|
|
47
50
|
"@aws-sdk/client-dynamodb": "^3.717.0",
|
|
48
|
-
"@aws-sdk/client-s3": "^3.
|
|
51
|
+
"@aws-sdk/client-s3": "^3.1048.0",
|
|
49
52
|
"@aws-sdk/client-sqs": "^3.717.0",
|
|
50
53
|
"@aws-sdk/lib-dynamodb": "^3.717.0",
|
|
51
54
|
"@aws-sdk/util-dynamodb": "^3.717.0",
|
|
@@ -58,6 +61,6 @@
|
|
|
58
61
|
"aws-cdk-lib": "^2.174.0",
|
|
59
62
|
"postcss": "^8.4.0",
|
|
60
63
|
"tailwindcss": "^4.0.0",
|
|
61
|
-
"typescript": "^
|
|
64
|
+
"typescript": "^6.0.3"
|
|
62
65
|
}
|
|
63
66
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Public-site proxy (Next.js 16 rename of "middleware"). Implementation
|
|
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.
|
|
7
|
+
//
|
|
8
|
+
// See `@ampless/runtime/middleware` for behaviour details: multi-site
|
|
9
|
+
// host rewrite, `<slug>.html` → raw route, `?previewTheme=` header
|
|
10
|
+
// forwarding, multi-site Cache-Control override.
|
|
11
|
+
|
|
12
|
+
import cmsConfig from './cms.config'
|
|
13
|
+
import { createAmplessMiddleware } from '@ampless/runtime/middleware'
|
|
14
|
+
|
|
15
|
+
export const proxy = createAmplessMiddleware({ cmsConfig })
|
|
16
|
+
|
|
17
|
+
// Next.js 16's Turbopack requires `config` to be a statically
|
|
18
|
+
// analysable object literal — referencing an imported variable
|
|
19
|
+
// (e.g. `defaultMatcherConfig` from @ampless/runtime/middleware)
|
|
20
|
+
// causes a build error:
|
|
21
|
+
// "Next.js can't recognize the exported `config` field in route.
|
|
22
|
+
// It needs to be a static object."
|
|
23
|
+
//
|
|
24
|
+
// So we inline the matcher here. If you change it, keep it in sync
|
|
25
|
+
// with `defaultMatcherConfig` documented in @ampless/runtime/middleware.
|
|
26
|
+
// The matcher excludes admin / api / login / static assets /
|
|
27
|
+
// amplify_outputs.json so the public-site proxy doesn't rewrite
|
|
28
|
+
// legitimate non-blog routes.
|
|
29
|
+
export const config = {
|
|
30
|
+
matcher: [
|
|
31
|
+
'/((?!admin|api|login|_next/static|_next/image|favicon\\.ico|amplify_outputs\\.json).*)',
|
|
32
|
+
],
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ampless",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.10",
|
|
4
4
|
"description": "Create a new ampless project",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"homepage": "https://github.com/heavymoons/ampless#readme",
|
|
23
23
|
"bugs": "https://github.com/heavymoons/ampless/issues",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@clack/prompts": "^
|
|
25
|
+
"@clack/prompts": "^1.4.0",
|
|
26
|
+
"execa": "^9.6.1",
|
|
26
27
|
"picocolors": "^1.1.1"
|
|
27
28
|
},
|
|
28
29
|
"keywords": [
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// Public-site middleware. Implementation moved to `@ampless/runtime`
|
|
2
|
-
// (L1 extraction); this file wires the project's `cms.config` into
|
|
3
|
-
// the factory and re-exports the default matcher.
|
|
4
|
-
//
|
|
5
|
-
// See `@ampless/runtime/middleware` for behaviour details: multi-site
|
|
6
|
-
// host rewrite, `<slug>.html` → raw route, `?previewTheme=` header
|
|
7
|
-
// forwarding, multi-site Cache-Control override.
|
|
8
|
-
|
|
9
|
-
import cmsConfig from './cms.config'
|
|
10
|
-
import { createAmplessMiddleware, defaultMatcherConfig } from '@ampless/runtime/middleware'
|
|
11
|
-
|
|
12
|
-
export const middleware = createAmplessMiddleware({ cmsConfig })
|
|
13
|
-
export const config = defaultMatcherConfig
|