subaya 1.0.1 → 1.0.3

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 (98) hide show
  1. package/dist/commands/axios/AxiosGeneratorCommand.d.ts.map +1 -1
  2. package/dist/commands/axios/AxiosGeneratorCommand.js +101 -17
  3. package/dist/commands/axios/AxiosGeneratorCommand.js.map +1 -1
  4. package/dist/commands/git/PushGeneratorCommand.d.ts +5 -0
  5. package/dist/commands/git/PushGeneratorCommand.d.ts.map +1 -0
  6. package/dist/commands/git/PushGeneratorCommand.js +51 -0
  7. package/dist/commands/git/PushGeneratorCommand.js.map +1 -0
  8. package/dist/commands/provider/ProviderGeneratorCommand.d.ts +2 -1
  9. package/dist/commands/provider/ProviderGeneratorCommand.d.ts.map +1 -1
  10. package/dist/commands/provider/ProviderGeneratorCommand.js.map +1 -1
  11. package/dist/commands/route/NextRouteGeneratorCommand.js +1 -1
  12. package/dist/commands/route/NextRouteGeneratorCommand.js.map +1 -1
  13. package/dist/commands/supabase/SupabaseCommand.d.ts +2 -1
  14. package/dist/commands/supabase/SupabaseCommand.d.ts.map +1 -1
  15. package/dist/commands/supabase/SupabaseCommand.js +97 -25
  16. package/dist/commands/supabase/SupabaseCommand.js.map +1 -1
  17. package/dist/core/EnsureSystem.d.ts +3 -0
  18. package/dist/core/EnsureSystem.d.ts.map +1 -1
  19. package/dist/core/EnsureSystem.js +16 -0
  20. package/dist/core/EnsureSystem.js.map +1 -1
  21. package/dist/core/FileSystemService.d.ts +1 -1
  22. package/dist/core/FileSystemService.d.ts.map +1 -1
  23. package/dist/core/FileSystemService.js +8 -0
  24. package/dist/core/FileSystemService.js.map +1 -1
  25. package/dist/template/axios/instance.d.ts +3 -1
  26. package/dist/template/axios/instance.d.ts.map +1 -1
  27. package/dist/template/axios/instance.js +204 -19
  28. package/dist/template/axios/instance.js.map +1 -1
  29. package/dist/template/axios/nextServerJwt.d.ts +4 -0
  30. package/dist/template/axios/nextServerJwt.d.ts.map +1 -0
  31. package/dist/template/axios/nextServerJwt.js +60 -0
  32. package/dist/template/axios/nextServerJwt.js.map +1 -0
  33. package/dist/template/axios/protectedProxy.d.ts +2 -0
  34. package/dist/template/axios/protectedProxy.d.ts.map +1 -0
  35. package/dist/template/axios/protectedProxy.js +40 -0
  36. package/dist/template/axios/protectedProxy.js.map +1 -0
  37. package/dist/template/axios/refresh.d.ts.map +1 -1
  38. package/dist/template/axios/refresh.js +46 -59
  39. package/dist/template/axios/refresh.js.map +1 -1
  40. package/dist/template/axios/useLoginHook.d.ts +2 -0
  41. package/dist/template/axios/useLoginHook.d.ts.map +1 -0
  42. package/dist/template/axios/useLoginHook.js +16 -0
  43. package/dist/template/axios/useLoginHook.js.map +1 -0
  44. package/dist/template/axios/useLogoutHook.d.ts +2 -0
  45. package/dist/template/axios/useLogoutHook.d.ts.map +1 -0
  46. package/dist/template/axios/useLogoutHook.js +15 -0
  47. package/dist/template/axios/useLogoutHook.js.map +1 -0
  48. package/dist/template/axios/utilJwt.d.ts +2 -0
  49. package/dist/template/axios/utilJwt.d.ts.map +1 -0
  50. package/dist/template/axios/utilJwt.js +52 -0
  51. package/dist/template/axios/utilJwt.js.map +1 -0
  52. package/dist/template/supabase/actions/auth.d.ts +2 -0
  53. package/dist/template/supabase/actions/auth.d.ts.map +1 -0
  54. package/dist/template/supabase/actions/auth.js +61 -0
  55. package/dist/template/supabase/actions/auth.js.map +1 -0
  56. package/dist/template/supabase/actions/crud.d.ts +3 -0
  57. package/dist/template/supabase/actions/crud.d.ts.map +1 -0
  58. package/dist/template/supabase/actions/crud.js +72 -0
  59. package/dist/template/supabase/actions/crud.js.map +1 -0
  60. package/dist/template/supabase/actions/user.d.ts +2 -0
  61. package/dist/template/supabase/actions/user.d.ts.map +1 -0
  62. package/dist/template/supabase/actions/user.js +36 -0
  63. package/dist/template/supabase/actions/user.js.map +1 -0
  64. package/dist/template/supabase/admin/supabaseAdminLayout.d.ts +2 -0
  65. package/dist/template/supabase/admin/supabaseAdminLayout.d.ts.map +1 -0
  66. package/dist/template/supabase/admin/supabaseAdminLayout.js +7 -0
  67. package/dist/template/supabase/admin/supabaseAdminLayout.js.map +1 -0
  68. package/dist/template/supabase/admin/supabaseAdminLoginLayout.d.ts +2 -0
  69. package/dist/template/supabase/admin/supabaseAdminLoginLayout.d.ts.map +1 -0
  70. package/dist/template/supabase/admin/supabaseAdminLoginLayout.js +114 -0
  71. package/dist/template/supabase/admin/supabaseAdminLoginLayout.js.map +1 -0
  72. package/dist/template/supabase/proxy/adminProxy.d.ts +2 -0
  73. package/dist/template/supabase/proxy/adminProxy.d.ts.map +1 -0
  74. package/dist/template/supabase/proxy/adminProxy.js +45 -0
  75. package/dist/template/supabase/proxy/adminProxy.js.map +1 -0
  76. package/dist/template/supabase/proxy/authAdminProxy.d.ts +2 -0
  77. package/dist/template/supabase/proxy/authAdminProxy.d.ts.map +1 -0
  78. package/dist/template/supabase/proxy/authAdminProxy.js +61 -0
  79. package/dist/template/supabase/proxy/authAdminProxy.js.map +1 -0
  80. package/dist/template/supabase/proxy/authProxy.d.ts +2 -0
  81. package/dist/template/supabase/proxy/authProxy.d.ts.map +1 -0
  82. package/dist/template/supabase/proxy/authProxy.js +49 -0
  83. package/dist/template/supabase/proxy/authProxy.js.map +1 -0
  84. package/dist/template/supabase/route/googleCallback.d.ts +2 -0
  85. package/dist/template/supabase/route/googleCallback.d.ts.map +1 -0
  86. package/dist/template/supabase/route/googleCallback.js +25 -0
  87. package/dist/template/supabase/route/googleCallback.js.map +1 -0
  88. package/dist/template/supabase/schemas/user.d.ts +2 -0
  89. package/dist/template/supabase/schemas/user.d.ts.map +1 -0
  90. package/dist/template/supabase/schemas/user.js +14 -0
  91. package/dist/template/supabase/schemas/user.js.map +1 -0
  92. package/dist/template/supabase/utilBase.d.ts +1 -1
  93. package/dist/template/supabase/utilBase.d.ts.map +1 -1
  94. package/dist/template/supabase/utilBase.js +2 -2
  95. package/dist/types/BaseExtensionCommands.d.ts +2 -1
  96. package/dist/types/BaseExtensionCommands.d.ts.map +1 -1
  97. package/dist/types/BaseExtensionCommands.js.map +1 -1
  98. package/package.json +1 -1
