create-smoodly-app 0.0.51 → 0.0.52
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 +22 -33
- package/dist/index.js +87 -347
- package/package.json +4 -5
- package/templates/astro-blank/AGENTS.md +2 -8
- package/templates/astro-blank/README.md +13 -23
- package/templates/astro-blank/package.json +2 -3
- package/templates/astro-blank/scripts/seed.ts +9 -3
- package/templates/astro-blank/src/smoodly/collections.ts +2 -2
- package/templates/astro-blank-intl/AGENTS.md +2 -8
- package/templates/astro-blank-intl/README.md +13 -23
- package/templates/astro-blank-intl/package.json +2 -3
- package/templates/astro-blank-intl/scripts/seed.ts +9 -3
- package/templates/astro-blank-intl/src/smoodly/collections.ts +2 -2
- package/templates/astro-lorem/AGENTS.md +2 -8
- package/templates/astro-lorem/README.md +12 -16
- package/templates/astro-lorem/package.json +2 -3
- package/templates/astro-lorem/scripts/seed.ts +9 -3
- package/templates/astro-lorem/src/components/sections/PageHero.schema.ts +3 -1
- package/templates/astro-lorem/src/sections/pageHero.astro +1 -1
- package/templates/astro-lorem-intl/AGENTS.md +2 -8
- package/templates/astro-lorem-intl/README.md +12 -16
- package/templates/astro-lorem-intl/package.json +2 -3
- package/templates/astro-lorem-intl/scripts/seed.ts +9 -3
- package/templates/astro-lorem-intl/src/components/sections/PageHero.schema.ts +3 -1
- package/templates/astro-lorem-intl/src/sections/pageHero.astro +1 -1
- package/templates/blank/AGENTS.md +7 -13
- package/templates/blank/README.md +12 -22
- package/templates/blank/app/(smoodly)/admin/[[...segments]]/route.ts +6 -5
- package/templates/blank/next.config.ts +1 -4
- package/templates/blank/package.json +4 -4
- package/templates/blank/scripts/seed.ts +9 -3
- package/templates/blank/smoodly/collections.ts +2 -2
- package/templates/blank/smoodly/server.ts +24 -46
- package/templates/blank-intl/AGENTS.md +7 -13
- package/templates/blank-intl/README.md +12 -22
- package/templates/blank-intl/app/(smoodly)/admin/[[...segments]]/route.ts +6 -5
- package/templates/blank-intl/next.config.ts +1 -4
- package/templates/blank-intl/package.json +4 -4
- package/templates/blank-intl/scripts/seed.ts +9 -3
- package/templates/blank-intl/smoodly/collections.ts +2 -2
- package/templates/blank-intl/smoodly/server.ts +24 -46
- package/templates/blank-intl.tsconfig.json +0 -3
- package/templates/blank.tsconfig.json +0 -3
- package/templates/lorem/AGENTS.md +7 -13
- package/templates/lorem/README.md +13 -17
- package/templates/lorem/app/(smoodly)/admin/[[...segments]]/route.ts +6 -5
- package/templates/lorem/components/sections/PageHero.schema.ts +3 -1
- package/templates/lorem/components/sections/PageHero.tsx +1 -1
- package/templates/lorem/next.config.ts +1 -4
- package/templates/lorem/package.json +4 -4
- package/templates/lorem/scripts/seed.ts +9 -3
- package/templates/lorem/smoodly/server.ts +24 -46
- package/templates/lorem-intl/AGENTS.md +7 -13
- package/templates/lorem-intl/README.md +13 -17
- package/templates/lorem-intl/app/(smoodly)/admin/[[...segments]]/route.ts +6 -5
- package/templates/lorem-intl/components/sections/PageHero.schema.ts +3 -1
- package/templates/lorem-intl/components/sections/PageHero.tsx +1 -1
- package/templates/lorem-intl/next.config.ts +1 -4
- package/templates/lorem-intl/package.json +4 -4
- package/templates/lorem-intl/scripts/seed.ts +9 -3
- package/templates/lorem-intl/smoodly/server.ts +24 -46
- package/templates/lorem-intl.tsconfig.json +0 -3
- package/templates/lorem.tsconfig.json +0 -3
- package/templates/astro-blank/supabase/migrations/20260926120000_smoodly_v1.sql +0 -535
- package/templates/astro-blank/supabase/migrations/20260926130000_smoodly_v2.sql +0 -26
- package/templates/astro-blank/supabase/migrations/20260926140000_smoodly_v3.sql +0 -38
- package/templates/astro-blank/supabase/migrations/20260926150000_smoodly_v4.sql +0 -41
- package/templates/astro-blank/supabase/migrations/20260929120000_smoodly_v5.sql +0 -56
- package/templates/astro-blank/supabase/migrations/20260929135523_smoodly_v6.sql +0 -200
- package/templates/astro-blank/supabase/migrations/20260930040956_smoodly_v7.sql +0 -84
- package/templates/astro-blank/supabase/migrations/20261007120000_smoodly_v8.sql +0 -154
- package/templates/astro-blank/supabase/migrations/20261007200000_smoodly_v9.sql +0 -30
- package/templates/astro-blank/supabase/migrations/20261008120000_smoodly_v10.sql +0 -47
- package/templates/astro-blank/supabase/migrations/20261009120000_smoodly_v11.sql +0 -49
- package/templates/astro-blank/supabase/migrations/20261009120100_smoodly_views.sql +0 -20
- package/templates/astro-blank-intl/supabase/migrations/20260926120000_smoodly_v1.sql +0 -535
- package/templates/astro-blank-intl/supabase/migrations/20260926130000_smoodly_v2.sql +0 -26
- package/templates/astro-blank-intl/supabase/migrations/20260926140000_smoodly_v3.sql +0 -38
- package/templates/astro-blank-intl/supabase/migrations/20260926150000_smoodly_v4.sql +0 -41
- package/templates/astro-blank-intl/supabase/migrations/20260929120000_smoodly_v5.sql +0 -56
- package/templates/astro-blank-intl/supabase/migrations/20260929135523_smoodly_v6.sql +0 -200
- package/templates/astro-blank-intl/supabase/migrations/20260930040956_smoodly_v7.sql +0 -84
- package/templates/astro-blank-intl/supabase/migrations/20261007120000_smoodly_v8.sql +0 -154
- package/templates/astro-blank-intl/supabase/migrations/20261007200000_smoodly_v9.sql +0 -30
- package/templates/astro-blank-intl/supabase/migrations/20261008120000_smoodly_v10.sql +0 -47
- package/templates/astro-blank-intl/supabase/migrations/20261009120000_smoodly_v11.sql +0 -49
- package/templates/astro-blank-intl/supabase/migrations/20261009120100_smoodly_views.sql +0 -20
- package/templates/astro-lorem/supabase/migrations/20260926120000_smoodly_v1.sql +0 -535
- package/templates/astro-lorem/supabase/migrations/20260926130000_smoodly_v2.sql +0 -26
- package/templates/astro-lorem/supabase/migrations/20260926140000_smoodly_v3.sql +0 -38
- package/templates/astro-lorem/supabase/migrations/20260926150000_smoodly_v4.sql +0 -41
- package/templates/astro-lorem/supabase/migrations/20260929120000_smoodly_v5.sql +0 -56
- package/templates/astro-lorem/supabase/migrations/20260929135523_smoodly_v6.sql +0 -200
- package/templates/astro-lorem/supabase/migrations/20260930040956_smoodly_v7.sql +0 -84
- package/templates/astro-lorem/supabase/migrations/20261007120000_smoodly_v8.sql +0 -154
- package/templates/astro-lorem/supabase/migrations/20261007200000_smoodly_v9.sql +0 -30
- package/templates/astro-lorem/supabase/migrations/20261008120000_smoodly_v10.sql +0 -47
- package/templates/astro-lorem/supabase/migrations/20261009120000_smoodly_v11.sql +0 -49
- package/templates/astro-lorem/supabase/migrations/20261009120100_smoodly_views.sql +0 -58
- package/templates/astro-lorem-intl/supabase/migrations/20260926120000_smoodly_v1.sql +0 -535
- package/templates/astro-lorem-intl/supabase/migrations/20260926130000_smoodly_v2.sql +0 -26
- package/templates/astro-lorem-intl/supabase/migrations/20260926140000_smoodly_v3.sql +0 -38
- package/templates/astro-lorem-intl/supabase/migrations/20260926150000_smoodly_v4.sql +0 -41
- package/templates/astro-lorem-intl/supabase/migrations/20260929120000_smoodly_v5.sql +0 -56
- package/templates/astro-lorem-intl/supabase/migrations/20260929135523_smoodly_v6.sql +0 -200
- package/templates/astro-lorem-intl/supabase/migrations/20260930040956_smoodly_v7.sql +0 -84
- package/templates/astro-lorem-intl/supabase/migrations/20261007120000_smoodly_v8.sql +0 -154
- package/templates/astro-lorem-intl/supabase/migrations/20261007200000_smoodly_v9.sql +0 -30
- package/templates/astro-lorem-intl/supabase/migrations/20261008120000_smoodly_v10.sql +0 -47
- package/templates/astro-lorem-intl/supabase/migrations/20261009120000_smoodly_v11.sql +0 -49
- package/templates/astro-lorem-intl/supabase/migrations/20261009120100_smoodly_views.sql +0 -58
- package/templates/blank/supabase/migrations/20260926120000_smoodly_v1.sql +0 -535
- package/templates/blank/supabase/migrations/20260926130000_smoodly_v2.sql +0 -26
- package/templates/blank/supabase/migrations/20260926140000_smoodly_v3.sql +0 -38
- package/templates/blank/supabase/migrations/20260926150000_smoodly_v4.sql +0 -41
- package/templates/blank/supabase/migrations/20260929120000_smoodly_v5.sql +0 -56
- package/templates/blank/supabase/migrations/20260929135523_smoodly_v6.sql +0 -200
- package/templates/blank/supabase/migrations/20260930040956_smoodly_v7.sql +0 -84
- package/templates/blank/supabase/migrations/20261007120000_smoodly_v8.sql +0 -154
- package/templates/blank/supabase/migrations/20261007200000_smoodly_v9.sql +0 -30
- package/templates/blank/supabase/migrations/20261008120000_smoodly_v10.sql +0 -47
- package/templates/blank/supabase/migrations/20261009120000_smoodly_v11.sql +0 -49
- package/templates/blank/supabase/migrations/20261009120100_smoodly_views.sql +0 -20
- package/templates/blank-intl/supabase/migrations/20260926120000_smoodly_v1.sql +0 -535
- package/templates/blank-intl/supabase/migrations/20260926130000_smoodly_v2.sql +0 -26
- package/templates/blank-intl/supabase/migrations/20260926140000_smoodly_v3.sql +0 -38
- package/templates/blank-intl/supabase/migrations/20260926150000_smoodly_v4.sql +0 -41
- package/templates/blank-intl/supabase/migrations/20260929120000_smoodly_v5.sql +0 -56
- package/templates/blank-intl/supabase/migrations/20260929135523_smoodly_v6.sql +0 -200
- package/templates/blank-intl/supabase/migrations/20260930040956_smoodly_v7.sql +0 -84
- package/templates/blank-intl/supabase/migrations/20261007120000_smoodly_v8.sql +0 -154
- package/templates/blank-intl/supabase/migrations/20261007200000_smoodly_v9.sql +0 -30
- package/templates/blank-intl/supabase/migrations/20261008120000_smoodly_v10.sql +0 -47
- package/templates/blank-intl/supabase/migrations/20261009120000_smoodly_v11.sql +0 -49
- package/templates/blank-intl/supabase/migrations/20261009120100_smoodly_views.sql +0 -20
- package/templates/lorem/supabase/migrations/20260926120000_smoodly_v1.sql +0 -535
- package/templates/lorem/supabase/migrations/20260926130000_smoodly_v2.sql +0 -26
- package/templates/lorem/supabase/migrations/20260926140000_smoodly_v3.sql +0 -38
- package/templates/lorem/supabase/migrations/20260926150000_smoodly_v4.sql +0 -41
- package/templates/lorem/supabase/migrations/20260929120000_smoodly_v5.sql +0 -56
- package/templates/lorem/supabase/migrations/20260929135523_smoodly_v6.sql +0 -200
- package/templates/lorem/supabase/migrations/20260930040956_smoodly_v7.sql +0 -84
- package/templates/lorem/supabase/migrations/20261007120000_smoodly_v8.sql +0 -154
- package/templates/lorem/supabase/migrations/20261007200000_smoodly_v9.sql +0 -30
- package/templates/lorem/supabase/migrations/20261008120000_smoodly_v10.sql +0 -47
- package/templates/lorem/supabase/migrations/20261009120000_smoodly_v11.sql +0 -49
- package/templates/lorem/supabase/migrations/20261009120100_smoodly_views.sql +0 -58
- package/templates/lorem-intl/supabase/migrations/20260926120000_smoodly_v1.sql +0 -535
- package/templates/lorem-intl/supabase/migrations/20260926130000_smoodly_v2.sql +0 -26
- package/templates/lorem-intl/supabase/migrations/20260926140000_smoodly_v3.sql +0 -38
- package/templates/lorem-intl/supabase/migrations/20260926150000_smoodly_v4.sql +0 -41
- package/templates/lorem-intl/supabase/migrations/20260929120000_smoodly_v5.sql +0 -56
- package/templates/lorem-intl/supabase/migrations/20260929135523_smoodly_v6.sql +0 -200
- package/templates/lorem-intl/supabase/migrations/20260930040956_smoodly_v7.sql +0 -84
- package/templates/lorem-intl/supabase/migrations/20261007120000_smoodly_v8.sql +0 -154
- package/templates/lorem-intl/supabase/migrations/20261007200000_smoodly_v9.sql +0 -30
- package/templates/lorem-intl/supabase/migrations/20261008120000_smoodly_v10.sql +0 -47
- package/templates/lorem-intl/supabase/migrations/20261009120000_smoodly_v11.sql +0 -49
- package/templates/lorem-intl/supabase/migrations/20261009120100_smoodly_views.sql +0 -58
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Smoodly site
|
|
2
2
|
|
|
3
|
-
Created by `create-smoodly-app`. Content lives in
|
|
4
|
-
mounted at `/admin` by the `smoodly/astro` integration. AGENTS.md
|
|
5
|
-
rules for an agent (or a person) building the site.
|
|
3
|
+
Created by `create-smoodly-app`. Content lives in Smoodly's service; the
|
|
4
|
+
admin is mounted at `/admin` by the `smoodly/astro` integration. AGENTS.md
|
|
5
|
+
holds the rules for an agent (or a person) building the site.
|
|
6
6
|
|
|
7
7
|
npm run dev # http://localhost:4321 — /admin is the editor
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ rules for an agent (or a person) building the site.
|
|
|
19
19
|
- `src/live.config.ts` — the live collections the views read with `getLiveCollection` and `getLiveEntry`.
|
|
20
20
|
- `scripts/seed.ts` — the home page and the site item, written through `createContent(config)`. `npm run seed` is idempotent.
|
|
21
21
|
- `src/styles/global.css` — a reset, a container, the two tones. Replace it.
|
|
22
|
-
- `.env` — `
|
|
22
|
+
- `.env` — `SMOODLY_SPACE_ID`, `SMOODLY_SECRET_KEY`, `SMOODLY_PUBLISHABLE_KEY` (the space's values from smoodly.io) and `SITE_URL`.
|
|
23
23
|
|
|
24
24
|
## Add a section
|
|
25
25
|
|
|
@@ -46,13 +46,7 @@ editor's "/" menu.
|
|
|
46
46
|
Copy the `posts` block in `src/smoodly/collections.ts`, add the new
|
|
47
47
|
collection to `collections` and a loader for it in `src/live.config.ts`,
|
|
48
48
|
and write its entry page, `src/entry-pages/<collection>.astro`, by
|
|
49
|
-
copying `posts.astro`.
|
|
50
|
-
apply them:
|
|
51
|
-
|
|
52
|
-
npx smoodly migrate
|
|
53
|
-
supabase db push # hosted; `supabase migration up` for the local stack (keeps the content)
|
|
54
|
-
|
|
55
|
-
The same command brings the core schema forward after a `smoodly` upgrade.
|
|
49
|
+
copying `posts.astro`.
|
|
56
50
|
|
|
57
51
|
## Add a global item
|
|
58
52
|
|
|
@@ -60,7 +54,7 @@ Copy the `site` block in `src/smoodly/globals.ts`, add it to `globals`
|
|
|
60
54
|
and give it a loader in `src/live.config.ts`. A view reads it with
|
|
61
55
|
`getLiveEntry("name", { locale })`. Edit it under Globals in the admin.
|
|
62
56
|
|
|
63
|
-
Reseed an empty
|
|
57
|
+
Reseed an empty space any time with `npm run seed`.
|
|
64
58
|
|
|
65
59
|
## Moving the admin
|
|
66
60
|
|
|
@@ -73,16 +67,12 @@ The two must agree; the admin says so when they do not.
|
|
|
73
67
|
|
|
74
68
|
## Editors
|
|
75
69
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
(Authentication → Users), then in the SQL editor:
|
|
79
|
-
|
|
80
|
-
insert into editors (user_id, role) values ('<the user id>', 'editor');
|
|
81
|
-
|
|
82
|
-
## Hosted Supabase
|
|
70
|
+
Editors sign in at `/admin` with their smoodly.io account. Colleagues are
|
|
71
|
+
invited from the project at smoodly.io; the admin's Members page lists them.
|
|
83
72
|
|
|
84
|
-
|
|
85
|
-
supabase link # pick the project
|
|
86
|
-
supabase db push # applies supabase/migrations/
|
|
73
|
+
## Deploying
|
|
87
74
|
|
|
88
|
-
|
|
75
|
+
`.env` holds the preview space's values, for development. Where you
|
|
76
|
+
deploy, set the production space's three values and `SITE_URL` in the
|
|
77
|
+
host's environment variables; each build pushes the
|
|
78
|
+
schema to its space. https://smoodly.io/docs/getting-started/deploying
|
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "astro dev",
|
|
7
|
-
"build": "
|
|
7
|
+
"build": "astro build",
|
|
8
8
|
"start": "node --env-file-if-exists=.env dist/server/entry.mjs",
|
|
9
9
|
"seed": "tsx scripts/seed.ts",
|
|
10
10
|
"typecheck": "astro check"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@astrojs/node": "^11.1.6",
|
|
14
|
-
"@supabase/supabase-js": "^2.113.0",
|
|
15
14
|
"astro": "^7.3.5",
|
|
16
|
-
"smoodly": "0.0.
|
|
15
|
+
"smoodly": "0.0.52"
|
|
17
16
|
},
|
|
18
17
|
"devDependencies": {
|
|
19
18
|
"@astrojs/check": "^0.9.10",
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
// from smoodly/astro): the admin's own operations, so validation and
|
|
3
3
|
// the publish checks apply and a failure throws. It is also the example
|
|
4
4
|
// of writing content from code. Ships in the scaffold; create-smoodly-app
|
|
5
|
-
// runs `npm run seed` after the
|
|
5
|
+
// runs `npm run seed` after it pushes the schema. Idempotent: exits once the
|
|
6
6
|
// home page has content in the default locale. Writes the same copy into every configured locale, whatever
|
|
7
7
|
// their codes, so every locale's "/" resolves.
|
|
8
|
-
// Run: npm run seed (needs .env
|
|
8
|
+
// Run: npm run seed (needs .env).
|
|
9
9
|
import type { PageTree, TreeNode } from "smoodly";
|
|
10
10
|
|
|
11
|
+
// A refusal from Smoodly's API (a space with no schema yet, a wrong key) prints its message and code, not a stack trace.
|
|
12
|
+
process.on("uncaughtException", (e) => {
|
|
13
|
+
console.error(e.name === "SmoodlyContentError" ? `${e.message} (${(e as Error & { code?: string }).code})` : e);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
});
|
|
16
|
+
|
|
11
17
|
const { config } = await import("../src/smoodly/config");
|
|
12
18
|
const { node } = await import("smoodly");
|
|
13
19
|
const { createContent } = await import("smoodly/astro");
|
|
@@ -19,7 +25,7 @@ const DEFAULT = config.locales.default;
|
|
|
19
25
|
const OTHERS = config.locales.supported.filter((l) => l !== DEFAULT);
|
|
20
26
|
|
|
21
27
|
// The home page is code-owned: `find` returns its record, creating it when
|
|
22
|
-
// the
|
|
28
|
+
// the space is new. It is seeded once somebody has given it sections.
|
|
23
29
|
const home = (await c.pages.find(DEFAULT, "/"))!;
|
|
24
30
|
if (Object.values((await c.pages.getTree(home.id, DEFAULT))?.zones ?? {}).some((nodes) => nodes.length > 0)) {
|
|
25
31
|
console.log(`Already seeded — the home page has content in "${DEFAULT}".`);
|
|
@@ -5,8 +5,8 @@ import { text } from "./toolsets";
|
|
|
5
5
|
// `path` by its entry page (src/entry-pages/posts.astro). Fields marked
|
|
6
6
|
// .localized() are stored per locale; the rest are shared across
|
|
7
7
|
// locales. To add a collection: copy this block, add it to
|
|
8
|
-
// `collections
|
|
9
|
-
//
|
|
8
|
+
// `collections`; the dev server and every build push the change to your
|
|
9
|
+
// space.
|
|
10
10
|
export const posts = smoodly.collection({
|
|
11
11
|
name: "posts",
|
|
12
12
|
title: "Posts",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Working in this Smoodly site
|
|
2
2
|
|
|
3
|
-
This is an Astro site with Smoodly installed: content lives in
|
|
3
|
+
This is an Astro site with Smoodly installed: content lives in Smoodly's service, reached through the API, the admin is mounted at /admin by the `smoodly/astro` integration in `astro.config.ts`, and the site reads content through live collections (`src/live.config.ts`). Read README.md first: it says where things are.
|
|
4
4
|
|
|
5
5
|
## Rules
|
|
6
6
|
|
|
@@ -14,12 +14,6 @@ This is an Astro site with Smoodly installed: content lives in Supabase, the adm
|
|
|
14
14
|
names a schema with no file, and a file with no schema, at the first request.
|
|
15
15
|
- **A `.schema.ts` file imports no component.** Zones, toolsets, global items and
|
|
16
16
|
`node()` take schemas (`z.locked(heroSchema)`), never views.
|
|
17
|
-
- **After a new collection or a `smoodly` upgrade, run `npx smoodly migrate`**
|
|
18
|
-
and apply what it writes (`supabase db push` hosted, `supabase migration up`
|
|
19
|
-
local). It copies the core schema files the package ships and writes a
|
|
20
|
-
read view and order index per collection. Never edit a file it wrote.
|
|
21
|
-
The admin reads the base tables, so it lists a collection either way;
|
|
22
|
-
the view is for SQL and PostgREST readers, the index for `order`.
|
|
23
17
|
- **Content from code goes through `createContent(config)`** from `smoodly/astro`:
|
|
24
18
|
`scripts/seed.ts` is starter content written with it — the admin's own
|
|
25
19
|
operations, so validation and publish checks apply and a failure throws. Never
|
|
@@ -49,7 +43,7 @@ This is an Astro site with Smoodly installed: content lives in Supabase, the adm
|
|
|
49
43
|
## Commands
|
|
50
44
|
|
|
51
45
|
npm run dev # http://localhost:4321, /admin is the editor
|
|
52
|
-
npm run build #
|
|
46
|
+
npm run build # astro build
|
|
53
47
|
npm run start # the built server (dist/server/entry.mjs)
|
|
54
48
|
npm run seed # starter content, idempotent
|
|
55
49
|
npm run typecheck # astro check
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Smoodly site
|
|
2
2
|
|
|
3
|
-
Created by `create-smoodly-app`. Content lives in
|
|
4
|
-
mounted at `/admin` by the `smoodly/astro` integration. AGENTS.md
|
|
5
|
-
rules for an agent (or a person) building the site.
|
|
3
|
+
Created by `create-smoodly-app`. Content lives in Smoodly's service; the
|
|
4
|
+
admin is mounted at `/admin` by the `smoodly/astro` integration. AGENTS.md
|
|
5
|
+
holds the rules for an agent (or a person) building the site.
|
|
6
6
|
|
|
7
7
|
npm run dev # http://localhost:4321 — /admin is the editor
|
|
8
8
|
|
|
@@ -20,7 +20,7 @@ rules for an agent (or a person) building the site.
|
|
|
20
20
|
- `src/live.config.ts` — the live collections the views read with `getLiveCollection` and `getLiveEntry`.
|
|
21
21
|
- `scripts/seed.ts` — the home page and the site item, written through `createContent(config)`. `npm run seed` is idempotent.
|
|
22
22
|
- `src/styles/global.css` — a reset, a container, the two tones. Replace it.
|
|
23
|
-
- `.env` — `
|
|
23
|
+
- `.env` — `SMOODLY_SPACE_ID`, `SMOODLY_SECRET_KEY`, `SMOODLY_PUBLISHABLE_KEY` (the space's values from smoodly.io) and `SITE_URL`.
|
|
24
24
|
|
|
25
25
|
## Add a section
|
|
26
26
|
|
|
@@ -47,13 +47,7 @@ editor's "/" menu.
|
|
|
47
47
|
Copy the `posts` block in `src/smoodly/collections.ts`, add the new
|
|
48
48
|
collection to `collections` and a loader for it in `src/live.config.ts`,
|
|
49
49
|
and write its entry page, `src/entry-pages/<collection>.astro`, by
|
|
50
|
-
copying `posts.astro`.
|
|
51
|
-
apply them:
|
|
52
|
-
|
|
53
|
-
npx smoodly migrate
|
|
54
|
-
supabase db push # hosted; `supabase migration up` for the local stack (keeps the content)
|
|
55
|
-
|
|
56
|
-
The same command brings the core schema forward after a `smoodly` upgrade.
|
|
50
|
+
copying `posts.astro`.
|
|
57
51
|
|
|
58
52
|
## Add a global item
|
|
59
53
|
|
|
@@ -61,7 +55,7 @@ Copy the `site` block in `src/smoodly/globals.ts`, add it to `globals`
|
|
|
61
55
|
and give it a loader in `src/live.config.ts`. A view reads it with
|
|
62
56
|
`getLiveEntry("name", { locale })`. Edit it under Globals in the admin.
|
|
63
57
|
|
|
64
|
-
Reseed an empty
|
|
58
|
+
Reseed an empty space any time with `npm run seed`.
|
|
65
59
|
|
|
66
60
|
## Moving the admin
|
|
67
61
|
|
|
@@ -74,16 +68,12 @@ The two must agree; the admin says so when they do not.
|
|
|
74
68
|
|
|
75
69
|
## Editors
|
|
76
70
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
(Authentication → Users), then in the SQL editor:
|
|
80
|
-
|
|
81
|
-
insert into editors (user_id, role) values ('<the user id>', 'editor');
|
|
82
|
-
|
|
83
|
-
## Hosted Supabase
|
|
71
|
+
Editors sign in at `/admin` with their smoodly.io account. Colleagues are
|
|
72
|
+
invited from the project at smoodly.io; the admin's Members page lists them.
|
|
84
73
|
|
|
85
|
-
|
|
86
|
-
supabase link # pick the project
|
|
87
|
-
supabase db push # applies supabase/migrations/
|
|
74
|
+
## Deploying
|
|
88
75
|
|
|
89
|
-
|
|
76
|
+
`.env` holds the preview space's values, for development. Where you
|
|
77
|
+
deploy, set the production space's three values and `SITE_URL` in the
|
|
78
|
+
host's environment variables; each build pushes the
|
|
79
|
+
schema to its space. https://smoodly.io/docs/getting-started/deploying
|
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "astro dev",
|
|
7
|
-
"build": "
|
|
7
|
+
"build": "astro build",
|
|
8
8
|
"start": "node --env-file-if-exists=.env dist/server/entry.mjs",
|
|
9
9
|
"seed": "tsx scripts/seed.ts",
|
|
10
10
|
"typecheck": "astro check"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@astrojs/node": "^11.1.6",
|
|
14
|
-
"@supabase/supabase-js": "^2.113.0",
|
|
15
14
|
"astro": "^7.3.5",
|
|
16
|
-
"smoodly": "0.0.
|
|
15
|
+
"smoodly": "0.0.52"
|
|
17
16
|
},
|
|
18
17
|
"devDependencies": {
|
|
19
18
|
"@astrojs/check": "^0.9.10",
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
// from smoodly/astro): the admin's own operations, so validation and
|
|
3
3
|
// the publish checks apply and a failure throws. It is also the example
|
|
4
4
|
// of writing content from code. Ships in the scaffold; create-smoodly-app
|
|
5
|
-
// runs `npm run seed` after the
|
|
5
|
+
// runs `npm run seed` after it pushes the schema. Idempotent: exits once the
|
|
6
6
|
// home page has content in the default locale. Writes the same copy into every configured locale, whatever
|
|
7
7
|
// their codes, so every locale's "/" resolves.
|
|
8
|
-
// Run: npm run seed (needs .env
|
|
8
|
+
// Run: npm run seed (needs .env).
|
|
9
9
|
import type { PageTree, TreeNode } from "smoodly";
|
|
10
10
|
|
|
11
|
+
// A refusal from Smoodly's API (a space with no schema yet, a wrong key) prints its message and code, not a stack trace.
|
|
12
|
+
process.on("uncaughtException", (e) => {
|
|
13
|
+
console.error(e.name === "SmoodlyContentError" ? `${e.message} (${(e as Error & { code?: string }).code})` : e);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
});
|
|
16
|
+
|
|
11
17
|
const { config } = await import("../src/smoodly/config");
|
|
12
18
|
const { node } = await import("smoodly");
|
|
13
19
|
const { createContent } = await import("smoodly/astro");
|
|
@@ -19,7 +25,7 @@ const DEFAULT = config.locales.default;
|
|
|
19
25
|
const OTHERS = config.locales.supported.filter((l) => l !== DEFAULT);
|
|
20
26
|
|
|
21
27
|
// The home page is code-owned: `find` returns its record, creating it when
|
|
22
|
-
// the
|
|
28
|
+
// the space is new. It is seeded once somebody has given it sections.
|
|
23
29
|
const home = (await c.pages.find(DEFAULT, "/"))!;
|
|
24
30
|
if (Object.values((await c.pages.getTree(home.id, DEFAULT))?.zones ?? {}).some((nodes) => nodes.length > 0)) {
|
|
25
31
|
console.log(`Already seeded — the home page has content in "${DEFAULT}".`);
|
|
@@ -5,8 +5,8 @@ import { text } from "./toolsets";
|
|
|
5
5
|
// `path` by its entry page (src/entry-pages/posts.astro). Fields marked
|
|
6
6
|
// .localized() are stored per locale; the rest are shared across
|
|
7
7
|
// locales. To add a collection: copy this block, add it to
|
|
8
|
-
// `collections
|
|
9
|
-
//
|
|
8
|
+
// `collections`; the dev server and every build push the change to your
|
|
9
|
+
// space.
|
|
10
10
|
export const posts = smoodly.collection({
|
|
11
11
|
name: "posts",
|
|
12
12
|
title: "Posts",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Working in this Smoodly site
|
|
2
2
|
|
|
3
|
-
This is an Astro site with Smoodly installed: content lives in
|
|
3
|
+
This is an Astro site with Smoodly installed: content lives in Smoodly's service, reached through the API, the admin is mounted at /admin by the `smoodly/astro` integration in `astro.config.ts`, and the site reads content through live collections (`src/live.config.ts`). Read README.md first: it says where things are.
|
|
4
4
|
|
|
5
5
|
## Rules
|
|
6
6
|
|
|
@@ -14,12 +14,6 @@ This is an Astro site with Smoodly installed: content lives in Supabase, the adm
|
|
|
14
14
|
names a schema with no file, and a file with no schema, at the first request.
|
|
15
15
|
- **A `.schema.ts` file imports no component.** Zones, toolsets, global items and
|
|
16
16
|
`node()` take schemas (`z.locked(heroSchema)`), never views.
|
|
17
|
-
- **After a new collection or a `smoodly` upgrade, run `npx smoodly migrate`**
|
|
18
|
-
and apply what it writes (`supabase db push` hosted, `supabase migration up`
|
|
19
|
-
local). It copies the core schema files the package ships and writes a
|
|
20
|
-
read view and order index per collection. Never edit a file it wrote.
|
|
21
|
-
The admin reads the base tables, so it lists a collection either way;
|
|
22
|
-
the view is for SQL and PostgREST readers, the index for `order`.
|
|
23
17
|
- **Content from code goes through `createContent(config)`** from `smoodly/astro`:
|
|
24
18
|
`scripts/seed.ts` is starter content written with it — the admin's own
|
|
25
19
|
operations, so validation and publish checks apply and a failure throws. Never
|
|
@@ -49,7 +43,7 @@ This is an Astro site with Smoodly installed: content lives in Supabase, the adm
|
|
|
49
43
|
## Commands
|
|
50
44
|
|
|
51
45
|
npm run dev # http://localhost:4321, /admin is the editor
|
|
52
|
-
npm run build #
|
|
46
|
+
npm run build # astro build
|
|
53
47
|
npm run start # the built server (dist/server/entry.mjs)
|
|
54
48
|
npm run seed # starter content, idempotent
|
|
55
49
|
npm run typecheck # astro check
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Smoodly site
|
|
2
2
|
|
|
3
|
-
Created by `create-smoodly-app`. Content lives in
|
|
4
|
-
mounted at `/admin` by the `smoodly/astro` integration. AGENTS.md
|
|
5
|
-
rules for an agent (or a person) building the site.
|
|
3
|
+
Created by `create-smoodly-app`. Content lives in Smoodly's service; the
|
|
4
|
+
admin is mounted at `/admin` by the `smoodly/astro` integration. AGENTS.md
|
|
5
|
+
holds the rules for an agent (or a person) building the site.
|
|
6
6
|
|
|
7
7
|
npm run dev # http://localhost:4321 — /admin is the editor
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ rules for an agent (or a person) building the site.
|
|
|
19
19
|
- `src/strings.ts`, `src/messages/` — the site's own UI strings in the page's language.
|
|
20
20
|
- `public/images/` — the starter's photos; image fields hold URLs like `/images/hero_image.jpg`.
|
|
21
21
|
- `scripts/seed.ts` — the starter content, written through `createContent(config)`. `npm run seed` is idempotent.
|
|
22
|
-
- `.env` — `
|
|
22
|
+
- `.env` — `SMOODLY_SPACE_ID`, `SMOODLY_SECRET_KEY`, `SMOODLY_PUBLISHABLE_KEY` (the space's values from smoodly.io) and `SITE_URL`.
|
|
23
23
|
|
|
24
24
|
## What is in the starter
|
|
25
25
|
|
|
@@ -32,7 +32,7 @@ The Lorem Co. site the installer seeded is a tour of the features:
|
|
|
32
32
|
- **An article** — a collection entry with a richtext body, tags (a localized list), a date and an author ref; versioned, so every save is a snapshot.
|
|
33
33
|
- **Global content** — the header and footer every page renders through \`src/layouts/Layout.astro\`, the contact details the footer reads, the quote pages place.
|
|
34
34
|
|
|
35
|
-
Reseed an empty
|
|
35
|
+
Reseed an empty space any time with `npm run seed`.
|
|
36
36
|
|
|
37
37
|
## Moving the admin
|
|
38
38
|
|
|
@@ -45,16 +45,12 @@ The two must agree; the admin says so when they do not.
|
|
|
45
45
|
|
|
46
46
|
## Editors
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
(Authentication → Users), then in the SQL editor:
|
|
48
|
+
Editors sign in at `/admin` with their smoodly.io account. Colleagues are
|
|
49
|
+
invited from the project at smoodly.io; the admin's Members page lists them.
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
## Deploying
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
supabase db push # applies supabase/migrations/
|
|
59
|
-
|
|
60
|
-
Then put the project's URL and keys in `.env`.
|
|
53
|
+
`.env` holds the preview space's values, for development. Where you
|
|
54
|
+
deploy, set the production space's three values and `SITE_URL` in the
|
|
55
|
+
host's environment variables; each build pushes the
|
|
56
|
+
schema to its space. https://smoodly.io/docs/getting-started/deploying
|
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "astro dev",
|
|
7
|
-
"build": "
|
|
7
|
+
"build": "astro build",
|
|
8
8
|
"start": "node --env-file-if-exists=.env dist/server/entry.mjs",
|
|
9
9
|
"seed": "tsx scripts/seed.ts",
|
|
10
10
|
"typecheck": "astro check"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@astrojs/node": "^11.1.6",
|
|
14
|
-
"@supabase/supabase-js": "^2.113.0",
|
|
15
14
|
"astro": "^7.3.5",
|
|
16
|
-
"smoodly": "0.0.
|
|
15
|
+
"smoodly": "0.0.52"
|
|
17
16
|
},
|
|
18
17
|
"devDependencies": {
|
|
19
18
|
"@astrojs/check": "^0.9.10",
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// from smoodly/astro): the admin's own operations, so validation and
|
|
3
3
|
// the publish checks apply and a failure throws. This file is also the
|
|
4
4
|
// example of writing content from code. Content only; it ships in the template and create-smoodly-app runs
|
|
5
|
-
// `npm run seed` after the
|
|
5
|
+
// `npm run seed` after it pushes the schema. (The example repo's demo
|
|
6
6
|
// editor account is a separate, example-only script.)
|
|
7
|
-
// Run: npm run seed (needs .env
|
|
7
|
+
// Run: npm run seed (needs .env).
|
|
8
8
|
//
|
|
9
9
|
// Locales: the English content goes into the configured default locale,
|
|
10
10
|
// whatever its code, and the Finnish rows are written only when `fi` is
|
|
@@ -17,6 +17,12 @@
|
|
|
17
17
|
// page has content.
|
|
18
18
|
import type { PageTree, TreeNode } from "smoodly";
|
|
19
19
|
|
|
20
|
+
// A refusal from Smoodly's API (a space with no schema yet, a wrong key) prints its message and code, not a stack trace.
|
|
21
|
+
process.on("uncaughtException", (e) => {
|
|
22
|
+
console.error(e.name === "SmoodlyContentError" ? `${e.message} (${(e as Error & { code?: string }).code})` : e);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
});
|
|
25
|
+
|
|
20
26
|
const { config } = await import("../src/smoodly/config");
|
|
21
27
|
const { articles, news } = await import("../src/smoodly/collections");
|
|
22
28
|
const { node } = await import("smoodly");
|
|
@@ -34,7 +40,7 @@ const EN = config.locales.default;
|
|
|
34
40
|
const FI = config.locales.supported.includes("fi") && EN !== "fi" ? "fi" : null;
|
|
35
41
|
|
|
36
42
|
// The home page is code-owned: `find` returns its record, creating it when
|
|
37
|
-
// the
|
|
43
|
+
// the space is new. It is seeded once somebody has given it sections.
|
|
38
44
|
const home = (await c.pages.find(EN, "/"))!;
|
|
39
45
|
if (Object.values((await c.pages.getTree(home.id, EN))?.zones ?? {}).some((nodes) => nodes.length > 0)) {
|
|
40
46
|
console.log(`Already seeded — the home page has content in "${EN}".`);
|
|
@@ -4,6 +4,8 @@ import { f, smoodly } from "smoodly";
|
|
|
4
4
|
// text and an optional wide photo. Page and Articles lock it — each page
|
|
5
5
|
// shape locks its own hero, which is the point: a locked zone is per
|
|
6
6
|
// shape. Without an image the copy stands alone (the Articles index).
|
|
7
|
+
// The photo has two named crops: wide on a desktop, tall on a phone; the
|
|
8
|
+
// view says which applies where.
|
|
7
9
|
export const pageHeroSchema = smoodly.schema.section({
|
|
8
10
|
name: "pageHero",
|
|
9
11
|
title: "Page hero",
|
|
@@ -12,7 +14,7 @@ export const pageHeroSchema = smoodly.schema.section({
|
|
|
12
14
|
kicker: f.text().optional(),
|
|
13
15
|
heading: f.text(),
|
|
14
16
|
text: f.text(),
|
|
15
|
-
image: f.image({
|
|
17
|
+
image: f.image({ crops: { wide: "21:9", tall: "4:5" } }).optional(),
|
|
16
18
|
},
|
|
17
19
|
sample: {
|
|
18
20
|
heading: "About us",
|
|
@@ -15,6 +15,6 @@ const m = smoodly.marks(pageHeroSchema);
|
|
|
15
15
|
<h1 class="page-hero__heading" {...m.field("heading")}>{heading}</h1>
|
|
16
16
|
<p class="page-hero__text" {...m.field("text")}>{text}</p>
|
|
17
17
|
</div>
|
|
18
|
-
{image && <Image image={image} class="page-hero__image" sizes="100vw" priority {...m.field("image")} />}
|
|
18
|
+
{image && <Image image={image} media={{ tall: "(max-width: 767px)" }} class="page-hero__image" sizes="100vw" priority {...m.field("image")} />}
|
|
19
19
|
</div>
|
|
20
20
|
</Section>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Working in this Smoodly site
|
|
2
2
|
|
|
3
|
-
This is an Astro site with Smoodly installed: content lives in
|
|
3
|
+
This is an Astro site with Smoodly installed: content lives in Smoodly's service, reached through the API, the admin is mounted at /admin by the `smoodly/astro` integration in `astro.config.ts`, and the site reads content through live collections (`src/live.config.ts`). Read README.md first: it says where things are.
|
|
4
4
|
|
|
5
5
|
## Rules
|
|
6
6
|
|
|
@@ -14,12 +14,6 @@ This is an Astro site with Smoodly installed: content lives in Supabase, the adm
|
|
|
14
14
|
names a schema with no file, and a file with no schema, at the first request.
|
|
15
15
|
- **A `.schema.ts` file imports no component.** Zones, toolsets, global items and
|
|
16
16
|
`node()` take schemas (`z.locked(heroSchema)`), never views.
|
|
17
|
-
- **After a new collection or a `smoodly` upgrade, run `npx smoodly migrate`**
|
|
18
|
-
and apply what it writes (`supabase db push` hosted, `supabase migration up`
|
|
19
|
-
local). It copies the core schema files the package ships and writes a
|
|
20
|
-
read view and order index per collection. Never edit a file it wrote.
|
|
21
|
-
The admin reads the base tables, so it lists a collection either way;
|
|
22
|
-
the view is for SQL and PostgREST readers, the index for `order`.
|
|
23
17
|
- **Content from code goes through `createContent(config)`** from `smoodly/astro`:
|
|
24
18
|
`scripts/seed.ts` is starter content written with it — the admin's own
|
|
25
19
|
operations, so validation and publish checks apply and a failure throws. Never
|
|
@@ -49,7 +43,7 @@ This is an Astro site with Smoodly installed: content lives in Supabase, the adm
|
|
|
49
43
|
## Commands
|
|
50
44
|
|
|
51
45
|
npm run dev # http://localhost:4321, /admin is the editor
|
|
52
|
-
npm run build #
|
|
46
|
+
npm run build # astro build
|
|
53
47
|
npm run start # the built server (dist/server/entry.mjs)
|
|
54
48
|
npm run seed # starter content, idempotent
|
|
55
49
|
npm run typecheck # astro check
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Smoodly site
|
|
2
2
|
|
|
3
|
-
Created by `create-smoodly-app`. Content lives in
|
|
4
|
-
mounted at `/admin` by the `smoodly/astro` integration. AGENTS.md
|
|
5
|
-
rules for an agent (or a person) building the site.
|
|
3
|
+
Created by `create-smoodly-app`. Content lives in Smoodly's service; the
|
|
4
|
+
admin is mounted at `/admin` by the `smoodly/astro` integration. AGENTS.md
|
|
5
|
+
holds the rules for an agent (or a person) building the site.
|
|
6
6
|
|
|
7
7
|
npm run dev # http://localhost:4321 — /admin is the editor
|
|
8
8
|
|
|
@@ -20,7 +20,7 @@ rules for an agent (or a person) building the site.
|
|
|
20
20
|
- `src/strings.ts`, `src/messages/` — the site's own UI strings in the page's language.
|
|
21
21
|
- `public/images/` — the starter's photos; image fields hold URLs like `/images/hero_image.jpg`.
|
|
22
22
|
- `scripts/seed.ts` — the starter content, written through `createContent(config)`. `npm run seed` is idempotent.
|
|
23
|
-
- `.env` — `
|
|
23
|
+
- `.env` — `SMOODLY_SPACE_ID`, `SMOODLY_SECRET_KEY`, `SMOODLY_PUBLISHABLE_KEY` (the space's values from smoodly.io) and `SITE_URL`.
|
|
24
24
|
|
|
25
25
|
## What is in the starter
|
|
26
26
|
|
|
@@ -34,7 +34,7 @@ The Lorem Co. site the installer seeded is a tour of the features:
|
|
|
34
34
|
- **Global content** — the header and footer every page renders through \`src/layouts/Layout.astro\`, the contact details the footer reads, the quote pages place.
|
|
35
35
|
|
|
36
36
|
Every page and entry exists in each locale with its own slug. Reseed an
|
|
37
|
-
empty
|
|
37
|
+
empty space any time with `npm run seed`.
|
|
38
38
|
|
|
39
39
|
## Moving the admin
|
|
40
40
|
|
|
@@ -47,16 +47,12 @@ The two must agree; the admin says so when they do not.
|
|
|
47
47
|
|
|
48
48
|
## Editors
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
(Authentication → Users), then in the SQL editor:
|
|
50
|
+
Editors sign in at `/admin` with their smoodly.io account. Colleagues are
|
|
51
|
+
invited from the project at smoodly.io; the admin's Members page lists them.
|
|
53
52
|
|
|
54
|
-
|
|
53
|
+
## Deploying
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
supabase db push # applies supabase/migrations/
|
|
61
|
-
|
|
62
|
-
Then put the project's URL and keys in `.env`.
|
|
55
|
+
`.env` holds the preview space's values, for development. Where you
|
|
56
|
+
deploy, set the production space's three values and `SITE_URL` in the
|
|
57
|
+
host's environment variables; each build pushes the
|
|
58
|
+
schema to its space. https://smoodly.io/docs/getting-started/deploying
|
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "astro dev",
|
|
7
|
-
"build": "
|
|
7
|
+
"build": "astro build",
|
|
8
8
|
"start": "node --env-file-if-exists=.env dist/server/entry.mjs",
|
|
9
9
|
"seed": "tsx scripts/seed.ts",
|
|
10
10
|
"typecheck": "astro check"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@astrojs/node": "^11.1.6",
|
|
14
|
-
"@supabase/supabase-js": "^2.113.0",
|
|
15
14
|
"astro": "^7.3.5",
|
|
16
|
-
"smoodly": "0.0.
|
|
15
|
+
"smoodly": "0.0.52"
|
|
17
16
|
},
|
|
18
17
|
"devDependencies": {
|
|
19
18
|
"@astrojs/check": "^0.9.10",
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// from smoodly/astro): the admin's own operations, so validation and
|
|
3
3
|
// the publish checks apply and a failure throws. This file is also the
|
|
4
4
|
// example of writing content from code. Content only; it ships in the template and create-smoodly-app runs
|
|
5
|
-
// `npm run seed` after the
|
|
5
|
+
// `npm run seed` after it pushes the schema. (The example repo's demo
|
|
6
6
|
// editor account is a separate, example-only script.)
|
|
7
|
-
// Run: npm run seed (needs .env
|
|
7
|
+
// Run: npm run seed (needs .env).
|
|
8
8
|
//
|
|
9
9
|
// Locales: the English content goes into the configured default locale,
|
|
10
10
|
// whatever its code, and the Finnish rows are written only when `fi` is
|
|
@@ -17,6 +17,12 @@
|
|
|
17
17
|
// page has content.
|
|
18
18
|
import type { PageTree, TreeNode } from "smoodly";
|
|
19
19
|
|
|
20
|
+
// A refusal from Smoodly's API (a space with no schema yet, a wrong key) prints its message and code, not a stack trace.
|
|
21
|
+
process.on("uncaughtException", (e) => {
|
|
22
|
+
console.error(e.name === "SmoodlyContentError" ? `${e.message} (${(e as Error & { code?: string }).code})` : e);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
});
|
|
25
|
+
|
|
20
26
|
const { config } = await import("../src/smoodly/config");
|
|
21
27
|
const { articles, news } = await import("../src/smoodly/collections");
|
|
22
28
|
const { node } = await import("smoodly");
|
|
@@ -34,7 +40,7 @@ const EN = config.locales.default;
|
|
|
34
40
|
const FI = config.locales.supported.includes("fi") && EN !== "fi" ? "fi" : null;
|
|
35
41
|
|
|
36
42
|
// The home page is code-owned: `find` returns its record, creating it when
|
|
37
|
-
// the
|
|
43
|
+
// the space is new. It is seeded once somebody has given it sections.
|
|
38
44
|
const home = (await c.pages.find(EN, "/"))!;
|
|
39
45
|
if (Object.values((await c.pages.getTree(home.id, EN))?.zones ?? {}).some((nodes) => nodes.length > 0)) {
|
|
40
46
|
console.log(`Already seeded — the home page has content in "${EN}".`);
|
|
@@ -4,6 +4,8 @@ import { f, smoodly } from "smoodly";
|
|
|
4
4
|
// text and an optional wide photo. Page and Articles lock it — each page
|
|
5
5
|
// shape locks its own hero, which is the point: a locked zone is per
|
|
6
6
|
// shape. Without an image the copy stands alone (the Articles index).
|
|
7
|
+
// The photo has two named crops: wide on a desktop, tall on a phone; the
|
|
8
|
+
// view says which applies where.
|
|
7
9
|
export const pageHeroSchema = smoodly.schema.section({
|
|
8
10
|
name: "pageHero",
|
|
9
11
|
title: "Page hero",
|
|
@@ -12,7 +14,7 @@ export const pageHeroSchema = smoodly.schema.section({
|
|
|
12
14
|
kicker: f.text().optional(),
|
|
13
15
|
heading: f.text(),
|
|
14
16
|
text: f.text(),
|
|
15
|
-
image: f.image({
|
|
17
|
+
image: f.image({ crops: { wide: "21:9", tall: "4:5" } }).optional(),
|
|
16
18
|
},
|
|
17
19
|
sample: {
|
|
18
20
|
heading: "About us",
|
|
@@ -15,6 +15,6 @@ const m = smoodly.marks(pageHeroSchema);
|
|
|
15
15
|
<h1 class="page-hero__heading" {...m.field("heading")}>{heading}</h1>
|
|
16
16
|
<p class="page-hero__text" {...m.field("text")}>{text}</p>
|
|
17
17
|
</div>
|
|
18
|
-
{image && <Image image={image} class="page-hero__image" sizes="100vw" priority {...m.field("image")} />}
|
|
18
|
+
{image && <Image image={image} media={{ tall: "(max-width: 767px)" }} class="page-hero__image" sizes="100vw" priority {...m.field("image")} />}
|
|
19
19
|
</div>
|
|
20
20
|
</Section>
|