create-smoodly-app 0.0.4 → 0.0.6

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.
Files changed (52) hide show
  1. package/README.md +64 -10
  2. package/dist/index.js +66 -9
  3. package/package.json +1 -1
  4. package/templates/next/README.md +6 -5
  5. package/templates/next/app/(smoodly)/admin/[[...segments]]/page.tsx +1 -1
  6. package/templates/next/app/(smoodly)/admin/layout.tsx +1 -1
  7. package/templates/next/app/[...path]/page.tsx +15 -0
  8. package/templates/next/app/page.tsx +5 -42
  9. package/templates/next/components/pages/Article.tsx +15 -0
  10. package/templates/next/components/pages/Home.tsx +35 -0
  11. package/templates/next/components/pages/Page.tsx +40 -0
  12. package/templates/next/components/sections/ArticleList.tsx +1 -1
  13. package/templates/next/package.json +2 -2
  14. package/templates/next/smoodly/admin.tsx +6 -0
  15. package/templates/next/smoodly/collections.ts +26 -0
  16. package/templates/next/smoodly/config.ts +27 -0
  17. package/templates/next/smoodly/ops.ts +11 -0
  18. package/templates/next/smoodly/sections.ts +8 -0
  19. package/templates/next/smoodly/server.ts +72 -0
  20. package/templates/next/supabase/migrations/00000000000000_smoodly.sql +92 -5
  21. package/templates/next/tsconfig.json +5 -0
  22. package/templates/next-intl/README.md +40 -0
  23. package/templates/next-intl/_gitignore +5 -0
  24. package/templates/next-intl/app/(smoodly)/admin/[[...segments]]/page.tsx +1 -0
  25. package/templates/next-intl/app/(smoodly)/admin/layout.tsx +15 -0
  26. package/templates/next-intl/app/[locale]/[...path]/page.tsx +18 -0
  27. package/templates/next-intl/app/[locale]/layout.tsx +21 -0
  28. package/templates/next-intl/app/[locale]/page.tsx +15 -0
  29. package/templates/next-intl/components/pages/Article.tsx +15 -0
  30. package/templates/next-intl/components/pages/Home.tsx +35 -0
  31. package/templates/next-intl/components/pages/Page.tsx +40 -0
  32. package/templates/next-intl/components/sections/ArticleList.tsx +31 -0
  33. package/templates/next-intl/components/sections/CtaBanner.tsx +35 -0
  34. package/templates/next-intl/components/sections/Hero.tsx +24 -0
  35. package/templates/next-intl/i18n/navigation.ts +6 -0
  36. package/templates/next-intl/i18n/request.ts +17 -0
  37. package/templates/next-intl/i18n/routing.ts +17 -0
  38. package/templates/next-intl/next.config.ts +8 -0
  39. package/templates/next-intl/package.json +25 -0
  40. package/templates/next-intl/proxy.ts +11 -0
  41. package/templates/{next/lib → next-intl}/smoodly/admin.tsx +2 -2
  42. package/templates/{next → next-intl/smoodly}/collections.ts +1 -0
  43. package/templates/next-intl/smoodly/config.ts +31 -0
  44. package/templates/{next/lib → next-intl}/smoodly/ops.ts +3 -3
  45. package/templates/next-intl/smoodly/sections.ts +8 -0
  46. package/templates/next-intl/smoodly/server.ts +73 -0
  47. package/templates/next-intl/supabase/migrations/00000000000000_smoodly.sql +427 -0
  48. package/templates/next-intl/tsconfig.json +41 -0
  49. package/templates/next/app/[slug]/page.tsx +0 -42
  50. package/templates/next/lib/smoodly/index.ts +0 -64
  51. package/templates/next/sections.ts +0 -8
  52. package/templates/next/smoodly.config.ts +0 -19
