@ingram-tech/nk-dev 0.2.0 → 0.2.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.
- package/README.md +1 -1
- package/guide.md +22 -1
- package/lib/init.js +18 -5
- package/package.json +1 -1
- package/tsconfig/base.json +8 -2
- package/tsconfig/nextjs.json +5 -0
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ bun install # the prepare script wires the git hook
|
|
|
34
34
|
| `.oxlintrc.json` | `extends` the shared oxlint rules (relative path — oxlint doesn't resolve package specifiers) |
|
|
35
35
|
| `.oxfmtrc.json` | a copy of the house format config (oxfmt has no `extends`) |
|
|
36
36
|
| `tsconfig.json` | `extends` `@ingram-tech/nk-dev/tsconfig/nextjs.json` + the site's own `include`/`paths` |
|
|
37
|
-
| `knip.json` | seed config
|
|
37
|
+
| `knip.json` | seed config (knip has no shareable config): gates on dependency/file hygiene, with unused exports/types off (noisy); ignores `@ingram-tech/nk-dev` |
|
|
38
38
|
| `.githooks/pre-commit` + `prepare` script | oxfmt format-on-commit |
|
|
39
39
|
| `CLAUDE.md` | the agent-guide `@import` |
|
|
40
40
|
|
package/guide.md
CHANGED
|
@@ -10,7 +10,10 @@ package. Stay a thin, standard Next.js app (bun · oxlint + oxfmt · strict TS).
|
|
|
10
10
|
(server: `verifyHuman` → silently drop bots; client: honeypot + signed token).
|
|
11
11
|
Never ship a form without it.
|
|
12
12
|
- **Send email only via `@ingram-tech/email`** — never add another mail client.
|
|
13
|
-
-
|
|
13
|
+
- **Never trust an external request body's shape — validate it with Zod, never
|
|
14
|
+
`as`-cast it.** Every `/api` route and webhook handler takes untrusted input;
|
|
15
|
+
an `as` cast is a lie the type-checker can't catch at runtime.
|
|
16
|
+
- Format/lint with **oxlint + oxfmt** via `nk` (`@ingram-tech/nk-dev`); don't
|
|
14
17
|
reintroduce ESLint, nor Prettier for code (`nk` uses Prettier only for SQL,
|
|
15
18
|
which oxfmt can't format). `nk` is optional convenience that only orchestrates
|
|
16
19
|
the standard tools — the site must stay buildable with plain `next build` / `next dev`.
|
|
@@ -48,6 +51,24 @@ if your frontend fetches it as an API, it's **`/api/…`**; if a provider, cron,
|
|
|
48
51
|
queue calls it, it's **`/internal/…`**. Never put OAuth callbacks or webhooks in
|
|
49
52
|
the UI/page tree, and never expose internal plumbing under `/api/`.
|
|
50
53
|
|
|
54
|
+
## Data & migrations
|
|
55
|
+
|
|
56
|
+
- **IDs are UUIDv7** — never UUIDv4 / `gen_random_uuid()` / `defaultRandom()` /
|
|
57
|
+
nanoids. UUIDv7 is time-ordered, so it keeps index locality instead of
|
|
58
|
+
fragmenting the B-tree on random inserts, and one uniform id format spans every
|
|
59
|
+
table. On Postgres ≥18 the column default is native `uuidv7()`
|
|
60
|
+
(`uuid("id").primaryKey().default(sql\`uuidv7()\`)`); set Better Auth
|
|
61
|
+
`advanced.database.generateId: false` so the DB — not Better Auth's JS nanoid —
|
|
62
|
+
mints ids. Ids that cross a **public contract** are skinned to `prefix_base58`
|
|
63
|
+
via `@ingram-tech/nk-db/id` (`createIdRegistry`) — never expose a raw UUID.
|
|
64
|
+
External ids you don't mint (Stripe `cus_`, OAuth) stay `text`.
|
|
65
|
+
- **Migrations don't auto-apply on deploy.** Code ships ahead of the prod schema
|
|
66
|
+
unless someone runs the migration against the target DB — a page that reads a
|
|
67
|
+
newly-added column 500s in prod until then. Apply migrations with
|
|
68
|
+
`@ingram-tech/nk-db`'s drift-aware runner (`@ingram-tech/nk-db/migrate`), which
|
|
69
|
+
surfaces the real Postgres error and pre-flights journal drift. Generate **and
|
|
70
|
+
apply** in the same step; don't leave "run the migration" as a handoff.
|
|
71
|
+
|
|
51
72
|
## What nextkit provides (reach for these)
|
|
52
73
|
|
|
53
74
|
- `@ingram-tech/email` — Cloudflare email: `sendEmail`, `fromAddress`
|
package/lib/init.js
CHANGED
|
@@ -50,14 +50,27 @@ const TSCONFIG = {
|
|
|
50
50
|
|
|
51
51
|
const VITEST_HINT = `import { mergeConfig } from "vitest/config";\\nimport { nextkitTestConfig } from "@ingram-tech/nk-dev/vitest";\\nexport default mergeConfig(nextkitTestConfig, {});`;
|
|
52
52
|
|
|
53
|
-
// knip has no shareable config, so each site carries its own.
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
53
|
+
// knip has no shareable config, so each site carries its own seed. The house
|
|
54
|
+
// policy: gate on dependency/file hygiene (unused files/deps, unlisted,
|
|
55
|
+
// unresolved) — its low-false-positive checks — and turn OFF unused
|
|
56
|
+
// exports/types, which are noisy and usually intentional API surface. Run an
|
|
57
|
+
// export-cleanup pass by flipping those back on when you want it.
|
|
58
|
+
//
|
|
59
|
+
// ignoreDependencies keeps @ingram-tech/nk-dev: knip doesn't follow the
|
|
60
|
+
// relative-path `extends` in .oxlintrc/tsconfig, so a site that doesn't call the
|
|
61
|
+
// `nk` bin gives knip no way to see nk-dev as used. Add `entry`/`ignore` as the
|
|
62
|
+
// project grows (e.g. `scripts/**`, a self-contained `pulumi/**`).
|
|
58
63
|
const KNIP = {
|
|
59
64
|
$schema: "https://unpkg.com/knip@6/schema.json",
|
|
60
65
|
ignoreDependencies: ["@ingram-tech/nk-dev"],
|
|
66
|
+
rules: {
|
|
67
|
+
exports: "off",
|
|
68
|
+
types: "off",
|
|
69
|
+
nsExports: "off",
|
|
70
|
+
nsTypes: "off",
|
|
71
|
+
enumMembers: "off",
|
|
72
|
+
duplicates: "off",
|
|
73
|
+
},
|
|
61
74
|
};
|
|
62
75
|
|
|
63
76
|
const PRE_COMMIT = `#!/bin/sh
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ingram-tech/nk-dev",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "The nextkit dev toolchain in one package: the `nk` CLI plus shared oxlint/oxfmt, TypeScript, and Vitest config, the format-on-commit hook, and the AI agent guide. `nk init` scaffolds a site to use it.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/tsconfig/base.json
CHANGED
|
@@ -4,8 +4,14 @@
|
|
|
4
4
|
"compilerOptions": {
|
|
5
5
|
"target": "ESNext",
|
|
6
6
|
"lib": ["esnext"],
|
|
7
|
-
"
|
|
8
|
-
|
|
7
|
+
// NodeNext so published packages ("type": "module") emit real Node ESM and
|
|
8
|
+
// tsc ENFORCES explicit .js extensions on relative imports (TS2835).
|
|
9
|
+
// "bundler" silently tolerates extensionless imports and emits them
|
|
10
|
+
// verbatim — invalid under Node ESM / Turbopack, a recurring break source.
|
|
11
|
+
// App consumers override back to "bundler" in nextjs.json (Next resolves
|
|
12
|
+
// modules itself and must not require .js extensions in app source).
|
|
13
|
+
"module": "nodenext",
|
|
14
|
+
"moduleResolution": "nodenext",
|
|
9
15
|
"allowJs": true,
|
|
10
16
|
"skipLibCheck": true,
|
|
11
17
|
"strict": true,
|
package/tsconfig/nextjs.json
CHANGED
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
"extends": "./base.json",
|
|
5
5
|
"compilerOptions": {
|
|
6
6
|
"lib": ["dom", "dom.iterable", "esnext"],
|
|
7
|
+
// Next apps let the bundler resolve modules — keep "bundler" here so app
|
|
8
|
+
// source needn't use .js import extensions. (base.json is "nodenext" for
|
|
9
|
+
// published packages; this override insulates apps from that.)
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
7
12
|
"jsx": "preserve",
|
|
8
13
|
"noEmit": true,
|
|
9
14
|
"declaration": false,
|