@timbenniks/contentstack-platform-app-scaffold 0.1.0 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -0
- package/dist/commands/scaffold.d.ts +0 -1
- package/dist/commands/scaffold.d.ts.map +1 -1
- package/dist/commands/scaffold.js +0 -5
- package/dist/commands/scaffold.js.map +1 -1
- package/dist/services/prompts.d.ts.map +1 -1
- package/dist/services/prompts.js +94 -7
- package/dist/services/prompts.js.map +1 -1
- package/dist/services/scaffold.d.ts.map +1 -1
- package/dist/services/scaffold.js +68 -19
- package/dist/services/scaffold.js.map +1 -1
- package/dist/types.d.ts +0 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/oclif.manifest.json +5 -21
- package/package.json +6 -2
- package/templates/nextjs/.env.example.hbs +31 -4
- package/templates/nextjs/app/api/auth/[...nextauth]/route.ts.hbs +1 -0
- package/templates/nextjs/app/api/brandkit/[...path]/route.ts.hbs +7 -18
- package/templates/nextjs/app/api/cma/[...path]/route.ts.hbs +7 -18
- package/templates/nextjs/app/api/launch/[...path]/route.ts.hbs +7 -18
- package/templates/nextjs/app/assets/page.tsx.hbs +27 -12
- package/templates/nextjs/app/brandkit/page.tsx.hbs +32 -19
- package/templates/nextjs/app/entries/page.tsx.hbs +29 -13
- package/templates/nextjs/app/globals.css.hbs +175 -0
- package/templates/nextjs/app/launch/page.tsx.hbs +32 -19
- package/templates/nextjs/app/layout.tsx.hbs +19 -4
- package/templates/nextjs/app/page.tsx.hbs +142 -38
- package/templates/nextjs/app/providers.tsx.hbs +13 -1
- package/templates/nextjs/lib/auth.ts.hbs +48 -10
- package/templates/nextjs/manifest.json +3 -4
- package/templates/nextjs/next.config.ts +7 -0
- package/templates/nextjs/types/next-auth.d.ts.hbs +8 -0
- package/templates/nextjs/next.config.js +0 -4
- package/templates/nextjs/package.json.hbs +0 -24
- package/templates/nextjs/tsconfig.json +0 -21
|
@@ -1,55 +1,159 @@
|
|
|
1
1
|
{{#if features.oauth}}
|
|
2
|
-
import { auth } from "@/lib/auth"
|
|
3
|
-
{
|
|
2
|
+
import { auth, signIn, signOut } from "@/lib/auth"
|
|
3
|
+
import { Button } from "@/components/ui/button"
|
|
4
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
5
|
+
|
|
6
|
+
export const dynamic = "force-dynamic"
|
|
4
7
|
|
|
5
|
-
export default
|
|
6
|
-
{{#if features.oauth}}
|
|
8
|
+
export default async function Home() {
|
|
7
9
|
const session = await auth()
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
if (session) {
|
|
12
|
+
return (
|
|
13
|
+
<main className="min-h-screen p-8 max-w-2xl mx-auto">
|
|
14
|
+
<h1 className="text-3xl font-bold mb-2">
|
|
15
|
+
Welcome, {(session.user as { name?: string })?.name ?? "User"}
|
|
16
|
+
</h1>
|
|
17
|
+
<p className="text-muted-foreground mb-8">You are signed in with Contentstack.</p>
|
|
18
|
+
|
|
19
|
+
<div className="grid gap-4">
|
|
20
|
+
{{#if features.cma}}
|
|
21
|
+
<Card>
|
|
22
|
+
<CardHeader>
|
|
23
|
+
<CardTitle>Content Management</CardTitle>
|
|
24
|
+
<CardDescription>Manage your entries and assets</CardDescription>
|
|
25
|
+
</CardHeader>
|
|
26
|
+
<CardContent className="flex gap-2">
|
|
27
|
+
<Button variant="secondary" asChild><a href="/entries">Entries</a></Button>
|
|
28
|
+
<Button variant="secondary" asChild><a href="/assets">Assets</a></Button>
|
|
29
|
+
</CardContent>
|
|
30
|
+
</Card>
|
|
31
|
+
{{/if}}
|
|
32
|
+
{{#if features.launch}}
|
|
33
|
+
<Card>
|
|
34
|
+
<CardHeader>
|
|
35
|
+
<CardTitle>Launch</CardTitle>
|
|
36
|
+
<CardDescription>Manage your deployment projects</CardDescription>
|
|
37
|
+
</CardHeader>
|
|
38
|
+
<CardContent>
|
|
39
|
+
<Button variant="secondary" asChild><a href="/launch">Projects</a></Button>
|
|
40
|
+
</CardContent>
|
|
41
|
+
</Card>
|
|
42
|
+
{{/if}}
|
|
43
|
+
{{#if features.brandkit}}
|
|
44
|
+
<Card>
|
|
45
|
+
<CardHeader>
|
|
46
|
+
<CardTitle>Brand Kit AI</CardTitle>
|
|
47
|
+
<CardDescription>Manage your brand kits and voice profiles</CardDescription>
|
|
48
|
+
</CardHeader>
|
|
49
|
+
<CardContent>
|
|
50
|
+
<Button variant="secondary" asChild><a href="/brandkit">Brand Kits</a></Button>
|
|
51
|
+
</CardContent>
|
|
52
|
+
</Card>
|
|
53
|
+
{{/if}}
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<form
|
|
57
|
+
className="mt-8"
|
|
58
|
+
action={async () => {
|
|
59
|
+
"use server"
|
|
60
|
+
await signOut({ redirectTo: "/" })
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
<Button variant="outline" type="submit">Sign Out</Button>
|
|
64
|
+
</form>
|
|
65
|
+
</main>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
9
68
|
|
|
10
69
|
return (
|
|
11
|
-
<main
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
70
|
+
<main className="min-h-screen flex items-center justify-center p-8">
|
|
71
|
+
<Card className="w-full max-w-md">
|
|
72
|
+
<CardHeader>
|
|
73
|
+
<CardTitle className="text-2xl">{{projectName}}</CardTitle>
|
|
74
|
+
<CardDescription>
|
|
75
|
+
Region: <code className="text-xs bg-muted px-1 py-0.5 rounded">{{region}}</code>
|
|
76
|
+
</CardDescription>
|
|
77
|
+
</CardHeader>
|
|
78
|
+
<CardContent className="space-y-4">
|
|
79
|
+
<ol className="list-decimal list-inside text-sm text-muted-foreground space-y-1">
|
|
80
|
+
<li>Copy <code className="text-xs bg-muted px-1 py-0.5 rounded">.env.example</code> to <code className="text-xs bg-muted px-1 py-0.5 rounded">.env.local</code></li>
|
|
81
|
+
<li>Fill in your Contentstack credentials</li>
|
|
82
|
+
<li>Start building!</li>
|
|
83
|
+
</ol>
|
|
84
|
+
<form
|
|
85
|
+
action={async () => {
|
|
86
|
+
"use server"
|
|
87
|
+
await signIn("contentstack", { redirectTo: "/" })
|
|
88
|
+
}}
|
|
89
|
+
>
|
|
90
|
+
<Button className="w-full" type="submit">Sign in with Contentstack</Button>
|
|
91
|
+
</form>
|
|
92
|
+
</CardContent>
|
|
93
|
+
</Card>
|
|
94
|
+
</main>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
{{else}}
|
|
98
|
+
import { Button } from "@/components/ui/button"
|
|
99
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
|
100
|
+
|
|
101
|
+
export default function Home() {
|
|
102
|
+
return (
|
|
103
|
+
<main className="min-h-screen p-8 max-w-2xl mx-auto">
|
|
104
|
+
<h1 className="text-3xl font-bold mb-2">{{projectName}}</h1>
|
|
105
|
+
<p className="text-muted-foreground mb-8">
|
|
106
|
+
Region: <code className="text-xs bg-muted px-1 py-0.5 rounded">{{region}}</code>
|
|
107
|
+
</p>
|
|
108
|
+
|
|
109
|
+
<Card className="mb-6">
|
|
110
|
+
<CardHeader>
|
|
111
|
+
<CardTitle>Getting Started</CardTitle>
|
|
112
|
+
<CardDescription>Set up your Contentstack credentials to begin</CardDescription>
|
|
113
|
+
</CardHeader>
|
|
114
|
+
<CardContent>
|
|
115
|
+
<ol className="list-decimal list-inside text-sm text-muted-foreground space-y-1">
|
|
116
|
+
<li>Copy <code className="text-xs bg-muted px-1 py-0.5 rounded">.env.example</code> to <code className="text-xs bg-muted px-1 py-0.5 rounded">.env.local</code></li>
|
|
117
|
+
<li>Fill in your Contentstack credentials</li>
|
|
118
|
+
<li>Start building!</li>
|
|
119
|
+
</ol>
|
|
120
|
+
</CardContent>
|
|
121
|
+
</Card>
|
|
31
122
|
{{#if features.cma}}
|
|
32
123
|
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
124
|
+
<Card className="mb-4">
|
|
125
|
+
<CardHeader>
|
|
126
|
+
<CardTitle>Content Management</CardTitle>
|
|
127
|
+
</CardHeader>
|
|
128
|
+
<CardContent className="flex gap-2">
|
|
129
|
+
<Button variant="secondary" asChild><a href="/entries">Entries</a></Button>
|
|
130
|
+
<Button variant="secondary" asChild><a href="/assets">Assets</a></Button>
|
|
131
|
+
</CardContent>
|
|
132
|
+
</Card>
|
|
38
133
|
{{/if}}
|
|
39
134
|
{{#if features.launch}}
|
|
40
135
|
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
136
|
+
<Card className="mb-4">
|
|
137
|
+
<CardHeader>
|
|
138
|
+
<CardTitle>Launch</CardTitle>
|
|
139
|
+
</CardHeader>
|
|
140
|
+
<CardContent>
|
|
141
|
+
<Button variant="secondary" asChild><a href="/launch">Projects</a></Button>
|
|
142
|
+
</CardContent>
|
|
143
|
+
</Card>
|
|
45
144
|
{{/if}}
|
|
46
145
|
{{#if features.brandkit}}
|
|
47
146
|
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
147
|
+
<Card className="mb-4">
|
|
148
|
+
<CardHeader>
|
|
149
|
+
<CardTitle>Brand Kit AI</CardTitle>
|
|
150
|
+
</CardHeader>
|
|
151
|
+
<CardContent>
|
|
152
|
+
<Button variant="secondary" asChild><a href="/brandkit">Brand Kits</a></Button>
|
|
153
|
+
</CardContent>
|
|
154
|
+
</Card>
|
|
52
155
|
{{/if}}
|
|
53
156
|
</main>
|
|
54
157
|
)
|
|
55
158
|
}
|
|
159
|
+
{{/if}}
|
|
@@ -4,7 +4,19 @@ import { ContentstackProvider } from "@timbenniks/contentstack-platform-sdk/reac
|
|
|
4
4
|
|
|
5
5
|
export function Providers({ children }: { children: React.ReactNode }) {
|
|
6
6
|
return (
|
|
7
|
-
<ContentstackProvider
|
|
7
|
+
<ContentstackProvider
|
|
8
|
+
region={process.env.NEXT_PUBLIC_CONTENTSTACK_REGION as "{{region}}" ?? "{{region}}"}
|
|
9
|
+
apiKey={process.env.NEXT_PUBLIC_CONTENTSTACK_API_KEY ?? ""}
|
|
10
|
+
proxyBasePath="/api/cma"
|
|
11
|
+
{{#if features.launch}}
|
|
12
|
+
organizationUid={process.env.NEXT_PUBLIC_CONTENTSTACK_ORGANIZATION_UID ?? ""}
|
|
13
|
+
{{else if features.brandkit}}
|
|
14
|
+
organizationUid={process.env.NEXT_PUBLIC_CONTENTSTACK_ORGANIZATION_UID ?? ""}
|
|
15
|
+
{{/if}}
|
|
16
|
+
{{#if features.brandkit}}
|
|
17
|
+
brandKitUid={process.env.NEXT_PUBLIC_CONTENTSTACK_BRAND_KIT_UID ?? ""}
|
|
18
|
+
{{/if}}
|
|
19
|
+
>
|
|
8
20
|
{children}
|
|
9
21
|
</ContentstackProvider>
|
|
10
22
|
)
|
|
@@ -1,12 +1,50 @@
|
|
|
1
|
-
import { createContentstackAuth } from "@timbenniks/contentstack-platform-sdk/server/middleware"
|
|
2
1
|
import type { ContentstackRegion } from "@timbenniks/contentstack-platform-sdk/regions"
|
|
2
|
+
import { createContentstackAuth } from "@timbenniks/contentstack-platform-sdk/server/middleware"
|
|
3
|
+
import type { NextRequest } from "next/server"
|
|
4
|
+
|
|
5
|
+
type AuthConfig = Awaited<ReturnType<typeof createContentstackAuth>>
|
|
6
|
+
|
|
7
|
+
let _authConfig: AuthConfig | null = null
|
|
8
|
+
|
|
9
|
+
async function getAuthConfig(): Promise<AuthConfig> {
|
|
10
|
+
if (!_authConfig) {
|
|
11
|
+
_authConfig = await createContentstackAuth({
|
|
12
|
+
region: (process.env.CONTENTSTACK_REGION ?? "{{region}}") as ContentstackRegion,
|
|
13
|
+
appId: process.env.CONTENTSTACK_APP_ID!,
|
|
14
|
+
clientId: process.env.CONTENTSTACK_CLIENT_ID!,
|
|
15
|
+
clientSecret: process.env.CONTENTSTACK_CLIENT_SECRET!,
|
|
16
|
+
secret: process.env.AUTH_SECRET!,
|
|
17
|
+
scopes: [{{#each scopes}}"{{this}}"{{#unless @last}}, {{/unless}}{{/each}}],
|
|
18
|
+
trustHost: true,
|
|
19
|
+
signInPage: "/",
|
|
20
|
+
errorPage: "/",
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
return _authConfig
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const handlers = {
|
|
27
|
+
GET: async (req: NextRequest) => {
|
|
28
|
+
const config = await getAuthConfig()
|
|
29
|
+
return config.handlers.GET(req)
|
|
30
|
+
},
|
|
31
|
+
POST: async (req: NextRequest) => {
|
|
32
|
+
const config = await getAuthConfig()
|
|
33
|
+
return config.handlers.POST(req)
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function auth() {
|
|
38
|
+
const config = await getAuthConfig()
|
|
39
|
+
return config.auth()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function signIn(provider?: string, options?: Record<string, unknown>) {
|
|
43
|
+
const config = await getAuthConfig()
|
|
44
|
+
return config.signIn(provider, options)
|
|
45
|
+
}
|
|
3
46
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
clientSecret: process.env.CONTENTSTACK_CLIENT_SECRET!,
|
|
9
|
-
secret: process.env.AUTH_SECRET!,
|
|
10
|
-
scopes: [{{#each scopes}}"{{this}}"{{#unless @last}}, {{/unless}}{{/each}}],
|
|
11
|
-
trustHost: true,
|
|
12
|
-
})
|
|
47
|
+
export async function signOut(options?: Record<string, unknown>) {
|
|
48
|
+
const config = await getAuthConfig()
|
|
49
|
+
return config.signOut(options)
|
|
50
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
[
|
|
2
|
-
{ "path": "package.json" },
|
|
3
2
|
{ "path": ".env.example" },
|
|
4
|
-
{ "path": ".
|
|
5
|
-
{ "path": "
|
|
6
|
-
{ "path": "next.config.js" },
|
|
3
|
+
{ "path": "next.config.ts" },
|
|
4
|
+
{ "path": "types/next-auth.d.ts", "requiredFeatures": ["oauth"] },
|
|
7
5
|
{ "path": "lib/auth.ts", "requiredFeatures": ["oauth"] },
|
|
6
|
+
{ "path": "app/globals.css" },
|
|
8
7
|
{ "path": "app/layout.tsx" },
|
|
9
8
|
{ "path": "app/page.tsx" },
|
|
10
9
|
{ "path": "app/providers.tsx", "anyFeatures": ["cma", "launch", "brandkit"] },
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{projectName}}",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "next dev",
|
|
7
|
-
"build": "next build",
|
|
8
|
-
"start": "next start",
|
|
9
|
-
"lint": "next lint"
|
|
10
|
-
},
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"next": "^15.0.0",
|
|
13
|
-
"react": "^19.0.0",
|
|
14
|
-
"react-dom": "^19.0.0",
|
|
15
|
-
"@timbenniks/contentstack-platform-sdk": "^{{sdkVersion}}"{{#if features.oauth}},
|
|
16
|
-
"next-auth": "5.0.0-beta.30"{{/if}}
|
|
17
|
-
},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"typescript": "^5.5.0",
|
|
20
|
-
"@types/react": "^19.0.0",
|
|
21
|
-
"@types/react-dom": "^19.0.0",
|
|
22
|
-
"@types/node": "^22.0.0"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2017",
|
|
4
|
-
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
-
"allowJs": true,
|
|
6
|
-
"skipLibCheck": true,
|
|
7
|
-
"strict": true,
|
|
8
|
-
"noEmit": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"module": "esnext",
|
|
11
|
-
"moduleResolution": "bundler",
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"isolatedModules": true,
|
|
14
|
-
"jsx": "preserve",
|
|
15
|
-
"incremental": true,
|
|
16
|
-
"plugins": [{ "name": "next" }],
|
|
17
|
-
"paths": { "@/*": ["./*"] }
|
|
18
|
-
},
|
|
19
|
-
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
|
20
|
-
"exclude": ["node_modules"]
|
|
21
|
-
}
|