@@ -0,0 +1,15 @@
1
+ export const useLogoutHook = () => `import { CommonErrorType } from "@/generated/api/@types/data-contracts"
2
+ import { useMutation } from "@tanstack/react-query"
3
+ import axios, { AxiosError } from "axios"
4
+
5
+ export const useLogoutMutation = () => {
6
+ return useMutation<void, AxiosError<CommonErrorType>, void>({
7
+ mutationKey: ["AUTH_JWT_LOGOUT_CREATE"],
8
+ mutationFn: async () => {
9
+ const res = await axios.post("/api/auth/logout")
10
+ return res.data
11
+ },
12
+ })
13
+ }
14
+ `;
15
+ //# sourceMappingURL=useLogoutHook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLogoutHook.js","sourceRoot":"","sources":["../../../src/template/axios/useLogoutHook.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC;;;;;;;;;;;;;CAalC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const utilJwt: () => string;
2
+ //# sourceMappingURL=utilJwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utilJwt.d.ts","sourceRoot":"","sources":["../../../src/template/axios/utilJwt.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,cAkDnB,CAAA"}
@@ -0,0 +1,52 @@
1
+ export const utilJwt = () => `import { cookies } from "next/headers"
2
+
3
+ export const AUTH_ENDPOINTS = {
4
+ LOGIN: "/v1/user/login/", // TODO: Change to the actual login endpoint
5
+ REFRESH: "/v1/user/refresh/",
6
+ }
7
+
8
+ export const TOKEN_KEYS = {
9
+ ACCESS: "accessToken",
10
+ REFRESH: "refreshToken",
11
+ } as const
12
+
13
+ const cookieOptions = {
14
+ httpOnly: true,
15
+ secure: process.env.NODE_ENV === "production",
16
+ sameSite: process.env.NODE_ENV === "production" ? "lax" : "none",
17
+ path: "/",
18
+ } as const
19
+
20
+ export async function setTokens(accessToken: string, refreshToken?: string) {
21
+ const cookieStore = await cookies()
22
+
23
+ cookieStore.set(TOKEN_KEYS.ACCESS, accessToken, {
24
+ ...cookieOptions,
25
+ maxAge: 60 * 15, // 15min
26
+ })
27
+
28
+ if (refreshToken) {
29
+ cookieStore.set(TOKEN_KEYS.REFRESH, refreshToken, {
30
+ ...cookieOptions,
31
+ maxAge: 60 * 60 * 24 * 7, // 7days
32
+ })
33
+ }
34
+ }
35
+
36
+ export async function clearTokens() {
37
+ const cookieStore = await cookies()
38
+
39
+ cookieStore.delete(TOKEN_KEYS.ACCESS)
40
+ cookieStore.delete(TOKEN_KEYS.REFRESH)
41
+ }
42
+
43
+ export async function getTokens() {
44
+ const cookieStore = await cookies()
45
+
46
+ return {
47
+ accessToken: cookieStore.get(TOKEN_KEYS.ACCESS)?.value,
48
+ refreshToken: cookieStore.get(TOKEN_KEYS.REFRESH)?.value,
49
+ }
50
+ }
51
+ `;
52
+ //# sourceMappingURL=utilJwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utilJwt.js","sourceRoot":"","sources":["../../../src/template/axios/utilJwt.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkD5B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const supabaseAuthActions: (isNeedAuth: boolean) => string;
2
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/actions/auth.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,GAAI,YAAY,OAAO,WA6DtD,CAAA"}
@@ -0,0 +1,61 @@
1
+ export const supabaseAuthActions = (isNeedAuth) => `"use server"
2
+
3
+ ${!isNeedAuth ? `import { ROUTES } from "@/generated/path/routes"` : 'import { ENV } from "@/configs/env"'}
4
+ import { createClient } from "@/lib/supabase/server"
5
+ import { redirect } from "next/navigation"
6
+
7
+ export async function login(formData: FormData) {
8
+ const supabase = await createClient()
9
+ const email = formData.get("email") as string
10
+ const password = formData.get("password") as string
11
+
12
+ const { error } = await supabase.auth.signInWithPassword({
13
+ email,
14
+ password,
15
+ })
16
+
17
+ if (error) {
18
+ redirect(${isNeedAuth ? '"/login?message=login_failed"' : '"/"'})
19
+ }
20
+
21
+ redirect(${isNeedAuth ? '"/"' : "ROUTES.ADMIN"})
22
+ }
23
+
24
+ ${isNeedAuth
25
+ ? `export async function signup(formData: FormData) {
26
+ const supabase = await createClient()
27
+ const email = formData.get("email") as string
28
+ const password = formData.get("password") as string
29
+
30
+ const { error } = await supabase.auth.signUp({
31
+ email,
32
+ password,
33
+ })
34
+
35
+ if (error) {
36
+ redirect("/login?message=signup_failed")
37
+ }
38
+
39
+ redirect("/login?message=signup_success")
40
+ }
41
+
42
+ export async function signInWithGoogle() {
43
+ const supabase = await createClient()
44
+ const { data, error } = await supabase.auth.signInWithOAuth({
45
+ provider: "google",
46
+ options: {
47
+ redirectTo: \`\${ENV.DOMAIN}/api/auth/google/callback\`,
48
+ },
49
+ })
50
+
51
+ if (error) {
52
+ redirect("/login?message=signin_with_failed&provider=google")
53
+ }
54
+
55
+ if (data.url) {
56
+ redirect(data.url)
57
+ }
58
+ }`
59
+ : ""}
60
+ `;
61
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../../src/template/supabase/actions/auth.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,UAAmB,EAAE,EAAE,CAAC;;EAE1D,CAAC,UAAU,CAAC,CAAC,CAAC,kDAAkD,CAAC,CAAC,CAAC,qCAAqC;;;;;;;;;;;;;;;eAe3F,UAAU,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,KAAK;;;aAGtD,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc;;;EAI9C,UAAU;IACR,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCJ;IACE,CAAC,CAAC,EACN;CACC,CAAA"}
@@ -0,0 +1,3 @@
1
+ export declare const supabaseCrudService: (tableName: string) => string;
2
+ export declare const supabaseCrudActions: (tableName: string) => string;
3
+ //# sourceMappingURL=crud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/actions/crud.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,WAsCpD,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,WA8BpD,CAAA"}
@@ -0,0 +1,72 @@
1
+ import { capitalCase } from "change-case";
2
+ export const supabaseCrudService = (tableName) => `import "server-only"
3
+
4
+ import { createClient } from "@/lib/supabase/server"
5
+
6
+ const TABLE_NAME = "${tableName}"
7
+
8
+ export async function insert${capitalCase(tableName)}(title: string) {
9
+ const supabase = await createClient()
10
+ const { data, error } = await supabase
11
+ .from(TABLE_NAME)
12
+ .insert([{ title, is_completed: false }])
13
+ .select()
14
+ .single()
15
+
16
+ if (error) throw new Error(error.message)
17
+ return data
18
+ }
19
+
20
+ export async function modify${capitalCase(tableName)}(id: string, isCompleted: boolean) {
21
+ const supabase = await createClient()
22
+ const { data, error } = await supabase
23
+ .from(TABLE_NAME)
24
+ .update({ is_completed: isCompleted })
25
+ .eq("id", id)
26
+ .select()
27
+ .single()
28
+
29
+ if (error) throw new Error(error.message)
30
+ return data
31
+ }
32
+
33
+ export async function remove${capitalCase(tableName)}(id: string) {
34
+ const supabase = await createClient()
35
+ const { error } = await supabase.from(TABLE_NAME).delete().eq("id", id)
36
+
37
+ if (error) throw new Error(error.message)
38
+ return true
39
+ }
40
+ `;
41
+ export const supabaseCrudActions = (tableName) => `"use server"
42
+
43
+ import { insert${capitalCase(tableName)}, modify${capitalCase(tableName)}, remove${capitalCase(tableName)} } from "@/services/${tableName}.service"
44
+
45
+ export async function add${capitalCase(tableName)}Action(title: string) {
46
+ try {
47
+ const data = await insert${capitalCase(tableName)}(title)
48
+ return { success: true, data }
49
+ } catch (error: any) {
50
+ return { success: false, error: error.message }
51
+ }
52
+ }
53
+
54
+ export async function update${capitalCase(tableName)}Action(id: string, isCompleted: boolean) {
55
+ try {
56
+ const data = await modify${capitalCase(tableName)}(id, isCompleted)
57
+ return { success: true, data }
58
+ } catch (error: any) {
59
+ return { success: false, error: error.message }
60
+ }
61
+ }
62
+
63
+ export async function delete${capitalCase(tableName)}Action(id: string) {
64
+ try {
65
+ await remove${capitalCase(tableName)}(id)
66
+ return { success: true }
67
+ } catch (error: any) {
68
+ return { success: false, error: error.message }
69
+ }
70
+ }
71
+ `;
72
+ //# sourceMappingURL=crud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.js","sourceRoot":"","sources":["../../../../src/template/supabase/actions/crud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC;;;;sBAIpC,SAAS;;8BAED,WAAW,CAAC,SAAS,CAAC;;;;;;;;;;;;8BAYtB,WAAW,CAAC,SAAS,CAAC;;;;;;;;;;;;;8BAatB,WAAW,CAAC,SAAS,CAAC;;;;;;;CAOnD,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC;;iBAEzC,WAAW,CAAC,SAAS,CAAC,WAAW,WAAW,CAAC,SAAS,CAAC,WAAW,WAAW,CAAC,SAAS,CAAC,uBAAuB,SAAS;;2BAE9G,WAAW,CAAC,SAAS,CAAC;;+BAElB,WAAW,CAAC,SAAS,CAAC;;;;;;;8BAOvB,WAAW,CAAC,SAAS,CAAC;;+BAErB,WAAW,CAAC,SAAS,CAAC;;;;;;;8BAOvB,WAAW,CAAC,SAAS,CAAC;;kBAElC,WAAW,CAAC,SAAS,CAAC;;;;;;CAMvC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const supabaseUserActions: () => string;
2
+ //# sourceMappingURL=user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/actions/user.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,cAkC/B,CAAA"}
@@ -0,0 +1,36 @@
1
+ export const supabaseUserActions = () => `"use server"
2
+
3
+ import { createClient } from "@/lib/supabase/server"
4
+ import { SafeUserDefaultSchema, SafeUserDTO } from "@/schemas/user"
5
+ import { experimental_taintObjectReference as taintObjectReference } from "react"
6
+
7
+ export async function getUserAction(): Promise<SafeUserDTO> {
8
+ const supabase = await createClient()
9
+ const { data, error } = await supabase.auth.getUser()
10
+
11
+ if (error || !data.user) {
12
+ throw new Error("Not authenticated user")
13
+ }
14
+
15
+ taintObjectReference(
16
+ "Warning: Supabase original User object is not allowed to be directly returned to the client. Must pass through DTO.",
17
+ data.user,
18
+ )
19
+
20
+ if (data.user.user_metadata) {
21
+ taintObjectReference("Warning: user_metadata original object exposure risk", data.user.user_metadata)
22
+ }
23
+
24
+ const safeData = SafeUserDefaultSchema.parse({
25
+ id: data.user.id,
26
+ email: data.user.email,
27
+ phone: data.user.phone,
28
+ name: data.user.user_metadata?.full_name,
29
+ providers: data.user.app_metadata?.providers ?? ["email"],
30
+ avatarUrl: data.user.user_metadata?.avatar_url,
31
+ })
32
+
33
+ return safeData
34
+ }
35
+ `;
36
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../../../src/template/supabase/actions/user.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCxC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const supabaseAdminLayout = "\"use client\"\n\nexport default function AdminPage() {\n return <div>AdminPage</div>\n}\n";
2
+ //# sourceMappingURL=supabaseAdminLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabaseAdminLayout.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/admin/supabaseAdminLayout.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,gGAK/B,CAAA"}
@@ -0,0 +1,7 @@
1
+ export const supabaseAdminLayout = `"use client"
2
+
3
+ export default function AdminPage() {
4
+ return <div>AdminPage</div>
5
+ }
6
+ `;
7
+ //# sourceMappingURL=supabaseAdminLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabaseAdminLayout.js","sourceRoot":"","sources":["../../../../src/template/supabase/admin/supabaseAdminLayout.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;CAKlC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const supabaseAdminLoginLayout = "\"use client\"\n\nimport { login } from \"@/actions/auth.action\"\nimport { useState, useTransition } from \"react\"\n\nexport default function AdminLoginPage() {\n const [email, setEmail] = useState(\"\")\n const [password, setPassword] = useState(\"\")\n const [isPending, startTransition] = useTransition()\n const [error, setError] = useState<string | null>(null)\n\n const handleLogin = async (e: React.SubmitEvent<HTMLFormElement>) => {\n e.preventDefault()\n setError(null)\n\n const formData = new FormData()\n formData.set(\"email\", email)\n formData.set(\"password\", password)\n\n startTransition(async () => {\n await login(formData)\n })\n }\n\n return (\n <div className=\"flex justify-center items-center min-h-screen bg-linear-to-br from-black to-zinc-900\">\n <div className=\"rounded-2xl shadow-xl bg-zinc-900 p-8 w-full max-w-md border border-gray-700\">\n <h1 className=\"text-3xl font-bold mb-1 text-center text-white\">Login</h1>\n <p className=\"mb-6 text-zinc-500 text-center\">Login as admin</p>\n <form onSubmit={handleLogin} className=\"flex flex-col gap-4\">\n <div className=\"flex flex-col gap-1.5\">\n <label htmlFor=\"admin-email\" className=\"text-sm font-medium text-zinc-700\">\n Email\n </label>\n <input\n id=\"admin-email\"\n type=\"email\"\n value={email}\n autoComplete=\"off\"\n autoFocus\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Enter Email\"\n required\n disabled={isPending}\n className=\"border border-gray-700 rounded-lg px-4 py-2 transition focus:outline-none focus:ring-1 ring-gray-500 bg-zinc-900 placeholder-white text-white autofill:bg-zinc-900 autofill:text-white\"\n style={{\n WebkitBoxShadow: \"0 0 0 1000px #18181b inset\",\n boxShadow: \"0 0 0 1000px #18181b inset\",\n WebkitTextFillColor: \"#fff\",\n }}\n />\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <label htmlFor=\"admin-password\" className=\"text-sm font-medium text-zinc-700\">\n Password\n </label>\n <input\n id=\"admin-password\"\n type=\"password\"\n value={password}\n autoComplete=\"off\"\n onChange={(e) => setPassword(e.target.value)}\n placeholder=\"Enter Password\"\n required\n disabled={isPending}\n className=\"border border-gray-700 rounded-lg px-4 py-2 transition focus:outline-none focus:ring-1 ring-gray-500 bg-zinc-900 placeholder-white text-white\"\n style={{\n WebkitBoxShadow: \"0 0 0 1000px #18181b inset\",\n boxShadow: \"0 0 0 1000px #18181b inset\",\n WebkitTextFillColor: \"#fff\",\n }}\n />\n </div>\n {error && (\n <div className=\"text-red-500 text-sm mt-1 rounded bg-red-50 p-2 border border-red-100 text-center animate-pulse\">\n {error}\n </div>\n )}\n <button\n type=\"submit\"\n disabled={isPending}\n className=\"mt-2 rounded-lg bg-blue-600 hover:bg-blue-700 transition text-white font-semibold py-2 shadow text-lg disabled:opacity-60 disabled:cursor-not-allowed\"\n >\n {isPending ? (\n <span className=\"flex justify-center items-center gap-2\">\n <svg className=\"animate-spin h-5 w-5 text-white\" viewBox=\"0 0 24 24\">\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n fill=\"none\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8v4l3-3-3-3v4a8 8 0 000 16v-4l-3 3 3 3v-4a8 8 0 01-8-8z\"\n />\n </svg>\n Logging in...\n </span>\n ) : (\n \"Submit\"\n )}\n </button>\n </form>\n </div>\n </div>\n )\n}\n";
2
+ //# sourceMappingURL=supabaseAdminLoginLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabaseAdminLoginLayout.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/admin/supabaseAdminLoginLayout.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,85IAgHpC,CAAA"}
@@ -0,0 +1,114 @@
1
+ export const supabaseAdminLoginLayout = `"use client"
2
+
3
+ import { login } from "@/actions/auth.action"
4
+ import { useState, useTransition } from "react"
5
+
6
+ export default function AdminLoginPage() {
7
+ const [email, setEmail] = useState("")
8
+ const [password, setPassword] = useState("")
9
+ const [isPending, startTransition] = useTransition()
10
+ const [error, setError] = useState<string | null>(null)
11
+
12
+ const handleLogin = async (e: React.SubmitEvent<HTMLFormElement>) => {
13
+ e.preventDefault()
14
+ setError(null)
15
+
16
+ const formData = new FormData()
17
+ formData.set("email", email)
18
+ formData.set("password", password)
19
+
20
+ startTransition(async () => {
21
+ await login(formData)
22
+ })
23
+ }
24
+
25
+ return (
26
+ <div className="flex justify-center items-center min-h-screen bg-linear-to-br from-black to-zinc-900">
27
+ <div className="rounded-2xl shadow-xl bg-zinc-900 p-8 w-full max-w-md border border-gray-700">
28
+ <h1 className="text-3xl font-bold mb-1 text-center text-white">Login</h1>
29
+ <p className="mb-6 text-zinc-500 text-center">Login as admin</p>
30
+ <form onSubmit={handleLogin} className="flex flex-col gap-4">
31
+ <div className="flex flex-col gap-1.5">
32
+ <label htmlFor="admin-email" className="text-sm font-medium text-zinc-700">
33
+ Email
34
+ </label>
35
+ <input
36
+ id="admin-email"
37
+ type="email"
38
+ value={email}
39
+ autoComplete="off"
40
+ autoFocus
41
+ onChange={(e) => setEmail(e.target.value)}
42
+ placeholder="Enter Email"
43
+ required
44
+ disabled={isPending}
45
+ className="border border-gray-700 rounded-lg px-4 py-2 transition focus:outline-none focus:ring-1 ring-gray-500 bg-zinc-900 placeholder-white text-white autofill:bg-zinc-900 autofill:text-white"
46
+ style={{
47
+ WebkitBoxShadow: "0 0 0 1000px #18181b inset",
48
+ boxShadow: "0 0 0 1000px #18181b inset",
49
+ WebkitTextFillColor: "#fff",
50
+ }}
51
+ />
52
+ </div>
53
+ <div className="flex flex-col gap-1.5">
54
+ <label htmlFor="admin-password" className="text-sm font-medium text-zinc-700">
55
+ Password
56
+ </label>
57
+ <input
58
+ id="admin-password"
59
+ type="password"
60
+ value={password}
61
+ autoComplete="off"
62
+ onChange={(e) => setPassword(e.target.value)}
63
+ placeholder="Enter Password"
64
+ required
65
+ disabled={isPending}
66
+ className="border border-gray-700 rounded-lg px-4 py-2 transition focus:outline-none focus:ring-1 ring-gray-500 bg-zinc-900 placeholder-white text-white"
67
+ style={{
68
+ WebkitBoxShadow: "0 0 0 1000px #18181b inset",
69
+ boxShadow: "0 0 0 1000px #18181b inset",
70
+ WebkitTextFillColor: "#fff",
71
+ }}
72
+ />
73
+ </div>
74
+ {error && (
75
+ <div className="text-red-500 text-sm mt-1 rounded bg-red-50 p-2 border border-red-100 text-center animate-pulse">
76
+ {error}
77
+ </div>
78
+ )}
79
+ <button
80
+ type="submit"
81
+ disabled={isPending}
82
+ className="mt-2 rounded-lg bg-blue-600 hover:bg-blue-700 transition text-white font-semibold py-2 shadow text-lg disabled:opacity-60 disabled:cursor-not-allowed"
83
+ >
84
+ {isPending ? (
85
+ <span className="flex justify-center items-center gap-2">
86
+ <svg className="animate-spin h-5 w-5 text-white" viewBox="0 0 24 24">
87
+ <circle
88
+ className="opacity-25"
89
+ cx="12"
90
+ cy="12"
91
+ r="10"
92
+ stroke="currentColor"
93
+ strokeWidth="4"
94
+ fill="none"
95
+ />
96
+ <path
97
+ className="opacity-75"
98
+ fill="currentColor"
99
+ d="M4 12a8 8 0 018-8v4l3-3-3-3v4a8 8 0 000 16v-4l-3 3 3 3v-4a8 8 0 01-8-8z"
100
+ />
101
+ </svg>
102
+ Logging in...
103
+ </span>
104
+ ) : (
105
+ "Submit"
106
+ )}
107
+ </button>
108
+ </form>
109
+ </div>
110
+ </div>
111
+ )
112
+ }
113
+ `;
114
+ //# sourceMappingURL=supabaseAdminLoginLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabaseAdminLoginLayout.js","sourceRoot":"","sources":["../../../../src/template/supabase/admin/supabaseAdminLoginLayout.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgHvC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const adminProxy = "import { ENV } from \"@/configs/env\"\nimport { createServerClient } from \"@supabase/ssr\"\nimport { NextResponse, type NextRequest } from \"next/server\"\n\nexport async function proxy(request: NextRequest) {\n let supabaseResponse = NextResponse.next({ request })\n const { pathname } = request.nextUrl\n\n const isAdminRoute = pathname.startsWith(\"/admin\")\n\n if (isAdminRoute) {\n if (pathname.startsWith(\"/admin/login\")) {\n return supabaseResponse\n }\n\n const supabase = createServerClient(ENV.SUPABASE_URL!, ENV.SUPABASE_ANON_KEY!, {\n cookies: {\n getAll() {\n return request.cookies.getAll()\n },\n setAll(cookiesToSet) {\n cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value))\n supabaseResponse = NextResponse.next({ request })\n cookiesToSet.forEach(({ name, value, options }) => supabaseResponse.cookies.set(name, value, options))\n },\n },\n })\n\n const {\n data: { user },\n } = await supabase.auth.getUser()\n\n if (!user || user.id !== ENV.SUPABASE_ADMIN_UID) {\n return NextResponse.redirect(new URL(\"/\", request.url))\n }\n }\n\n return supabaseResponse\n}\n\nexport const config = {\n matcher: [\"/((?!_next/static|_next/image|favicon.ico|.*\\\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)\"],\n}\n";
2
+ //# sourceMappingURL=adminProxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adminProxy.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/proxy/adminProxy.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,u1CA2CtB,CAAA"}
@@ -0,0 +1,45 @@
1
+ export const adminProxy = `import { ENV } from "@/configs/env"
2
+ import { createServerClient } from "@supabase/ssr"
3
+ import { NextResponse, type NextRequest } from "next/server"
4
+
5
+ export async function proxy(request: NextRequest) {
6
+ let supabaseResponse = NextResponse.next({ request })
7
+ const { pathname } = request.nextUrl
8
+
9
+ const isAdminRoute = pathname.startsWith("/admin")
10
+
11
+ if (isAdminRoute) {
12
+ if (pathname.startsWith("/admin/login")) {
13
+ return supabaseResponse
14
+ }
15
+
16
+ const supabase = createServerClient(ENV.SUPABASE_URL!, ENV.SUPABASE_ANON_KEY!, {
17
+ cookies: {
18
+ getAll() {
19
+ return request.cookies.getAll()
20
+ },
21
+ setAll(cookiesToSet) {
22
+ cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value))
23
+ supabaseResponse = NextResponse.next({ request })
24
+ cookiesToSet.forEach(({ name, value, options }) => supabaseResponse.cookies.set(name, value, options))
25
+ },
26
+ },
27
+ })
28
+
29
+ const {
30
+ data: { user },
31
+ } = await supabase.auth.getUser()
32
+
33
+ if (!user || user.id !== ENV.SUPABASE_ADMIN_UID) {
34
+ return NextResponse.redirect(new URL("/", request.url))
35
+ }
36
+ }
37
+
38
+ return supabaseResponse
39
+ }
40
+
41
+ export const config = {
42
+ matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)"],
43
+ }
44
+ `;
45
+ //# sourceMappingURL=adminProxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adminProxy.js","sourceRoot":"","sources":["../../../../src/template/supabase/proxy/adminProxy.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CzB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const authAdminProxy: () => string;
2
+ //# sourceMappingURL=authAdminProxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authAdminProxy.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/proxy/authAdminProxy.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,cA2D1B,CAAA"}
@@ -0,0 +1,61 @@
1
+ export const authAdminProxy = () => `import { PROTECTED_ROUTES, ROUTES } from "@/generated/path/routes"
2
+ import { createServerClient } from "@supabase/ssr"
3
+ import { NextResponse, type NextRequest } from "next/server"
4
+ import { ENV } from "./configs/env"
5
+
6
+ export async function proxy(request: NextRequest) {
7
+ let supabaseResponse = NextResponse.next({
8
+ request: {
9
+ headers: request.headers,
10
+ },
11
+ })
12
+ const { pathname } = request.nextUrl
13
+
14
+ const supabase = createServerClient(
15
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
16
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
17
+ {
18
+ cookies: {
19
+ getAll() {
20
+ return request.cookies.getAll()
21
+ },
22
+ setAll(cookiesToSet) {
23
+ cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value))
24
+ supabaseResponse = NextResponse.next({
25
+ request,
26
+ })
27
+ cookiesToSet.forEach(({ name, value, options }) => supabaseResponse.cookies.set(name, value, options))
28
+ },
29
+ },
30
+ },
31
+ )
32
+
33
+ const {
34
+ data: { user },
35
+ } = await supabase.auth.getUser()
36
+
37
+ const isAdminRoute = pathname.startsWith("/admin")
38
+
39
+ if (isAdminRoute) {
40
+ if (!user) {
41
+ return NextResponse.redirect(new URL("/", request.url))
42
+ }
43
+ if (user.id !== ENV.SUPABASE_ADMIN_UID) {
44
+ return NextResponse.redirect(new URL("/", request.url))
45
+ }
46
+ }
47
+
48
+ const isProtectedRoute = PROTECTED_ROUTES.some((route) => pathname.startsWith(route))
49
+
50
+ if (isProtectedRoute && !user) {
51
+ return NextResponse.redirect(new URL(ROUTES.LOGIN, request.url))
52
+ }
53
+
54
+ return supabaseResponse
55
+ }
56
+
57
+ export const config = {
58
+ matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)"],
59
+ }
60
+ `;
61
+ //# sourceMappingURL=authAdminProxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authAdminProxy.js","sourceRoot":"","sources":["../../../../src/template/supabase/proxy/authAdminProxy.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DnC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const authProxy: () => string;
2
+ //# sourceMappingURL=authProxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authProxy.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/proxy/authProxy.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,cA+CrB,CAAA"}
@@ -0,0 +1,49 @@
1
+ export const authProxy = () => `import { PROTECTED_ROUTES, ROUTES } from "@/generated/path/routes"
2
+ import { createServerClient } from "@supabase/ssr"
3
+ import { NextResponse, type NextRequest } from "next/server"
4
+
5
+ export async function proxy(request: NextRequest) {
6
+ let supabaseResponse = NextResponse.next({
7
+ request: {
8
+ headers: request.headers,
9
+ },
10
+ })
11
+ const { pathname } = request.nextUrl
12
+
13
+ const supabase = createServerClient(
14
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
15
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
16
+ {
17
+ cookies: {
18
+ getAll() {
19
+ return request.cookies.getAll()
20
+ },
21
+ setAll(cookiesToSet) {
22
+ cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value))
23
+ supabaseResponse = NextResponse.next({
24
+ request,
25
+ })
26
+ cookiesToSet.forEach(({ name, value, options }) => supabaseResponse.cookies.set(name, value, options))
27
+ },
28
+ },
29
+ },
30
+ )
31
+
32
+ const {
33
+ data: { user },
34
+ } = await supabase.auth.getUser()
35
+
36
+ const isProtectedRoute = PROTECTED_ROUTES.some((route) => pathname.startsWith(route))
37
+
38
+ if (isProtectedRoute && !user) {
39
+ return NextResponse.redirect(new URL(ROUTES.LOGIN, request.url))
40
+ }
41
+
42
+ return supabaseResponse
43
+ }
44
+
45
+ export const config = {
46
+ matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)"],
47
+ }
48
+ `;
49
+ //# sourceMappingURL=authProxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authProxy.js","sourceRoot":"","sources":["../../../../src/template/supabase/proxy/authProxy.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+C9B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const googleCallback: () => string;
2
+ //# sourceMappingURL=googleCallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"googleCallback.d.ts","sourceRoot":"","sources":["../../../../src/template/supabase/route/googleCallback.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,cAuB1B,CAAA"}