@better-t-stack/template-generator 3.28.2 → 3.29.0
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/core/template-reader.d.mts.map +1 -1
- package/dist/fs-writer.d.mts.map +1 -1
- package/dist/fs-writer.mjs.map +1 -1
- package/dist/index.d.mts +16 -15
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +766 -605
- package/dist/index.mjs.map +1 -1
- package/dist/is-binary-path-maAgJE_Q.mjs.map +1 -1
- package/dist/template-reader-DVuwwW6S.mjs.map +1 -1
- package/dist/types-CzW_c7t0.d.mts.map +1 -1
- package/package.json +7 -7
package/dist/index.mjs
CHANGED
|
@@ -694,8 +694,8 @@ function renameDevScriptsForAlchemy(vfs, config) {
|
|
|
694
694
|
//#region src/utils/add-deps.ts
|
|
695
695
|
const dependencyVersionMap = {
|
|
696
696
|
typescript: "^6",
|
|
697
|
-
"better-auth": "1.6.
|
|
698
|
-
"@better-auth/expo": "1.6.
|
|
697
|
+
"better-auth": "1.6.11",
|
|
698
|
+
"@better-auth/expo": "1.6.11",
|
|
699
699
|
"@clerk/backend": "^3.2.1",
|
|
700
700
|
"@clerk/express": "^2.0.5",
|
|
701
701
|
"@clerk/fastify": "^3.1.3",
|
|
@@ -715,16 +715,17 @@ const dependencyVersionMap = {
|
|
|
715
715
|
"@types/ws": "^8.18.1",
|
|
716
716
|
ws: "^8.18.3",
|
|
717
717
|
mysql2: "^3.14.0",
|
|
718
|
-
"@prisma/client": "^7.
|
|
719
|
-
prisma: "^7.
|
|
720
|
-
"@prisma/adapter-d1": "^7.
|
|
721
|
-
"@prisma/adapter-neon": "^7.
|
|
722
|
-
"@prisma/adapter-mariadb": "^7.
|
|
723
|
-
"@prisma/adapter-libsql": "^7.
|
|
724
|
-
"@prisma/adapter-better-sqlite3": "^7.
|
|
725
|
-
"@prisma/adapter-pg": "^7.
|
|
726
|
-
"@prisma/adapter-planetscale": "^7.
|
|
727
|
-
mongoose: "^
|
|
718
|
+
"@prisma/client": "^7.8.0",
|
|
719
|
+
prisma: "^7.8.0",
|
|
720
|
+
"@prisma/adapter-d1": "^7.8.0",
|
|
721
|
+
"@prisma/adapter-neon": "^7.8.0",
|
|
722
|
+
"@prisma/adapter-mariadb": "^7.8.0",
|
|
723
|
+
"@prisma/adapter-libsql": "^7.8.0",
|
|
724
|
+
"@prisma/adapter-better-sqlite3": "^7.8.0",
|
|
725
|
+
"@prisma/adapter-pg": "^7.8.0",
|
|
726
|
+
"@prisma/adapter-planetscale": "^7.8.0",
|
|
727
|
+
mongoose: "^9.6.2",
|
|
728
|
+
mongodb: "^7.2.0",
|
|
728
729
|
"vite-plugin-pwa": "^1.2.0",
|
|
729
730
|
"@vite-pwa/assets-generator": "^1.0.2",
|
|
730
731
|
"@tauri-apps/cli": "^2.4.0",
|
|
@@ -777,7 +778,7 @@ const dependencyVersionMap = {
|
|
|
777
778
|
"convex-svelte": "^0.0.12",
|
|
778
779
|
"convex-nuxt": "0.1.5",
|
|
779
780
|
"convex-vue": "^0.1.5",
|
|
780
|
-
"@convex-dev/better-auth": "^0.12.
|
|
781
|
+
"@convex-dev/better-auth": "^0.12.2",
|
|
781
782
|
"@tanstack/svelte-query": "^5.85.3",
|
|
782
783
|
"@tanstack/svelte-query-devtools": "^5.85.3",
|
|
783
784
|
"@tanstack/vue-query-devtools": "^6.1.5",
|
|
@@ -806,7 +807,7 @@ const dependencyVersionMap = {
|
|
|
806
807
|
"@t3-oss/env-core": "^0.13.1",
|
|
807
808
|
"@t3-oss/env-nextjs": "^0.13.1",
|
|
808
809
|
"@t3-oss/env-nuxt": "^0.13.1",
|
|
809
|
-
"@polar-sh/better-auth": "^1.8.
|
|
810
|
+
"@polar-sh/better-auth": "^1.8.4",
|
|
810
811
|
"@polar-sh/sdk": "^0.42.2",
|
|
811
812
|
evlog: "^2.14.1"
|
|
812
813
|
};
|
|
@@ -1488,7 +1489,7 @@ function addConvexDeps(vfs, frontend, frontendType) {
|
|
|
1488
1489
|
}
|
|
1489
1490
|
//#endregion
|
|
1490
1491
|
//#region src/processors/auth-deps.ts
|
|
1491
|
-
const CONVEX_BETTER_AUTH_VERSION = "1.6.9";
|
|
1492
|
+
const CONVEX_BETTER_AUTH_VERSION = "~1.6.9";
|
|
1492
1493
|
function processAuthDeps(vfs, config) {
|
|
1493
1494
|
const { auth, backend } = config;
|
|
1494
1495
|
if (!auth || auth === "none") return;
|
|
@@ -1599,7 +1600,7 @@ function processConvexAuthDeps(vfs, config) {
|
|
|
1599
1600
|
}
|
|
1600
1601
|
}
|
|
1601
1602
|
function processStandardAuthDeps(vfs, config) {
|
|
1602
|
-
const { auth, backend, frontend } = config;
|
|
1603
|
+
const { auth, backend, frontend, orm } = config;
|
|
1603
1604
|
const authPath = "packages/auth/package.json";
|
|
1604
1605
|
const apiPath = "packages/api/package.json";
|
|
1605
1606
|
const webPath = "apps/web/package.json";
|
|
@@ -1696,10 +1697,12 @@ function processStandardAuthDeps(vfs, config) {
|
|
|
1696
1697
|
}
|
|
1697
1698
|
} else if (auth === "better-auth") {
|
|
1698
1699
|
if (authExists) {
|
|
1700
|
+
const authDependencies = ["better-auth"];
|
|
1701
|
+
if (orm === "mongoose") authDependencies.push("mongodb");
|
|
1699
1702
|
addPackageDependency({
|
|
1700
1703
|
vfs,
|
|
1701
1704
|
packagePath: authPath,
|
|
1702
|
-
dependencies:
|
|
1705
|
+
dependencies: authDependencies
|
|
1703
1706
|
});
|
|
1704
1707
|
if (hasNative) addPackageDependency({
|
|
1705
1708
|
vfs,
|
|
@@ -1871,13 +1874,13 @@ function processPrismaDeps(vfs, config, dbPkgPath, webPkgPath, webExists) {
|
|
|
1871
1874
|
addPackageDependency({
|
|
1872
1875
|
vfs,
|
|
1873
1876
|
packagePath: dbPkgPath,
|
|
1874
|
-
customDependencies: { "@prisma/client": "6.19.
|
|
1875
|
-
customDevDependencies: { prisma: "6.19.
|
|
1877
|
+
customDependencies: { "@prisma/client": "6.19.3" },
|
|
1878
|
+
customDevDependencies: { prisma: "6.19.3" }
|
|
1876
1879
|
});
|
|
1877
1880
|
if (webExists) addPackageDependency({
|
|
1878
1881
|
vfs,
|
|
1879
1882
|
packagePath: webPkgPath,
|
|
1880
|
-
customDependencies: { "@prisma/client": "6.19.
|
|
1883
|
+
customDependencies: { "@prisma/client": "6.19.3" }
|
|
1881
1884
|
});
|
|
1882
1885
|
return;
|
|
1883
1886
|
}
|
|
@@ -2208,6 +2211,8 @@ function buildNativeVars(frontend, backend, auth) {
|
|
|
2208
2211
|
return vars;
|
|
2209
2212
|
}
|
|
2210
2213
|
function buildConvexBackendVars(frontend, auth, examples) {
|
|
2214
|
+
const hasReactRouter = frontend.includes("react-router");
|
|
2215
|
+
const hasTanStackRouter = frontend.includes("tanstack-router");
|
|
2211
2216
|
const hasNextJs = frontend.includes("next");
|
|
2212
2217
|
const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
|
|
2213
2218
|
const hasWeb = frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("tanstack-start") || hasNextJs || frontend.includes("nuxt") || frontend.includes("solid") || frontend.includes("svelte") || frontend.includes("astro");
|
|
@@ -2220,6 +2225,12 @@ function buildConvexBackendVars(frontend, auth, examples) {
|
|
|
2220
2225
|
comment: "Google AI API key for AI agent"
|
|
2221
2226
|
});
|
|
2222
2227
|
if (auth === "better-auth") {
|
|
2228
|
+
if (hasReactRouter || hasTanStackRouter) vars.push({
|
|
2229
|
+
key: "CONVEX_SITE_URL",
|
|
2230
|
+
value: "",
|
|
2231
|
+
condition: true,
|
|
2232
|
+
comment: "Same as CONVEX_URL but ends in .site"
|
|
2233
|
+
});
|
|
2223
2234
|
if (hasNative) vars.push({
|
|
2224
2235
|
key: "EXPO_PUBLIC_CONVEX_SITE_URL",
|
|
2225
2236
|
value: "",
|
|
@@ -2247,6 +2258,7 @@ function buildConvexBackendVars(frontend, auth, examples) {
|
|
|
2247
2258
|
return vars;
|
|
2248
2259
|
}
|
|
2249
2260
|
function buildConvexCommentBlocks(frontend, auth, examples) {
|
|
2261
|
+
const needsConvexSiteUrl = frontend.includes("react-router") || frontend.includes("tanstack-router");
|
|
2250
2262
|
const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
|
|
2251
2263
|
const hasWeb = frontend.includes("react-router") || frontend.includes("tanstack-router") || frontend.includes("tanstack-start") || frontend.includes("next") || frontend.includes("nuxt") || frontend.includes("solid") || frontend.includes("svelte") || frontend.includes("astro");
|
|
2252
2264
|
const defaultSiteUrl = hasNative && !hasWeb ? "http://localhost:8081" : frontend.includes("react-router") || frontend.includes("svelte") ? "http://localhost:5173" : frontend.includes("astro") ? "http://localhost:4321" : "http://localhost:3001";
|
|
@@ -2257,7 +2269,7 @@ function buildConvexCommentBlocks(frontend, auth, examples) {
|
|
|
2257
2269
|
`;
|
|
2258
2270
|
if (auth === "better-auth") commentBlocks += `# Set Convex environment variables
|
|
2259
2271
|
# npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32)
|
|
2260
|
-
${hasWeb || hasNative ? `# npx convex env set SITE_URL ${defaultSiteUrl}\n` : ""}`;
|
|
2272
|
+
${needsConvexSiteUrl ? "# npx convex env set CONVEX_SITE_URL https://<YOUR_CONVEX_SITE_URL>\n" : ""}${hasWeb || hasNative ? `# npx convex env set SITE_URL ${defaultSiteUrl}\n` : ""}`;
|
|
2261
2273
|
return commentBlocks;
|
|
2262
2274
|
}
|
|
2263
2275
|
function buildServerVars(backend, frontend, auth, api, database, dbSetup, runtime, webDeploy, serverDeploy, payments, examples) {
|
|
@@ -3275,7 +3287,6 @@ function getDeployTasks() {
|
|
|
3275
3287
|
}
|
|
3276
3288
|
//#endregion
|
|
3277
3289
|
//#region src/processors/workspace-deps.ts
|
|
3278
|
-
const NATIVE_TYPESCRIPT_VERSION = "~5.9.2";
|
|
3279
3290
|
function processWorkspaceDeps(vfs, config) {
|
|
3280
3291
|
const { projectName, packageManager, runtime, backend, database, auth, api, serverDeploy, webDeploy } = config;
|
|
3281
3292
|
const workspaceVersion = packageManager === "npm" ? "*" : "workspace:*";
|
|
@@ -3411,10 +3422,7 @@ function processWorkspaceDeps(vfs, config) {
|
|
|
3411
3422
|
packagePath: "apps/native/package.json",
|
|
3412
3423
|
dependencies: commonDeps,
|
|
3413
3424
|
customDependencies: nativeDeps,
|
|
3414
|
-
customDevDependencies:
|
|
3415
|
-
...configDep,
|
|
3416
|
-
typescript: NATIVE_TYPESCRIPT_VERSION
|
|
3417
|
-
}
|
|
3425
|
+
customDevDependencies: configDep
|
|
3418
3426
|
});
|
|
3419
3427
|
}
|
|
3420
3428
|
}
|
|
@@ -3445,11 +3453,6 @@ function processDependencies(vfs, config) {
|
|
|
3445
3453
|
}
|
|
3446
3454
|
//#endregion
|
|
3447
3455
|
//#region src/template-handlers/utils.ts
|
|
3448
|
-
function hasTemplatesWithPrefix(templates, prefix) {
|
|
3449
|
-
const normalizedPrefix = prefix.endsWith("/") ? prefix : `${prefix}/`;
|
|
3450
|
-
for (const path of templates.keys()) if (path.startsWith(normalizedPrefix)) return true;
|
|
3451
|
-
return false;
|
|
3452
|
-
}
|
|
3453
3456
|
function processSingleTemplate(vfs, templates, templatePath, destPath, config) {
|
|
3454
3457
|
const templateKey = templatePath.endsWith(".hbs") ? templatePath : `${templatePath}.hbs`;
|
|
3455
3458
|
const content = templates.get(templateKey);
|
|
@@ -3829,11 +3832,9 @@ async function processExtrasTemplates(vfs, templates, config) {
|
|
|
3829
3832
|
"native-unistyles"
|
|
3830
3833
|
].includes(f));
|
|
3831
3834
|
const hasNuxt = config.frontend.includes("nuxt");
|
|
3832
|
-
if (config.packageManager === "pnpm")
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
if (config.packageManager === "bun") processTemplatesFromPrefix(vfs, templates, "extras/bunfig.toml", "", config);
|
|
3836
|
-
if (config.packageManager === "pnpm" && (hasNative || hasNuxt)) processTemplatesFromPrefix(vfs, templates, "extras/_npmrc", "", config);
|
|
3835
|
+
if (config.packageManager === "pnpm") processSingleTemplate(vfs, templates, "extras/pnpm-workspace.yaml", "pnpm-workspace.yaml", config);
|
|
3836
|
+
if (config.packageManager === "bun") processSingleTemplate(vfs, templates, "extras/bunfig.toml", "bunfig.toml", config);
|
|
3837
|
+
if (config.packageManager === "pnpm" && (hasNative || hasNuxt)) processSingleTemplate(vfs, templates, "extras/_npmrc", ".npmrc", config);
|
|
3837
3838
|
if (config.serverDeploy === "cloudflare" || config.backend === "self" && config.webDeploy === "cloudflare") processSingleTemplate(vfs, templates, "extras/env.d.ts", "packages/env/env.d.ts", config);
|
|
3838
3839
|
}
|
|
3839
3840
|
//#endregion
|
|
@@ -4792,7 +4793,7 @@ import { auth } from "@{{projectName}}/auth";
|
|
|
4792
4793
|
{{/if}}
|
|
4793
4794
|
{{/if}}
|
|
4794
4795
|
|
|
4795
|
-
export async function createContext(req: NextRequest){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4796
|
+
export async function createContext({{#if (eq auth "none")}}_req{{else}}req{{/if}}: NextRequest){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4796
4797
|
{{#if (eq auth "better-auth")}}
|
|
4797
4798
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
4798
4799
|
headers: req.headers,
|
|
@@ -4824,7 +4825,7 @@ import { auth } from "@{{projectName}}/auth";
|
|
|
4824
4825
|
{{/if}}
|
|
4825
4826
|
{{/if}}
|
|
4826
4827
|
|
|
4827
|
-
export async function createContext({ req }: { req: Request }){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4828
|
+
export async function createContext({{#if (eq auth "none")}}_options{{else}}{ req }{{/if}}: { req: Request }){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4828
4829
|
{{#if (eq auth "better-auth")}}
|
|
4829
4830
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
4830
4831
|
headers: req.headers,
|
|
@@ -4860,7 +4861,7 @@ export type CreateContextOptions = {
|
|
|
4860
4861
|
headers: Headers;
|
|
4861
4862
|
};
|
|
4862
4863
|
|
|
4863
|
-
export async function createContext({ headers }: CreateContextOptions) {
|
|
4864
|
+
export async function createContext({{#if (eq auth "none")}}_options{{else}}{ headers }{{/if}}: CreateContextOptions) {
|
|
4864
4865
|
{{#if (eq auth "better-auth")}}
|
|
4865
4866
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({ headers });
|
|
4866
4867
|
return {
|
|
@@ -4894,7 +4895,7 @@ export type CreateContextOptions = {
|
|
|
4894
4895
|
{{/if}}
|
|
4895
4896
|
};
|
|
4896
4897
|
|
|
4897
|
-
export async function createContext({ headers{{#if (eq webDeploy "cloudflare")}}, env{{/if}} }: CreateContextOptions) {
|
|
4898
|
+
export async function createContext({{#if (eq auth "none")}}{{#if (eq webDeploy "cloudflare")}}{ env: _env }{{else}}_options{{/if}}{{else}}{ headers{{#if (eq webDeploy "cloudflare")}}, env{{/if}} }{{/if}}: CreateContextOptions) {
|
|
4898
4899
|
{{#if (eq auth "better-auth")}}
|
|
4899
4900
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth({{#if (eq webDeploy "cloudflare")}}env{{/if}}){{else}}auth{{/if}}.api.getSession({ headers });
|
|
4900
4901
|
return {
|
|
@@ -4928,7 +4929,7 @@ export type CreateContextOptions = {
|
|
|
4928
4929
|
headers: Headers;
|
|
4929
4930
|
};
|
|
4930
4931
|
|
|
4931
|
-
export async function createContext({ headers }: CreateContextOptions) {
|
|
4932
|
+
export async function createContext({{#if (eq auth "none")}}_options{{else}}{ headers }{{/if}}: CreateContextOptions) {
|
|
4932
4933
|
{{#if (eq auth "better-auth")}}
|
|
4933
4934
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({ headers });
|
|
4934
4935
|
return {
|
|
@@ -4957,7 +4958,7 @@ export type CreateContextOptions = {
|
|
|
4957
4958
|
context: HonoContext;
|
|
4958
4959
|
};
|
|
4959
4960
|
|
|
4960
|
-
export async function createContext({ context }: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4961
|
+
export async function createContext({{#if (eq auth "none")}}_options{{else}}{ context }{{/if}}: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4961
4962
|
{{#if (eq auth "better-auth")}}
|
|
4962
4963
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
4963
4964
|
headers: context.req.raw.headers,
|
|
@@ -4990,7 +4991,7 @@ export type CreateContextOptions = {
|
|
|
4990
4991
|
context: ElysiaContext;
|
|
4991
4992
|
};
|
|
4992
4993
|
|
|
4993
|
-
export async function createContext({ context }: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4994
|
+
export async function createContext({{#if (eq auth "none")}}_options{{else}}{ context }{{/if}}: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
4994
4995
|
{{#if (eq auth "better-auth")}}
|
|
4995
4996
|
const session = await auth.api.getSession({
|
|
4996
4997
|
headers: context.request.headers,
|
|
@@ -5026,7 +5027,7 @@ interface CreateContextOptions {
|
|
|
5026
5027
|
req: Request;
|
|
5027
5028
|
}
|
|
5028
5029
|
|
|
5029
|
-
export async function createContext(opts: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5030
|
+
export async function createContext({{#if (eq auth "none")}}_opts{{else}}opts{{/if}}: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5030
5031
|
{{#if (eq auth "better-auth")}}
|
|
5031
5032
|
const session = await auth.api.getSession({
|
|
5032
5033
|
headers: fromNodeHeaders(opts.req.headers),
|
|
@@ -5076,6 +5077,7 @@ export async function createContext(req: {{#if (eq auth "clerk")}}Parameters<typ
|
|
|
5076
5077
|
session: null,
|
|
5077
5078
|
};
|
|
5078
5079
|
{{else}}
|
|
5080
|
+
void req;
|
|
5079
5081
|
return {
|
|
5080
5082
|
auth: null,
|
|
5081
5083
|
session: null,
|
|
@@ -5094,7 +5096,7 @@ export async function createContext() {
|
|
|
5094
5096
|
|
|
5095
5097
|
export type Context = Awaited<ReturnType<typeof createContext>>;
|
|
5096
5098
|
`],
|
|
5097
|
-
["api/orpc/server/src/index.ts.hbs", `import { ORPCError, os } from "@orpc/server";
|
|
5099
|
+
["api/orpc/server/src/index.ts.hbs", `import { {{#if (or (eq auth "better-auth") (eq auth "clerk"))}}ORPCError, {{/if}}os } from "@orpc/server";
|
|
5098
5100
|
import type { Context } from "./context";
|
|
5099
5101
|
|
|
5100
5102
|
export const o = os.$context<Context>();
|
|
@@ -5716,7 +5718,7 @@ import { auth } from "@{{projectName}}/auth";
|
|
|
5716
5718
|
{{/if}}
|
|
5717
5719
|
{{/if}}
|
|
5718
5720
|
|
|
5719
|
-
export async function createContext(req: NextRequest){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5721
|
+
export async function createContext({{#if (eq auth "none")}}_req{{else}}req{{/if}}: NextRequest){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5720
5722
|
{{#if (eq auth "better-auth")}}
|
|
5721
5723
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
5722
5724
|
headers: req.headers,
|
|
@@ -5748,7 +5750,7 @@ import { auth } from "@{{projectName}}/auth";
|
|
|
5748
5750
|
{{/if}}
|
|
5749
5751
|
{{/if}}
|
|
5750
5752
|
|
|
5751
|
-
export async function createContext({ req }: { req: Request }){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5753
|
+
export async function createContext({{#if (eq auth "none")}}_options{{else}}{ req }{{/if}}: { req: Request }){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5752
5754
|
{{#if (eq auth "better-auth")}}
|
|
5753
5755
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
5754
5756
|
headers: req.headers,
|
|
@@ -5785,7 +5787,7 @@ export type CreateContextOptions = {
|
|
|
5785
5787
|
context: HonoContext;
|
|
5786
5788
|
};
|
|
5787
5789
|
|
|
5788
|
-
export async function createContext({ context }: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5790
|
+
export async function createContext({{#if (eq auth "none")}}_options{{else}}{ context }{{/if}}: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5789
5791
|
{{#if (eq auth "better-auth")}}
|
|
5790
5792
|
const session = await {{#if (or (eq runtime "workers") (eq serverDeploy "cloudflare") (and (eq backend "self") (eq webDeploy "cloudflare")))}}createAuth(){{else}}auth{{/if}}.api.getSession({
|
|
5791
5793
|
headers: context.req.raw.headers,
|
|
@@ -5818,7 +5820,7 @@ export type CreateContextOptions = {
|
|
|
5818
5820
|
context: ElysiaContext;
|
|
5819
5821
|
};
|
|
5820
5822
|
|
|
5821
|
-
export async function createContext({ context }: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5823
|
+
export async function createContext({{#if (eq auth "none")}}_options{{else}}{ context }{{/if}}: CreateContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5822
5824
|
{{#if (eq auth "better-auth")}}
|
|
5823
5825
|
const session = await auth.api.getSession({
|
|
5824
5826
|
headers: context.request.headers,
|
|
@@ -5850,7 +5852,7 @@ import { auth } from "@{{projectName}}/auth";
|
|
|
5850
5852
|
import { getAuth } from "@clerk/express";
|
|
5851
5853
|
{{/if}}
|
|
5852
5854
|
|
|
5853
|
-
export async function createContext(opts: CreateExpressContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5855
|
+
export async function createContext({{#if (eq auth "none")}}_opts{{else}}opts{{/if}}: CreateExpressContextOptions){{#if (eq auth "clerk")}}: Promise<ClerkRequestContext>{{/if}} {
|
|
5854
5856
|
{{#if (eq auth "better-auth")}}
|
|
5855
5857
|
const session = await auth.api.getSession({
|
|
5856
5858
|
headers: fromNodeHeaders(opts.req.headers),
|
|
@@ -5898,6 +5900,7 @@ export async function createContext({ req }: CreateFastifyContextOptions){{#if (
|
|
|
5898
5900
|
session: null,
|
|
5899
5901
|
};
|
|
5900
5902
|
{{else}}
|
|
5903
|
+
void req;
|
|
5901
5904
|
return {
|
|
5902
5905
|
auth: null,
|
|
5903
5906
|
session: null,
|
|
@@ -5916,7 +5919,7 @@ export async function createContext() {
|
|
|
5916
5919
|
|
|
5917
5920
|
export type Context = Awaited<ReturnType<typeof createContext>>;
|
|
5918
5921
|
`],
|
|
5919
|
-
["api/trpc/server/src/index.ts.hbs", `import { initTRPC, TRPCError } from "@trpc/server";
|
|
5922
|
+
["api/trpc/server/src/index.ts.hbs", `import { initTRPC{{#if (or (eq auth "better-auth") (eq auth "clerk"))}}, TRPCError{{/if}} } from "@trpc/server";
|
|
5920
5923
|
import type { Context } from "./context";
|
|
5921
5924
|
|
|
5922
5925
|
export const t = initTRPC.context<Context>().create();
|
|
@@ -6184,11 +6187,14 @@ export const authComponent = createClient<DataModel>(components.betterAuth);
|
|
|
6184
6187
|
|
|
6185
6188
|
function createAuth(ctx: GenericCtx<DataModel>) {
|
|
6186
6189
|
return betterAuth({
|
|
6190
|
+
{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router"))}}
|
|
6191
|
+
baseURL: process.env.CONVEX_SITE_URL,
|
|
6192
|
+
{{/if}}
|
|
6187
6193
|
{{#if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
6188
6194
|
baseURL: siteUrl,
|
|
6189
6195
|
{{/if}}
|
|
6190
6196
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
6191
|
-
trustedOrigins: [siteUrl, nativeAppUrl,
|
|
6197
|
+
trustedOrigins: [siteUrl, nativeAppUrl, "exp://"],
|
|
6192
6198
|
{{else if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
|
|
6193
6199
|
trustedOrigins: [siteUrl],
|
|
6194
6200
|
{{else if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
@@ -6229,14 +6235,7 @@ import { authComponent, createAuth } from "./auth";
|
|
|
6229
6235
|
const http = httpRouter();
|
|
6230
6236
|
|
|
6231
6237
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles") (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
|
|
6232
|
-
{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
|
|
6233
|
-
authComponent.registerRoutesLazy(http, createAuth, {
|
|
6234
|
-
cors: true,
|
|
6235
|
-
trustedOrigins: [process.env.SITE_URL!],
|
|
6236
|
-
});
|
|
6237
|
-
{{else}}
|
|
6238
6238
|
authComponent.registerRoutes(http, createAuth, { cors: true });
|
|
6239
|
-
{{/if}}
|
|
6240
6239
|
{{else}}
|
|
6241
6240
|
authComponent.registerRoutes(http, createAuth);
|
|
6242
6241
|
{{/if}}
|
|
@@ -8300,7 +8299,7 @@ import { env } from "@{{projectName}}/env/web";
|
|
|
8300
8299
|
|
|
8301
8300
|
export const authClient = createAuthClient({
|
|
8302
8301
|
baseURL: env.VITE_CONVEX_SITE_URL,
|
|
8303
|
-
plugins: [
|
|
8302
|
+
plugins: [convexClient(), crossDomainClient()],
|
|
8304
8303
|
});
|
|
8305
8304
|
`],
|
|
8306
8305
|
["auth/better-auth/convex/web/react/react-router/src/routes/dashboard.tsx.hbs", `import SignInForm from "@/components/sign-in-form";
|
|
@@ -8704,7 +8703,7 @@ import { env } from "@{{projectName}}/env/web";
|
|
|
8704
8703
|
|
|
8705
8704
|
export const authClient = createAuthClient({
|
|
8706
8705
|
baseURL: env.VITE_CONVEX_SITE_URL,
|
|
8707
|
-
plugins: [
|
|
8706
|
+
plugins: [convexClient(), crossDomainClient()],
|
|
8708
8707
|
});
|
|
8709
8708
|
`],
|
|
8710
8709
|
["auth/better-auth/convex/web/react/tanstack-router/src/routes/dashboard.tsx.hbs", `import SignInForm from "@/components/sign-in-form";
|
|
@@ -9321,7 +9320,8 @@ export const Route = createFileRoute('/api/auth/$')({
|
|
|
9321
9320
|
},
|
|
9322
9321
|
})
|
|
9323
9322
|
`],
|
|
9324
|
-
["auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs", `import {
|
|
9323
|
+
["auth/better-auth/native/bare/app/(drawer)/index.tsx.hbs", `import { Button, Column, Host, Text as ExpoUIText } from "@expo/ui";
|
|
9324
|
+
import { View, ScrollView, StyleSheet } from "react-native";
|
|
9325
9325
|
import { Container } from "@/components/container";
|
|
9326
9326
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
9327
9327
|
import { NAV_THEME } from "@/lib/constants";
|
|
@@ -9358,65 +9358,101 @@ return (
|
|
|
9358
9358
|
<Container>
|
|
9359
9359
|
<ScrollView style={styles.scrollView}>
|
|
9360
9360
|
<View style={styles.content}>
|
|
9361
|
-
<
|
|
9362
|
-
|
|
9363
|
-
|
|
9361
|
+
<Host style={styles.titleHost} matchContents=\\{{ vertical: true }}>
|
|
9362
|
+
<Column>
|
|
9363
|
+
<ExpoUIText
|
|
9364
|
+
textStyle=\\{{ color: theme.text, fontSize: 24, fontWeight: "bold" }}
|
|
9365
|
+
>
|
|
9366
|
+
BETTER T STACK
|
|
9367
|
+
</ExpoUIText>
|
|
9368
|
+
</Column>
|
|
9369
|
+
</Host>
|
|
9364
9370
|
|
|
9365
9371
|
{session?.user ? (
|
|
9366
9372
|
<View style={[styles.userCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
9367
|
-
<
|
|
9368
|
-
<
|
|
9369
|
-
|
|
9370
|
-
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
|
|
9373
|
+
<Host style={styles.userHeader} matchContents=\\{{ vertical: true }}>
|
|
9374
|
+
<Column spacing={8}>
|
|
9375
|
+
<ExpoUIText textStyle=\\{{ color: theme.text, fontSize: 16 }}>
|
|
9376
|
+
{\`Welcome, \${session.user.name}\`}
|
|
9377
|
+
</ExpoUIText>
|
|
9378
|
+
<ExpoUIText
|
|
9379
|
+
textStyle=\\{{ color: theme.text, fontSize: 14 }}
|
|
9380
|
+
style=\\{{ opacity: 0.7 }}
|
|
9381
|
+
>
|
|
9382
|
+
{session.user.email}
|
|
9383
|
+
</ExpoUIText>
|
|
9384
|
+
</Column>
|
|
9385
|
+
</Host>
|
|
9386
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
9387
|
+
<Button
|
|
9388
|
+
label="Sign Out"
|
|
9389
|
+
variant="outlined"
|
|
9390
|
+
onPress={() => {
|
|
9391
|
+
authClient.signOut();
|
|
9392
|
+
{{#if (eq api "orpc")}}
|
|
9393
|
+
queryClient.invalidateQueries();
|
|
9394
|
+
{{/if}}
|
|
9395
|
+
{{#if (eq api "trpc")}}
|
|
9396
|
+
queryClient.invalidateQueries();
|
|
9397
|
+
{{/if}}
|
|
9398
|
+
}}
|
|
9399
|
+
/>
|
|
9400
|
+
</Host>
|
|
9387
9401
|
</View>
|
|
9388
9402
|
) : null}
|
|
9389
9403
|
|
|
9390
9404
|
{{#unless (eq api "none")}}
|
|
9391
9405
|
<View style={[styles.statusCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
9392
|
-
<
|
|
9393
|
-
|
|
9394
|
-
|
|
9406
|
+
<Host style={styles.cardTitleHost} matchContents=\\{{ vertical: true }}>
|
|
9407
|
+
<ExpoUIText
|
|
9408
|
+
textStyle=\\{{ color: theme.text, fontSize: 16, fontWeight: "bold" }}
|
|
9409
|
+
>
|
|
9410
|
+
System Status
|
|
9411
|
+
</ExpoUIText>
|
|
9412
|
+
</Host>
|
|
9395
9413
|
<View style={styles.statusRow}>
|
|
9396
9414
|
<View style={[styles.statusIndicator, { backgroundColor: isConnected ? "#10b981" : "#ef4444" }]} />
|
|
9397
9415
|
<View style={styles.statusContent}>
|
|
9398
|
-
<
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9416
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
9417
|
+
<Column spacing={4}>
|
|
9418
|
+
<ExpoUIText
|
|
9419
|
+
textStyle=\\{{ color: theme.text, fontSize: 14, fontWeight: "bold" }}
|
|
9420
|
+
>
|
|
9421
|
+
{{#if (eq api "orpc")}}ORPC{{else}}TRPC{{/if}} Backend
|
|
9422
|
+
</ExpoUIText>
|
|
9423
|
+
<ExpoUIText
|
|
9424
|
+
textStyle=\\{{ color: theme.text, fontSize: 12 }}
|
|
9425
|
+
style=\\{{ opacity: 0.7 }}
|
|
9426
|
+
>
|
|
9427
|
+
{isLoading
|
|
9428
|
+
? "Checking connection..."
|
|
9429
|
+
: isConnected
|
|
9430
|
+
? "Connected to API"
|
|
9431
|
+
: "API Disconnected"}
|
|
9432
|
+
</ExpoUIText>
|
|
9433
|
+
</Column>
|
|
9434
|
+
</Host>
|
|
9408
9435
|
</View>
|
|
9409
9436
|
</View>
|
|
9410
9437
|
</View>
|
|
9411
9438
|
|
|
9412
9439
|
<View style={[styles.privateDataCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
9413
|
-
<
|
|
9414
|
-
|
|
9415
|
-
|
|
9440
|
+
<Host style={styles.cardTitleHost} matchContents=\\{{ vertical: true }}>
|
|
9441
|
+
<ExpoUIText
|
|
9442
|
+
textStyle=\\{{ color: theme.text, fontSize: 16, fontWeight: "bold" }}
|
|
9443
|
+
>
|
|
9444
|
+
Private Data
|
|
9445
|
+
</ExpoUIText>
|
|
9446
|
+
</Host>
|
|
9416
9447
|
{privateData && (
|
|
9417
|
-
<
|
|
9418
|
-
|
|
9419
|
-
|
|
9448
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
9449
|
+
<ExpoUIText
|
|
9450
|
+
textStyle=\\{{ color: theme.text, fontSize: 14 }}
|
|
9451
|
+
style=\\{{ opacity: 0.7 }}
|
|
9452
|
+
>
|
|
9453
|
+
{privateData.data?.message ?? ""}
|
|
9454
|
+
</ExpoUIText>
|
|
9455
|
+
</Host>
|
|
9420
9456
|
)}
|
|
9421
9457
|
</View>
|
|
9422
9458
|
{{/unless}}
|
|
@@ -9438,45 +9474,30 @@ scrollView: {
|
|
|
9438
9474
|
flex: 1,
|
|
9439
9475
|
},
|
|
9440
9476
|
content: {
|
|
9441
|
-
|
|
9477
|
+
paddingHorizontal: 20,
|
|
9478
|
+
paddingTop: 28,
|
|
9479
|
+
paddingBottom: 32,
|
|
9442
9480
|
},
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
marginBottom: 16,
|
|
9481
|
+
titleHost: {
|
|
9482
|
+
alignSelf: "center",
|
|
9483
|
+
marginBottom: 24,
|
|
9447
9484
|
},
|
|
9448
9485
|
userCard: {
|
|
9449
9486
|
marginBottom: 16,
|
|
9450
9487
|
padding: 16,
|
|
9451
9488
|
borderWidth: 1,
|
|
9489
|
+
borderRadius: 16,
|
|
9452
9490
|
},
|
|
9453
9491
|
userHeader: {
|
|
9454
9492
|
marginBottom: 8,
|
|
9455
9493
|
},
|
|
9456
|
-
userText: {
|
|
9457
|
-
fontSize: 16,
|
|
9458
|
-
},
|
|
9459
|
-
userName: {
|
|
9460
|
-
fontWeight: "bold",
|
|
9461
|
-
},
|
|
9462
|
-
userEmail: {
|
|
9463
|
-
fontSize: 14,
|
|
9464
|
-
marginBottom: 12,
|
|
9465
|
-
},
|
|
9466
|
-
signOutButton: {
|
|
9467
|
-
padding: 12,
|
|
9468
|
-
},
|
|
9469
|
-
signOutText: {
|
|
9470
|
-
color: "#ffffff",
|
|
9471
|
-
},
|
|
9472
9494
|
statusCard: {
|
|
9473
9495
|
marginBottom: 16,
|
|
9474
9496
|
padding: 16,
|
|
9475
9497
|
borderWidth: 1,
|
|
9498
|
+
borderRadius: 16,
|
|
9476
9499
|
},
|
|
9477
|
-
|
|
9478
|
-
fontSize: 16,
|
|
9479
|
-
fontWeight: "bold",
|
|
9500
|
+
cardTitleHost: {
|
|
9480
9501
|
marginBottom: 12,
|
|
9481
9502
|
},
|
|
9482
9503
|
statusRow: {
|
|
@@ -9491,22 +9512,14 @@ width: 8,
|
|
|
9491
9512
|
statusContent: {
|
|
9492
9513
|
flex: 1,
|
|
9493
9514
|
},
|
|
9494
|
-
statusTitle: {
|
|
9495
|
-
fontSize: 14,
|
|
9496
|
-
fontWeight: "bold",
|
|
9497
|
-
},
|
|
9498
|
-
statusText: {
|
|
9499
|
-
fontSize: 12,
|
|
9500
|
-
},
|
|
9501
9515
|
privateDataCard: {
|
|
9502
9516
|
marginBottom: 16,
|
|
9503
9517
|
padding: 16,
|
|
9504
9518
|
borderWidth: 1,
|
|
9519
|
+
borderRadius: 16,
|
|
9505
9520
|
},
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
},
|
|
9509
|
-
});`],
|
|
9521
|
+
});
|
|
9522
|
+
`],
|
|
9510
9523
|
["auth/better-auth/native/bare/components/sign-in.tsx.hbs", `import { authClient } from "@/lib/auth-client";
|
|
9511
9524
|
{{#if (eq api "trpc")}}
|
|
9512
9525
|
import { queryClient } from "@/utils/trpc";
|
|
@@ -11259,14 +11272,8 @@ export function createAuth({{#if (and (eq backend "self") (eq webDeploy "cloudfl
|
|
|
11259
11272
|
env.CORS_ORIGIN,
|
|
11260
11273
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
11261
11274
|
"{{projectName}}://",
|
|
11262
|
-
|
|
11263
|
-
|
|
11264
|
-
"exp://",
|
|
11265
|
-
"exp://**",
|
|
11266
|
-
"exp://192.168.*.*:*/**",
|
|
11267
|
-
"http://localhost:8081",
|
|
11268
|
-
]
|
|
11269
|
-
: []),
|
|
11275
|
+
"exp://",
|
|
11276
|
+
"http://localhost:8081",
|
|
11270
11277
|
{{/if}}
|
|
11271
11278
|
],
|
|
11272
11279
|
emailAndPassword: {
|
|
@@ -11348,14 +11355,8 @@ export function createAuth({{#if (and (eq backend "self") (eq webDeploy "cloudfl
|
|
|
11348
11355
|
env.CORS_ORIGIN,
|
|
11349
11356
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
11350
11357
|
"{{projectName}}://",
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
"exp://",
|
|
11354
|
-
"exp://**",
|
|
11355
|
-
"exp://192.168.*.*:*/**",
|
|
11356
|
-
"http://localhost:8081",
|
|
11357
|
-
]
|
|
11358
|
-
: []),
|
|
11358
|
+
"exp://",
|
|
11359
|
+
"http://localhost:8081",
|
|
11359
11360
|
{{/if}}
|
|
11360
11361
|
],
|
|
11361
11362
|
emailAndPassword: {
|
|
@@ -11428,14 +11429,8 @@ export function createAuth() {
|
|
|
11428
11429
|
env.CORS_ORIGIN,
|
|
11429
11430
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
11430
11431
|
"{{projectName}}://",
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
"exp://",
|
|
11434
|
-
"exp://**",
|
|
11435
|
-
"exp://192.168.*.*:*/**",
|
|
11436
|
-
"http://localhost:8081",
|
|
11437
|
-
]
|
|
11438
|
-
: []),
|
|
11432
|
+
"exp://",
|
|
11433
|
+
"http://localhost:8081",
|
|
11439
11434
|
{{/if}}
|
|
11440
11435
|
],
|
|
11441
11436
|
emailAndPassword: {
|
|
@@ -11515,14 +11510,8 @@ export function createAuth({{#if (and (eq backend "self") (eq webDeploy "cloudfl
|
|
|
11515
11510
|
env.CORS_ORIGIN,
|
|
11516
11511
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
11517
11512
|
"{{projectName}}://",
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
"exp://",
|
|
11521
|
-
"exp://**",
|
|
11522
|
-
"exp://192.168.*.*:*/**",
|
|
11523
|
-
"http://localhost:8081",
|
|
11524
|
-
]
|
|
11525
|
-
: []),
|
|
11513
|
+
"exp://",
|
|
11514
|
+
"http://localhost:8081",
|
|
11526
11515
|
{{/if}}
|
|
11527
11516
|
],
|
|
11528
11517
|
emailAndPassword: {
|
|
@@ -11593,14 +11582,8 @@ export function createAuth({{#if (and (eq backend "self") (eq webDeploy "cloudfl
|
|
|
11593
11582
|
env.CORS_ORIGIN,
|
|
11594
11583
|
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
11595
11584
|
"{{projectName}}://",
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
"exp://",
|
|
11599
|
-
"exp://**",
|
|
11600
|
-
"exp://192.168.*.*:*/**",
|
|
11601
|
-
"http://localhost:8081",
|
|
11602
|
-
]
|
|
11603
|
-
: []),
|
|
11585
|
+
"exp://",
|
|
11586
|
+
"http://localhost:8081",
|
|
11604
11587
|
{{/if}}
|
|
11605
11588
|
],
|
|
11606
11589
|
emailAndPassword: {
|
|
@@ -11963,40 +11946,42 @@ export const accountRelations = relations(account, ({ one }) => ({
|
|
|
11963
11946
|
["auth/better-auth/server/db/mongoose/mongodb/src/models/auth.model.ts.hbs", `import mongoose from 'mongoose';
|
|
11964
11947
|
|
|
11965
11948
|
const { Schema, model } = mongoose;
|
|
11949
|
+
const { ObjectId } = Schema.Types;
|
|
11966
11950
|
|
|
11967
11951
|
const userSchema = new Schema(
|
|
11968
11952
|
{
|
|
11969
|
-
_id: { type:
|
|
11953
|
+
_id: { type: ObjectId, auto: true },
|
|
11970
11954
|
name: { type: String, required: true },
|
|
11971
11955
|
email: { type: String, required: true, unique: true },
|
|
11972
|
-
emailVerified: { type: Boolean, required: true },
|
|
11956
|
+
emailVerified: { type: Boolean, required: true, default: false },
|
|
11973
11957
|
image: { type: String },
|
|
11974
|
-
createdAt: { type: Date, required: true },
|
|
11975
|
-
updatedAt: { type: Date, required: true },
|
|
11958
|
+
createdAt: { type: Date, required: true, default: Date.now },
|
|
11959
|
+
updatedAt: { type: Date, required: true, default: Date.now },
|
|
11976
11960
|
},
|
|
11977
11961
|
{ collection: 'user' }
|
|
11978
11962
|
);
|
|
11979
11963
|
|
|
11980
11964
|
const sessionSchema = new Schema(
|
|
11981
11965
|
{
|
|
11982
|
-
_id: { type:
|
|
11966
|
+
_id: { type: ObjectId, auto: true },
|
|
11983
11967
|
expiresAt: { type: Date, required: true },
|
|
11984
11968
|
token: { type: String, required: true, unique: true },
|
|
11985
|
-
createdAt: { type: Date, required: true },
|
|
11986
|
-
updatedAt: { type: Date, required: true },
|
|
11969
|
+
createdAt: { type: Date, required: true, default: Date.now },
|
|
11970
|
+
updatedAt: { type: Date, required: true, default: Date.now },
|
|
11987
11971
|
ipAddress: { type: String },
|
|
11988
11972
|
userAgent: { type: String },
|
|
11989
|
-
userId: { type:
|
|
11973
|
+
userId: { type: ObjectId, ref: 'User', required: true },
|
|
11990
11974
|
},
|
|
11991
11975
|
{ collection: 'session' }
|
|
11992
11976
|
);
|
|
11977
|
+
sessionSchema.index({ userId: 1 });
|
|
11993
11978
|
|
|
11994
11979
|
const accountSchema = new Schema(
|
|
11995
11980
|
{
|
|
11996
|
-
_id: { type:
|
|
11981
|
+
_id: { type: ObjectId, auto: true },
|
|
11997
11982
|
accountId: { type: String, required: true },
|
|
11998
11983
|
providerId: { type: String, required: true },
|
|
11999
|
-
userId: { type:
|
|
11984
|
+
userId: { type: ObjectId, ref: 'User', required: true },
|
|
12000
11985
|
accessToken: { type: String },
|
|
12001
11986
|
refreshToken: { type: String },
|
|
12002
11987
|
idToken: { type: String },
|
|
@@ -12004,23 +11989,25 @@ const accountSchema = new Schema(
|
|
|
12004
11989
|
refreshTokenExpiresAt: { type: Date },
|
|
12005
11990
|
scope: { type: String },
|
|
12006
11991
|
password: { type: String },
|
|
12007
|
-
createdAt: { type: Date, required: true },
|
|
12008
|
-
updatedAt: { type: Date, required: true },
|
|
11992
|
+
createdAt: { type: Date, required: true, default: Date.now },
|
|
11993
|
+
updatedAt: { type: Date, required: true, default: Date.now },
|
|
12009
11994
|
},
|
|
12010
11995
|
{ collection: 'account' }
|
|
12011
11996
|
);
|
|
11997
|
+
accountSchema.index({ userId: 1 });
|
|
12012
11998
|
|
|
12013
11999
|
const verificationSchema = new Schema(
|
|
12014
12000
|
{
|
|
12015
|
-
_id: { type:
|
|
12001
|
+
_id: { type: ObjectId, auto: true },
|
|
12016
12002
|
identifier: { type: String, required: true },
|
|
12017
12003
|
value: { type: String, required: true },
|
|
12018
12004
|
expiresAt: { type: Date, required: true },
|
|
12019
|
-
createdAt: { type: Date },
|
|
12020
|
-
updatedAt: { type: Date },
|
|
12005
|
+
createdAt: { type: Date, required: true, default: Date.now },
|
|
12006
|
+
updatedAt: { type: Date, required: true, default: Date.now },
|
|
12021
12007
|
},
|
|
12022
12008
|
{ collection: 'verification' }
|
|
12023
12009
|
);
|
|
12010
|
+
verificationSchema.index({ identifier: 1 });
|
|
12024
12011
|
|
|
12025
12012
|
const User = model('User', userSchema);
|
|
12026
12013
|
const Session = model('Session', sessionSchema);
|
|
@@ -17295,6 +17282,82 @@ export const startInstance = createStart(() => {
|
|
|
17295
17282
|
`],
|
|
17296
17283
|
["backend/convex/packages/backend/_gitignore", `
|
|
17297
17284
|
.env.local
|
|
17285
|
+
`],
|
|
17286
|
+
["backend/convex/packages/backend/convex/_generated/api.d.ts", `/* eslint-disable */
|
|
17287
|
+
export declare const api: any;
|
|
17288
|
+
export declare const internal: any;
|
|
17289
|
+
export declare const components: any;
|
|
17290
|
+
`],
|
|
17291
|
+
["backend/convex/packages/backend/convex/_generated/api.js", `/* eslint-disable */
|
|
17292
|
+
import { anyApi, componentsGeneric } from "convex/server";
|
|
17293
|
+
|
|
17294
|
+
export const api = anyApi;
|
|
17295
|
+
export const internal = anyApi;
|
|
17296
|
+
export const components = componentsGeneric();
|
|
17297
|
+
`],
|
|
17298
|
+
["backend/convex/packages/backend/convex/_generated/dataModel.d.ts", `/* eslint-disable */
|
|
17299
|
+
import type {
|
|
17300
|
+
DataModelFromSchemaDefinition,
|
|
17301
|
+
DocumentByName,
|
|
17302
|
+
SystemTableNames,
|
|
17303
|
+
TableNamesInDataModel,
|
|
17304
|
+
} from "convex/server";
|
|
17305
|
+
import type { GenericId } from "convex/values";
|
|
17306
|
+
|
|
17307
|
+
import schema from "../schema.js";
|
|
17308
|
+
|
|
17309
|
+
export type DataModel = DataModelFromSchemaDefinition<typeof schema>;
|
|
17310
|
+
export type TableNames = TableNamesInDataModel<DataModel>;
|
|
17311
|
+
export type Doc<TableName extends TableNames> = DocumentByName<DataModel, TableName>;
|
|
17312
|
+
export type Id<TableName extends TableNames | SystemTableNames> = GenericId<TableName>;
|
|
17313
|
+
`],
|
|
17314
|
+
["backend/convex/packages/backend/convex/_generated/server.d.ts", `/* eslint-disable */
|
|
17315
|
+
import type {
|
|
17316
|
+
ActionBuilder,
|
|
17317
|
+
GenericActionCtx,
|
|
17318
|
+
GenericDatabaseReader,
|
|
17319
|
+
GenericDatabaseWriter,
|
|
17320
|
+
GenericMutationCtx,
|
|
17321
|
+
GenericQueryCtx,
|
|
17322
|
+
HttpActionBuilder,
|
|
17323
|
+
MutationBuilder,
|
|
17324
|
+
QueryBuilder,
|
|
17325
|
+
} from "convex/server";
|
|
17326
|
+
|
|
17327
|
+
import type { DataModel } from "./dataModel.js";
|
|
17328
|
+
|
|
17329
|
+
export declare const query: QueryBuilder<DataModel, "public">;
|
|
17330
|
+
export declare const internalQuery: QueryBuilder<DataModel, "internal">;
|
|
17331
|
+
export declare const mutation: MutationBuilder<DataModel, "public">;
|
|
17332
|
+
export declare const internalMutation: MutationBuilder<DataModel, "internal">;
|
|
17333
|
+
export declare const action: ActionBuilder<DataModel, "public">;
|
|
17334
|
+
export declare const internalAction: ActionBuilder<DataModel, "internal">;
|
|
17335
|
+
export declare const httpAction: HttpActionBuilder;
|
|
17336
|
+
|
|
17337
|
+
export type QueryCtx = GenericQueryCtx<DataModel>;
|
|
17338
|
+
export type MutationCtx = GenericMutationCtx<DataModel>;
|
|
17339
|
+
export type ActionCtx = GenericActionCtx<DataModel>;
|
|
17340
|
+
export type DatabaseReader = GenericDatabaseReader<DataModel>;
|
|
17341
|
+
export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
|
|
17342
|
+
`],
|
|
17343
|
+
["backend/convex/packages/backend/convex/_generated/server.js", `/* eslint-disable */
|
|
17344
|
+
import {
|
|
17345
|
+
actionGeneric,
|
|
17346
|
+
httpActionGeneric,
|
|
17347
|
+
internalActionGeneric,
|
|
17348
|
+
internalMutationGeneric,
|
|
17349
|
+
internalQueryGeneric,
|
|
17350
|
+
mutationGeneric,
|
|
17351
|
+
queryGeneric,
|
|
17352
|
+
} from "convex/server";
|
|
17353
|
+
|
|
17354
|
+
export const query = queryGeneric;
|
|
17355
|
+
export const internalQuery = internalQueryGeneric;
|
|
17356
|
+
export const mutation = mutationGeneric;
|
|
17357
|
+
export const internalMutation = internalMutationGeneric;
|
|
17358
|
+
export const action = actionGeneric;
|
|
17359
|
+
export const internalAction = internalActionGeneric;
|
|
17360
|
+
export const httpAction = httpActionGeneric;
|
|
17298
17361
|
`],
|
|
17299
17362
|
["backend/convex/packages/backend/convex/convex.config.ts.hbs", `import { defineApp } from "convex/server";
|
|
17300
17363
|
{{#if (eq auth "better-auth")}}
|
|
@@ -17436,6 +17499,7 @@ export default defineSchema({
|
|
|
17436
17499
|
"jsx": "react-jsx",
|
|
17437
17500
|
"skipLibCheck": true,
|
|
17438
17501
|
"allowSyntheticDefaultImports": true,
|
|
17502
|
+
"types": ["node"],
|
|
17439
17503
|
|
|
17440
17504
|
/* These compiler options are required by Convex */
|
|
17441
17505
|
"target": "ESNext",
|
|
@@ -17712,10 +17776,8 @@ import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
|
|
|
17712
17776
|
import { RPCHandler } from "@orpc/server/node";
|
|
17713
17777
|
import { onError } from "@orpc/server";
|
|
17714
17778
|
import { appRouter } from "@{{projectName}}/api/routers/index";
|
|
17715
|
-
{{#if (or (eq auth "better-auth") (eq auth "clerk"))}}
|
|
17716
17779
|
import { createContext } from "@{{projectName}}/api/context";
|
|
17717
17780
|
{{/if}}
|
|
17718
|
-
{{/if}}
|
|
17719
17781
|
import cors from "cors";
|
|
17720
17782
|
import express from "express";
|
|
17721
17783
|
{{#if (includes examples "ai")}}
|
|
@@ -17788,21 +17850,13 @@ const apiHandler = new OpenAPIHandler(appRouter, {
|
|
|
17788
17850
|
app.use(async (req, res, next) => {
|
|
17789
17851
|
const rpcResult = await rpcHandler.handle(req, res, {
|
|
17790
17852
|
prefix: "/rpc",
|
|
17791
|
-
{{#if (or (eq auth "better-auth") (eq auth "clerk"))}}
|
|
17792
17853
|
context: await createContext({ req }),
|
|
17793
|
-
{{else}}
|
|
17794
|
-
context: {},
|
|
17795
|
-
{{/if}}
|
|
17796
17854
|
});
|
|
17797
17855
|
if (rpcResult.matched) return;
|
|
17798
17856
|
|
|
17799
17857
|
const apiResult = await apiHandler.handle(req, res, {
|
|
17800
17858
|
prefix: "/api-reference",
|
|
17801
|
-
{{#if (or (eq auth "better-auth") (eq auth "clerk"))}}
|
|
17802
17859
|
context: await createContext({ req }),
|
|
17803
|
-
{{else}}
|
|
17804
|
-
context: {},
|
|
17805
|
-
{{/if}}
|
|
17806
17860
|
});
|
|
17807
17861
|
if (apiResult.matched) return;
|
|
17808
17862
|
|
|
@@ -17913,7 +17967,10 @@ const fastify = Fastify({
|
|
|
17913
17967
|
|
|
17914
17968
|
fastify.register(fastifyCors, baseCorsConfig);
|
|
17915
17969
|
{{#if (eq auth "clerk")}}
|
|
17916
|
-
fastify.register(clerkPlugin
|
|
17970
|
+
fastify.register(clerkPlugin, {
|
|
17971
|
+
publishableKey: env.CLERK_PUBLISHABLE_KEY,
|
|
17972
|
+
secretKey: env.CLERK_SECRET_KEY,
|
|
17973
|
+
});
|
|
17917
17974
|
{{/if}}
|
|
17918
17975
|
|
|
17919
17976
|
{{#if (eq api "orpc")}}
|
|
@@ -18678,14 +18735,13 @@ export function createDb() {
|
|
|
18678
18735
|
}
|
|
18679
18736
|
{{/if}}
|
|
18680
18737
|
`],
|
|
18738
|
+
["db/drizzle/sqlite/src/migrations/.gitkeep", ``],
|
|
18681
18739
|
["db/mongoose/mongodb/src/index.ts.hbs", `import mongoose from "mongoose";
|
|
18682
18740
|
import { env } from "@{{projectName}}/env/server";
|
|
18683
18741
|
|
|
18684
|
-
await mongoose.connect(env.DATABASE_URL)
|
|
18685
|
-
console.log("Error connecting to database:", error);
|
|
18686
|
-
});
|
|
18742
|
+
await mongoose.connect(env.DATABASE_URL);
|
|
18687
18743
|
|
|
18688
|
-
const client = mongoose.connection.getClient().db(
|
|
18744
|
+
const client = mongoose.connection.getClient().db();
|
|
18689
18745
|
|
|
18690
18746
|
export { client };
|
|
18691
18747
|
`],
|
|
@@ -19007,6 +19063,7 @@ export default defineConfig({
|
|
|
19007
19063
|
{{/if}}
|
|
19008
19064
|
},
|
|
19009
19065
|
});`],
|
|
19066
|
+
["db/prisma/sqlite/prisma/migrations/.gitkeep", ``],
|
|
19010
19067
|
["db/prisma/sqlite/prisma/schema/schema.prisma.hbs", `generator client {
|
|
19011
19068
|
provider = "prisma-client"
|
|
19012
19069
|
output = "../generated"
|
|
@@ -19252,7 +19309,6 @@ import { Ionicons } from "@expo/vector-icons";
|
|
|
19252
19309
|
import {
|
|
19253
19310
|
useUIMessages,
|
|
19254
19311
|
useSmoothText,
|
|
19255
|
-
type UIMessage,
|
|
19256
19312
|
} from "@convex-dev/agent/react";
|
|
19257
19313
|
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
19258
19314
|
import { useMutation } from "convex/react";
|
|
@@ -19306,7 +19362,7 @@ export default function AIScreen() {
|
|
|
19306
19362
|
);
|
|
19307
19363
|
|
|
19308
19364
|
const hasStreamingMessage = messages?.some(
|
|
19309
|
-
(m
|
|
19365
|
+
(m) => m.status === "streaming",
|
|
19310
19366
|
);
|
|
19311
19367
|
|
|
19312
19368
|
useEffect(() => {
|
|
@@ -19363,7 +19419,7 @@ export default function AIScreen() {
|
|
|
19363
19419
|
</View>
|
|
19364
19420
|
) : (
|
|
19365
19421
|
<View style={styles.messagesList}>
|
|
19366
|
-
{messages.map((message
|
|
19422
|
+
{messages.map((message) => (
|
|
19367
19423
|
<View
|
|
19368
19424
|
key={message.key}
|
|
19369
19425
|
style={[
|
|
@@ -19383,7 +19439,9 @@ export default function AIScreen() {
|
|
|
19383
19439
|
{message.role === "user" ? "You" : "AI Assistant"}
|
|
19384
19440
|
</Text>
|
|
19385
19441
|
<MessageContent
|
|
19386
|
-
text={message.
|
|
19442
|
+
text={(message.parts ?? [])
|
|
19443
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
19444
|
+
.join("")}
|
|
19387
19445
|
isStreaming={message.status === "streaming"}
|
|
19388
19446
|
textColor={theme.text}
|
|
19389
19447
|
/>
|
|
@@ -19546,6 +19604,7 @@ const styles = StyleSheet.create({
|
|
|
19546
19604
|
});
|
|
19547
19605
|
{{else}}
|
|
19548
19606
|
import { useRef, useEffect, useState } from "react";
|
|
19607
|
+
import { Ionicons } from "@expo/vector-icons";
|
|
19549
19608
|
import {
|
|
19550
19609
|
View,
|
|
19551
19610
|
Text,
|
|
@@ -19558,8 +19617,6 @@ import {
|
|
|
19558
19617
|
} from "react-native";
|
|
19559
19618
|
import { useChat } from "@ai-sdk/react";
|
|
19560
19619
|
import { DefaultChatTransport } from "ai";
|
|
19561
|
-
import { fetch as expoFetch } from "expo/fetch";
|
|
19562
|
-
import { Ionicons } from "@expo/vector-icons";
|
|
19563
19620
|
import { Container } from "@/components/container";
|
|
19564
19621
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
19565
19622
|
import { NAV_THEME } from "@/lib/constants";
|
|
@@ -19582,7 +19639,6 @@ export default function AIScreen() {
|
|
|
19582
19639
|
const [input, setInput] = useState("");
|
|
19583
19640
|
const { messages, error, sendMessage } = useChat({
|
|
19584
19641
|
transport: new DefaultChatTransport({
|
|
19585
|
-
fetch: expoFetch as unknown as typeof globalThis.fetch,
|
|
19586
19642
|
api: generateAPIUrl("/ai"),
|
|
19587
19643
|
}),
|
|
19588
19644
|
onError: (error) => console.error(error, "AI Chat Error"),
|
|
@@ -19862,7 +19918,6 @@ import { Ionicons } from "@expo/vector-icons";
|
|
|
19862
19918
|
import {
|
|
19863
19919
|
useUIMessages,
|
|
19864
19920
|
useSmoothText,
|
|
19865
|
-
type UIMessage,
|
|
19866
19921
|
} from "@convex-dev/agent/react";
|
|
19867
19922
|
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
19868
19923
|
import { useMutation } from "convex/react";
|
|
@@ -19913,7 +19968,7 @@ export default function AIScreen() {
|
|
|
19913
19968
|
);
|
|
19914
19969
|
|
|
19915
19970
|
const hasStreamingMessage = messages?.some(
|
|
19916
|
-
(m
|
|
19971
|
+
(m) => m.status === "streaming",
|
|
19917
19972
|
);
|
|
19918
19973
|
|
|
19919
19974
|
useEffect(() => {
|
|
@@ -19969,7 +20024,7 @@ export default function AIScreen() {
|
|
|
19969
20024
|
</View>
|
|
19970
20025
|
) : (
|
|
19971
20026
|
<View style={styles.messagesWrapper}>
|
|
19972
|
-
{messages.map((message
|
|
20027
|
+
{messages.map((message) => (
|
|
19973
20028
|
<View
|
|
19974
20029
|
key={message.key}
|
|
19975
20030
|
style={[
|
|
@@ -19983,7 +20038,9 @@ export default function AIScreen() {
|
|
|
19983
20038
|
{message.role === "user" ? "You" : "AI Assistant"}
|
|
19984
20039
|
</Text>
|
|
19985
20040
|
<MessageContent
|
|
19986
|
-
text={message.
|
|
20041
|
+
text={(message.parts ?? [])
|
|
20042
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
20043
|
+
.join("")}
|
|
19987
20044
|
isStreaming={message.status === "streaming"}
|
|
19988
20045
|
style={styles.messageContent}
|
|
19989
20046
|
/>
|
|
@@ -20163,7 +20220,6 @@ import {
|
|
|
20163
20220
|
} from "react-native";
|
|
20164
20221
|
import { useChat } from "@ai-sdk/react";
|
|
20165
20222
|
import { DefaultChatTransport } from "ai";
|
|
20166
|
-
import { fetch as expoFetch } from "expo/fetch";
|
|
20167
20223
|
import { Ionicons } from "@expo/vector-icons";
|
|
20168
20224
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
20169
20225
|
import { Container } from "@/components/container";
|
|
@@ -20185,7 +20241,6 @@ export default function AIScreen() {
|
|
|
20185
20241
|
const [input, setInput] = useState("");
|
|
20186
20242
|
const { messages, error, sendMessage } = useChat({
|
|
20187
20243
|
transport: new DefaultChatTransport({
|
|
20188
|
-
fetch: expoFetch as unknown as typeof globalThis.fetch,
|
|
20189
20244
|
api: generateAPIUrl("/ai"),
|
|
20190
20245
|
}),
|
|
20191
20246
|
onError: (error) => console.error(error, "AI Chat Error"),
|
|
@@ -20474,7 +20529,6 @@ import { Ionicons } from "@expo/vector-icons";
|
|
|
20474
20529
|
import {
|
|
20475
20530
|
useUIMessages,
|
|
20476
20531
|
useSmoothText,
|
|
20477
|
-
type UIMessage,
|
|
20478
20532
|
} from "@convex-dev/agent/react";
|
|
20479
20533
|
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
20480
20534
|
import { useMutation } from "convex/react";
|
|
@@ -20521,7 +20575,7 @@ export default function AIScreen() {
|
|
|
20521
20575
|
);
|
|
20522
20576
|
|
|
20523
20577
|
const hasStreamingMessage = messages?.some(
|
|
20524
|
-
(m
|
|
20578
|
+
(m) => m.status === "streaming",
|
|
20525
20579
|
);
|
|
20526
20580
|
|
|
20527
20581
|
useEffect(() => {
|
|
@@ -20576,7 +20630,7 @@ export default function AIScreen() {
|
|
|
20576
20630
|
</Surface>
|
|
20577
20631
|
) : (
|
|
20578
20632
|
<View className="gap-3">
|
|
20579
|
-
{messages.map((message
|
|
20633
|
+
{messages.map((message) => (
|
|
20580
20634
|
<Surface
|
|
20581
20635
|
key={message.key}
|
|
20582
20636
|
variant={message.role === "user" ? "tertiary" : "secondary"}
|
|
@@ -20586,7 +20640,9 @@ export default function AIScreen() {
|
|
|
20586
20640
|
{message.role === "user" ? "You" : "AI"}
|
|
20587
20641
|
</Text>
|
|
20588
20642
|
<MessageContent
|
|
20589
|
-
text={message.
|
|
20643
|
+
text={(message.parts ?? [])
|
|
20644
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
20645
|
+
.join("")}
|
|
20590
20646
|
isStreaming={message.status === "streaming"}
|
|
20591
20647
|
/>
|
|
20592
20648
|
</Surface>
|
|
@@ -20649,7 +20705,6 @@ import {
|
|
|
20649
20705
|
} from "react-native";
|
|
20650
20706
|
import { useChat } from "@ai-sdk/react";
|
|
20651
20707
|
import { DefaultChatTransport } from "ai";
|
|
20652
|
-
import { fetch as expoFetch } from "expo/fetch";
|
|
20653
20708
|
import { Ionicons } from "@expo/vector-icons";
|
|
20654
20709
|
import { Container } from "@/components/container";
|
|
20655
20710
|
import { Button, Separator, FieldError, Spinner, Surface, Input, TextField, useThemeColor } from "heroui-native";
|
|
@@ -20670,7 +20725,6 @@ export default function AIScreen() {
|
|
|
20670
20725
|
const [input, setInput] = useState("");
|
|
20671
20726
|
const { messages, error, sendMessage, status } = useChat({
|
|
20672
20727
|
transport: new DefaultChatTransport({
|
|
20673
|
-
fetch: expoFetch as unknown as typeof globalThis.fetch,
|
|
20674
20728
|
api: generateAPIUrl("/ai"),
|
|
20675
20729
|
}),
|
|
20676
20730
|
onError: (error) => console.error(error, "AI Chat Error"),
|
|
@@ -20994,7 +21048,6 @@ import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
|
20994
21048
|
import {
|
|
20995
21049
|
useUIMessages,
|
|
20996
21050
|
useSmoothText,
|
|
20997
|
-
type UIMessage,
|
|
20998
21051
|
} from "@convex-dev/agent/react";
|
|
20999
21052
|
import { useMutation } from "convex/react";
|
|
21000
21053
|
import { Send, Loader2 } from "lucide-react";
|
|
@@ -21053,7 +21106,7 @@ export default function AIPage() {
|
|
|
21053
21106
|
}, [messages]);
|
|
21054
21107
|
|
|
21055
21108
|
const hasStreamingMessage = messages?.some(
|
|
21056
|
-
(m
|
|
21109
|
+
(m) => m.status === "streaming",
|
|
21057
21110
|
);
|
|
21058
21111
|
|
|
21059
21112
|
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
|
@@ -21087,7 +21140,7 @@ export default function AIPage() {
|
|
|
21087
21140
|
Ask me anything to get started!
|
|
21088
21141
|
</div>
|
|
21089
21142
|
) : (
|
|
21090
|
-
messages.map((message
|
|
21143
|
+
messages.map((message) => (
|
|
21091
21144
|
<div
|
|
21092
21145
|
key={message.key}
|
|
21093
21146
|
className={\`p-3 rounded-lg \${
|
|
@@ -21100,7 +21153,9 @@ export default function AIPage() {
|
|
|
21100
21153
|
{message.role === "user" ? "You" : "AI Assistant"}
|
|
21101
21154
|
</p>
|
|
21102
21155
|
<MessageContent
|
|
21103
|
-
text={message.
|
|
21156
|
+
text={(message.parts ?? [])
|
|
21157
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
21158
|
+
.join("")}
|
|
21104
21159
|
isStreaming={message.status === "streaming"}
|
|
21105
21160
|
/>
|
|
21106
21161
|
</div>
|
|
@@ -21260,7 +21315,6 @@ import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
|
21260
21315
|
import {
|
|
21261
21316
|
useUIMessages,
|
|
21262
21317
|
useSmoothText,
|
|
21263
|
-
type UIMessage,
|
|
21264
21318
|
} from "@convex-dev/agent/react";
|
|
21265
21319
|
import { useMutation } from "convex/react";
|
|
21266
21320
|
import { Send, Loader2 } from "lucide-react";
|
|
@@ -21303,7 +21357,7 @@ const AI: React.FC = () => {
|
|
|
21303
21357
|
}, [messages]);
|
|
21304
21358
|
|
|
21305
21359
|
const hasStreamingMessage = messages?.some(
|
|
21306
|
-
(m
|
|
21360
|
+
(m) => m.status === "streaming",
|
|
21307
21361
|
);
|
|
21308
21362
|
|
|
21309
21363
|
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
|
@@ -21337,7 +21391,7 @@ const AI: React.FC = () => {
|
|
|
21337
21391
|
Ask me anything to get started!
|
|
21338
21392
|
</div>
|
|
21339
21393
|
) : (
|
|
21340
|
-
messages.map((message
|
|
21394
|
+
messages.map((message) => (
|
|
21341
21395
|
<div
|
|
21342
21396
|
key={message.key}
|
|
21343
21397
|
className={\`p-3 rounded-lg \${
|
|
@@ -21350,7 +21404,9 @@ const AI: React.FC = () => {
|
|
|
21350
21404
|
{message.role === "user" ? "You" : "AI Assistant"}
|
|
21351
21405
|
</p>
|
|
21352
21406
|
<MessageContent
|
|
21353
|
-
text={message.
|
|
21407
|
+
text={(message.parts ?? [])
|
|
21408
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
21409
|
+
.join("")}
|
|
21354
21410
|
isStreaming={message.status === "streaming"}
|
|
21355
21411
|
/>
|
|
21356
21412
|
</div>
|
|
@@ -21496,7 +21552,6 @@ import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
|
21496
21552
|
import {
|
|
21497
21553
|
useUIMessages,
|
|
21498
21554
|
useSmoothText,
|
|
21499
|
-
type UIMessage,
|
|
21500
21555
|
} from "@convex-dev/agent/react";
|
|
21501
21556
|
import { createFileRoute } from "@tanstack/react-router";
|
|
21502
21557
|
import { useMutation } from "convex/react";
|
|
@@ -21544,7 +21599,7 @@ function RouteComponent() {
|
|
|
21544
21599
|
}, [messages]);
|
|
21545
21600
|
|
|
21546
21601
|
const hasStreamingMessage = messages?.some(
|
|
21547
|
-
(m
|
|
21602
|
+
(m) => m.status === "streaming",
|
|
21548
21603
|
);
|
|
21549
21604
|
|
|
21550
21605
|
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
|
@@ -21578,7 +21633,7 @@ function RouteComponent() {
|
|
|
21578
21633
|
Ask me anything to get started!
|
|
21579
21634
|
</div>
|
|
21580
21635
|
) : (
|
|
21581
|
-
messages.map((message
|
|
21636
|
+
messages.map((message) => (
|
|
21582
21637
|
<div
|
|
21583
21638
|
key={message.key}
|
|
21584
21639
|
className={\`p-3 rounded-lg \${
|
|
@@ -21591,7 +21646,9 @@ function RouteComponent() {
|
|
|
21591
21646
|
{message.role === "user" ? "You" : "AI Assistant"}
|
|
21592
21647
|
</p>
|
|
21593
21648
|
<MessageContent
|
|
21594
|
-
text={message.
|
|
21649
|
+
text={(message.parts ?? [])
|
|
21650
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
21651
|
+
.join("")}
|
|
21595
21652
|
isStreaming={message.status === "streaming"}
|
|
21596
21653
|
/>
|
|
21597
21654
|
</div>
|
|
@@ -21739,7 +21796,6 @@ import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
|
21739
21796
|
import {
|
|
21740
21797
|
useUIMessages,
|
|
21741
21798
|
useSmoothText,
|
|
21742
|
-
type UIMessage,
|
|
21743
21799
|
} from "@convex-dev/agent/react";
|
|
21744
21800
|
import { createFileRoute } from "@tanstack/react-router";
|
|
21745
21801
|
import { useMutation } from "convex/react";
|
|
@@ -21787,7 +21843,7 @@ function RouteComponent() {
|
|
|
21787
21843
|
}, [messages]);
|
|
21788
21844
|
|
|
21789
21845
|
const hasStreamingMessage = messages?.some(
|
|
21790
|
-
(m
|
|
21846
|
+
(m) => m.status === "streaming",
|
|
21791
21847
|
);
|
|
21792
21848
|
|
|
21793
21849
|
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
|
@@ -21821,7 +21877,7 @@ function RouteComponent() {
|
|
|
21821
21877
|
Ask me anything to get started!
|
|
21822
21878
|
</div>
|
|
21823
21879
|
) : (
|
|
21824
|
-
messages.map((message
|
|
21880
|
+
messages.map((message) => (
|
|
21825
21881
|
<div
|
|
21826
21882
|
key={message.key}
|
|
21827
21883
|
className={\`p-3 rounded-lg \${
|
|
@@ -21834,7 +21890,9 @@ function RouteComponent() {
|
|
|
21834
21890
|
{message.role === "user" ? "You" : "AI Assistant"}
|
|
21835
21891
|
</p>
|
|
21836
21892
|
<MessageContent
|
|
21837
|
-
text={message.
|
|
21893
|
+
text={(message.parts ?? [])
|
|
21894
|
+
.map((part) => (part.type === "text" ? part.text : ""))
|
|
21895
|
+
.join("")}
|
|
21838
21896
|
isStreaming={message.status === "streaming"}
|
|
21839
21897
|
/>
|
|
21840
21898
|
</div>
|
|
@@ -22149,7 +22207,7 @@ import { Ionicons } from "@expo/vector-icons";
|
|
|
22149
22207
|
{{#if (eq backend "convex")}}
|
|
22150
22208
|
import { useMutation, useQuery } from "convex/react";
|
|
22151
22209
|
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
22152
|
-
import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
22210
|
+
import type { Doc, Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
22153
22211
|
{{else}}
|
|
22154
22212
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
22155
22213
|
{{/if}}
|
|
@@ -22199,7 +22257,7 @@ export default function TodosScreen() {
|
|
|
22199
22257
|
}
|
|
22200
22258
|
|
|
22201
22259
|
const isLoading = !todos;
|
|
22202
|
-
const completedCount = todos?.filter((t) => t.completed).length || 0;
|
|
22260
|
+
const completedCount = todos?.filter((t: Doc<"todos">) => t.completed).length || 0;
|
|
22203
22261
|
const totalCount = todos?.length || 0;
|
|
22204
22262
|
{{else}}
|
|
22205
22263
|
{{#if (eq api "orpc")}}
|
|
@@ -22408,7 +22466,7 @@ export default function TodosScreen() {
|
|
|
22408
22466
|
|
|
22409
22467
|
{todos && todos.length > 0 && (
|
|
22410
22468
|
<View style={styles.todosList}>
|
|
22411
|
-
{todos.map((todo) => (
|
|
22469
|
+
{todos.map((todo: Doc<"todos">) => (
|
|
22412
22470
|
<View
|
|
22413
22471
|
key={todo._id}
|
|
22414
22472
|
style={[
|
|
@@ -22598,9 +22656,10 @@ const styles = StyleSheet.create({
|
|
|
22598
22656
|
fontSize: 16,
|
|
22599
22657
|
},
|
|
22600
22658
|
addButton: {
|
|
22601
|
-
|
|
22602
|
-
|
|
22659
|
+
width: 48,
|
|
22660
|
+
height: 48,
|
|
22603
22661
|
alignItems: "center",
|
|
22662
|
+
justifyContent: "center",
|
|
22604
22663
|
},
|
|
22605
22664
|
centerContainer: {
|
|
22606
22665
|
alignItems: "center",
|
|
@@ -22638,23 +22697,24 @@ const styles = StyleSheet.create({
|
|
|
22638
22697
|
alignItems: "center",
|
|
22639
22698
|
gap: 12,
|
|
22640
22699
|
},
|
|
22641
|
-
checkbox: {
|
|
22642
|
-
width: 20,
|
|
22643
|
-
height: 20,
|
|
22644
|
-
borderWidth: 2,
|
|
22645
|
-
justifyContent: "center",
|
|
22646
|
-
alignItems: "center",
|
|
22647
|
-
},
|
|
22648
22700
|
todoTextContainer: {
|
|
22649
22701
|
flex: 1,
|
|
22650
22702
|
},
|
|
22651
22703
|
todoText: {
|
|
22652
22704
|
fontSize: 16,
|
|
22653
22705
|
},
|
|
22706
|
+
checkbox: {
|
|
22707
|
+
width: 24,
|
|
22708
|
+
height: 24,
|
|
22709
|
+
borderWidth: 2,
|
|
22710
|
+
alignItems: "center",
|
|
22711
|
+
justifyContent: "center",
|
|
22712
|
+
},
|
|
22654
22713
|
deleteButton: {
|
|
22655
|
-
padding:
|
|
22714
|
+
padding: 4,
|
|
22656
22715
|
},
|
|
22657
|
-
})
|
|
22716
|
+
});
|
|
22717
|
+
`],
|
|
22658
22718
|
["examples/todo/native/unistyles/app/(drawer)/todos.tsx.hbs", `import { useState } from "react";
|
|
22659
22719
|
import {
|
|
22660
22720
|
View,
|
|
@@ -22671,7 +22731,7 @@ import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
|
22671
22731
|
{{#if (eq backend "convex")}}
|
|
22672
22732
|
import { useMutation, useQuery } from "convex/react";
|
|
22673
22733
|
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
22674
|
-
import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
22734
|
+
import type { Doc, Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
22675
22735
|
{{else}}
|
|
22676
22736
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
22677
22737
|
{{/if}}
|
|
@@ -22839,7 +22899,7 @@ export default function TodosScreen() {
|
|
|
22839
22899
|
{todos && todos.length === 0 && !isLoading && (
|
|
22840
22900
|
<Text style={styles.emptyText}>No todos yet. Add one!</Text>
|
|
22841
22901
|
)}
|
|
22842
|
-
{todos?.map((todo) => (
|
|
22902
|
+
{todos?.map((todo: Doc<"todos">) => (
|
|
22843
22903
|
<View key={todo._id} style={styles.todoItem}>
|
|
22844
22904
|
<TouchableOpacity
|
|
22845
22905
|
onPress={() => handleToggleTodo(todo._id, todo.completed)}
|
|
@@ -23002,7 +23062,7 @@ import { Ionicons } from "@expo/vector-icons";
|
|
|
23002
23062
|
{{#if (eq backend "convex")}}
|
|
23003
23063
|
import { useMutation, useQuery } from "convex/react";
|
|
23004
23064
|
import { api } from "@{{projectName}}/backend/convex/_generated/api";
|
|
23005
|
-
import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
23065
|
+
import type { Doc, Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
23006
23066
|
{{else}}
|
|
23007
23067
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
23008
23068
|
{{/if}}
|
|
@@ -23093,7 +23153,7 @@ export default function TodosScreen() {
|
|
|
23093
23153
|
};
|
|
23094
23154
|
|
|
23095
23155
|
const isLoading = !todos;
|
|
23096
|
-
const completedCount = todos?.filter((t) => t.completed).length || 0;
|
|
23156
|
+
const completedCount = todos?.filter((t: Doc<"todos">) => t.completed).length || 0;
|
|
23097
23157
|
const totalCount = todos?.length || 0;
|
|
23098
23158
|
{{else}}
|
|
23099
23159
|
const handleAddTodo = () => {
|
|
@@ -23205,7 +23265,7 @@ export default function TodosScreen() {
|
|
|
23205
23265
|
|
|
23206
23266
|
{todos && todos.length > 0 && (
|
|
23207
23267
|
<View className="gap-2">
|
|
23208
|
-
{todos.map((todo) => (
|
|
23268
|
+
{todos.map((todo: Doc<"todos">) => (
|
|
23209
23269
|
<Surface key={todo._id} variant="secondary" className="p-3 rounded-lg">
|
|
23210
23270
|
<View className="flex-row items-center gap-3">
|
|
23211
23271
|
<Checkbox
|
|
@@ -23277,7 +23337,8 @@ export default function TodosScreen() {
|
|
|
23277
23337
|
</ScrollView>
|
|
23278
23338
|
</Container>
|
|
23279
23339
|
);
|
|
23280
|
-
}
|
|
23340
|
+
}
|
|
23341
|
+
`],
|
|
23281
23342
|
["examples/todo/server/drizzle/base/src/routers/todo.ts.hbs", `{{#if (eq api "orpc")}}
|
|
23282
23343
|
import { eq } from "drizzle-orm";
|
|
23283
23344
|
import z from "zod";
|
|
@@ -23412,19 +23473,22 @@ export const todo = sqliteTable("todo", {
|
|
|
23412
23473
|
`],
|
|
23413
23474
|
["examples/todo/server/mongoose/base/src/routers/todo.ts.hbs", `{{#if (eq api "orpc")}}
|
|
23414
23475
|
import z from "zod";
|
|
23476
|
+
import "@{{projectName}}/db";
|
|
23415
23477
|
import { publicProcedure } from "../index";
|
|
23416
23478
|
import { Todo } from "@{{projectName}}/db/models/todo.model";
|
|
23417
23479
|
|
|
23418
23480
|
export const todoRouter = {
|
|
23419
23481
|
getAll: publicProcedure.handler(async () => {
|
|
23420
|
-
|
|
23482
|
+
const todos = await Todo.find().lean();
|
|
23483
|
+
return todos.map((todo) => ({ ...todo, id: todo.id }));
|
|
23421
23484
|
}),
|
|
23422
23485
|
|
|
23423
23486
|
create: publicProcedure
|
|
23424
23487
|
.input(z.object({ text: z.string().min(1) }))
|
|
23425
23488
|
.handler(async ({ input }) => {
|
|
23426
23489
|
const newTodo = await Todo.create({ text: input.text });
|
|
23427
|
-
|
|
23490
|
+
const todo = newTodo.toObject();
|
|
23491
|
+
return { ...todo, id: todo.id };
|
|
23428
23492
|
}),
|
|
23429
23493
|
|
|
23430
23494
|
toggle: publicProcedure
|
|
@@ -23446,19 +23510,22 @@ export const todoRouter = {
|
|
|
23446
23510
|
|
|
23447
23511
|
{{#if (eq api "trpc")}}
|
|
23448
23512
|
import z from "zod";
|
|
23513
|
+
import "@{{projectName}}/db";
|
|
23449
23514
|
import { router, publicProcedure } from "../index";
|
|
23450
23515
|
import { Todo } from "@{{projectName}}/db/models/todo.model";
|
|
23451
23516
|
|
|
23452
23517
|
export const todoRouter = router({
|
|
23453
23518
|
getAll: publicProcedure.query(async () => {
|
|
23454
|
-
|
|
23519
|
+
const todos = await Todo.find().lean();
|
|
23520
|
+
return todos.map((todo) => ({ ...todo, id: todo.id }));
|
|
23455
23521
|
}),
|
|
23456
23522
|
|
|
23457
23523
|
create: publicProcedure
|
|
23458
23524
|
.input(z.object({ text: z.string().min(1) }))
|
|
23459
23525
|
.mutation(async ({ input }) => {
|
|
23460
23526
|
const newTodo = await Todo.create({ text: input.text });
|
|
23461
|
-
|
|
23527
|
+
const todo = newTodo.toObject();
|
|
23528
|
+
return { ...todo, id: todo.id };
|
|
23462
23529
|
}),
|
|
23463
23530
|
|
|
23464
23531
|
toggle: publicProcedure
|
|
@@ -23483,8 +23550,9 @@ const { Schema, model } = mongoose;
|
|
|
23483
23550
|
|
|
23484
23551
|
const todoSchema = new Schema({
|
|
23485
23552
|
id: {
|
|
23486
|
-
type:
|
|
23487
|
-
|
|
23553
|
+
type: String,
|
|
23554
|
+
required: true,
|
|
23555
|
+
default: () => new mongoose.Types.ObjectId().toString(),
|
|
23488
23556
|
},
|
|
23489
23557
|
text: {
|
|
23490
23558
|
type: String,
|
|
@@ -23495,7 +23563,8 @@ const todoSchema = new Schema({
|
|
|
23495
23563
|
default: false,
|
|
23496
23564
|
},
|
|
23497
23565
|
}, {
|
|
23498
|
-
collection: 'todo'
|
|
23566
|
+
collection: 'todo',
|
|
23567
|
+
id: false,
|
|
23499
23568
|
});
|
|
23500
23569
|
|
|
23501
23570
|
const Todo = model('Todo', todoSchema);
|
|
@@ -24103,6 +24172,9 @@ import { trpc } from "@/utils/trpc";
|
|
|
24103
24172
|
{{/if}}
|
|
24104
24173
|
{{/if}}
|
|
24105
24174
|
|
|
24175
|
+
{{#unless (eq backend "convex")}}
|
|
24176
|
+
type TodoId = {{#if (or (eq orm "mongoose") (eq database "mongodb"))}}string{{else}}number{{/if}};
|
|
24177
|
+
{{/unless}}
|
|
24106
24178
|
|
|
24107
24179
|
export default function TodosPage() {
|
|
24108
24180
|
const [newTodoText, setNewTodoText] = useState("");
|
|
@@ -24179,11 +24251,11 @@ export default function TodosPage() {
|
|
|
24179
24251
|
}
|
|
24180
24252
|
};
|
|
24181
24253
|
|
|
24182
|
-
const handleToggleTodo = (id:
|
|
24254
|
+
const handleToggleTodo = (id: TodoId, completed: boolean) => {
|
|
24183
24255
|
toggleMutation.mutate({ id, completed: !completed });
|
|
24184
24256
|
};
|
|
24185
24257
|
|
|
24186
|
-
const handleDeleteTodo = (id:
|
|
24258
|
+
const handleDeleteTodo = (id: TodoId) => {
|
|
24187
24259
|
deleteMutation.mutate({ id });
|
|
24188
24260
|
};
|
|
24189
24261
|
{{/if}}
|
|
@@ -24347,6 +24419,10 @@ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
|
24347
24419
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
24348
24420
|
{{/if}}
|
|
24349
24421
|
|
|
24422
|
+
{{#unless (eq backend "convex")}}
|
|
24423
|
+
type TodoId = {{#if (or (eq orm "mongoose") (eq database "mongodb"))}}string{{else}}number{{/if}};
|
|
24424
|
+
{{/unless}}
|
|
24425
|
+
|
|
24350
24426
|
export default function Todos() {
|
|
24351
24427
|
const [newTodoText, setNewTodoText] = useState("");
|
|
24352
24428
|
|
|
@@ -24422,11 +24498,11 @@ export default function Todos() {
|
|
|
24422
24498
|
}
|
|
24423
24499
|
};
|
|
24424
24500
|
|
|
24425
|
-
const handleToggleTodo = (id:
|
|
24501
|
+
const handleToggleTodo = (id: TodoId, completed: boolean) => {
|
|
24426
24502
|
toggleMutation.mutate({ id, completed: !completed });
|
|
24427
24503
|
};
|
|
24428
24504
|
|
|
24429
|
-
const handleDeleteTodo = (id:
|
|
24505
|
+
const handleDeleteTodo = (id: TodoId) => {
|
|
24430
24506
|
deleteMutation.mutate({ id });
|
|
24431
24507
|
};
|
|
24432
24508
|
{{/if}}
|
|
@@ -24591,6 +24667,10 @@ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
|
|
|
24591
24667
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
24592
24668
|
{{/if}}
|
|
24593
24669
|
|
|
24670
|
+
{{#unless (eq backend "convex")}}
|
|
24671
|
+
type TodoId = {{#if (or (eq orm "mongoose") (eq database "mongodb"))}}string{{else}}number{{/if}};
|
|
24672
|
+
{{/unless}}
|
|
24673
|
+
|
|
24594
24674
|
export const Route = createFileRoute("/todos")({
|
|
24595
24675
|
component: TodosRoute,
|
|
24596
24676
|
});
|
|
@@ -24670,11 +24750,11 @@ function TodosRoute() {
|
|
|
24670
24750
|
}
|
|
24671
24751
|
};
|
|
24672
24752
|
|
|
24673
|
-
const handleToggleTodo = (id:
|
|
24753
|
+
const handleToggleTodo = (id: TodoId, completed: boolean) => {
|
|
24674
24754
|
toggleMutation.mutate({ id, completed: !completed });
|
|
24675
24755
|
};
|
|
24676
24756
|
|
|
24677
|
-
const handleDeleteTodo = (id:
|
|
24757
|
+
const handleDeleteTodo = (id: TodoId) => {
|
|
24678
24758
|
deleteMutation.mutate({ id });
|
|
24679
24759
|
};
|
|
24680
24760
|
{{/if}}
|
|
@@ -24845,6 +24925,10 @@ import { orpc } from "@/utils/orpc";
|
|
|
24845
24925
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
24846
24926
|
{{/if}}
|
|
24847
24927
|
|
|
24928
|
+
{{#unless (eq backend "convex")}}
|
|
24929
|
+
type TodoId = {{#if (or (eq orm "mongoose") (eq database "mongodb"))}}string{{else}}number{{/if}};
|
|
24930
|
+
{{/unless}}
|
|
24931
|
+
|
|
24848
24932
|
export const Route = createFileRoute("/todos")({
|
|
24849
24933
|
component: TodosRoute,
|
|
24850
24934
|
});
|
|
@@ -24946,11 +25030,11 @@ function TodosRoute() {
|
|
|
24946
25030
|
}
|
|
24947
25031
|
};
|
|
24948
25032
|
|
|
24949
|
-
const handleToggleTodo = (id:
|
|
25033
|
+
const handleToggleTodo = (id: TodoId, completed: boolean) => {
|
|
24950
25034
|
toggleMutation.mutate({ id, completed: !completed });
|
|
24951
25035
|
};
|
|
24952
25036
|
|
|
24953
|
-
const handleDeleteTodo = (id:
|
|
25037
|
+
const handleDeleteTodo = (id: TodoId) => {
|
|
24954
25038
|
deleteMutation.mutate({ id });
|
|
24955
25039
|
};
|
|
24956
25040
|
{{/if}}
|
|
@@ -25541,11 +25625,15 @@ shamefully-hoist=true
|
|
|
25541
25625
|
strict-peer-dependencies=false
|
|
25542
25626
|
{{/if}}`],
|
|
25543
25627
|
["extras/bunfig.toml.hbs", `[install]
|
|
25544
|
-
{{#if (
|
|
25545
|
-
linker = "hoisted" #
|
|
25628
|
+
{{#if (includes frontend "nuxt")}}
|
|
25629
|
+
linker = "hoisted" # Nuxt needs hoisting for its dependency resolver
|
|
25546
25630
|
{{else}}
|
|
25547
25631
|
linker = "isolated"
|
|
25548
|
-
{{
|
|
25632
|
+
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
25633
|
+
peer = false # Expo native projects declare SDK peers explicitly; this keeps Bun isolated installs deduped for native modules
|
|
25634
|
+
{{/if}}
|
|
25635
|
+
{{/if}}
|
|
25636
|
+
`],
|
|
25549
25637
|
["extras/env.d.ts.hbs", `{{#if (eq serverDeploy "cloudflare")}}
|
|
25550
25638
|
import { type server } from "@{{projectName}}/infra/alchemy.run";
|
|
25551
25639
|
{{else}}
|
|
@@ -25567,9 +25655,40 @@ declare module "cloudflare:workers" {
|
|
|
25567
25655
|
}
|
|
25568
25656
|
}
|
|
25569
25657
|
`],
|
|
25570
|
-
["extras/pnpm-workspace.yaml", `packages:
|
|
25658
|
+
["extras/pnpm-workspace.yaml.hbs", `packages:
|
|
25571
25659
|
- "apps/*"
|
|
25572
25660
|
- "packages/*"
|
|
25661
|
+
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (eq orm "prisma") (includes addons "lefthook") (includes addons "nx") (includes addons "pwa") (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
25662
|
+
|
|
25663
|
+
# pnpm 11 blocks dependency lifecycle scripts unless they are approved here.
|
|
25664
|
+
# Entries are scoped to packages this generated stack can pull in.
|
|
25665
|
+
allowBuilds:
|
|
25666
|
+
{{#if (or (eq runtime "node") (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (includes frontend "tanstack-start"))}}
|
|
25667
|
+
esbuild: true
|
|
25668
|
+
{{/if}}
|
|
25669
|
+
{{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "tanstack-start") (includes frontend "next"))}}
|
|
25670
|
+
msw: true
|
|
25671
|
+
{{/if}}
|
|
25672
|
+
{{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
|
|
25673
|
+
msgpackr-extract: true
|
|
25674
|
+
{{/if}}
|
|
25675
|
+
{{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare") (includes addons "pwa"))}}
|
|
25676
|
+
sharp: true
|
|
25677
|
+
{{/if}}
|
|
25678
|
+
{{#if (or (eq webDeploy "cloudflare") (eq serverDeploy "cloudflare"))}}
|
|
25679
|
+
workerd: true
|
|
25680
|
+
{{/if}}
|
|
25681
|
+
{{#if (eq orm "prisma")}}
|
|
25682
|
+
"@prisma/engines": true
|
|
25683
|
+
prisma: true
|
|
25684
|
+
{{/if}}
|
|
25685
|
+
{{#if (includes addons "lefthook")}}
|
|
25686
|
+
lefthook: true
|
|
25687
|
+
{{/if}}
|
|
25688
|
+
{{#if (includes addons "nx")}}
|
|
25689
|
+
nx: true
|
|
25690
|
+
{{/if}}
|
|
25691
|
+
{{/if}}
|
|
25573
25692
|
`],
|
|
25574
25693
|
["frontend/astro/_gitignore", `# build output
|
|
25575
25694
|
dist/
|
|
@@ -25938,12 +26057,7 @@ import { env } from "@{{projectName}}/env/native";
|
|
|
25938
26057
|
{{/if}}
|
|
25939
26058
|
|
|
25940
26059
|
import { Stack } from "expo-router";
|
|
25941
|
-
import {
|
|
25942
|
-
DarkTheme,
|
|
25943
|
-
DefaultTheme,
|
|
25944
|
-
type Theme,
|
|
25945
|
-
ThemeProvider,
|
|
25946
|
-
} from "@react-navigation/native";
|
|
26060
|
+
import { DarkTheme, DefaultTheme, ThemeProvider } from "expo-router/react-navigation";
|
|
25947
26061
|
import { StatusBar } from "expo-status-bar";
|
|
25948
26062
|
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
|
25949
26063
|
{{#if (eq api "trpc")}}
|
|
@@ -25956,11 +26070,11 @@ import { NAV_THEME } from "@/lib/constants";
|
|
|
25956
26070
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
25957
26071
|
import { StyleSheet } from "react-native";
|
|
25958
26072
|
|
|
25959
|
-
const LIGHT_THEME
|
|
26073
|
+
const LIGHT_THEME = {
|
|
25960
26074
|
...DefaultTheme,
|
|
25961
26075
|
colors: NAV_THEME.light,
|
|
25962
26076
|
};
|
|
25963
|
-
const DARK_THEME
|
|
26077
|
+
const DARK_THEME = {
|
|
25964
26078
|
...DarkTheme,
|
|
25965
26079
|
colors: NAV_THEME.dark,
|
|
25966
26080
|
};
|
|
@@ -25971,9 +26085,6 @@ export const unstable_settings = {
|
|
|
25971
26085
|
|
|
25972
26086
|
{{#if (eq backend "convex")}}
|
|
25973
26087
|
const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
|
|
25974
|
-
{{#if (eq auth "better-auth")}}
|
|
25975
|
-
expectAuth: true,
|
|
25976
|
-
{{/if}}
|
|
25977
26088
|
unsavedChangesWarning: false,
|
|
25978
26089
|
});
|
|
25979
26090
|
{{/if}}
|
|
@@ -26240,7 +26351,8 @@ export default function TabLayout() {
|
|
|
26240
26351
|
|
|
26241
26352
|
`],
|
|
26242
26353
|
["frontend/native/bare/app/(drawer)/(tabs)/index.tsx.hbs", `import { Container } from "@/components/container";
|
|
26243
|
-
import {
|
|
26354
|
+
import { Column, Host, Text as ExpoUIText } from "@expo/ui";
|
|
26355
|
+
import { ScrollView, View, StyleSheet } from "react-native";
|
|
26244
26356
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
26245
26357
|
import { NAV_THEME } from "@/lib/constants";
|
|
26246
26358
|
|
|
@@ -26252,12 +26364,21 @@ export default function TabOne() {
|
|
|
26252
26364
|
<Container>
|
|
26253
26365
|
<ScrollView style={styles.scrollView}>
|
|
26254
26366
|
<View style={styles.content}>
|
|
26255
|
-
<
|
|
26256
|
-
|
|
26257
|
-
|
|
26258
|
-
|
|
26259
|
-
|
|
26260
|
-
|
|
26367
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26368
|
+
<Column spacing={8}>
|
|
26369
|
+
<ExpoUIText
|
|
26370
|
+
textStyle=\\{{ color: theme.text, fontSize: 24, fontWeight: "bold" }}
|
|
26371
|
+
>
|
|
26372
|
+
Tab One
|
|
26373
|
+
</ExpoUIText>
|
|
26374
|
+
<ExpoUIText
|
|
26375
|
+
textStyle=\\{{ color: theme.text, fontSize: 16 }}
|
|
26376
|
+
style=\\{{ opacity: 0.7 }}
|
|
26377
|
+
>
|
|
26378
|
+
Explore the first section of your app
|
|
26379
|
+
</ExpoUIText>
|
|
26380
|
+
</Column>
|
|
26381
|
+
</Host>
|
|
26261
26382
|
</View>
|
|
26262
26383
|
</ScrollView>
|
|
26263
26384
|
</Container>
|
|
@@ -26272,19 +26393,11 @@ const styles = StyleSheet.create({
|
|
|
26272
26393
|
content: {
|
|
26273
26394
|
paddingVertical: 16,
|
|
26274
26395
|
},
|
|
26275
|
-
title: {
|
|
26276
|
-
fontSize: 24,
|
|
26277
|
-
fontWeight: "bold",
|
|
26278
|
-
marginBottom: 8,
|
|
26279
|
-
},
|
|
26280
|
-
subtitle: {
|
|
26281
|
-
fontSize: 16,
|
|
26282
|
-
},
|
|
26283
26396
|
});
|
|
26284
|
-
|
|
26285
26397
|
`],
|
|
26286
26398
|
["frontend/native/bare/app/(drawer)/(tabs)/two.tsx.hbs", `import { Container } from "@/components/container";
|
|
26287
|
-
import {
|
|
26399
|
+
import { Column, Host, Text as ExpoUIText } from "@expo/ui";
|
|
26400
|
+
import { ScrollView, View, StyleSheet } from "react-native";
|
|
26288
26401
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
26289
26402
|
import { NAV_THEME } from "@/lib/constants";
|
|
26290
26403
|
|
|
@@ -26296,12 +26409,21 @@ export default function TabTwo() {
|
|
|
26296
26409
|
<Container>
|
|
26297
26410
|
<ScrollView style={styles.scrollView}>
|
|
26298
26411
|
<View style={styles.content}>
|
|
26299
|
-
<
|
|
26300
|
-
|
|
26301
|
-
|
|
26302
|
-
|
|
26303
|
-
|
|
26304
|
-
|
|
26412
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26413
|
+
<Column spacing={8}>
|
|
26414
|
+
<ExpoUIText
|
|
26415
|
+
textStyle=\\{{ color: theme.text, fontSize: 24, fontWeight: "bold" }}
|
|
26416
|
+
>
|
|
26417
|
+
Tab Two
|
|
26418
|
+
</ExpoUIText>
|
|
26419
|
+
<ExpoUIText
|
|
26420
|
+
textStyle=\\{{ color: theme.text, fontSize: 16 }}
|
|
26421
|
+
style=\\{{ opacity: 0.7 }}
|
|
26422
|
+
>
|
|
26423
|
+
Discover more features and content
|
|
26424
|
+
</ExpoUIText>
|
|
26425
|
+
</Column>
|
|
26426
|
+
</Host>
|
|
26305
26427
|
</View>
|
|
26306
26428
|
</ScrollView>
|
|
26307
26429
|
</Container>
|
|
@@ -26316,18 +26438,10 @@ const styles = StyleSheet.create({
|
|
|
26316
26438
|
content: {
|
|
26317
26439
|
paddingVertical: 16,
|
|
26318
26440
|
},
|
|
26319
|
-
title: {
|
|
26320
|
-
fontSize: 24,
|
|
26321
|
-
fontWeight: "bold",
|
|
26322
|
-
marginBottom: 8,
|
|
26323
|
-
},
|
|
26324
|
-
subtitle: {
|
|
26325
|
-
fontSize: 16,
|
|
26326
|
-
},
|
|
26327
26441
|
});
|
|
26328
|
-
|
|
26329
26442
|
`],
|
|
26330
|
-
["frontend/native/bare/app/(drawer)/index.tsx.hbs", `import {
|
|
26443
|
+
["frontend/native/bare/app/(drawer)/index.tsx.hbs", `import { {{#if (or (eq auth "clerk") (eq auth "better-auth"))}}Button, {{/if}}Column, Host, Text as ExpoUIText } from "@expo/ui";
|
|
26444
|
+
import { View, ScrollView, StyleSheet } from "react-native";
|
|
26331
26445
|
import { Container } from "@/components/container";
|
|
26332
26446
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
26333
26447
|
import { NAV_THEME } from "@/lib/constants";
|
|
@@ -26340,13 +26454,13 @@ import { useQuery } from "@tanstack/react-query";
|
|
|
26340
26454
|
import { trpc } from "@/utils/trpc";
|
|
26341
26455
|
{{/if}}
|
|
26342
26456
|
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
|
|
26343
|
-
import {
|
|
26457
|
+
import { router } from "expo-router";
|
|
26344
26458
|
import { Authenticated, AuthLoading, Unauthenticated, useQuery } from "convex/react";
|
|
26345
26459
|
import { api } from "@{{ projectName }}/backend/convex/_generated/api";
|
|
26346
26460
|
import { useUser } from "@clerk/expo";
|
|
26347
26461
|
import { SignOutButton } from "@/components/sign-out-button";
|
|
26348
26462
|
{{else if (and (ne backend "convex") (eq auth "clerk"))}}
|
|
26349
|
-
import {
|
|
26463
|
+
import { router } from "expo-router";
|
|
26350
26464
|
import { useAuth, useUser } from "@clerk/expo";
|
|
26351
26465
|
import { SignOutButton } from "@/components/sign-out-button";
|
|
26352
26466
|
{{else if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
@@ -26388,9 +26502,15 @@ return (
|
|
|
26388
26502
|
<Container>
|
|
26389
26503
|
<ScrollView style={styles.scrollView}>
|
|
26390
26504
|
<View style={styles.content}>
|
|
26391
|
-
<
|
|
26392
|
-
|
|
26393
|
-
|
|
26505
|
+
<Host style={styles.titleHost} matchContents=\\{{ vertical: true }}>
|
|
26506
|
+
<Column>
|
|
26507
|
+
<ExpoUIText
|
|
26508
|
+
textStyle=\\{{ color: theme.text, fontSize: 24, fontWeight: "bold" }}
|
|
26509
|
+
>
|
|
26510
|
+
BETTER T STACK
|
|
26511
|
+
</ExpoUIText>
|
|
26512
|
+
</Column>
|
|
26513
|
+
</Host>
|
|
26394
26514
|
|
|
26395
26515
|
{{#unless (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
26396
26516
|
<View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
@@ -26398,16 +26518,25 @@ return (
|
|
|
26398
26518
|
<View style={styles.statusRow}>
|
|
26399
26519
|
<View style={[styles.statusIndicator, { backgroundColor: healthCheck ? "#10b981" : "#f59e0b" }]} />
|
|
26400
26520
|
<View style={styles.statusContent}>
|
|
26401
|
-
<
|
|
26402
|
-
|
|
26403
|
-
|
|
26404
|
-
|
|
26405
|
-
|
|
26406
|
-
|
|
26407
|
-
|
|
26408
|
-
|
|
26409
|
-
|
|
26410
|
-
|
|
26521
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26522
|
+
<Column spacing={4}>
|
|
26523
|
+
<ExpoUIText
|
|
26524
|
+
textStyle=\\{{ color: theme.text, fontSize: 14, fontWeight: "bold" }}
|
|
26525
|
+
>
|
|
26526
|
+
Convex
|
|
26527
|
+
</ExpoUIText>
|
|
26528
|
+
<ExpoUIText
|
|
26529
|
+
textStyle=\\{{ color: theme.text, fontSize: 12 }}
|
|
26530
|
+
style=\\{{ opacity: 0.7 }}
|
|
26531
|
+
>
|
|
26532
|
+
{healthCheck === undefined
|
|
26533
|
+
? "Checking..."
|
|
26534
|
+
: healthCheck === "OK"
|
|
26535
|
+
? "Connected to API"
|
|
26536
|
+
: "API Disconnected"}
|
|
26537
|
+
</ExpoUIText>
|
|
26538
|
+
</Column>
|
|
26539
|
+
</Host>
|
|
26411
26540
|
</View>
|
|
26412
26541
|
</View>
|
|
26413
26542
|
{{else}}
|
|
@@ -26415,16 +26544,25 @@ return (
|
|
|
26415
26544
|
<View style={styles.statusRow}>
|
|
26416
26545
|
<View style={[styles.statusIndicator, { backgroundColor: healthCheck.data ? "#10b981" : "#f59e0b" }]} />
|
|
26417
26546
|
<View style={styles.statusContent}>
|
|
26418
|
-
<
|
|
26419
|
-
|
|
26420
|
-
|
|
26421
|
-
|
|
26422
|
-
|
|
26423
|
-
|
|
26424
|
-
|
|
26425
|
-
|
|
26426
|
-
|
|
26427
|
-
|
|
26547
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26548
|
+
<Column spacing={4}>
|
|
26549
|
+
<ExpoUIText
|
|
26550
|
+
textStyle=\\{{ color: theme.text, fontSize: 14, fontWeight: "bold" }}
|
|
26551
|
+
>
|
|
26552
|
+
{{#if (eq api "orpc")}}ORPC{{else}}TRPC{{/if}}
|
|
26553
|
+
</ExpoUIText>
|
|
26554
|
+
<ExpoUIText
|
|
26555
|
+
textStyle=\\{{ color: theme.text, fontSize: 12 }}
|
|
26556
|
+
style=\\{{ opacity: 0.7 }}
|
|
26557
|
+
>
|
|
26558
|
+
{healthCheck.isLoading
|
|
26559
|
+
? "Checking connection..."
|
|
26560
|
+
: healthCheck.data
|
|
26561
|
+
? "All systems operational"
|
|
26562
|
+
: "Service unavailable"}
|
|
26563
|
+
</ExpoUIText>
|
|
26564
|
+
</Column>
|
|
26565
|
+
</Host>
|
|
26428
26566
|
</View>
|
|
26429
26567
|
</View>
|
|
26430
26568
|
{{/unless}}
|
|
@@ -26434,85 +26572,139 @@ return (
|
|
|
26434
26572
|
|
|
26435
26573
|
{{#if (and (eq backend "convex") (eq auth "clerk"))}}
|
|
26436
26574
|
<Authenticated>
|
|
26437
|
-
<
|
|
26438
|
-
|
|
26575
|
+
<Host style={styles.authHost} matchContents=\\{{ vertical: true }}>
|
|
26576
|
+
<Column spacing={6}>
|
|
26577
|
+
<ExpoUIText textStyle=\\{{ color: theme.text, fontSize: 14 }}>
|
|
26578
|
+
{\`Hello \${user?.emailAddresses[0].emailAddress ?? ""}\`}
|
|
26579
|
+
</ExpoUIText>
|
|
26580
|
+
<ExpoUIText textStyle=\\{{ color: theme.text, fontSize: 14 }}>
|
|
26581
|
+
{\`Private Data: \${privateData?.message ?? ""}\`}
|
|
26582
|
+
</ExpoUIText>
|
|
26583
|
+
</Column>
|
|
26584
|
+
</Host>
|
|
26439
26585
|
<SignOutButton />
|
|
26440
26586
|
</Authenticated>
|
|
26441
26587
|
<Unauthenticated>
|
|
26442
|
-
<
|
|
26443
|
-
|
|
26444
|
-
|
|
26445
|
-
|
|
26446
|
-
|
|
26447
|
-
|
|
26588
|
+
<Host style={styles.authActionsHost} matchContents=\\{{ vertical: true }}>
|
|
26589
|
+
<Column spacing={8}>
|
|
26590
|
+
<Button
|
|
26591
|
+
label="Sign in"
|
|
26592
|
+
variant="outlined"
|
|
26593
|
+
onPress={() => router.push("/(auth)/sign-in")}
|
|
26594
|
+
/>
|
|
26595
|
+
<Button
|
|
26596
|
+
label="Sign up"
|
|
26597
|
+
onPress={() => router.push("/(auth)/sign-up")}
|
|
26598
|
+
/>
|
|
26599
|
+
</Column>
|
|
26600
|
+
</Host>
|
|
26448
26601
|
</Unauthenticated>
|
|
26449
26602
|
<AuthLoading>
|
|
26450
|
-
<
|
|
26603
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26604
|
+
<ExpoUIText textStyle=\\{{ color: theme.text, fontSize: 14 }}>
|
|
26605
|
+
Loading...
|
|
26606
|
+
</ExpoUIText>
|
|
26607
|
+
</Host>
|
|
26451
26608
|
</AuthLoading>
|
|
26452
26609
|
{{/if}}
|
|
26453
26610
|
|
|
26454
26611
|
{{#if (and (ne backend "convex") (eq auth "clerk"))}}
|
|
26455
26612
|
{!isLoaded ? (
|
|
26456
|
-
<
|
|
26613
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26614
|
+
<ExpoUIText textStyle=\\{{ color: theme.text, fontSize: 14 }}>
|
|
26615
|
+
Loading...
|
|
26616
|
+
</ExpoUIText>
|
|
26617
|
+
</Host>
|
|
26457
26618
|
) : isSignedIn ? (
|
|
26458
26619
|
<View style={[styles.userCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
26459
|
-
<
|
|
26460
|
-
<
|
|
26461
|
-
|
|
26462
|
-
|
|
26463
|
-
|
|
26464
|
-
|
|
26465
|
-
|
|
26466
|
-
|
|
26620
|
+
<Host style={styles.userHeader} matchContents=\\{{ vertical: true }}>
|
|
26621
|
+
<Column spacing={8}>
|
|
26622
|
+
<ExpoUIText textStyle=\\{{ color: theme.text, fontSize: 16 }}>
|
|
26623
|
+
{\`Welcome, \${user?.fullName ?? user?.firstName ?? "there"}\`}
|
|
26624
|
+
</ExpoUIText>
|
|
26625
|
+
<ExpoUIText
|
|
26626
|
+
textStyle=\\{{ color: theme.text, fontSize: 14 }}
|
|
26627
|
+
style=\\{{ opacity: 0.7 }}
|
|
26628
|
+
>
|
|
26629
|
+
{user?.emailAddresses[0]?.emailAddress ?? ""}
|
|
26630
|
+
</ExpoUIText>
|
|
26631
|
+
</Column>
|
|
26632
|
+
</Host>
|
|
26467
26633
|
<SignOutButton />
|
|
26468
26634
|
</View>
|
|
26469
26635
|
) : (
|
|
26470
26636
|
<View style={[styles.card, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
26471
|
-
<
|
|
26472
|
-
<
|
|
26473
|
-
|
|
26474
|
-
|
|
26475
|
-
|
|
26476
|
-
|
|
26637
|
+
<Host style={styles.authActionsHost} matchContents=\\{{ vertical: true }}>
|
|
26638
|
+
<Column spacing={8}>
|
|
26639
|
+
<Button
|
|
26640
|
+
label="Sign in"
|
|
26641
|
+
variant="outlined"
|
|
26642
|
+
onPress={() => router.push("/(auth)/sign-in")}
|
|
26643
|
+
/>
|
|
26644
|
+
<Button
|
|
26645
|
+
label="Sign up"
|
|
26646
|
+
onPress={() => router.push("/(auth)/sign-up")}
|
|
26647
|
+
/>
|
|
26648
|
+
</Column>
|
|
26649
|
+
</Host>
|
|
26477
26650
|
</View>
|
|
26478
26651
|
)}
|
|
26479
26652
|
{{/if}}
|
|
26480
26653
|
|
|
26481
26654
|
{{#if (and (eq backend "convex") (eq auth "better-auth"))}}
|
|
26482
|
-
{user ? (
|
|
26483
|
-
<View style={[styles.userCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
26484
|
-
<View style={styles.userHeader}>
|
|
26485
|
-
<Text style={[styles.userText, { color: theme.text }]}>
|
|
26486
|
-
Welcome, <Text style={styles.userName}>{user.name}</Text>
|
|
26487
|
-
</Text>
|
|
26488
|
-
</View>
|
|
26489
|
-
<Text style={[styles.userEmail, { color: theme.text, opacity: 0.7 }]}>
|
|
26490
|
-
{user.email}
|
|
26491
|
-
</Text>
|
|
26492
|
-
<TouchableOpacity style={[styles.signOutButton, { backgroundColor: theme.notification }]} onPress={()=> {
|
|
26493
|
-
authClient.signOut();
|
|
26494
|
-
}}
|
|
26495
|
-
>
|
|
26496
|
-
<Text style={styles.signOutText}>Sign Out</Text>
|
|
26497
|
-
</TouchableOpacity>
|
|
26498
|
-
</View>
|
|
26499
|
-
) : null}
|
|
26500
26655
|
<View style={[styles.statusCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
26501
|
-
<
|
|
26502
|
-
|
|
26503
|
-
|
|
26656
|
+
<Host style={styles.statusCardTitleHost} matchContents=\\{{ vertical: true }}>
|
|
26657
|
+
<ExpoUIText
|
|
26658
|
+
textStyle=\\{{ color: theme.text, fontSize: 16, fontWeight: "bold" }}
|
|
26659
|
+
>
|
|
26660
|
+
API Status
|
|
26661
|
+
</ExpoUIText>
|
|
26662
|
+
</Host>
|
|
26504
26663
|
<View style={styles.statusRow}>
|
|
26505
|
-
<View style={[styles.statusIndicator, { backgroundColor: healthCheck ? "#10b981" : "#
|
|
26506
|
-
<
|
|
26507
|
-
{
|
|
26508
|
-
|
|
26509
|
-
|
|
26510
|
-
|
|
26511
|
-
|
|
26512
|
-
|
|
26664
|
+
<View style={[styles.statusIndicator, { backgroundColor: healthCheck ? "#10b981" : "#f59e0b" }]} />
|
|
26665
|
+
<View style={styles.statusContent}>
|
|
26666
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26667
|
+
<ExpoUIText
|
|
26668
|
+
textStyle=\\{{ color: theme.text, fontSize: 12 }}
|
|
26669
|
+
style=\\{{ opacity: 0.7 }}
|
|
26670
|
+
>
|
|
26671
|
+
{healthCheck === undefined
|
|
26672
|
+
? "Checking..."
|
|
26673
|
+
: healthCheck === "OK"
|
|
26674
|
+
? "Connected to API"
|
|
26675
|
+
: "API Disconnected"}
|
|
26676
|
+
</ExpoUIText>
|
|
26677
|
+
</Host>
|
|
26678
|
+
</View>
|
|
26513
26679
|
</View>
|
|
26514
26680
|
</View>
|
|
26515
|
-
|
|
26681
|
+
|
|
26682
|
+
{user ? (
|
|
26683
|
+
<View style={[styles.userCard, { backgroundColor: theme.card, borderColor: theme.border }]}>
|
|
26684
|
+
<Host style={styles.userHeader} matchContents>
|
|
26685
|
+
<Column spacing={6}>
|
|
26686
|
+
<ExpoUIText textStyle=\\{{ color: theme.text, fontSize: 16, fontWeight: "bold" }}>
|
|
26687
|
+
{\`Welcome, \${user.name}\`}
|
|
26688
|
+
</ExpoUIText>
|
|
26689
|
+
<ExpoUIText
|
|
26690
|
+
textStyle=\\{{ color: theme.text, fontSize: 14 }}
|
|
26691
|
+
style=\\{{ opacity: 0.7 }}
|
|
26692
|
+
>
|
|
26693
|
+
{user.email}
|
|
26694
|
+
</ExpoUIText>
|
|
26695
|
+
</Column>
|
|
26696
|
+
</Host>
|
|
26697
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26698
|
+
<Button
|
|
26699
|
+
label="Sign Out"
|
|
26700
|
+
variant="outlined"
|
|
26701
|
+
onPress={() => {
|
|
26702
|
+
authClient.signOut();
|
|
26703
|
+
}}
|
|
26704
|
+
/>
|
|
26705
|
+
</Host>
|
|
26706
|
+
</View>
|
|
26707
|
+
) : (
|
|
26516
26708
|
<>
|
|
26517
26709
|
<SignIn />
|
|
26518
26710
|
<SignUp />
|
|
@@ -26530,12 +26722,13 @@ scrollView: {
|
|
|
26530
26722
|
flex: 1,
|
|
26531
26723
|
},
|
|
26532
26724
|
content: {
|
|
26533
|
-
|
|
26725
|
+
paddingHorizontal: 20,
|
|
26726
|
+
paddingTop: 28,
|
|
26727
|
+
paddingBottom: 32,
|
|
26534
26728
|
},
|
|
26535
|
-
|
|
26536
|
-
|
|
26537
|
-
|
|
26538
|
-
marginBottom: 16,
|
|
26729
|
+
titleHost: {
|
|
26730
|
+
alignSelf: "center",
|
|
26731
|
+
marginBottom: 24,
|
|
26539
26732
|
},
|
|
26540
26733
|
card: {
|
|
26541
26734
|
padding: 16,
|
|
@@ -26548,56 +26741,42 @@ alignItems: "center",
|
|
|
26548
26741
|
gap: 8,
|
|
26549
26742
|
},
|
|
26550
26743
|
statusIndicator: {
|
|
26551
|
-
height:
|
|
26552
|
-
width:
|
|
26744
|
+
height: 10,
|
|
26745
|
+
width: 10,
|
|
26746
|
+
borderRadius: 999,
|
|
26553
26747
|
},
|
|
26554
26748
|
statusContent: {
|
|
26555
26749
|
flex: 1,
|
|
26556
26750
|
},
|
|
26557
|
-
statusTitle: {
|
|
26558
|
-
fontSize: 14,
|
|
26559
|
-
fontWeight: "bold",
|
|
26560
|
-
},
|
|
26561
|
-
statusText: {
|
|
26562
|
-
fontSize: 12,
|
|
26563
|
-
},
|
|
26564
26751
|
userCard: {
|
|
26565
26752
|
marginBottom: 16,
|
|
26566
26753
|
padding: 16,
|
|
26567
26754
|
borderWidth: 1,
|
|
26755
|
+
borderRadius: 16,
|
|
26568
26756
|
},
|
|
26569
26757
|
userHeader: {
|
|
26570
26758
|
marginBottom: 8,
|
|
26571
26759
|
},
|
|
26572
|
-
|
|
26573
|
-
fontSize: 16,
|
|
26574
|
-
},
|
|
26575
|
-
userName: {
|
|
26576
|
-
fontWeight: "bold",
|
|
26577
|
-
},
|
|
26578
|
-
userEmail: {
|
|
26579
|
-
fontSize: 14,
|
|
26760
|
+
authHost: {
|
|
26580
26761
|
marginBottom: 12,
|
|
26581
26762
|
},
|
|
26582
|
-
|
|
26583
|
-
|
|
26584
|
-
},
|
|
26585
|
-
signOutText: {
|
|
26586
|
-
color: "#ffffff",
|
|
26763
|
+
authActionsHost: {
|
|
26764
|
+
marginTop: 4,
|
|
26587
26765
|
},
|
|
26588
26766
|
statusCard: {
|
|
26589
26767
|
marginBottom: 16,
|
|
26590
26768
|
padding: 16,
|
|
26591
26769
|
borderWidth: 1,
|
|
26770
|
+
borderRadius: 16,
|
|
26592
26771
|
},
|
|
26593
|
-
|
|
26772
|
+
statusCardTitleHost: {
|
|
26594
26773
|
marginBottom: 8,
|
|
26595
|
-
fontWeight: "bold",
|
|
26596
26774
|
},
|
|
26597
26775
|
});
|
|
26598
26776
|
`],
|
|
26599
26777
|
["frontend/native/bare/app/+not-found.tsx.hbs", `import { Container } from "@/components/container";
|
|
26600
|
-
import {
|
|
26778
|
+
import { Button, Column, Host, Text as ExpoUIText } from "@expo/ui";
|
|
26779
|
+
import { Stack, router } from "expo-router";
|
|
26601
26780
|
import { Text, View, StyleSheet } from "react-native";
|
|
26602
26781
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
26603
26782
|
import { NAV_THEME } from "@/lib/constants";
|
|
@@ -26613,17 +26792,26 @@ export default function NotFoundScreen() {
|
|
|
26613
26792
|
<View style={styles.container}>
|
|
26614
26793
|
<View style={styles.content}>
|
|
26615
26794
|
<Text style={styles.emoji}>🤔</Text>
|
|
26616
|
-
<
|
|
26617
|
-
|
|
26618
|
-
|
|
26619
|
-
|
|
26620
|
-
|
|
26621
|
-
|
|
26622
|
-
|
|
26623
|
-
|
|
26624
|
-
|
|
26625
|
-
|
|
26626
|
-
|
|
26795
|
+
<Host matchContents=\\{{ vertical: true }}>
|
|
26796
|
+
<Column spacing={12} alignment="center">
|
|
26797
|
+
<ExpoUIText
|
|
26798
|
+
textStyle=\\{{ color: theme.text, fontSize: 20, fontWeight: "bold", textAlign: "center" }}
|
|
26799
|
+
>
|
|
26800
|
+
Page Not Found
|
|
26801
|
+
</ExpoUIText>
|
|
26802
|
+
<ExpoUIText
|
|
26803
|
+
textStyle=\\{{ color: theme.text, fontSize: 14, textAlign: "center" }}
|
|
26804
|
+
style=\\{{ opacity: 0.7 }}
|
|
26805
|
+
>
|
|
26806
|
+
Sorry, the page you're looking for doesn't exist.
|
|
26807
|
+
</ExpoUIText>
|
|
26808
|
+
<Button
|
|
26809
|
+
label="Go to Home"
|
|
26810
|
+
variant="outlined"
|
|
26811
|
+
onPress={() => router.replace("/")}
|
|
26812
|
+
/>
|
|
26813
|
+
</Column>
|
|
26814
|
+
</Host>
|
|
26627
26815
|
</View>
|
|
26628
26816
|
</View>
|
|
26629
26817
|
</Container>
|
|
@@ -26645,25 +26833,11 @@ const styles = StyleSheet.create({
|
|
|
26645
26833
|
fontSize: 48,
|
|
26646
26834
|
marginBottom: 16,
|
|
26647
26835
|
},
|
|
26648
|
-
title: {
|
|
26649
|
-
fontSize: 20,
|
|
26650
|
-
fontWeight: "bold",
|
|
26651
|
-
marginBottom: 8,
|
|
26652
|
-
textAlign: "center",
|
|
26653
|
-
},
|
|
26654
|
-
subtitle: {
|
|
26655
|
-
fontSize: 14,
|
|
26656
|
-
textAlign: "center",
|
|
26657
|
-
marginBottom: 24,
|
|
26658
|
-
},
|
|
26659
|
-
link: {
|
|
26660
|
-
padding: 12,
|
|
26661
|
-
},
|
|
26662
26836
|
});
|
|
26663
|
-
|
|
26664
26837
|
`],
|
|
26665
26838
|
["frontend/native/bare/app/modal.tsx.hbs", `import { Container } from "@/components/container";
|
|
26666
|
-
import {
|
|
26839
|
+
import { Button, Column, Host, Text as ExpoUIText } from "@expo/ui";
|
|
26840
|
+
import { View, StyleSheet } from "react-native";
|
|
26667
26841
|
import { useColorScheme } from "@/lib/use-color-scheme";
|
|
26668
26842
|
import { NAV_THEME } from "@/lib/constants";
|
|
26669
26843
|
|
|
@@ -26674,9 +26848,22 @@ export default function Modal() {
|
|
|
26674
26848
|
return (
|
|
26675
26849
|
<Container>
|
|
26676
26850
|
<View style={styles.container}>
|
|
26677
|
-
<
|
|
26678
|
-
<
|
|
26679
|
-
|
|
26851
|
+
<Host style={styles.expoUiHost}>
|
|
26852
|
+
<Column spacing={12} alignment="center">
|
|
26853
|
+
<ExpoUIText
|
|
26854
|
+
textStyle=\\{{ color: theme.text, fontSize: 20, fontWeight: "bold" }}
|
|
26855
|
+
>
|
|
26856
|
+
Modal
|
|
26857
|
+
</ExpoUIText>
|
|
26858
|
+
<ExpoUIText
|
|
26859
|
+
textStyle=\\{{ color: theme.text, fontSize: 14, textAlign: "center" }}
|
|
26860
|
+
style=\\{{ opacity: 0.7 }}
|
|
26861
|
+
>
|
|
26862
|
+
Built with Expo UI universal components
|
|
26863
|
+
</ExpoUIText>
|
|
26864
|
+
<Button label="Native control" onPress={() => null} />
|
|
26865
|
+
</Column>
|
|
26866
|
+
</Host>
|
|
26680
26867
|
</View>
|
|
26681
26868
|
</Container>
|
|
26682
26869
|
);
|
|
@@ -26687,15 +26874,11 @@ const styles = StyleSheet.create({
|
|
|
26687
26874
|
flex: 1,
|
|
26688
26875
|
padding: 16,
|
|
26689
26876
|
},
|
|
26690
|
-
|
|
26691
|
-
|
|
26692
|
-
|
|
26693
|
-
title: {
|
|
26694
|
-
fontSize: 20,
|
|
26695
|
-
fontWeight: "bold",
|
|
26877
|
+
expoUiHost: {
|
|
26878
|
+
alignSelf: "stretch",
|
|
26879
|
+
padding: 16,
|
|
26696
26880
|
},
|
|
26697
26881
|
});
|
|
26698
|
-
|
|
26699
26882
|
`],
|
|
26700
26883
|
["frontend/native/bare/components/container.tsx.hbs", `import React from "react";
|
|
26701
26884
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
@@ -26773,13 +26956,14 @@ const styles = StyleSheet.create({
|
|
|
26773
26956
|
`],
|
|
26774
26957
|
["frontend/native/bare/components/tabbar-icon.tsx.hbs", `import FontAwesome from "@expo/vector-icons/FontAwesome";
|
|
26775
26958
|
|
|
26959
|
+
type FontAwesomeProps = React.ComponentProps<typeof FontAwesome>;
|
|
26960
|
+
|
|
26776
26961
|
export const TabBarIcon = (props: {
|
|
26777
|
-
name:
|
|
26778
|
-
color:
|
|
26962
|
+
name: FontAwesomeProps["name"];
|
|
26963
|
+
color: FontAwesomeProps["color"];
|
|
26779
26964
|
}) => {
|
|
26780
26965
|
return <FontAwesome size={24} style=\\{{ marginBottom: -3 }} {...props} />;
|
|
26781
26966
|
};
|
|
26782
|
-
|
|
26783
26967
|
`],
|
|
26784
26968
|
["frontend/native/bare/lib/constants.ts.hbs", `export const NAV_THEME = {
|
|
26785
26969
|
light: {
|
|
@@ -26841,41 +27025,39 @@ module.exports = config;
|
|
|
26841
27025
|
"web": "expo start --web"
|
|
26842
27026
|
},
|
|
26843
27027
|
"dependencies": {
|
|
27028
|
+
"@expo/ui": "~56.0.12",
|
|
26844
27029
|
"@expo/vector-icons": "^15.1.1",
|
|
26845
|
-
"@react-navigation/bottom-tabs": "^7.15.9",
|
|
26846
|
-
"@react-navigation/drawer": "^7.9.4",
|
|
26847
|
-
"@react-navigation/native": "^7.2.2",
|
|
26848
27030
|
"@tanstack/react-query": "^5.99.2",
|
|
26849
27031
|
{{#if (includes examples "ai")}}
|
|
26850
27032
|
"@stardazed/streams-text-encoding": "^1.0.2",
|
|
26851
27033
|
"@ungap/structured-clone": "^1.3.0",
|
|
26852
27034
|
{{/if}}
|
|
26853
|
-
"expo": "
|
|
26854
|
-
"expo-constants": "~
|
|
26855
|
-
"expo-crypto": "~
|
|
26856
|
-
"expo-font": "~
|
|
26857
|
-
"expo-linking": "~
|
|
26858
|
-
"expo-network": "~
|
|
26859
|
-
"expo-router": "~
|
|
26860
|
-
"expo-secure-store": "~
|
|
26861
|
-
"expo-splash-screen": "~
|
|
26862
|
-
"expo-status-bar": "~
|
|
26863
|
-
"expo-system-ui": "~
|
|
26864
|
-
"expo-web-browser": "~
|
|
26865
|
-
"react": "19.2.
|
|
26866
|
-
"react-dom": "19.2.
|
|
26867
|
-
"react-native": "0.
|
|
26868
|
-
"react-native-gesture-handler": "~2.
|
|
26869
|
-
"react-native-reanimated": "4.
|
|
26870
|
-
"react-native-safe-area-context": "~5.
|
|
26871
|
-
"react-native-screens": "
|
|
27035
|
+
"expo": "~56.0.3",
|
|
27036
|
+
"expo-constants": "~56.0.14",
|
|
27037
|
+
"expo-crypto": "~56.0.3",
|
|
27038
|
+
"expo-font": "~56.0.5",
|
|
27039
|
+
"expo-linking": "~56.0.11",
|
|
27040
|
+
"expo-network": "~56.0.4",
|
|
27041
|
+
"expo-router": "~56.2.5",
|
|
27042
|
+
"expo-secure-store": "~56.0.4",
|
|
27043
|
+
"expo-splash-screen": "~56.0.9",
|
|
27044
|
+
"expo-status-bar": "~56.0.4",
|
|
27045
|
+
"expo-system-ui": "~56.0.5",
|
|
27046
|
+
"expo-web-browser": "~56.0.5",
|
|
27047
|
+
"react": "19.2.3",
|
|
27048
|
+
"react-dom": "19.2.3",
|
|
27049
|
+
"react-native": "0.85.3",
|
|
27050
|
+
"react-native-gesture-handler": "~2.31.1",
|
|
27051
|
+
"react-native-reanimated": "4.3.1",
|
|
27052
|
+
"react-native-safe-area-context": "~5.7.0",
|
|
27053
|
+
"react-native-screens": "4.25.1",
|
|
26872
27054
|
"react-native-web": "~0.21.0",
|
|
26873
|
-
"react-native-worklets": "0.
|
|
27055
|
+
"react-native-worklets": "0.8.3"
|
|
26874
27056
|
},
|
|
26875
27057
|
"devDependencies": {
|
|
26876
|
-
"@babel/core": "^7.
|
|
26877
|
-
"@types/react": "~19.2.
|
|
26878
|
-
"typescript": "
|
|
27058
|
+
"@babel/core": "^7.29.0",
|
|
27059
|
+
"@types/react": "~19.2.14",
|
|
27060
|
+
"typescript": "^6"
|
|
26879
27061
|
},
|
|
26880
27062
|
"private": true
|
|
26881
27063
|
}
|
|
@@ -27023,9 +27205,6 @@ export const unstable_settings = {
|
|
|
27023
27205
|
|
|
27024
27206
|
{{#if (eq backend "convex")}}
|
|
27025
27207
|
const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
|
|
27026
|
-
{{#if (eq auth "better-auth")}}
|
|
27027
|
-
expectAuth: true,
|
|
27028
|
-
{{/if}}
|
|
27029
27208
|
unsavedChangesWarning: false,
|
|
27030
27209
|
});
|
|
27031
27210
|
{{/if}}
|
|
@@ -28017,9 +28196,11 @@ const styles = StyleSheet.create((theme) => ({
|
|
|
28017
28196
|
`],
|
|
28018
28197
|
["frontend/native/unistyles/components/tabbar-icon.tsx.hbs", `import FontAwesome from "@expo/vector-icons/FontAwesome";
|
|
28019
28198
|
|
|
28199
|
+
type FontAwesomeProps = React.ComponentProps<typeof FontAwesome>;
|
|
28200
|
+
|
|
28020
28201
|
export const TabBarIcon = (props: {
|
|
28021
|
-
name:
|
|
28022
|
-
color:
|
|
28202
|
+
name: FontAwesomeProps["name"];
|
|
28203
|
+
color: FontAwesomeProps["color"];
|
|
28023
28204
|
}) => {
|
|
28024
28205
|
return <FontAwesome size={24} style=\\{{ marginBottom: -3 }} {...props} />;
|
|
28025
28206
|
};
|
|
@@ -28046,45 +28227,42 @@ module.exports = config;
|
|
|
28046
28227
|
},
|
|
28047
28228
|
"dependencies": {
|
|
28048
28229
|
"@expo/vector-icons": "^15.1.1",
|
|
28049
|
-
"@react-navigation/bottom-tabs": "^7.15.9",
|
|
28050
|
-
"@react-navigation/drawer": "^7.9.4",
|
|
28051
|
-
"@react-navigation/native": "^7.2.2",
|
|
28052
28230
|
{{#if (includes examples "ai")}}
|
|
28053
28231
|
"@stardazed/streams-text-encoding": "^1.0.2",
|
|
28054
28232
|
"@ungap/structured-clone": "^1.3.0",
|
|
28055
28233
|
{{/if}}
|
|
28056
|
-
"babel-preset-expo": "~
|
|
28057
|
-
"expo": "
|
|
28058
|
-
"expo-constants": "~
|
|
28059
|
-
"expo-crypto": "~
|
|
28060
|
-
"expo-dev-client": "~
|
|
28061
|
-
"expo-font": "~
|
|
28062
|
-
"expo-linking": "~
|
|
28063
|
-
"expo-network": "~
|
|
28064
|
-
"expo-router": "~
|
|
28065
|
-
"expo-secure-store": "~
|
|
28066
|
-
"expo-splash-screen": "~
|
|
28067
|
-
"expo-status-bar": "~
|
|
28068
|
-
"expo-system-ui": "~
|
|
28069
|
-
"expo-web-browser": "~
|
|
28070
|
-
"react": "19.2.
|
|
28071
|
-
"react-dom": "19.2.
|
|
28072
|
-
"react-native": "0.
|
|
28234
|
+
"babel-preset-expo": "~56.0.0",
|
|
28235
|
+
"expo": "~56.0.3",
|
|
28236
|
+
"expo-constants": "~56.0.14",
|
|
28237
|
+
"expo-crypto": "~56.0.3",
|
|
28238
|
+
"expo-dev-client": "~56.0.14",
|
|
28239
|
+
"expo-font": "~56.0.5",
|
|
28240
|
+
"expo-linking": "~56.0.11",
|
|
28241
|
+
"expo-network": "~56.0.4",
|
|
28242
|
+
"expo-router": "~56.2.5",
|
|
28243
|
+
"expo-secure-store": "~56.0.4",
|
|
28244
|
+
"expo-splash-screen": "~56.0.9",
|
|
28245
|
+
"expo-status-bar": "~56.0.4",
|
|
28246
|
+
"expo-system-ui": "~56.0.5",
|
|
28247
|
+
"expo-web-browser": "~56.0.5",
|
|
28248
|
+
"react": "19.2.3",
|
|
28249
|
+
"react-dom": "19.2.3",
|
|
28250
|
+
"react-native": "0.85.3",
|
|
28073
28251
|
"react-native-edge-to-edge": "^1.8.1",
|
|
28074
|
-
"react-native-gesture-handler": "~2.
|
|
28075
|
-
"react-native-nitro-modules": "^0.35.
|
|
28076
|
-
"react-native-reanimated": "4.
|
|
28077
|
-
"react-native-safe-area-context": "~5.
|
|
28078
|
-
"react-native-screens": "
|
|
28079
|
-
"react-native-unistyles": "^3.2.
|
|
28252
|
+
"react-native-gesture-handler": "~2.31.1",
|
|
28253
|
+
"react-native-nitro-modules": "^0.35.7",
|
|
28254
|
+
"react-native-reanimated": "4.3.1",
|
|
28255
|
+
"react-native-safe-area-context": "~5.7.0",
|
|
28256
|
+
"react-native-screens": "4.25.1",
|
|
28257
|
+
"react-native-unistyles": "^3.2.4",
|
|
28080
28258
|
"react-native-web": "~0.21.0",
|
|
28081
|
-
"react-native-worklets": "0.
|
|
28259
|
+
"react-native-worklets": "0.8.3"
|
|
28082
28260
|
},
|
|
28083
28261
|
"devDependencies": {
|
|
28084
|
-
"ajv": "^8.
|
|
28085
|
-
"@babel/core": "^7.
|
|
28086
|
-
"@types/react": "~19.2.
|
|
28087
|
-
"typescript": "
|
|
28262
|
+
"ajv": "^8.20.0",
|
|
28263
|
+
"@babel/core": "^7.29.0",
|
|
28264
|
+
"@types/react": "~19.2.14",
|
|
28265
|
+
"typescript": "^6"
|
|
28088
28266
|
}
|
|
28089
28267
|
}
|
|
28090
28268
|
`],
|
|
@@ -28194,7 +28372,7 @@ export const darkTheme = {
|
|
|
28194
28372
|
"strict": true,
|
|
28195
28373
|
"jsx": "react-jsx",
|
|
28196
28374
|
"paths": {
|
|
28197
|
-
"@/*": ["
|
|
28375
|
+
"@/*": ["./*"]
|
|
28198
28376
|
}
|
|
28199
28377
|
},
|
|
28200
28378
|
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]
|
|
@@ -28326,9 +28504,6 @@ export const unstable_settings = {
|
|
|
28326
28504
|
|
|
28327
28505
|
{{#if (eq backend "convex")}}
|
|
28328
28506
|
const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
|
|
28329
|
-
{{#if (eq auth "better-auth")}}
|
|
28330
|
-
expectAuth: true,
|
|
28331
|
-
{{/if}}
|
|
28332
28507
|
unsavedChangesWarning: false,
|
|
28333
28508
|
});
|
|
28334
28509
|
{{/if}}
|
|
@@ -28580,7 +28755,7 @@ export default function TabLayout() {
|
|
|
28580
28755
|
name="index"
|
|
28581
28756
|
options=\\{{
|
|
28582
28757
|
title: "Home",
|
|
28583
|
-
tabBarIcon: ({ color, size }
|
|
28758
|
+
tabBarIcon: ({ color, size }) => (
|
|
28584
28759
|
<Ionicons name="home" size={size} color={color} />
|
|
28585
28760
|
),
|
|
28586
28761
|
}}
|
|
@@ -28589,7 +28764,7 @@ export default function TabLayout() {
|
|
|
28589
28764
|
name="two"
|
|
28590
28765
|
options=\\{{
|
|
28591
28766
|
title: "Explore",
|
|
28592
|
-
tabBarIcon: ({ color, size }
|
|
28767
|
+
tabBarIcon: ({ color, size }) => (
|
|
28593
28768
|
<Ionicons name="compass" size={size} color={color} />
|
|
28594
28769
|
),
|
|
28595
28770
|
}}
|
|
@@ -29106,46 +29281,44 @@ module.exports = uniwindConfig;
|
|
|
29106
29281
|
"web": "expo start --web"
|
|
29107
29282
|
},
|
|
29108
29283
|
"dependencies": {
|
|
29109
|
-
"@expo/metro-runtime": "~
|
|
29284
|
+
"@expo/metro-runtime": "~56.0.11",
|
|
29110
29285
|
"@expo/vector-icons": "^15.1.1",
|
|
29111
|
-
"@gorhom/bottom-sheet": "^5.2.
|
|
29112
|
-
"@react-navigation/drawer": "^7.9.4",
|
|
29113
|
-
"@react-navigation/elements": "^2.9.14",
|
|
29286
|
+
"@gorhom/bottom-sheet": "^5.2.14",
|
|
29114
29287
|
{{#if (includes examples "ai")}}
|
|
29115
29288
|
"@stardazed/streams-text-encoding": "^1.0.2",
|
|
29116
29289
|
"@ungap/structured-clone": "^1.3.0",
|
|
29117
29290
|
{{/if}}
|
|
29118
|
-
"expo": "
|
|
29119
|
-
"expo-constants": "~
|
|
29120
|
-
"expo-font": "~
|
|
29121
|
-
"expo-haptics": "~
|
|
29122
|
-
"expo-linking": "~
|
|
29123
|
-
"expo-network": "~
|
|
29124
|
-
"expo-router": "~
|
|
29125
|
-
"expo-secure-store": "~
|
|
29126
|
-
"expo-status-bar": "~
|
|
29127
|
-
"expo-web-browser": "~
|
|
29128
|
-
"heroui-native": "^1.0.
|
|
29129
|
-
"react": "19.2.
|
|
29130
|
-
"react-dom": "19.2.
|
|
29131
|
-
"react-native": "0.
|
|
29132
|
-
"react-native-gesture-handler": "~2.
|
|
29133
|
-
"react-native-keyboard-controller": "1.
|
|
29134
|
-
"react-native-reanimated": "4.
|
|
29135
|
-
"react-native-safe-area-context": "~5.
|
|
29136
|
-
"react-native-screens": "
|
|
29137
|
-
"react-native-svg": "15.15.
|
|
29291
|
+
"expo": "~56.0.3",
|
|
29292
|
+
"expo-constants": "~56.0.14",
|
|
29293
|
+
"expo-font": "~56.0.5",
|
|
29294
|
+
"expo-haptics": "~56.0.3",
|
|
29295
|
+
"expo-linking": "~56.0.11",
|
|
29296
|
+
"expo-network": "~56.0.4",
|
|
29297
|
+
"expo-router": "~56.2.5",
|
|
29298
|
+
"expo-secure-store": "~56.0.4",
|
|
29299
|
+
"expo-status-bar": "~56.0.4",
|
|
29300
|
+
"expo-web-browser": "~56.0.5",
|
|
29301
|
+
"heroui-native": "^1.0.3",
|
|
29302
|
+
"react": "19.2.3",
|
|
29303
|
+
"react-dom": "19.2.3",
|
|
29304
|
+
"react-native": "0.85.3",
|
|
29305
|
+
"react-native-gesture-handler": "~2.31.1",
|
|
29306
|
+
"react-native-keyboard-controller": "1.21.6",
|
|
29307
|
+
"react-native-reanimated": "4.3.1",
|
|
29308
|
+
"react-native-safe-area-context": "~5.7.0",
|
|
29309
|
+
"react-native-screens": "4.25.1",
|
|
29310
|
+
"react-native-svg": "15.15.4",
|
|
29138
29311
|
"react-native-web": "~0.21.0",
|
|
29139
|
-
"react-native-worklets": "0.
|
|
29140
|
-
"tailwind-merge": "^3.
|
|
29312
|
+
"react-native-worklets": "0.8.3",
|
|
29313
|
+
"tailwind-merge": "^3.6.0",
|
|
29141
29314
|
"tailwind-variants": "^3.2.2",
|
|
29142
|
-
"tailwindcss": "^4.
|
|
29143
|
-
"uniwind": "^1.
|
|
29315
|
+
"tailwindcss": "^4.3.0",
|
|
29316
|
+
"uniwind": "^1.7.0"
|
|
29144
29317
|
},
|
|
29145
29318
|
"devDependencies": {
|
|
29146
|
-
"@types/node": "^
|
|
29147
|
-
"@types/react": "~19.2.
|
|
29148
|
-
"typescript": "
|
|
29319
|
+
"@types/node": "^25.9.1",
|
|
29320
|
+
"@types/react": "~19.2.14",
|
|
29321
|
+
"typescript": "^6"
|
|
29149
29322
|
}
|
|
29150
29323
|
}
|
|
29151
29324
|
`],
|
|
@@ -29165,6 +29338,8 @@ module.exports = uniwindConfig;
|
|
|
29165
29338
|
]
|
|
29166
29339
|
}`],
|
|
29167
29340
|
["frontend/native/uniwind/uniwind-env.d.ts", `/// <reference types="uniwind/types" />
|
|
29341
|
+
|
|
29342
|
+
declare module "*.css";
|
|
29168
29343
|
`],
|
|
29169
29344
|
["frontend/nuxt/_gitignore", `# Nuxt dev/build outputs
|
|
29170
29345
|
.output
|
|
@@ -29505,15 +29680,15 @@ initOpenNextCloudflareForDev();
|
|
|
29505
29680
|
"lucide-react": "^0.546.0",
|
|
29506
29681
|
"next": "^16.2.0",
|
|
29507
29682
|
"next-themes": "^0.4.6",
|
|
29508
|
-
"react": "^19.2.
|
|
29509
|
-
"react-dom": "^19.2.
|
|
29683
|
+
"react": "^19.2.6",
|
|
29684
|
+
"react-dom": "^19.2.6",
|
|
29510
29685
|
"sonner": "^2.0.5",
|
|
29511
29686
|
"babel-plugin-react-compiler": "^1.0.0"
|
|
29512
29687
|
},
|
|
29513
29688
|
"devDependencies": {
|
|
29514
29689
|
"@tailwindcss/postcss": "^4.1.18",
|
|
29515
29690
|
"@types/node": "^20",
|
|
29516
|
-
"@types/react": "^19.2.
|
|
29691
|
+
"@types/react": "^19.2.15",
|
|
29517
29692
|
"@types/react-dom": "^19.2.3",
|
|
29518
29693
|
"tailwindcss": "^4.1.18"
|
|
29519
29694
|
}
|
|
@@ -29910,8 +30085,8 @@ export function ThemeProvider({
|
|
|
29910
30085
|
"isbot": "^5.1.39",
|
|
29911
30086
|
"lucide-react": "^1.8.0",
|
|
29912
30087
|
"next-themes": "^0.4.6",
|
|
29913
|
-
"react": "^19.2.
|
|
29914
|
-
"react-dom": "^19.2.
|
|
30088
|
+
"react": "^19.2.6",
|
|
30089
|
+
"react-dom": "^19.2.6",
|
|
29915
30090
|
"react-router": "^7.14.1",
|
|
29916
30091
|
"sonner": "^2.0.7"
|
|
29917
30092
|
},
|
|
@@ -29919,7 +30094,7 @@ export function ThemeProvider({
|
|
|
29919
30094
|
"@react-router/dev": "^7.14.1",
|
|
29920
30095
|
"@tailwindcss/vite": "^4.2.2",
|
|
29921
30096
|
"@types/node": "^20",
|
|
29922
|
-
"@types/react": "^19.2.
|
|
30097
|
+
"@types/react": "^19.2.15",
|
|
29923
30098
|
"@types/react-dom": "^19.2.3",
|
|
29924
30099
|
"react-router-devtools": "^1.1.0",
|
|
29925
30100
|
"tailwindcss": "^4.2.2",
|
|
@@ -30085,13 +30260,7 @@ export default function App() {
|
|
|
30085
30260
|
{{else}}
|
|
30086
30261
|
export default function App() {
|
|
30087
30262
|
{{/if}}
|
|
30088
|
-
{{#if (eq auth "better-auth")}}
|
|
30089
|
-
const convex = new ConvexReactClient(env.VITE_CONVEX_URL, {
|
|
30090
|
-
expectAuth: true,
|
|
30091
|
-
});
|
|
30092
|
-
{{else}}
|
|
30093
30263
|
const convex = new ConvexReactClient(env.VITE_CONVEX_URL);
|
|
30094
|
-
{{/if}}
|
|
30095
30264
|
{{#if (eq auth "clerk")}}
|
|
30096
30265
|
return (
|
|
30097
30266
|
<ClerkProvider loaderData={loaderData}>
|
|
@@ -30453,15 +30622,15 @@ export default defineConfig({
|
|
|
30453
30622
|
"@tanstack/react-router": "^1.168.22",
|
|
30454
30623
|
"lucide-react": "^1.8.0",
|
|
30455
30624
|
"next-themes": "^0.4.6",
|
|
30456
|
-
"react": "^19.2.
|
|
30457
|
-
"react-dom": "^19.2.
|
|
30625
|
+
"react": "^19.2.6",
|
|
30626
|
+
"react-dom": "^19.2.6",
|
|
30458
30627
|
"sonner": "^2.0.7"
|
|
30459
30628
|
},
|
|
30460
30629
|
"devDependencies": {
|
|
30461
30630
|
"@tanstack/react-router-devtools": "^1.166.13",
|
|
30462
30631
|
"@tanstack/router-plugin": "^1.167.22",
|
|
30463
30632
|
"@types/node": "^22.13.14",
|
|
30464
|
-
"@types/react": "^19.2.
|
|
30633
|
+
"@types/react": "^19.2.15",
|
|
30465
30634
|
"@types/react-dom": "^19.2.3",
|
|
30466
30635
|
"@vitejs/plugin-react": "^6.0.1",
|
|
30467
30636
|
"postcss": "^8.5.10",
|
|
@@ -30545,13 +30714,7 @@ import { routeTree } from "./routeTree.gen";
|
|
|
30545
30714
|
{{else}}
|
|
30546
30715
|
import { ConvexProvider } from "convex/react";
|
|
30547
30716
|
{{/if}}
|
|
30548
|
-
{{#if (eq auth "better-auth")}}
|
|
30549
|
-
const convex = new ConvexReactClient(env.VITE_CONVEX_URL, {
|
|
30550
|
-
expectAuth: true,
|
|
30551
|
-
});
|
|
30552
|
-
{{else}}
|
|
30553
30717
|
const convex = new ConvexReactClient(env.VITE_CONVEX_URL);
|
|
30554
|
-
{{/if}}
|
|
30555
30718
|
{{/if}}
|
|
30556
30719
|
|
|
30557
30720
|
{{#if (and (eq auth "clerk") (ne backend "convex") (ne api "none"))}}
|
|
@@ -30904,8 +31067,8 @@ export default defineConfig({
|
|
|
30904
31067
|
"@tanstack/react-start": "^1.167.41",
|
|
30905
31068
|
"lucide-react": "^1.8.0",
|
|
30906
31069
|
"next-themes": "^0.4.6",
|
|
30907
|
-
"react": "^19.2.
|
|
30908
|
-
"react-dom": "^19.2.
|
|
31070
|
+
"react": "^19.2.6",
|
|
31071
|
+
"react-dom": "^19.2.6",
|
|
30909
31072
|
"sonner": "^2.0.7",
|
|
30910
31073
|
"tailwindcss": "^4.2.2"
|
|
30911
31074
|
},
|
|
@@ -30913,7 +31076,7 @@ export default defineConfig({
|
|
|
30913
31076
|
"@tanstack/react-router-devtools": "^1.166.13",
|
|
30914
31077
|
"@testing-library/dom": "^10.4.1",
|
|
30915
31078
|
"@testing-library/react": "^16.3.2",
|
|
30916
|
-
"@types/react": "^19.2.
|
|
31079
|
+
"@types/react": "^19.2.15",
|
|
30917
31080
|
"@types/react-dom": "^19.2.3",
|
|
30918
31081
|
"@vitejs/plugin-react": "^6.0.1",
|
|
30919
31082
|
"jsdom": "^29.0.2",
|
|
@@ -30933,12 +31096,10 @@ import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query
|
|
|
30933
31096
|
import { ConvexQueryClient } from "@convex-dev/react-query";
|
|
30934
31097
|
import { routeTree } from "./routeTree.gen";
|
|
30935
31098
|
import Loader from "./components/loader";
|
|
30936
|
-
import "./index.css";
|
|
30937
31099
|
import { env } from "@{{projectName}}/env/web";
|
|
30938
31100
|
{{else}}
|
|
30939
31101
|
import { createRouter as createTanStackRouter } from "@tanstack/react-router";
|
|
30940
31102
|
import Loader from "./components/loader";
|
|
30941
|
-
import "./index.css";
|
|
30942
31103
|
import { routeTree } from "./routeTree.gen";
|
|
30943
31104
|
{{#if (eq api "trpc")}}
|
|
30944
31105
|
import { QueryCache, QueryClient } from "@tanstack/react-query";
|
|
@@ -33106,14 +33267,14 @@ await app.finalize();
|
|
|
33106
33267
|
"clsx": "^2.1.1",
|
|
33107
33268
|
"lucide-react": "^0.546.0",
|
|
33108
33269
|
"next-themes": "^0.4.6",
|
|
33109
|
-
"react": "^19.2.
|
|
33110
|
-
"react-dom": "^19.2.
|
|
33270
|
+
"react": "^19.2.6",
|
|
33271
|
+
"react-dom": "^19.2.6",
|
|
33111
33272
|
"sonner": "^2.0.5",
|
|
33112
33273
|
"tailwind-merge": "^3.3.1",
|
|
33113
33274
|
"tw-animate-css": "^1.3.4"
|
|
33114
33275
|
},
|
|
33115
33276
|
"devDependencies": {
|
|
33116
|
-
"@types/react": "^19.2.
|
|
33277
|
+
"@types/react": "^19.2.15",
|
|
33117
33278
|
"@types/react-dom": "^19.2.3",
|
|
33118
33279
|
"tailwindcss": "^4.1.18"
|
|
33119
33280
|
},
|
|
@@ -34004,7 +34165,7 @@ function SuccessPage() {
|
|
|
34004
34165
|
</div>
|
|
34005
34166
|
`]
|
|
34006
34167
|
]);
|
|
34007
|
-
const TEMPLATE_COUNT =
|
|
34168
|
+
const TEMPLATE_COUNT = 474;
|
|
34008
34169
|
//#endregion
|
|
34009
34170
|
export { EMBEDDED_TEMPLATES, GeneratorError, Handlebars, TEMPLATE_COUNT, VirtualFileSystem, dependencyVersionMap, generate, generateReproducibleCommand, isBinaryFile, processAddonTemplates, processAddonsDeps, processFileContent, processTemplateString, transformFilename, writeBtsConfigToVfs };
|
|
34010
34171
|
|