@@ -1,42 +0,0 @@
1
- import { smoodly, z, Zone, type Props } from "smoodly";
2
- import { Hero } from "../../components/sections/Hero";
3
- import { ArticleList } from "../../components/sections/ArticleList";
4
- import { CtaBanner } from "../../components/sections/CtaBanner";
5
- import { renderSmoodlyPage, smoodlyMetadata } from "../../lib/smoodly";
6
-
7
- type SearchParams = Promise<Record<string, string | string[] | undefined>>;
8
- type Params = Promise<{ slug: string }>;
9
-
10
- // Open registration: editors create as many of these as they like, and
11
- // this one file serves all of them — at depth 1 only. Nested paths are
12
- // the catch-all's job (app/[...rest]).
13
- export const pageSchema = smoodly.schema.page({
14
- name: "page",
15
- title: "Page",
16
- zones: {
17
- hero: z.sections([Hero]).max(1),
18
- body: z.freeform({ sections: [ArticleList] }),
19
- // Locked: fields only. One CtaBanner, always there, never movable.
20
- prefooter: z.locked(CtaBanner),
21
- },
22
- meta: { seo: true },
23
- });
24
-
25
- function PageView({ zones }: Props<typeof pageSchema>) {
26
- return (
27
- <>
28
- <Zone of={zones.hero} />
29
- <Zone of={zones.body} />
30
- <Zone of={zones.prefooter} />
31
- </>
32
- );
33
- }
34
-
35
- export const StandardPage = smoodly.page(pageSchema, PageView);
36
-
37
- export const generateMetadata = async ({ params }: { params: Params }) =>
38
- smoodlyMetadata(StandardPage, { slug: (await params).slug });
39
-
40
- export default async function Page({ params, searchParams }: { params: Params; searchParams: SearchParams }) {
41
- return renderSmoodlyPage(StandardPage, { slug: (await params).slug, searchParams });
42
- }
@@ -1,64 +0,0 @@
1
- // Server-only glue: the client and both stores, constructed lazily so
2
- // `next build` doesn't need env vars at import time. The env shape is
3
- // the package's (SMOODLY_*); whether the secret is a service-role key or
4
- // a cloud write key is invisible here.
5
- import { createSmoodlyClient, resolveTree, smoodlyEnv, SupabaseEntryStore, SupabasePageStore, type PageTree } from "smoodly";
6
- import { supabaseAdminAuth, type AdminAuth, type AuthConfig } from "smoodly/admin/next";
7
- import { createPageRenderer } from "smoodly/next";
8
- import type { SupabaseClient } from "@supabase/supabase-js";
9
- import { collections } from "../../collections";
10
- import { sections } from "../../sections";
11
-
12
- let cached: { db: SupabaseClient; pages: SupabasePageStore; entries: SupabaseEntryStore; auth: AdminAuth } | null = null;
13
-
14
- function bound() {
15
- if (cached) return cached;
16
- const env = smoodlyEnv();
17
- const db = createSmoodlyClient(env);
18
- const entries = new SupabaseEntryStore(db, collections);
19
- const pages = new SupabasePageStore(db, { sections, entries });
20
- const auth = supabaseAdminAuth({ authUrl: env.authUrl, authKey: env.authKey, db });
21
- cached = { db, pages, entries, auth };
22
- return cached;
23
- }
24
-
25
- export function stores() {
26
- const { pages, entries } = bound();
27
- return { pages, entries };
28
- }
29
-
30
- /** The server-side client (seed script, one-off admin tasks). */
31
- export const client = () => bound().db;
32
-
33
- /** The admin gate: session verified against the auth project, editors row read with the write key. */
34
- export const adminAuth = () => bound().auth;
35
-
36
- /** What the browser needs to sign in — public values only. */
37
- export function publicAuth(): AuthConfig {
38
- const env = smoodlyEnv();
39
- return { url: env.authUrl, key: env.authKey };
40
- }
41
-
42
- export const pageTag = (slug: string) => `page:${slug}`;
43
-
44
- /** One batched pass hydrates every ref in the tree (smoodly's resolveTree);
45
- * the store's getMany IS the EntryFetcher. The published route passes
46
- * { status: "published" } so an entry demoted after publish resolves to
47
- * null on the next revalidation instead of leaking draft fields (OQ #16);
48
- * the draft-preview path reads unfiltered. */
49
- export function resolvedTree(tree: PageTree, options?: { status?: "published" }): Promise<PageTree> {
50
- return resolveTree(tree, {
51
- sections,
52
- collections,
53
- fetch: (collection, ids) => stores().entries.getMany(collection, ids, options),
54
- });
55
- }
56
-
57
- /** The site-route seam: draft branch, tag-cached published read, ref
58
- * resolution, 404 and editor bridge, bound once for the whole app. */
59
- export const { renderSmoodlyPage, smoodlyMetadata } = createPageRenderer({
60
- stores,
61
- sections,
62
- collections,
63
- tag: pageTag,
64
- });
@@ -1,8 +0,0 @@
1
- // The registry arrays live in their own modules so lib/smoodly can import
2
- // them WITHOUT importing smoodly.config.ts — the config imports the page
3
- // registrations out of app/, and those route files import lib/smoodly.
4
- import { Hero } from "./components/sections/Hero";
5
- import { ArticleList } from "./components/sections/ArticleList";
6
- import { CtaBanner } from "./components/sections/CtaBanner";
7
-
8
- export const sections = [Hero, ArticleList, CtaBanner];
@@ -1,19 +0,0 @@
1
- import { defineConfig, f } from "smoodly";
2
- import { collections } from "./collections";
3
- import { sections } from "./sections";
4
- import { HomePage } from "./app/page";
5
- import { StandardPage } from "./app/[slug]/page";
6
-
7
- export { collections, sections };
8
-
9
- export const config = defineConfig({
10
- registry: {
11
- sections,
12
- collections,
13
- pages: [HomePage, StandardPage],
14
- },
15
- locales: { default: "en", supported: ["en"] },
16
- styles: {
17
- sections: { spacing: f.select(["sm", "md", "lg"]).default("md") },
18
- },
19
- });