create-stackforge 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/README.md +125 -0
  2. package/bin/cli.js +2 -0
  3. package/dist/cli.js +3148 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/npm-registry-F7EVX3RR.js +18 -0
  6. package/dist/npm-registry-F7EVX3RR.js.map +1 -0
  7. package/package.json +74 -0
  8. package/templates/api/graphql/client-usage.jsx +14 -0
  9. package/templates/api/graphql/client-usage.tsx +14 -0
  10. package/templates/api/graphql/client.js +12 -0
  11. package/templates/api/graphql/client.ts +12 -0
  12. package/templates/api/graphql/route.js +32 -0
  13. package/templates/api/graphql/route.ts +23 -0
  14. package/templates/api/graphql/schema.graphql +13 -0
  15. package/templates/api/graphql/vite-server.js +27 -0
  16. package/templates/api/graphql/vite-server.ts +27 -0
  17. package/templates/api/rest/client-usage.jsx +14 -0
  18. package/templates/api/rest/client-usage.tsx +14 -0
  19. package/templates/api/rest/client.js +4 -0
  20. package/templates/api/rest/client.ts +4 -0
  21. package/templates/api/rest/route.js +3 -0
  22. package/templates/api/rest/route.ts +3 -0
  23. package/templates/api/rest/users-route.js +11 -0
  24. package/templates/api/rest/users-route.ts +11 -0
  25. package/templates/api/rest/vite-server.js +15 -0
  26. package/templates/api/rest/vite-server.ts +15 -0
  27. package/templates/api/trpc/client-usage.jsx +26 -0
  28. package/templates/api/trpc/client-usage.tsx +26 -0
  29. package/templates/api/trpc/client-vite.js +15 -0
  30. package/templates/api/trpc/client-vite.ts +16 -0
  31. package/templates/api/trpc/client.js +13 -0
  32. package/templates/api/trpc/client.ts +14 -0
  33. package/templates/api/trpc/root.ts +11 -0
  34. package/templates/api/trpc/route.js +12 -0
  35. package/templates/api/trpc/route.ts +12 -0
  36. package/templates/api/trpc/trpc.ts +6 -0
  37. package/templates/api/trpc/vite-server.js +9 -0
  38. package/templates/api/trpc/vite-server.ts +9 -0
  39. package/templates/auth/clerk-protected-page.jsx +11 -0
  40. package/templates/auth/clerk-protected-page.tsx +11 -0
  41. package/templates/auth/clerk-protected.jsx +11 -0
  42. package/templates/auth/clerk-protected.tsx +11 -0
  43. package/templates/auth/clerk-signin.jsx +11 -0
  44. package/templates/auth/clerk-signin.tsx +11 -0
  45. package/templates/auth/clerk.README.md +8 -0
  46. package/templates/auth/nextauth-options.js +3 -0
  47. package/templates/auth/nextauth-options.ts +5 -0
  48. package/templates/auth/nextauth-protected-page.jsx +12 -0
  49. package/templates/auth/nextauth-protected-page.tsx +12 -0
  50. package/templates/auth/nextauth-protected.jsx +12 -0
  51. package/templates/auth/nextauth-protected.tsx +12 -0
  52. package/templates/auth/nextauth-route.ts +6 -0
  53. package/templates/auth/nextauth-signin.jsx +15 -0
  54. package/templates/auth/nextauth-signin.tsx +15 -0
  55. package/templates/auth/nextauth.README.md +10 -0
  56. package/templates/auth/supabase-protected-page.jsx +13 -0
  57. package/templates/auth/supabase-protected-page.tsx +13 -0
  58. package/templates/auth/supabase-protected.jsx +13 -0
  59. package/templates/auth/supabase-protected.tsx +13 -0
  60. package/templates/auth/supabase-signin.jsx +25 -0
  61. package/templates/auth/supabase-signin.tsx +25 -0
  62. package/templates/auth/supabase-vite-signin.jsx +20 -0
  63. package/templates/auth/supabase-vite-signin.tsx +20 -0
  64. package/templates/auth/supabase.README.md +9 -0
  65. package/templates/database/drizzle/client.js +8 -0
  66. package/templates/database/drizzle/client.ts +8 -0
  67. package/templates/database/drizzle/drizzle.config.ts +6 -0
  68. package/templates/database/drizzle/example.js +6 -0
  69. package/templates/database/drizzle/example.ts +6 -0
  70. package/templates/database/drizzle/schema.ts +6 -0
  71. package/templates/database/mongoose/connection.js +13 -0
  72. package/templates/database/mongoose/connection.ts +13 -0
  73. package/templates/database/mongoose/model.js +7 -0
  74. package/templates/database/mongoose/model.ts +7 -0
  75. package/templates/database/prisma/client.js +3 -0
  76. package/templates/database/prisma/client.ts +3 -0
  77. package/templates/database/prisma/example.js +5 -0
  78. package/templates/database/prisma/example.ts +7 -0
  79. package/templates/database/prisma/schema.prisma +13 -0
  80. package/templates/database/providers/neon.README.md +9 -0
  81. package/templates/database/providers/supabase.README.md +9 -0
  82. package/templates/database/typeorm/data-source.js +15 -0
  83. package/templates/database/typeorm/data-source.ts +15 -0
  84. package/templates/database/typeorm/entity.js +10 -0
  85. package/templates/database/typeorm/entity.ts +10 -0
  86. package/templates/database/typeorm/migrations/README.md +5 -0
  87. package/templates/database/usage/drizzle-users.js +6 -0
  88. package/templates/database/usage/drizzle-users.ts +6 -0
  89. package/templates/database/usage/mongoose-users.js +5 -0
  90. package/templates/database/usage/mongoose-users.ts +5 -0
  91. package/templates/database/usage/prisma-users.js +5 -0
  92. package/templates/database/usage/prisma-users.ts +5 -0
  93. package/templates/database/usage/typeorm-users.js +9 -0
  94. package/templates/database/usage/typeorm-users.ts +9 -0
  95. package/templates/features/analytics/README.md +9 -0
  96. package/templates/features/analytics/posthog.js +7 -0
  97. package/templates/features/analytics/posthog.ts +9 -0
  98. package/templates/features/email/README.md +17 -0
  99. package/templates/features/email/resend.js +3 -0
  100. package/templates/features/email/resend.ts +3 -0
  101. package/templates/features/error-tracking/README.md +9 -0
  102. package/templates/features/error-tracking/sentry.js +7 -0
  103. package/templates/features/error-tracking/sentry.ts +7 -0
  104. package/templates/features/payments/README.md +17 -0
  105. package/templates/features/payments/stripe.js +5 -0
  106. package/templates/features/payments/stripe.ts +5 -0
  107. package/templates/features/storage/README.md +12 -0
  108. package/templates/features/storage/storage.js +5 -0
  109. package/templates/features/storage/storage.ts +5 -0
  110. package/templates/nextjs/app/actions.js +6 -0
  111. package/templates/nextjs/app/actions.ts +6 -0
  112. package/templates/nextjs/app/examples-page.jsx +16 -0
  113. package/templates/nextjs/app/examples-page.tsx +16 -0
  114. package/templates/nextjs/app/layout.jsx +7 -0
  115. package/templates/nextjs/app/layout.tsx +7 -0
  116. package/templates/nextjs/app/page.jsx +12 -0
  117. package/templates/nextjs/app/page.tsx +12 -0
  118. package/templates/nextjs/next.config.js +4 -0
  119. package/templates/nextjs/next.config.ts +7 -0
  120. package/templates/shared/.editorconfig +8 -0
  121. package/templates/ui/antd.README.md +7 -0
  122. package/templates/ui/antd.theme.js +5 -0
  123. package/templates/ui/antd.theme.ts +7 -0
  124. package/templates/ui/button.jsx +13 -0
  125. package/templates/ui/button.tsx +13 -0
  126. package/templates/ui/chakra.README.md +7 -0
  127. package/templates/ui/chakra.theme.js +8 -0
  128. package/templates/ui/chakra.theme.ts +8 -0
  129. package/templates/ui/components.json +14 -0
  130. package/templates/ui/demo-antd.jsx +5 -0
  131. package/templates/ui/demo-antd.tsx +5 -0
  132. package/templates/ui/demo-chakra.jsx +5 -0
  133. package/templates/ui/demo-chakra.tsx +5 -0
  134. package/templates/ui/demo-mantine.jsx +5 -0
  135. package/templates/ui/demo-mantine.tsx +5 -0
  136. package/templates/ui/demo-mui.jsx +5 -0
  137. package/templates/ui/demo-mui.tsx +5 -0
  138. package/templates/ui/demo-nextui.jsx +5 -0
  139. package/templates/ui/demo-nextui.tsx +5 -0
  140. package/templates/ui/demo-shadcn.jsx +5 -0
  141. package/templates/ui/demo-shadcn.tsx +5 -0
  142. package/templates/ui/demo-tailwind.jsx +3 -0
  143. package/templates/ui/demo-tailwind.tsx +3 -0
  144. package/templates/ui/mantine.README.md +7 -0
  145. package/templates/ui/mantine.theme.js +3 -0
  146. package/templates/ui/mantine.theme.ts +3 -0
  147. package/templates/ui/mui.README.md +7 -0
  148. package/templates/ui/mui.theme.js +7 -0
  149. package/templates/ui/mui.theme.ts +7 -0
  150. package/templates/ui/nextui.README.md +7 -0
  151. package/templates/ui/nextui.theme.js +1 -0
  152. package/templates/ui/nextui.theme.ts +1 -0
  153. package/templates/ui/postcss.config.js +1 -0
  154. package/templates/ui/shadcn.README.md +1 -0
  155. package/templates/ui/styles.css +3 -0
  156. package/templates/ui/tailwind.config.js +6 -0
  157. package/templates/ui/utils.js +3 -0
  158. package/templates/ui/utils.ts +3 -0
  159. package/templates/vite/App.jsx +12 -0
  160. package/templates/vite/App.tsx +12 -0
  161. package/templates/vite/index.html +12 -0
  162. package/templates/vite/main.jsx +12 -0
  163. package/templates/vite/main.tsx +12 -0
  164. package/templates/vite/vite-env.d.ts +1 -0
  165. package/templates/vite/vite.config.ts +12 -0
