create-ej-app 17.0.0 → 19.0.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/README.md +89 -13
- package/cli.js +9 -25
- package/cli.ts +10 -34
- package/package.json +2 -3
- package/template/api/.env.example +3 -0
- package/template/api/.github/copilot-instructions.md +129 -0
- package/template/api/.vscode/extensions.json +9 -0
- package/template/api/.vscode/settings.json +3 -0
- package/template/api/Dockerfile +23 -0
- package/template/api/package.json +31 -0
- package/template/api/prettier.config.mjs +11 -0
- package/template/api/src/data-access/todo.ts +142 -0
- package/template/api/src/db/fields.ts +46 -0
- package/template/api/src/db/index.ts +21 -0
- package/template/api/src/db/schema.ts +19 -0
- package/template/api/src/env.ts +24 -0
- package/template/api/src/index.ts +39 -0
- package/template/api/src/lib/util.ts +55 -0
- package/template/api/src/routes/index.ts +18 -0
- package/template/api/src/routes/todo/index.ts +241 -0
- package/template/api/src/scripts/seed.ts +25 -0
- package/template/api/tsconfig.json +33 -0
- package/template/nextjs/.vscode/extensions.json +11 -0
- package/template/nextjs/.vscode/settings.json +3 -0
- package/template/{base → nextjs}/components.json +4 -1
- package/template/nextjs/drizzle.config.ts +10 -0
- package/template/{base → nextjs}/package.json +25 -27
- package/template/{base → nextjs}/src/app/(admin)/layout.tsx +2 -2
- package/template/nextjs/src/app/(app)/app/page.tsx +3 -0
- package/template/{base → nextjs}/src/app/(app)/layout.tsx +1 -1
- package/template/{base → nextjs}/src/app/(auth)/login/email-login-form.tsx +33 -34
- package/template/{base → nextjs}/src/app/globals.css +127 -15
- package/template/{base → nextjs}/src/app/layout.tsx +8 -4
- package/template/{base → nextjs}/src/app/not-found.tsx +1 -1
- package/template/nextjs/src/components/theme-provider.tsx +67 -0
- package/template/nextjs/src/components/ui/button.tsx +67 -0
- package/template/{base → nextjs}/src/components/ui/card.tsx +17 -6
- package/template/nextjs/src/components/ui/field.tsx +238 -0
- package/template/nextjs/src/components/ui/input.tsx +19 -0
- package/template/{base → nextjs}/src/components/ui/label.tsx +1 -1
- package/template/{base → nextjs}/src/components/ui/separator.tsx +2 -2
- package/template/{base → nextjs}/src/components/ui/sonner.tsx +5 -0
- package/template/nextjs/src/db/common.ts +31 -0
- package/template/{base → nextjs}/src/db/schema.ts +2 -28
- package/template/nextjs/src/hooks/use-mobile.ts +19 -0
- package/template/{base → nextjs}/src/lib/auth.ts +2 -6
- package/template/nextjs/src/lib/format-currency.ts +27 -0
- package/template/nextjs/src/lib/format-date.ts +12 -0
- package/template/nextjs/src/scripts/seed.ts +11 -0
- package/template/{base → nextjs}/src/scripts/test-mail.ts +11 -5
- package/template/{base → nextjs}/tsconfig.json +2 -0
- package/template/base/src/app/api/[[...slugs]]/route.ts +0 -25
- package/template/base/src/components/ui/button.tsx +0 -60
- package/template/base/src/components/ui/form.tsx +0 -167
- package/template/base/src/components/ui/input.tsx +0 -21
- package/template/base/src/lib/eden.ts +0 -7
- /package/template/{base → api}/drizzle.config.ts +0 -0
- /package/template/{base → nextjs}/.dockerignore +0 -0
- /package/template/{base → nextjs}/.env.example +0 -0
- /package/template/{base → nextjs}/Dockerfile +0 -0
- /package/template/{base → nextjs}/eslint.config.mjs +0 -0
- /package/template/{base → nextjs}/next.config.ts +0 -0
- /package/template/{base → nextjs}/postcss.config.mjs +0 -0
- /package/template/{base → nextjs}/prettier.config.mjs +0 -0
- /package/template/{base → nextjs}/public/placeholder.svg +0 -0
- /package/template/{base → nextjs}/src/app/(admin)/admin/page.tsx +0 -0
- /package/template/{base → nextjs}/src/app/(auth)/login/page.tsx +0 -0
- /package/template/{base → nextjs}/src/app/(auth)/login/social-login-buttons.tsx +0 -0
- /package/template/{base → nextjs}/src/app/(marketing)/layout.tsx +0 -0
- /package/template/{base → nextjs}/src/app/(marketing)/page.tsx +0 -0
- /package/template/{base → nextjs}/src/app/(marketing)/privacy/page.tsx +0 -0
- /package/template/{base → nextjs}/src/app/(marketing)/terms/page.tsx +0 -0
- /package/template/{base → nextjs}/src/app/api/auth/[...all]/route.ts +0 -0
- /package/template/{base → nextjs}/src/app/favicon.ico +0 -0
- /package/template/{base → nextjs}/src/components/loader.tsx +0 -0
- /package/template/{base → nextjs}/src/components/react-query-provider.tsx +0 -0
- /package/template/{base → nextjs}/src/components/screen-size.tsx +0 -0
- /package/template/{base → nextjs}/src/components/site-footer.tsx +0 -0
- /package/template/{base → nextjs}/src/components/theme-toggle.tsx +0 -0
- /package/template/{base → nextjs}/src/db/index.ts +0 -0
- /package/template/{base → nextjs}/src/emails/components/email-layout.tsx +0 -0
- /package/template/{base → nextjs}/src/emails/magic-link.tsx +0 -0
- /package/template/{base → nextjs}/src/emails/test.tsx +0 -0
- /package/template/{base → nextjs}/src/emails/welcome.tsx +0 -0
- /package/template/{base → nextjs}/src/env.ts +0 -0
- /package/template/{base → nextjs}/src/instrumentation.ts +0 -0
- /package/template/{base → nextjs}/src/lib/auth-client.ts +0 -0
- /package/template/{base → nextjs}/src/lib/cn.ts +0 -0
- /package/template/{base → nextjs}/src/lib/delay.ts +0 -0
- /package/template/{base → nextjs}/src/lib/email-service.ts +0 -0
- /package/template/{base → nextjs}/src/lib/nodemailer.ts +0 -0
- /package/template/{base → nextjs}/src/lib/otel.ts +0 -0
- /package/template/{base → nextjs}/src/lib/safe-action-client.ts +0 -0
- /package/template/{base → nextjs}/src/lib/safe-action.ts +0 -0
- /package/template/{base → nextjs}/src/lib/siteConfig.ts +0 -0
- /package/template/{base → nextjs}/src/lib/toast-message.ts +0 -0
- /package/template/{base → nextjs}/terraform/artifact-registry.tf +0 -0
- /package/template/{base → nextjs}/terraform/backend-service.tf +0 -0
- /package/template/{base → nextjs}/terraform/cleanup.sh +0 -0
- /package/template/{base → nextjs}/terraform/cloudbuild.tf +0 -0
- /package/template/{base → nextjs}/terraform/cloudrun.tf +0 -0
- /package/template/{base → nextjs}/terraform/database.tf +0 -0
- /package/template/{base → nextjs}/terraform/forwarding-rule.tf +0 -0
- /package/template/{base → nextjs}/terraform/ip-address.tf +0 -0
- /package/template/{base → nextjs}/terraform/network-endpoint-group.tf +0 -0
- /package/template/{base → nextjs}/terraform/network.tf +0 -0
- /package/template/{base → nextjs}/terraform/pre.sh +0 -0
- /package/template/{base → nextjs}/terraform/providers.tf +0 -0
- /package/template/{base → nextjs}/terraform/secret.txt +0 -0
- /package/template/{base → nextjs}/terraform/setup.sh +0 -0
- /package/template/{base → nextjs}/terraform/ssl-certs.tf +0 -0
- /package/template/{base → nextjs}/terraform/target-https-proxy copy.tf +0 -0
- /package/template/{base → nextjs}/terraform/target-https-proxy.tf +0 -0
- /package/template/{base → nextjs}/terraform/terraform.tfvars +0 -0
- /package/template/{base → nextjs}/terraform/url-map.tf +0 -0
- /package/template/{base → nextjs}/terraform/variables.tf +0 -0
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import * as LabelPrimitive from '@radix-ui/react-label'
|
|
4
|
-
import { Slot } from '@radix-ui/react-slot'
|
|
5
|
-
import * as React from 'react'
|
|
6
|
-
import {
|
|
7
|
-
Controller,
|
|
8
|
-
FormProvider,
|
|
9
|
-
useFormContext,
|
|
10
|
-
useFormState,
|
|
11
|
-
type ControllerProps,
|
|
12
|
-
type FieldPath,
|
|
13
|
-
type FieldValues
|
|
14
|
-
} from 'react-hook-form'
|
|
15
|
-
|
|
16
|
-
import { Label } from '~/components/ui/label'
|
|
17
|
-
import { cn } from '~/lib/cn'
|
|
18
|
-
|
|
19
|
-
const Form = FormProvider
|
|
20
|
-
|
|
21
|
-
type FormFieldContextValue<
|
|
22
|
-
TFieldValues extends FieldValues = FieldValues,
|
|
23
|
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
|
24
|
-
> = {
|
|
25
|
-
name: TName
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const FormFieldContext = React.createContext<FormFieldContextValue>(
|
|
29
|
-
{} as FormFieldContextValue
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
const FormField = <
|
|
33
|
-
TFieldValues extends FieldValues = FieldValues,
|
|
34
|
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
|
35
|
-
>({
|
|
36
|
-
...props
|
|
37
|
-
}: ControllerProps<TFieldValues, TName>) => {
|
|
38
|
-
return (
|
|
39
|
-
<FormFieldContext.Provider value={{ name: props.name }}>
|
|
40
|
-
<Controller {...props} />
|
|
41
|
-
</FormFieldContext.Provider>
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const useFormField = () => {
|
|
46
|
-
const fieldContext = React.useContext(FormFieldContext)
|
|
47
|
-
const itemContext = React.useContext(FormItemContext)
|
|
48
|
-
const { getFieldState } = useFormContext()
|
|
49
|
-
const formState = useFormState({ name: fieldContext.name })
|
|
50
|
-
const fieldState = getFieldState(fieldContext.name, formState)
|
|
51
|
-
|
|
52
|
-
if (!fieldContext) {
|
|
53
|
-
throw new Error('useFormField should be used within <FormField>')
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const { id } = itemContext
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
id,
|
|
60
|
-
name: fieldContext.name,
|
|
61
|
-
formItemId: `${id}-form-item`,
|
|
62
|
-
formDescriptionId: `${id}-form-item-description`,
|
|
63
|
-
formMessageId: `${id}-form-item-message`,
|
|
64
|
-
...fieldState
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type FormItemContextValue = {
|
|
69
|
-
id: string
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const FormItemContext = React.createContext<FormItemContextValue>(
|
|
73
|
-
{} as FormItemContextValue
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
function FormItem({ className, ...props }: React.ComponentProps<'div'>) {
|
|
77
|
-
const id = React.useId()
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<FormItemContext.Provider value={{ id }}>
|
|
81
|
-
<div
|
|
82
|
-
data-slot="form-item"
|
|
83
|
-
className={cn('grid gap-2', className)}
|
|
84
|
-
{...props}
|
|
85
|
-
/>
|
|
86
|
-
</FormItemContext.Provider>
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function FormLabel({
|
|
91
|
-
className,
|
|
92
|
-
...props
|
|
93
|
-
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
|
94
|
-
const { error, formItemId } = useFormField()
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<Label
|
|
98
|
-
data-slot="form-label"
|
|
99
|
-
data-error={!!error}
|
|
100
|
-
className={cn('data-[error=true]:text-destructive', className)}
|
|
101
|
-
htmlFor={formItemId}
|
|
102
|
-
{...props}
|
|
103
|
-
/>
|
|
104
|
-
)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
|
|
108
|
-
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<Slot
|
|
112
|
-
data-slot="form-control"
|
|
113
|
-
id={formItemId}
|
|
114
|
-
aria-describedby={
|
|
115
|
-
!error
|
|
116
|
-
? `${formDescriptionId}`
|
|
117
|
-
: `${formDescriptionId} ${formMessageId}`
|
|
118
|
-
}
|
|
119
|
-
aria-invalid={!!error}
|
|
120
|
-
{...props}
|
|
121
|
-
/>
|
|
122
|
-
)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function FormDescription({ className, ...props }: React.ComponentProps<'p'>) {
|
|
126
|
-
const { formDescriptionId } = useFormField()
|
|
127
|
-
|
|
128
|
-
return (
|
|
129
|
-
<p
|
|
130
|
-
data-slot="form-description"
|
|
131
|
-
id={formDescriptionId}
|
|
132
|
-
className={cn('text-muted-foreground text-sm', className)}
|
|
133
|
-
{...props}
|
|
134
|
-
/>
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function FormMessage({ className, ...props }: React.ComponentProps<'p'>) {
|
|
139
|
-
const { error, formMessageId } = useFormField()
|
|
140
|
-
const body = error ? String(error?.message ?? '') : props.children
|
|
141
|
-
|
|
142
|
-
if (!body) {
|
|
143
|
-
return null
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return (
|
|
147
|
-
<p
|
|
148
|
-
data-slot="form-message"
|
|
149
|
-
id={formMessageId}
|
|
150
|
-
className={cn('text-destructive text-sm', className)}
|
|
151
|
-
{...props}
|
|
152
|
-
>
|
|
153
|
-
{body}
|
|
154
|
-
</p>
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export {
|
|
159
|
-
Form,
|
|
160
|
-
FormControl,
|
|
161
|
-
FormDescription,
|
|
162
|
-
FormField,
|
|
163
|
-
FormItem,
|
|
164
|
-
FormLabel,
|
|
165
|
-
FormMessage,
|
|
166
|
-
useFormField
|
|
167
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
|
|
3
|
-
import { cn } from '~/lib/cn'
|
|
4
|
-
|
|
5
|
-
function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
|
|
6
|
-
return (
|
|
7
|
-
<input
|
|
8
|
-
type={type}
|
|
9
|
-
data-slot="input"
|
|
10
|
-
className={cn(
|
|
11
|
-
'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
|
12
|
-
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
|
13
|
-
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
|
14
|
-
className
|
|
15
|
-
)}
|
|
16
|
-
{...props}
|
|
17
|
-
/>
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export { Input }
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|