create-smoodly-app 0.0.42 → 0.0.44
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 +15 -4
- package/package.json +1 -1
- package/templates/blank/package.json +1 -1
- package/templates/blank/smoodly/server.ts +15 -5
- package/templates/blank-intl/package.json +1 -1
- package/templates/blank-intl/smoodly/server.ts +15 -5
- package/templates/lorem/package.json +1 -1
- package/templates/lorem/smoodly/server.ts +15 -5
- package/templates/lorem-intl/package.json +1 -1
- package/templates/lorem-intl/smoodly/server.ts +15 -5
package/dist/index.js
CHANGED
|
@@ -489,12 +489,23 @@ async function run(answers2, deps) {
|
|
|
489
489
|
await sh("supabase", ["init"], { stdin: "ignore" });
|
|
490
490
|
const configPath = join2(cwd, "supabase/config.toml");
|
|
491
491
|
const toml = withoutSeedSql(await deps.fs.readFile(configPath));
|
|
492
|
-
const
|
|
492
|
+
const ports = blockPorts(toml);
|
|
493
|
+
const base = await findFreeBlock(ports, deps.isPortFree);
|
|
493
494
|
await deps.fs.writeFile(configPath, base !== DEFAULT_BASE ? shiftBlock(toml, base) : toml);
|
|
494
495
|
if (base !== DEFAULT_BASE) {
|
|
495
496
|
deps.log(`Ports ${DEFAULT_BASE / 100}xx are busy (another Supabase project running?), using ${base / 100}xx.`);
|
|
496
497
|
}
|
|
497
|
-
|
|
498
|
+
try {
|
|
499
|
+
await sh("supabase", LOCAL_START_ARGS);
|
|
500
|
+
} catch (e) {
|
|
501
|
+
const shifted = ports.map((p3) => base + (p3 - DEFAULT_BASE));
|
|
502
|
+
const taken = (await Promise.all(shifted.map(deps.isPortFree))).some((free) => !free);
|
|
503
|
+
if (!taken) throw e;
|
|
504
|
+
const next = await findFreeBlock(ports, deps.isPortFree);
|
|
505
|
+
await deps.fs.writeFile(configPath, shiftBlock(toml, next));
|
|
506
|
+
deps.log(`Ports ${base / 100}xx were taken while starting (another Supabase project?), retrying on ${next / 100}xx.`);
|
|
507
|
+
await sh("supabase", LOCAL_START_ARGS);
|
|
508
|
+
}
|
|
498
509
|
ctx.keys = parseStatusEnv((await sh("supabase", ["status", "-o", "env"], { capture: true })).stdout);
|
|
499
510
|
break;
|
|
500
511
|
}
|
|
@@ -540,7 +551,7 @@ var withoutSeedSql = (toml) => toml.replace(/(\[db\.seed\]\n(?:#.*\n)*enabled =
|
|
|
540
551
|
function fallbackFor(step, answers2, keys) {
|
|
541
552
|
const envLines = keys ? `Write ${answers2.dir}/.env.local:
|
|
542
553
|
|
|
543
|
-
${renderEnv(keys).split("\n").filter((l) => !l.startsWith("#")).join("\n").trimEnd()}` : `Write ${answers2.dir}/.env.local with SMOODLY_URL, SMOODLY_SECRET_KEY and SMOODLY_PUBLISHABLE_KEY (from \`supabase status\`).`;
|
|
554
|
+
${renderEnv(keys).split("\n").filter((l) => !l.startsWith("#")).join("\n").trimEnd()}` : `Write ${answers2.dir}/.env.local with SMOODLY_URL, SMOODLY_SECRET_KEY and SMOODLY_PUBLISHABLE_KEY (from \`supabase status\`), and SITE_URL=http://localhost:3000.`;
|
|
544
555
|
const editorLines = [
|
|
545
556
|
"Create the first editor, then the starter content:",
|
|
546
557
|
"",
|
|
@@ -549,7 +560,7 @@ ${renderEnv(keys).split("\n").filter((l) => !l.startsWith("#")).join("\n").trimE
|
|
|
549
560
|
].join("\n");
|
|
550
561
|
switch (step) {
|
|
551
562
|
case "supabaseLocal":
|
|
552
|
-
return [`cd ${answers2.dir} && supabase
|
|
563
|
+
return [`cd ${answers2.dir} && supabase ${LOCAL_START_ARGS.join(" ")}`, "", envLines, "", editorLines].join("\n");
|
|
553
564
|
case "supabaseInit": {
|
|
554
565
|
const commands = answers2.hosted?.linkAndPush ? [`cd ${answers2.dir} && supabase init && ${linkCommand(answers2)} && supabase db push`] : [`cd ${answers2.dir} && supabase init`, "", `When you are ready: ${linkCommand(answers2)} && supabase db push`];
|
|
555
566
|
return [...commands, "", envLines, "", editorLines].join("\n");
|
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
// shell in every live page's JavaScript.
|
|
19
19
|
import { createSmoodlyContent, supabaseAdminAuth, type AdminAuth, type AuthConfig, type SmoodlyContent } from "smoodly/admin";
|
|
20
20
|
import { createPageRenderer, createSmoodlyQueries, type PageRegistration } from "smoodly/next";
|
|
21
|
+
import { connection } from "next/server";
|
|
21
22
|
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
22
23
|
import { collections, config, elements, sections, globals } from "./config";
|
|
23
24
|
|
|
@@ -115,10 +116,19 @@ export const href = (path: string, _locale: string) => path;
|
|
|
115
116
|
* { locale })`, `q().getPageTree({ locale })`. Typed by the registry, the
|
|
116
117
|
* live draft in the editor preview, cached under tags the admin expires.
|
|
117
118
|
* Rename it if `q` is not to your taste — this file is yours. */
|
|
118
|
-
export const q = (): Queries =>
|
|
119
|
+
export const q = (): Queries =>
|
|
120
|
+
new Proxy({} as Queries, {
|
|
121
|
+
get: (_, name) => async (...args: unknown[]) => {
|
|
122
|
+
await connection();
|
|
123
|
+
return (bound().q as unknown as Record<string | symbol, (...a: unknown[]) => unknown>)[name](...args);
|
|
124
|
+
},
|
|
125
|
+
});
|
|
119
126
|
|
|
127
|
+
// A request first, then the env: `await connection()` makes the route dynamic before bound()
|
|
128
|
+
// reads SMOODLY_*, so `next build` prerenders nothing here and needs no keys — a layout
|
|
129
|
+
// reading a global through q() included (2026-10-02, tester round 6).
|
|
120
130
|
/** The two route files call these. */
|
|
121
|
-
export const renderSmoodlyPath: Renderer["renderSmoodlyPath"] = (...args) => bound().renderer.renderSmoodlyPath(...args);
|
|
122
|
-
export const smoodlyMetadata: Renderer["smoodlyMetadata"] = (...args) => bound().renderer.smoodlyMetadata(...args);
|
|
123
|
-
export const renderSmoodlyPage: Renderer["renderSmoodlyPage"] = (...args) => bound().renderer.renderSmoodlyPage(...args);
|
|
124
|
-
export const smoodlyPageMetadata: Renderer["smoodlyPageMetadata"] = (...args) => bound().renderer.smoodlyPageMetadata(...args);
|
|
131
|
+
export const renderSmoodlyPath: Renderer["renderSmoodlyPath"] = async (...args) => { await connection(); return bound().renderer.renderSmoodlyPath(...args); };
|
|
132
|
+
export const smoodlyMetadata: Renderer["smoodlyMetadata"] = async (...args) => { await connection(); return bound().renderer.smoodlyMetadata(...args); };
|
|
133
|
+
export const renderSmoodlyPage: Renderer["renderSmoodlyPage"] = async (...args) => { await connection(); return bound().renderer.renderSmoodlyPage(...args); };
|
|
134
|
+
export const smoodlyPageMetadata: Renderer["smoodlyPageMetadata"] = async (...args) => { await connection(); return bound().renderer.smoodlyPageMetadata(...args); };
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
// shell in every live page's JavaScript.
|
|
19
19
|
import { createSmoodlyContent, supabaseAdminAuth, type AdminAuth, type AuthConfig, type SmoodlyContent } from "smoodly/admin";
|
|
20
20
|
import { createPageRenderer, createSmoodlyQueries, type PageRegistration } from "smoodly/next";
|
|
21
|
+
import { connection } from "next/server";
|
|
21
22
|
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
22
23
|
import { getPathname } from "@/i18n/navigation";
|
|
23
24
|
import { collections, config, elements, sections, globals } from "./config";
|
|
@@ -116,10 +117,19 @@ export const href = (path: string, locale: string) => getPathname({ locale, href
|
|
|
116
117
|
* { locale })`, `q().getPageTree({ locale })`. Typed by the registry, the
|
|
117
118
|
* live draft in the editor preview, cached under tags the admin expires.
|
|
118
119
|
* Rename it if `q` is not to your taste — this file is yours. */
|
|
119
|
-
export const q = (): Queries =>
|
|
120
|
+
export const q = (): Queries =>
|
|
121
|
+
new Proxy({} as Queries, {
|
|
122
|
+
get: (_, name) => async (...args: unknown[]) => {
|
|
123
|
+
await connection();
|
|
124
|
+
return (bound().q as unknown as Record<string | symbol, (...a: unknown[]) => unknown>)[name](...args);
|
|
125
|
+
},
|
|
126
|
+
});
|
|
120
127
|
|
|
128
|
+
// A request first, then the env: `await connection()` makes the route dynamic before bound()
|
|
129
|
+
// reads SMOODLY_*, so `next build` prerenders nothing here and needs no keys — a layout
|
|
130
|
+
// reading a global through q() included (2026-10-02, tester round 6).
|
|
121
131
|
/** The two route files call these. */
|
|
122
|
-
export const renderSmoodlyPath: Renderer["renderSmoodlyPath"] = (...args) => bound().renderer.renderSmoodlyPath(...args);
|
|
123
|
-
export const smoodlyMetadata: Renderer["smoodlyMetadata"] = (...args) => bound().renderer.smoodlyMetadata(...args);
|
|
124
|
-
export const renderSmoodlyPage: Renderer["renderSmoodlyPage"] = (...args) => bound().renderer.renderSmoodlyPage(...args);
|
|
125
|
-
export const smoodlyPageMetadata: Renderer["smoodlyPageMetadata"] = (...args) => bound().renderer.smoodlyPageMetadata(...args);
|
|
132
|
+
export const renderSmoodlyPath: Renderer["renderSmoodlyPath"] = async (...args) => { await connection(); return bound().renderer.renderSmoodlyPath(...args); };
|
|
133
|
+
export const smoodlyMetadata: Renderer["smoodlyMetadata"] = async (...args) => { await connection(); return bound().renderer.smoodlyMetadata(...args); };
|
|
134
|
+
export const renderSmoodlyPage: Renderer["renderSmoodlyPage"] = async (...args) => { await connection(); return bound().renderer.renderSmoodlyPage(...args); };
|
|
135
|
+
export const smoodlyPageMetadata: Renderer["smoodlyPageMetadata"] = async (...args) => { await connection(); return bound().renderer.smoodlyPageMetadata(...args); };
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
// shell in every live page's JavaScript.
|
|
19
19
|
import { createSmoodlyContent, supabaseAdminAuth, type AdminAuth, type AuthConfig, type SmoodlyContent } from "smoodly/admin";
|
|
20
20
|
import { createPageRenderer, createSmoodlyQueries, type PageRegistration } from "smoodly/next";
|
|
21
|
+
import { connection } from "next/server";
|
|
21
22
|
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
22
23
|
import { collections, config, elements, sections, globals } from "./config";
|
|
23
24
|
|
|
@@ -115,10 +116,19 @@ export const href = (path: string, _locale: string) => path;
|
|
|
115
116
|
* { locale })`, `q().getPageTree({ locale })`. Typed by the registry, the
|
|
116
117
|
* live draft in the editor preview, cached under tags the admin expires.
|
|
117
118
|
* Rename it if `q` is not to your taste — this file is yours. */
|
|
118
|
-
export const q = (): Queries =>
|
|
119
|
+
export const q = (): Queries =>
|
|
120
|
+
new Proxy({} as Queries, {
|
|
121
|
+
get: (_, name) => async (...args: unknown[]) => {
|
|
122
|
+
await connection();
|
|
123
|
+
return (bound().q as unknown as Record<string | symbol, (...a: unknown[]) => unknown>)[name](...args);
|
|
124
|
+
},
|
|
125
|
+
});
|
|
119
126
|
|
|
127
|
+
// A request first, then the env: `await connection()` makes the route dynamic before bound()
|
|
128
|
+
// reads SMOODLY_*, so `next build` prerenders nothing here and needs no keys — a layout
|
|
129
|
+
// reading a global through q() included (2026-10-02, tester round 6).
|
|
120
130
|
/** The two route files call these. */
|
|
121
|
-
export const renderSmoodlyPath: Renderer["renderSmoodlyPath"] = (...args) => bound().renderer.renderSmoodlyPath(...args);
|
|
122
|
-
export const smoodlyMetadata: Renderer["smoodlyMetadata"] = (...args) => bound().renderer.smoodlyMetadata(...args);
|
|
123
|
-
export const renderSmoodlyPage: Renderer["renderSmoodlyPage"] = (...args) => bound().renderer.renderSmoodlyPage(...args);
|
|
124
|
-
export const smoodlyPageMetadata: Renderer["smoodlyPageMetadata"] = (...args) => bound().renderer.smoodlyPageMetadata(...args);
|
|
131
|
+
export const renderSmoodlyPath: Renderer["renderSmoodlyPath"] = async (...args) => { await connection(); return bound().renderer.renderSmoodlyPath(...args); };
|
|
132
|
+
export const smoodlyMetadata: Renderer["smoodlyMetadata"] = async (...args) => { await connection(); return bound().renderer.smoodlyMetadata(...args); };
|
|
133
|
+
export const renderSmoodlyPage: Renderer["renderSmoodlyPage"] = async (...args) => { await connection(); return bound().renderer.renderSmoodlyPage(...args); };
|
|
134
|
+
export const smoodlyPageMetadata: Renderer["smoodlyPageMetadata"] = async (...args) => { await connection(); return bound().renderer.smoodlyPageMetadata(...args); };
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
// shell in every live page's JavaScript.
|
|
19
19
|
import { createSmoodlyContent, supabaseAdminAuth, type AdminAuth, type AuthConfig, type SmoodlyContent } from "smoodly/admin";
|
|
20
20
|
import { createPageRenderer, createSmoodlyQueries, type PageRegistration } from "smoodly/next";
|
|
21
|
+
import { connection } from "next/server";
|
|
21
22
|
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
22
23
|
import { getPathname } from "@/i18n/navigation";
|
|
23
24
|
import { collections, config, elements, sections, globals } from "./config";
|
|
@@ -116,10 +117,19 @@ export const href = (path: string, locale: string) => getPathname({ locale, href
|
|
|
116
117
|
* { locale })`, `q().getPageTree({ locale })`. Typed by the registry, the
|
|
117
118
|
* live draft in the editor preview, cached under tags the admin expires.
|
|
118
119
|
* Rename it if `q` is not to your taste — this file is yours. */
|
|
119
|
-
export const q = (): Queries =>
|
|
120
|
+
export const q = (): Queries =>
|
|
121
|
+
new Proxy({} as Queries, {
|
|
122
|
+
get: (_, name) => async (...args: unknown[]) => {
|
|
123
|
+
await connection();
|
|
124
|
+
return (bound().q as unknown as Record<string | symbol, (...a: unknown[]) => unknown>)[name](...args);
|
|
125
|
+
},
|
|
126
|
+
});
|
|
120
127
|
|
|
128
|
+
// A request first, then the env: `await connection()` makes the route dynamic before bound()
|
|
129
|
+
// reads SMOODLY_*, so `next build` prerenders nothing here and needs no keys — a layout
|
|
130
|
+
// reading a global through q() included (2026-10-02, tester round 6).
|
|
121
131
|
/** The two route files call these. */
|
|
122
|
-
export const renderSmoodlyPath: Renderer["renderSmoodlyPath"] = (...args) => bound().renderer.renderSmoodlyPath(...args);
|
|
123
|
-
export const smoodlyMetadata: Renderer["smoodlyMetadata"] = (...args) => bound().renderer.smoodlyMetadata(...args);
|
|
124
|
-
export const renderSmoodlyPage: Renderer["renderSmoodlyPage"] = (...args) => bound().renderer.renderSmoodlyPage(...args);
|
|
125
|
-
export const smoodlyPageMetadata: Renderer["smoodlyPageMetadata"] = (...args) => bound().renderer.smoodlyPageMetadata(...args);
|
|
132
|
+
export const renderSmoodlyPath: Renderer["renderSmoodlyPath"] = async (...args) => { await connection(); return bound().renderer.renderSmoodlyPath(...args); };
|
|
133
|
+
export const smoodlyMetadata: Renderer["smoodlyMetadata"] = async (...args) => { await connection(); return bound().renderer.smoodlyMetadata(...args); };
|
|
134
|
+
export const renderSmoodlyPage: Renderer["renderSmoodlyPage"] = async (...args) => { await connection(); return bound().renderer.renderSmoodlyPage(...args); };
|
|
135
|
+
export const smoodlyPageMetadata: Renderer["smoodlyPageMetadata"] = async (...args) => { await connection(); return bound().renderer.smoodlyPageMetadata(...args); };
|