create-warlock 5.30.0 → 5.32.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/CHANGELOG.md +43 -2
- package/README.md +89 -15
- package/esm/commands/create-new-app/index.mjs +20 -17
- package/esm/commands/create-new-app/index.mjs.map +1 -1
- package/esm/commands/create-new-app/types.d.mts +14 -8
- package/esm/commands/create-warlock-app/index.mjs +2 -1
- package/esm/commands/create-warlock-app/index.mjs.map +1 -1
- package/esm/features/agent-kit-targets.mjs +1 -1
- package/esm/features/agent-kit-targets.mjs.map +1 -1
- package/esm/features/database-drivers.mjs +1 -1
- package/esm/features/database-drivers.mjs.map +1 -1
- package/esm/features/features-map.mjs +12 -12
- package/esm/features/features-map.mjs.map +1 -1
- package/esm/flags/assert-package-manager.mjs +1 -1
- package/esm/flags/assert-package-manager.mjs.map +1 -1
- package/esm/flags/definitions.mjs +6 -1
- package/esm/flags/definitions.mjs.map +1 -1
- package/esm/flags/seed-from-flags.mjs +2 -1
- package/esm/flags/seed-from-flags.mjs.map +1 -1
- package/esm/helpers/app.mjs +63 -6
- package/esm/helpers/app.mjs.map +1 -1
- package/esm/helpers/exec.mjs +1 -1
- package/esm/helpers/exec.mjs.map +1 -1
- package/esm/helpers/insert-import.mjs +1 -1
- package/esm/helpers/insert-import.mjs.map +1 -1
- package/esm/helpers/package-manager.mjs.map +1 -1
- package/esm/helpers/paths.mjs.map +1 -1
- package/esm/helpers/pnpm-build-approvals.mjs.map +1 -1
- package/esm/helpers/project-builder-helpers.mjs.map +1 -1
- package/esm/helpers/warlock-versions.mjs +1 -1
- package/esm/helpers/warlock-versions.mjs.map +1 -1
- package/esm/index.d.mts +3 -5
- package/esm/index.mjs +6 -4
- package/esm/index.mjs.map +1 -1
- package/esm/prompts/ask-agent-targets.mjs.map +1 -1
- package/esm/prompts/ask-ai-features.mjs.map +1 -1
- package/esm/prompts/ask-features.mjs +53 -0
- package/esm/prompts/ask-features.mjs.map +1 -0
- package/esm/prompts/ask-lint-toolchain.mjs +21 -0
- package/esm/prompts/ask-lint-toolchain.mjs.map +1 -0
- package/esm/prompts/fit-to-terminal.mjs.map +1 -1
- package/esm/summary.mjs +12 -2
- package/esm/summary.mjs.map +1 -1
- package/esm/ui/banner.mjs +115 -47
- package/esm/ui/banner.mjs.map +1 -1
- package/esm/ui/report.mjs.map +1 -1
- package/esm/ui/spinners.mjs.map +1 -1
- package/esm/ui/wrap-text.mjs +55 -0
- package/esm/ui/wrap-text.mjs.map +1 -0
- package/llms-full.txt +110 -25
- package/package.json +3 -3
- package/skills/create-a-warlock-project/SKILL.md +110 -25
- package/templates/toolchains/oxc/.oxfmtrc.json +15 -0
- package/templates/toolchains/oxc/.oxlintrc.json +24 -0
- package/templates/toolchains/oxc/.vscode/extensions.json +3 -0
- package/templates/toolchains/oxc/.vscode/settings.json +35 -0
- package/templates/warlock/.prettierrc.json +3 -1
- package/templates/warlock/AGENTS.md +22 -2
- package/templates/warlock/README.md +18 -3
- package/templates/warlock/package.json +8 -6
- package/templates/warlock/skills/api-design/SKILL.md +2 -2
- package/templates/warlock/skills/code-standards/SKILL.md +18 -4
- package/templates/warlock/skills/security-baseline/SKILL.md +12 -1
- package/templates/warlock/skills/testing-strategy/SKILL.md +17 -0
- package/templates/warlock/src/app/auth/controllers/login.controller.ts +1 -1
- package/templates/warlock/src/app/auth/routes.ts +25 -5
- package/templates/warlock/src/app/auth/utils/types.ts +6 -1
- package/templates/warlock/src/app/contact/controllers/contact.controller.ts +1 -1
- package/templates/warlock/src/app/contact/routes.ts +1 -1
- package/templates/warlock/src/app/locale/controllers/locale.controller.ts +1 -1
- package/templates/warlock/src/app/locale/routes.ts +1 -1
- package/templates/warlock/src/app/posts/controllers/create-new-post.controller.ts +1 -1
- package/templates/warlock/src/app/posts/controllers/update-post.controller.ts +1 -1
- package/templates/warlock/src/app/posts/models/post/post.model.ts +1 -1
- package/templates/warlock/src/app/posts/schema/create-post.schema.ts +1 -1
- package/templates/warlock/src/app/posts/schema/update-post.schema.ts +1 -1
- package/templates/warlock/src/app/users/controllers/create-new-user.controller.ts +1 -1
- package/templates/warlock/src/app/users/controllers/list-users.controller.ts +10 -2
- package/templates/warlock/src/app/users/models/user/user.model.ts +1 -1
- package/templates/warlock/src/app/users/schema/create-user.schema.ts +1 -1
- package/templates/warlock/src/app/users/schema/list-users.schema.ts +15 -0
- package/templates/warlock/src/config/storage.ts +1 -1
- package/templates/warlock/src/config/tests.ts +8 -0
- package/templates/warlock/src/web/404.css +2 -6
- package/templates/warlock/src/web/assets.d.ts +2 -0
- package/templates/warlock/src/web/home/components/contact-form-controls.tsx +1 -1
- package/templates/warlock/src/web/home/components/hero-section.tsx +1 -0
- package/templates/warlock/tsconfig.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: code-standards
|
|
3
|
-
description: 'Project-level TypeScript code standards for apps built on Warlock.js — `interface` vs `type`, access modifiers, no `any`, no inline-duplicated unions, file-naming suffixes (`.contract.ts` / `.type.ts` / `.service.ts` / `.model.ts` / `.resource.ts` / `.spec.ts`), single-responsibility files, FP-factory + internal-class pattern, brace-every-control-block readability with blank lines between consecutive blocks, JSDoc on public surface and non-obvious logic, error classes extending framework errors, async/await + `Promise.all`, `undefined` over `null`, Vitest co-located, ESLint
|
|
3
|
+
description: 'Project-level TypeScript code standards for apps built on Warlock.js — `interface` vs `type`, access modifiers, no `any`, no inline-duplicated unions, file-naming suffixes (`.contract.ts` / `.type.ts` / `.service.ts` / `.model.ts` / `.resource.ts` / `.spec.ts`), single-responsibility files, FP-factory + internal-class pattern, brace-every-control-block readability with blank lines between consecutive blocks, JSDoc on public surface and non-obvious logic, error classes extending framework errors, async/await + `Promise.all`, `undefined` over `null`, Vitest co-located, ESLint/Prettier or Oxlint/Oxfmt. Triggers: writing/editing any `.ts` / `.tsx` file in this project; user asks "what are the code standards / style rules / conventions"; spawning a sub-agent that will write code; reviewing a diff for style issues; deciding `interface` vs `type`, when to use a class, where helpers live, how to name a file, or whether something needs JSDoc. Skip: pure-Markdown / JSON / YAML edits with no code change; runtime / behavior questions about a specific framework primitive — load the relevant `@warlock.js/<pkg>` skill instead; package-publishing or CI workflow questions.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Code Standards
|
|
@@ -551,7 +551,20 @@ A secret with no safe default (a payment key, a signing secret) should fail loud
|
|
|
551
551
|
|
|
552
552
|
## 11. Tooling
|
|
553
553
|
|
|
554
|
-
|
|
554
|
+
Use the project's selected toolchain: `eslint.config.js` + `.prettierrc.json`, or
|
|
555
|
+
`.oxlintrc.json` + `.oxfmtrc.json`. Run `npm run lint:check` and
|
|
556
|
+
`npm run format:check` for non-mutating checks. The Oxc scaffold enables the
|
|
557
|
+
Oxlint development health checker and retains TypeScript checking.
|
|
558
|
+
|
|
559
|
+
`npx warlock check` is the one verify command, in either toolchain: it
|
|
560
|
+
typechecks, runs the configured linter and the affected tests, and checks the
|
|
561
|
+
framework's conventions — `request.validated()` instead of `request.all()`,
|
|
562
|
+
guarded or `public: true` mutating routes, safe redirects, redacted logs,
|
|
563
|
+
bounded regexes on input, one controller per file, `type` (not `kind`) as a
|
|
564
|
+
union's discriminator. Each problem has a `WL` code and its fix
|
|
565
|
+
(`npx warlock explain <CODE>`).
|
|
566
|
+
|
|
567
|
+
For ESLint, consider enabling these additional rules:
|
|
555
568
|
|
|
556
569
|
- `@typescript-eslint/explicit-member-accessibility` — enforces § 1.2
|
|
557
570
|
- `@typescript-eslint/no-explicit-any` — enforces § 1.3
|
|
@@ -561,7 +574,7 @@ Ship a `.eslintrc` with at least these rules on:
|
|
|
561
574
|
- `curly` — enforces braces (§ 4.4)
|
|
562
575
|
- `no-console` — enforces § 8
|
|
563
576
|
|
|
564
|
-
Match the
|
|
577
|
+
Match the selected formatter config: `.prettierrc.json` or `.oxfmtrc.json`. Both use 100 columns, double quotes, semicolons and trailing commas. Prettier uses `@ianvs/prettier-plugin-sort-imports` (Babel, independent of TypeScript); it sorts built-ins, packages, aliases (`app/*`, `web/*`, `@shared/*`) and relatives in one block while preserving separate type imports. Oxfmt sorts imports through its own configuration. Both retain unused imports: ESLint reports them through `unused-imports/no-unused-imports`, and Oxlint through `no-unused-vars`. Run the formatter, then the linter.
|
|
565
578
|
|
|
566
579
|
---
|
|
567
580
|
|
|
@@ -583,7 +596,8 @@ Before any change ships:
|
|
|
583
596
|
- [ ] JSDoc on every public export and every multi-method class
|
|
584
597
|
- [ ] No `console.log`, `log.<level>(module, action, message, context)` signature used correctly
|
|
585
598
|
- [ ] Tests co-located, public-surface-driven
|
|
586
|
-
- [ ] `tsc --noEmit` and `
|
|
599
|
+
- [ ] `tsc --noEmit`, `npm run lint:check` and `npm run format:check` pass clean
|
|
600
|
+
- [ ] `npx warlock check` exits 0
|
|
587
601
|
|
|
588
602
|
**Non-negotiable defaults**
|
|
589
603
|
- [ ] Every untrusted input has a `@warlock.js/seal` schema at the boundary
|
|
@@ -243,7 +243,17 @@ The framework sets `Content-Type: application/json` for `response.success(...)`
|
|
|
243
243
|
|
|
244
244
|
### 5.3 Open redirects
|
|
245
245
|
|
|
246
|
-
If you implement a "redirect back to where the user came from" feature, validate the destination URL against a whitelist of internal paths. Never blindly follow a user-supplied URL.
|
|
246
|
+
If you implement a "redirect back to where the user came from" feature, validate the destination URL against a whitelist of internal paths. Never blindly follow a user-supplied URL. `safeRedirect()` from `@warlock.js/core` does it: same-origin paths and the origins you allow pass, anything else becomes the fallback.
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
import { safeRedirect, type RequestHandler } from "@warlock.js/core";
|
|
250
|
+
|
|
251
|
+
export const afterLoginController: RequestHandler = async ({ request, response }) => {
|
|
252
|
+
return response.redirect(safeRedirect(request.input("next"), { fallback: "/dashboard" }));
|
|
253
|
+
};
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
`npx warlock check` reports a redirect target taken from request input without it as `WL9007`.
|
|
247
257
|
|
|
248
258
|
### 5.4 CORS
|
|
249
259
|
|
|
@@ -350,3 +360,4 @@ Before merging a change that touches input, identity, secrets, or persistence:
|
|
|
350
360
|
- [ ] Logger redaction config covers any new sensitive field introduced
|
|
351
361
|
- [ ] File uploads cap size, sniff MIME, server-generate the stored filename
|
|
352
362
|
- [ ] Webhooks verify signature before any other work
|
|
363
|
+
- [ ] `npx warlock check` reports no `WL9005`–`WL9009` problem (unvalidated `request.all()`, unguarded mutating route, unsafe redirect, sensitive value in a log, unbounded regex on input)
|
|
@@ -170,6 +170,23 @@ vi.advanceTimersByTime(1000);
|
|
|
170
170
|
|
|
171
171
|
A test that sleeps is a test that's slow and flaky. Stub the clock.
|
|
172
172
|
|
|
173
|
+
Code that reads time through `clock.now()` / `clock.timestamp()` from `@warlock.js/core` gets a frozen clock in tests already (`clockFake.travel(ms)` moves it), with no fake timers involved.
|
|
174
|
+
|
|
175
|
+
### 4.5 Mail, queue, cache, storage — fakes are already on
|
|
176
|
+
|
|
177
|
+
In the test environment `setupTest()` installs fakes for mail, queue, cache, storage, clock and ids. Assert on them instead of mocking the drivers:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { mailFake, queueFake } from "@warlock.js/core/tests";
|
|
181
|
+
|
|
182
|
+
const order = { id: 42 }; // what the code under test placed
|
|
183
|
+
|
|
184
|
+
mailFake.assertSent({ to: "ada@example.test" });
|
|
185
|
+
queueFake.assertPushed("invoices.send", { orderId: order.id });
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Fixtures come from `defineFactory()` (deterministic, no faker). Opt out of a fake in `src/config/tests.ts` (`fakes: { cache: false }`). `warlock test --changed` runs only the tests a change affects. See the `test-fakes` and `model-factories` skills of `@warlock.js/core`.
|
|
189
|
+
|
|
173
190
|
---
|
|
174
191
|
|
|
175
192
|
## 5. AAA structure
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Request, type RequestHandler } from "@warlock.js/core";
|
|
2
|
-
import { type LoginSchema
|
|
2
|
+
import { loginSchema, type LoginSchema } from "../schema/login.schema";
|
|
3
3
|
import { loginService } from "../services/auth.service";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loginThrottleMiddleware,
|
|
3
|
+
tokenConsumeThrottleMiddleware,
|
|
4
|
+
tokenIssueThrottleMiddleware,
|
|
5
|
+
} from "@warlock.js/auth";
|
|
1
6
|
import { router } from "@warlock.js/core";
|
|
2
7
|
import { guarded } from "app/shared/utils/router";
|
|
3
8
|
import { forgotPasswordController } from "./controllers/forgot-password.controller";
|
|
@@ -8,12 +13,27 @@ import { meController } from "./controllers/me.controller";
|
|
|
8
13
|
import { refreshTokenController } from "./controllers/refresh-token.controller";
|
|
9
14
|
import { resetPasswordController } from "./controllers/reset-password.controller";
|
|
10
15
|
|
|
11
|
-
// Auth routes
|
|
16
|
+
// Auth routes. Sign-in and password recovery are open by design (`public: true`)
|
|
17
|
+
// and throttled; the rest need a signed-in user.
|
|
12
18
|
router.prefix("/auth", () => {
|
|
13
|
-
|
|
14
|
-
router.post("/
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
// Failed sign-ins lock the account and the IP after 5 tries in 15 minutes.
|
|
20
|
+
router.post("/login", loginController, {
|
|
21
|
+
public: true,
|
|
22
|
+
middleware: [loginThrottleMiddleware()],
|
|
23
|
+
});
|
|
24
|
+
router.post("/refresh-token", refreshTokenController, {
|
|
25
|
+
public: true,
|
|
26
|
+
rateLimit: { max: 30, timeWindow: 60_000 },
|
|
27
|
+
});
|
|
28
|
+
// Reset mails: 3 per hour per email and per IP. Reset attempts: 10 failures per 15 minutes.
|
|
29
|
+
router.post("/forgot-password", forgotPasswordController, {
|
|
30
|
+
public: true,
|
|
31
|
+
middleware: [tokenIssueThrottleMiddleware()],
|
|
32
|
+
});
|
|
33
|
+
router.post("/reset-password", resetPasswordController, {
|
|
34
|
+
public: true,
|
|
35
|
+
middleware: [tokenConsumeThrottleMiddleware()],
|
|
36
|
+
});
|
|
17
37
|
guarded(() => {
|
|
18
38
|
router.post("/logout", logoutController);
|
|
19
39
|
router.post("/logout-all", logoutAllController);
|
|
@@ -7,4 +7,9 @@ export type OTPChannel = "email" | "sms" | "whatsapp" | "push";
|
|
|
7
7
|
* Common OTP types
|
|
8
8
|
*/
|
|
9
9
|
export type OTPType =
|
|
10
|
-
"password-reset"
|
|
10
|
+
| "password-reset"
|
|
11
|
+
| "email-verification"
|
|
12
|
+
| "phone-verification"
|
|
13
|
+
| "two-factor"
|
|
14
|
+
// Applications may also define their own OTP purposes.
|
|
15
|
+
| string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { contactSchema } from "@shared/contact.schema";
|
|
2
1
|
import { type Request, type RequestHandler } from "@warlock.js/core";
|
|
3
2
|
import { type Infer } from "@warlock.js/seal";
|
|
3
|
+
import { contactSchema } from "@shared/contact.schema";
|
|
4
4
|
|
|
5
5
|
export type ContactSchema = Infer.Output<typeof contactSchema>;
|
|
6
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { localeSchema, type LocaleSchema } from "@shared/locale.schema";
|
|
2
1
|
import { type Request, type RequestHandler } from "@warlock.js/core";
|
|
2
|
+
import { localeSchema, type LocaleSchema } from "@shared/locale.schema";
|
|
3
3
|
|
|
4
4
|
/** POST /api/locale — persists the visitor's locale preference in a cookie. */
|
|
5
5
|
export const localeController: RequestHandler<Request<LocaleSchema>> = async ({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type GuardedRequestHandler } from "app/auth/requests/guarded.request";
|
|
2
2
|
import { Post } from "../models/post/post.model";
|
|
3
|
-
import { type CreatePostSchema
|
|
3
|
+
import { createPostSchema, type CreatePostSchema } from "../schema/create-post.schema";
|
|
4
4
|
|
|
5
5
|
export const createNewPostController: GuardedRequestHandler<CreatePostSchema> = async ({
|
|
6
6
|
request,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type GuardedRequestHandler } from "app/auth/requests/guarded.request";
|
|
2
2
|
import { Post } from "../models/post/post.model";
|
|
3
|
-
import { type UpdatePostSchema
|
|
3
|
+
import { updatePostSchema, type UpdatePostSchema } from "../schema/update-post.schema";
|
|
4
4
|
|
|
5
5
|
export const updatePostController: GuardedRequestHandler<UpdatePostSchema> = async ({
|
|
6
6
|
request,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Model, RegisterModel } from "@warlock.js/cascade";
|
|
2
2
|
import { useComputedSlug } from "@warlock.js/core";
|
|
3
|
-
import { type Infer
|
|
3
|
+
import { v, type Infer } from "@warlock.js/seal";
|
|
4
4
|
import { PostResource } from "app/posts/resources/post.resource";
|
|
5
5
|
|
|
6
6
|
export const postSchema = v.object({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type GuardedRequestHandler } from "app/auth/requests/guarded.request";
|
|
2
2
|
import { User } from "../models/user";
|
|
3
|
-
import { type CreateUserSchema
|
|
3
|
+
import { createUserSchema, type CreateUserSchema } from "../schema/create-user.schema";
|
|
4
4
|
|
|
5
5
|
export const createNewUserController: GuardedRequestHandler<CreateUserSchema> = async ({
|
|
6
6
|
request,
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { type GuardedRequestHandler } from "app/auth/requests/guarded.request";
|
|
2
2
|
import { usersRepository } from "../repositories/users.repository";
|
|
3
|
+
import { listUsersSchema, type ListUsersSchema } from "../schema/list-users.schema";
|
|
3
4
|
|
|
4
|
-
export const listUsersController: GuardedRequestHandler = async ({
|
|
5
|
-
|
|
5
|
+
export const listUsersController: GuardedRequestHandler<ListUsersSchema> = async ({
|
|
6
|
+
request,
|
|
7
|
+
response,
|
|
8
|
+
}) => {
|
|
9
|
+
const users = await usersRepository.listCached(request.validated());
|
|
6
10
|
|
|
7
11
|
return response.success({
|
|
8
12
|
users,
|
|
@@ -10,3 +14,7 @@ export const listUsersController: GuardedRequestHandler = async ({ request, resp
|
|
|
10
14
|
};
|
|
11
15
|
|
|
12
16
|
listUsersController.description = "List Users Controller";
|
|
17
|
+
|
|
18
|
+
listUsersController.validation = {
|
|
19
|
+
schema: listUsersSchema,
|
|
20
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Auth } from "@warlock.js/auth";
|
|
2
2
|
import { RegisterModel } from "@warlock.js/cascade";
|
|
3
3
|
import { useHashedPassword } from "@warlock.js/core";
|
|
4
|
-
import { type Infer
|
|
4
|
+
import { v, type Infer } from "@warlock.js/seal";
|
|
5
5
|
import { UserResource } from "app/users/resources/user.resource";
|
|
6
6
|
|
|
7
7
|
export const userSchema = v.object({
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { v, type Infer } from "@warlock.js/seal";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Query parameters the user list accepts. Unknown keys are stripped, so a
|
|
5
|
+
* smuggled operator (`?email[$ne]=`) never reaches the repository filters.
|
|
6
|
+
*/
|
|
7
|
+
export const listUsersSchema = v.object({
|
|
8
|
+
id: v.string().optional(),
|
|
9
|
+
name: v.string().max(100).optional(),
|
|
10
|
+
email: v.string().max(255).optional(),
|
|
11
|
+
page: v.numeric().min(1).optional(),
|
|
12
|
+
limit: v.numeric().min(1).max(100).optional(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type ListUsersSchema = Infer<typeof listUsersSchema>;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
const testsConfigurations = {
|
|
2
|
+
// In tests, mail, queue, cache, storage, clock and ids are faked by default:
|
|
3
|
+
// nothing is delivered, pushed to Redis or uploaded, and assertions such as
|
|
4
|
+
// mailFake.assertSent(...) work (see @warlock.js/core/tests).
|
|
2
5
|
//
|
|
6
|
+
// Opt out of every fake, keeping the real drivers:
|
|
7
|
+
// fakes: false,
|
|
8
|
+
//
|
|
9
|
+
// ...or of one, e.g. keep the configured cache driver:
|
|
10
|
+
// fakes: { cache: false },
|
|
3
11
|
};
|
|
4
12
|
|
|
5
13
|
export default testsConfigurations;
|
|
@@ -14,12 +14,8 @@
|
|
|
14
14
|
padding-inline: clamp(1.5rem, 7vw, 8rem);
|
|
15
15
|
background: #fafafa;
|
|
16
16
|
color: #18181b;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-apple-system,
|
|
20
|
-
BlinkMacSystemFont,
|
|
21
|
-
"Segoe UI",
|
|
22
|
-
sans-serif;
|
|
17
|
+
/* prettier-ignore */
|
|
18
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
23
19
|
}
|
|
24
20
|
|
|
25
21
|
.not-found__content {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useFormControl, useSubmitButton, type FormControlProps } from "@mongez/react-form";
|
|
2
2
|
import { type ReactNode } from "react";
|
|
3
3
|
|
|
4
4
|
type ContactFieldProps = FormControlProps & {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
+
"types": ["node"],
|
|
3
4
|
"target": "ESNext",
|
|
4
5
|
"lib": ["esnext", "dom"],
|
|
5
6
|
"allowJs": false,
|
|
@@ -7,7 +8,6 @@
|
|
|
7
8
|
"experimentalDecorators": false,
|
|
8
9
|
"esModuleInterop": true,
|
|
9
10
|
"allowSyntheticDefaultImports": true,
|
|
10
|
-
"downlevelIteration": true,
|
|
11
11
|
"strict": true,
|
|
12
12
|
"forceConsistentCasingInFileNames": true,
|
|
13
13
|
"noFallthroughCasesInSwitch": true,
|