@@ -0,0 +1,18 @@
1
+ // src/utils/npm-registry.ts
2
+ import { exec } from "child_process";
3
+ function fetchLatestVersion(pkg) {
4
+ return new Promise((resolve) => {
5
+ exec(`npm view ${pkg} version`, (err, stdout) => {
6
+ if (err) {
7
+ resolve(null);
8
+ return;
9
+ }
10
+ const version = String(stdout).trim();
11
+ resolve(version || null);
12
+ });
13
+ });
14
+ }
15
+ export {
16
+ fetchLatestVersion
17
+ };
18
+ //# sourceMappingURL=npm-registry-F7EVX3RR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/npm-registry.ts"],"sourcesContent":["import { exec } from 'node:child_process';\n\nexport function fetchLatestVersion(pkg: string): Promise<string | null> {\n return new Promise((resolve) => {\n exec(`npm view ${pkg} version`, (err, stdout) => {\n if (err) {\n resolve(null);\n return;\n }\n const version = String(stdout).trim();\n resolve(version || null);\n });\n });\n}\n"],"mappings":";AAAA,SAAS,YAAY;AAEd,SAAS,mBAAmB,KAAqC;AACtE,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,SAAK,YAAY,GAAG,YAAY,CAAC,KAAK,WAAW;AAC/C,UAAI,KAAK;AACP,gBAAQ,IAAI;AACZ;AAAA,MACF;AACA,YAAM,UAAU,OAAO,MAAM,EAAE,KAAK;AACpC,cAAQ,WAAW,IAAI;AAAA,IACzB,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "create-stackforge",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "bin": {
7
+ "create-stackforge": "./bin/cli.js",
8
+ "stackforge": "./bin/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "bin",
13
+ "templates"
14
+ ],
15
+ "dependencies": {
16
+ "commander": "^12.1.0",
17
+ "inquirer": "^9.2.20"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^20.14.10",
21
+ "eslint": "^8.57.0",
22
+ "@changesets/cli": "^2.27.9",
23
+ "pkg": "^5.8.1",
24
+ "tsup": "^8.2.3",
25
+ "tsx": "^4.16.5",
26
+ "typescript": "^5.5.4"
27
+ },
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
31
+ "scripts": {
32
+ "dev": "tsx src/cli.ts",
33
+ "build": "tsup src/cli.ts --format esm --sourcemap --clean",
34
+ "release": "pnpm build && changeset publish",
35
+ "changeset": "changeset",
36
+ "changeset:version": "changeset version",
37
+ "lint": "eslint .",
38
+ "typecheck": "tsc -p tsconfig.json --noEmit",
39
+ "build:bin": "pnpm exec pkg . --targets node18-win-x64,node18-macos-x64,node18-linux-x64 --output dist/stackforge",
40
+ "test:smoke": "tsx scripts/smoke.ts",
41
+ "test:registry": "tsx scripts/registry-test.ts",
42
+ "test:add-remove": "tsx scripts/add-remove-test.ts",
43
+ "test:update": "tsx scripts/update-test.ts",
44
+ "test:list": "tsx scripts/list-test.ts",
45
+ "test:list-features": "tsx scripts/list-features-test.ts",
46
+ "test:doctor": "tsx scripts/doctor-test.ts",
47
+ "test:agents": "tsx scripts/agents-test.ts",
48
+ "test:agent-add-remove": "tsx scripts/agent-add-remove-test.ts",
49
+ "test:list-agents": "tsx scripts/list-agents-test.ts",
50
+ "test:readme": "tsx scripts/readme-test.ts",
51
+ "test:deps": "tsx scripts/deps-test.ts",
52
+ "test:create-agents": "tsx scripts/create-agents-test.ts",
53
+ "test:create": "tsx scripts/create-test.ts",
54
+ "test:create-features": "tsx scripts/create-features-test.ts",
55
+ "test:create-preset-features": "tsx scripts/create-preset-features-test.ts",
56
+ "test:versions": "tsx scripts/versions-test.ts",
57
+ "test:agent-tools": "tsx scripts/agent-tools-test.ts",
58
+ "test:agent-hints": "tsx scripts/agent-hints-test.ts",
59
+ "test:migrate": "tsx scripts/migrate-test.ts",
60
+ "test:auto-migrate": "tsx scripts/auto-migrate-test.ts",
61
+ "test:list-presets": "tsx scripts/list-presets-test.ts",
62
+ "test:list-presets-details": "tsx scripts/list-presets-details-test.ts",
63
+ "test:feature-email": "tsx scripts/feature-email-test.ts",
64
+ "test:feature-storage": "tsx scripts/feature-storage-test.ts",
65
+ "test:feature-payments": "tsx scripts/feature-payments-test.ts",
66
+ "test:feature-clients": "tsx scripts/feature-clients-test.ts",
67
+ "test:docs": "tsx scripts/docs-test.ts",
68
+ "test:unit": "node --test --import tsx tests/unit/**/*.test.ts",
69
+ "test:integration": "node --test --import tsx tests/integration/**/*.test.ts",
70
+ "test:e2e": "node --test --import tsx tests/e2e/**/*.test.ts",
71
+ "test:all": "node --test --import tsx tests/**/*.test.ts",
72
+ "clean:tests": "tsx scripts/clean-test-artifacts.ts"
73
+ }
74
+ }
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import { fetchHello } from './client';
5
+
6
+ export function GraphqlExample() {
7
+ const [message, setMessage] = useState('');
8
+
9
+ useEffect(() => {
10
+ fetchHello().then((data) => setMessage(data.hello));
11
+ }, []);
12
+
13
+ return <p>GraphQL says: {message}</p>;
14
+ }
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import { fetchHello } from './client';
5
+
6
+ export function GraphqlExample() {
7
+ const [message, setMessage] = useState('');
8
+
9
+ useEffect(() => {
10
+ fetchHello().then((data) => setMessage(data.hello));
11
+ }, []);
12
+
13
+ return <p>GraphQL says: {message}</p>;
14
+ }
@@ -0,0 +1,12 @@
1
+ import { GraphQLClient, gql } from 'graphql-request';
2
+
3
+ const client = new GraphQLClient('/api/graphql');
4
+
5
+ export async function fetchHello() {
6
+ const query = gql`
7
+ query Hello {
8
+ hello
9
+ }
10
+ `;
11
+ return client.request(query);
12
+ }
@@ -0,0 +1,12 @@
1
+ import { GraphQLClient, gql } from 'graphql-request';
2
+
3
+ const client = new GraphQLClient('/api/graphql');
4
+
5
+ export async function fetchHello() {
6
+ const query = gql`
7
+ query Hello {
8
+ hello
9
+ }
10
+ `;
11
+ return client.request(query);
12
+ }
@@ -0,0 +1,32 @@
1
+ import { createYoga, createSchema } from 'graphql-yoga';
2
+
3
+ const schema = createSchema({
4
+ typeDefs: /* GraphQL */ `
5
+ type User {
6
+ id: ID!
7
+ name: String!
8
+ }
9
+
10
+ type Query {
11
+ hello: String!
12
+ users: [User!]!
13
+ }
14
+
15
+ type Mutation {
16
+ addUser(name: String!): User!
17
+ }
18
+ `,
19
+ resolvers: {
20
+ Query: {
21
+ hello: () => 'hello',
22
+ users: () => [{ id: 1, name: 'Ada' }]
23
+ },
24
+ Mutation: {
25
+ addUser: (_parent, args) => ({ id: 2, name: args.name })
26
+ }
27
+ }
28
+ });
29
+
30
+ const yoga = createYoga({ schema });
31
+
32
+ export { yoga as GET, yoga as POST };
@@ -0,0 +1,23 @@
1
+ import { createYoga, createSchema } from 'graphql-yoga';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+
5
+ const schemaPath = join(process.cwd(), 'src', 'graphql', 'schema.graphql');
6
+ const typeDefs = readFileSync(schemaPath, 'utf8');
7
+
8
+ const yoga = createYoga({
9
+ schema: createSchema({
10
+ typeDefs,
11
+ resolvers: {
12
+ Query: {
13
+ hello: () => 'hello',
14
+ users: () => [{ id: 1, name: 'Ada' }]
15
+ },
16
+ Mutation: {
17
+ addUser: (_: unknown, args: { name: string }) => ({ id: 2, name: args.name })
18
+ }
19
+ }
20
+ })
21
+ });
22
+
23
+ export { yoga as GET, yoga as POST };
@@ -0,0 +1,13 @@
1
+ type Query {
2
+ hello: String
3
+ users: [User!]!
4
+ }
5
+
6
+ type User {
7
+ id: ID!
8
+ name: String!
9
+ }
10
+
11
+ type Mutation {
12
+ addUser(name: String!): User!
13
+ }
@@ -0,0 +1,27 @@
1
+ const http = require('node:http');
2
+ const { createYoga, createSchema } = require('graphql-yoga');
3
+ const { readFileSync } = require('node:fs');
4
+ const { join } = require('node:path');
5
+
6
+ const schemaPath = join(process.cwd(), 'src', 'graphql', 'schema.graphql');
7
+ const typeDefs = readFileSync(schemaPath, 'utf8');
8
+
9
+ const yoga = createYoga({
10
+ schema: createSchema({
11
+ typeDefs,
12
+ resolvers: {
13
+ Query: {
14
+ hello: () => 'hello',
15
+ users: () => [{ id: 1, name: 'Ada' }]
16
+ },
17
+ Mutation: {
18
+ addUser: (_, args) => ({ id: 2, name: args.name })
19
+ }
20
+ }
21
+ })
22
+ });
23
+
24
+ const server = http.createServer(yoga);
25
+ server.listen(3001, () => {
26
+ console.log('GraphQL server listening on http://localhost:3001/graphql');
27
+ });
@@ -0,0 +1,27 @@
1
+ import { createServer } from 'node:http';
2
+ import { createYoga, createSchema } from 'graphql-yoga';
3
+ import { readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+
6
+ const schemaPath = join(process.cwd(), 'src', 'graphql', 'schema.graphql');
7
+ const typeDefs = readFileSync(schemaPath, 'utf8');
8
+
9
+ const yoga = createYoga({
10
+ schema: createSchema({
11
+ typeDefs,
12
+ resolvers: {
13
+ Query: {
14
+ hello: () => 'hello',
15
+ users: () => [{ id: 1, name: 'Ada' }]
16
+ },
17
+ Mutation: {
18
+ addUser: (_: unknown, args: { name: string }) => ({ id: 2, name: args.name })
19
+ }
20
+ }
21
+ })
22
+ });
23
+
24
+ const server = createServer(yoga);
25
+ server.listen(3001, () => {
26
+ console.log('GraphQL server listening on http://localhost:3001/graphql');
27
+ });
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import { fetchHello } from './client';
5
+
6
+ export function RestExample() {
7
+ const [message, setMessage] = useState('');
8
+
9
+ useEffect(() => {
10
+ fetchHello().then((data) => setMessage(data.message));
11
+ }, []);
12
+
13
+ return <p>REST says: {message}</p>;
14
+ }
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import { fetchHello } from './client';
5
+
6
+ export function RestExample() {
7
+ const [message, setMessage] = useState('');
8
+
9
+ useEffect(() => {
10
+ fetchHello().then((data) => setMessage(data.message));
11
+ }, []);
12
+
13
+ return <p>REST says: {message}</p>;
14
+ }
@@ -0,0 +1,4 @@
1
+ export async function fetchHello() {
2
+ const res = await fetch('/api/hello');
3
+ return res.json();
4
+ }
@@ -0,0 +1,4 @@
1
+ export async function fetchHello() {
2
+ const res = await fetch('/api/hello');
3
+ return res.json();
4
+ }
@@ -0,0 +1,3 @@
1
+ export async function GET() {
2
+ return Response.json({ message: 'hello' });
3
+ }
@@ -0,0 +1,3 @@
1
+ export async function GET() {
2
+ return Response.json({ message: 'hello' });
3
+ }
@@ -0,0 +1,11 @@
1
+ import { listUsers } from '../../../src/db/users';
2
+
3
+ export async function GET() {
4
+ const users = await listUsers();
5
+ return Response.json(users);
6
+ }
7
+
8
+ export async function POST(request) {
9
+ const body = await request.json();
10
+ return Response.json({ id: 1, name: body.name ?? 'New user' });
11
+ }
@@ -0,0 +1,11 @@
1
+ import { listUsers } from '../../../src/db/users';
2
+
3
+ export async function GET() {
4
+ const users = await listUsers();
5
+ return Response.json(users);
6
+ }
7
+
8
+ export async function POST(request: Request) {
9
+ const body = await request.json();
10
+ return Response.json({ id: 1, name: body.name ?? 'New user' });
11
+ }
@@ -0,0 +1,15 @@
1
+ const http = require('node:http');
2
+
3
+ const server = http.createServer((req, res) => {
4
+ if (req.url === '/api/hello') {
5
+ res.writeHead(200, { 'Content-Type': 'application/json' });
6
+ res.end(JSON.stringify({ message: 'hello' }));
7
+ return;
8
+ }
9
+ res.writeHead(404);
10
+ res.end();
11
+ });
12
+
13
+ server.listen(3001, () => {
14
+ console.log('REST server listening on http://localhost:3001');
15
+ });
@@ -0,0 +1,15 @@
1
+ import { createServer } from 'node:http';
2
+
3
+ const server = createServer((req, res) => {
4
+ if (req.url === '/api/hello') {
5
+ res.writeHead(200, { 'Content-Type': 'application/json' });
6
+ res.end(JSON.stringify({ message: 'hello' }));
7
+ return;
8
+ }
9
+ res.writeHead(404);
10
+ res.end();
11
+ });
12
+
13
+ server.listen(3001, () => {
14
+ console.log('REST server listening on http://localhost:3001');
15
+ });
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import { fetchHello, trpcClient } from './client';
5
+
6
+ export function TrpcExample() {
7
+ const [message, setMessage] = useState('');
8
+ const [created, setCreated] = useState('');
9
+
10
+ useEffect(() => {
11
+ fetchHello().then((data) => setMessage(data));
12
+ }, []);
13
+
14
+ async function handleCreate() {
15
+ const user = await trpcClient.addUser.mutate({ name: 'Ada' });
16
+ setCreated(user.name);
17
+ }
18
+
19
+ return (
20
+ <div>
21
+ <p>tRPC says: {message}</p>
22
+ <button onClick={handleCreate}>Create user</button>
23
+ {created ? <p>Created: {created}</p> : null}
24
+ </div>
25
+ );
26
+ }
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import { fetchHello, trpcClient } from './client';
5
+
6
+ export function TrpcExample() {
7
+ const [message, setMessage] = useState('');
8
+ const [created, setCreated] = useState('');
9
+
10
+ useEffect(() => {
11
+ fetchHello().then((data) => setMessage(data));
12
+ }, []);
13
+
14
+ async function handleCreate() {
15
+ const user = await trpcClient.addUser.mutate({ name: 'Ada' });
16
+ setCreated(user.name);
17
+ }
18
+
19
+ return (
20
+ <div>
21
+ <p>tRPC says: {message}</p>
22
+ <button onClick={handleCreate}>Create user</button>
23
+ {created ? <p>Created: {created}</p> : null}
24
+ </div>
25
+ );
26
+ }
@@ -0,0 +1,15 @@
1
+ import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
2
+
3
+ const baseUrl = import.meta.env.VITE_API_URL || 'http://localhost:3001';
4
+
5
+ export const trpcClient = createTRPCProxyClient({
6
+ links: [
7
+ httpBatchLink({
8
+ url: `${baseUrl}/trpc`
9
+ })
10
+ ]
11
+ });
12
+
13
+ export async function fetchHello() {
14
+ return trpcClient.hello.query();
15
+ }
@@ -0,0 +1,16 @@
1
+ import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
2
+ import type { AppRouter } from '../server/api/root';
3
+
4
+ const baseUrl = import.meta.env.VITE_API_URL || 'http://localhost:3001';
5
+
6
+ export const trpcClient = createTRPCProxyClient<AppRouter>({
7
+ links: [
8
+ httpBatchLink({
9
+ url: `${baseUrl}/trpc`
10
+ })
11
+ ]
12
+ });
13
+
14
+ export async function fetchHello() {
15
+ return trpcClient.hello.query();
16
+ }
@@ -0,0 +1,13 @@
1
+ import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
2
+
3
+ export const trpcClient = createTRPCProxyClient({
4
+ links: [
5
+ httpBatchLink({
6
+ url: '/api/trpc'
7
+ })
8
+ ]
9
+ });
10
+
11
+ export async function fetchHello() {
12
+ return trpcClient.hello.query();
13
+ }
@@ -0,0 +1,14 @@
1
+ import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
2
+ import type { AppRouter } from '../server/api/root';
3
+
4
+ export const trpcClient = createTRPCProxyClient<AppRouter>({
5
+ links: [
6
+ httpBatchLink({
7
+ url: '/api/trpc'
8
+ })
9
+ ]
10
+ });
11
+
12
+ export async function fetchHello() {
13
+ return trpcClient.hello.query();
14
+ }
@@ -0,0 +1,11 @@
1
+ import { router, publicProcedure } from './trpc';
2
+ import { z } from 'zod';
3
+
4
+ export const appRouter = router({
5
+ hello: publicProcedure.input(z.string().optional()).query(({ input }) => `hello ${input ?? 'world'}`),
6
+ addUser: publicProcedure
7
+ .input(z.object({ name: z.string() }))
8
+ .mutation(({ input }) => ({ id: 1, name: input.name }))
9
+ });
10
+
11
+ export type AppRouter = typeof appRouter;
@@ -0,0 +1,12 @@
1
+ import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
2
+ import { appRouter } from '../../../../src/server/api/root';
3
+
4
+ const handler = (req) =>
5
+ fetchRequestHandler({
6
+ endpoint: '/api/trpc',
7
+ req,
8
+ router: appRouter,
9
+ createContext: async () => ({})
10
+ });
11
+
12
+ export { handler as GET, handler as POST };
@@ -0,0 +1,12 @@
1
+ import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
2
+ import { appRouter } from '../../../../src/server/api/root';
3
+
4
+ const handler = (req: Request) =>
5
+ fetchRequestHandler({
6
+ endpoint: '/api/trpc',
7
+ req,
8
+ router: appRouter,
9
+ createContext: async () => ({})
10
+ });
11
+
12
+ export { handler as GET, handler as POST };
@@ -0,0 +1,6 @@
1
+ import { initTRPC } from '@trpc/server';
2
+
3
+ const t = initTRPC.create();
4
+
5
+ export const router = t.router;
6
+ export const publicProcedure = t.procedure;
@@ -0,0 +1,9 @@
1
+ const { createHTTPServer } = require('@trpc/server/adapters/standalone');
2
+ const { appRouter } = require('./api/root');
3
+
4
+ const server = createHTTPServer({
5
+ router: appRouter
6
+ });
7
+
8
+ server.listen(3001);
9
+ console.log('tRPC server listening on http://localhost:3001');
@@ -0,0 +1,9 @@
1
+ import { createHTTPServer } from '@trpc/server/adapters/standalone';
2
+ import { appRouter } from './api/root';
3
+
4
+ const server = createHTTPServer({
5
+ router: appRouter
6
+ });
7
+
8
+ server.listen(3001);
9
+ console.log('tRPC server listening on http://localhost:3001');
@@ -0,0 +1,11 @@
1
+ import { auth } from '@clerk/nextjs/server';
2
+
3
+ export default async function ProtectedPage() {
4
+ const { userId } = auth();
5
+ return (
6
+ <div>
7
+ <h1>Protected</h1>
8
+ <p>User ID: {userId ?? 'anonymous'}</p>
9
+ </div>
10
+ );
11
+ }
@@ -0,0 +1,11 @@
1
+ import { auth } from '@clerk/nextjs/server';
2
+
3
+ export default async function ProtectedPage() {
4
+ const { userId } = auth();
5
+ return (
6
+ <div>
7
+ <h1>Protected</h1>
8
+ <p>User ID: {userId ?? 'anonymous'}</p>
9
+ </div>
10
+ );
11
+ }
@@ -0,0 +1,11 @@
1
+ import { auth } from '@clerk/nextjs/server';
2
+
3
+ export default async function ProtectedPage() {
4
+ const { userId } = auth();
5
+ return (
6
+ <div>
7
+ <h1>Protected</h1>
8
+ <p>User ID: {userId ?? 'anonymous'}</p>
9
+ </div>
10
+ );
11
+ }
@@ -0,0 +1,11 @@
1
+ import { auth } from '@clerk/nextjs/server';
2
+
3
+ export default async function ProtectedPage() {
4
+ const { userId } = auth();
5
+ return (
6
+ <div>
7
+ <h1>Protected</h1>
8
+ <p>User ID: {userId ?? 'anonymous'}</p>
9
+ </div>
10
+ );
11
+ }
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ import { SignIn } from '@clerk/nextjs';
4
+
5
+ export default function SignInPage() {
6
+ return (
7
+ <main>
8
+ <SignIn />
9
+ </main>
10
+ );
11
+ }
@@ -0,0 +1,11 @@
1
+ "use client";
2
+
3
+ import { SignIn } from '@clerk/nextjs';
4
+
5
+ export default function SignInPage() {
6
+ return (
7
+ <main>
8
+ <SignIn />
9
+ </main>
10
+ );
11
+ }