@thinhnguyencth1204/nextcli 0.7.0 → 0.8.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 +12 -2
- package/dist/cli.js +3 -3
- package/package.json +5 -3
- package/templates/features/supabase/src/lib/supabase/rich-text-image-sync.ts +28 -0
- package/templates/next-base/PROJECT_STRUCTURE.md +29 -18
- package/templates/next-base/bun.lock +59 -414
- package/templates/next-base/next-env.d.ts +1 -1
- package/templates/next-base/package.json +5 -0
- package/templates/next-base/src/app/blog-demo/page.tsx +9 -0
- package/templates/next-base/src/app/globals.css +57 -0
- package/templates/next-base/src/components/rich-text/adapters/textarea-field.tsx +50 -0
- package/templates/next-base/src/components/rich-text/client-only.tsx +23 -0
- package/templates/next-base/src/components/rich-text/editor-field.tsx +62 -0
- package/templates/next-base/src/components/rich-text/examples/blog-rich-text-demo.tsx +218 -0
- package/templates/next-base/src/components/rich-text/index.ts +11 -0
- package/templates/next-base/src/components/rich-text/lexical/extension.ts +37 -0
- package/templates/next-base/src/components/rich-text/lexical/nodes/image-node.tsx +187 -0
- package/templates/next-base/src/components/rich-text/lexical/plugins/image-plugin.tsx +40 -0
- package/templates/next-base/src/components/rich-text/lexical/plugins/initial-state-plugin.tsx +26 -0
- package/templates/next-base/src/components/rich-text/lexical/plugins/on-change-plugin.tsx +26 -0
- package/templates/next-base/src/components/rich-text/lexical/plugins/toolbar-plugin.tsx +190 -0
- package/templates/next-base/src/components/rich-text/lexical/rich-text-editor.tsx +121 -0
- package/templates/next-base/src/components/rich-text/lexical/theme.ts +18 -0
- package/templates/next-base/src/components/rich-text/rich-text-renderer.tsx +72 -0
- package/templates/next-base/src/components/rich-text/types.ts +60 -0
- package/templates/next-base/src/hooks/index.ts +1 -1
- package/templates/next-base/src/lib/rich-text/default-image-removal.ts +10 -0
- package/templates/next-base/src/lib/rich-text/image-urls.ts +41 -0
- package/templates/next-base/src/lib/rich-text/index.ts +12 -0
- package/templates/next-base/src/lib/rich-text/supabase-url.ts +67 -0
- package/templates/next-base/src/lib/rich-text/sync-removed-images.ts +48 -0
- package/templates/next-base/src/types/index.ts +0 -2
- package/templates/next-base/tsconfig.tsbuildinfo +1 -0
package/README.md
CHANGED
|
@@ -32,9 +32,18 @@ This command is fully interactive:
|
|
|
32
32
|
- normalizes project directory name into a safe project slug for generated `package.json` and env placeholders
|
|
33
33
|
- ships `SETUP.md` and `PROJECT_STRUCTURE.md` in the generated project root
|
|
34
34
|
|
|
35
|
-
**Default output is minimal:** Next.js shell, branding, theme,
|
|
35
|
+
**Default output is minimal:** Next.js shell, branding, theme, UI primitives, and Lexical rich text adapters only. Database, auth, dashboard, and other stacks are added only when selected.
|
|
36
36
|
|
|
37
|
-
##
|
|
37
|
+
## Rich text (base)
|
|
38
|
+
|
|
39
|
+
All generated projects include Lexical rich text building blocks:
|
|
40
|
+
|
|
41
|
+
- `EditorField` — swappable `textarea` or `lexical` adapter for forms
|
|
42
|
+
- `RichTextRenderer` — read-only playback of Lexical JSON from API data
|
|
43
|
+
- Toolbar: bold/italic/underline, emoji picker, image URL insertion
|
|
44
|
+
- Demo page: `/blog-demo`
|
|
45
|
+
|
|
46
|
+
Lexical content is stored as JSON (`SerializedEditorState`). With the `supabase` module, removed Supabase-managed image URLs trigger storage cleanup via `syncRemovedSupabaseRichTextImages`.
|
|
38
47
|
|
|
39
48
|
Available during `create` and `add module`:
|
|
40
49
|
|
|
@@ -174,6 +183,7 @@ Optional flags:
|
|
|
174
183
|
- shadcn-style shared UI folder (base)
|
|
175
184
|
- Zod validation (base)
|
|
176
185
|
- Sonner notifications (base)
|
|
186
|
+
- Lexical rich text editor + renderer (base)
|
|
177
187
|
- Optional: chat, supabase-realtime, seo, email
|
|
178
188
|
|
|
179
189
|
## Template structure
|
package/dist/cli.js
CHANGED
|
@@ -811,7 +811,7 @@ import { readdir as readdir3, readFile as readFile6, writeFile as writeFile6 } f
|
|
|
811
811
|
import path7 from "path";
|
|
812
812
|
import { readdir as readdir2, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
813
813
|
var defaultManifest = {
|
|
814
|
-
cli: "0.
|
|
814
|
+
cli: "0.8.0",
|
|
815
815
|
defaultLocale: "vi",
|
|
816
816
|
locales: [],
|
|
817
817
|
namespaces: [],
|
|
@@ -2113,7 +2113,7 @@ function registerAddCommand(program2) {
|
|
|
2113
2113
|
// src/commands/create.ts
|
|
2114
2114
|
import { spawn as spawn2 } from "child_process";
|
|
2115
2115
|
import path11 from "path";
|
|
2116
|
-
var CLI_VERSION = "0.
|
|
2116
|
+
var CLI_VERSION = "0.8.0";
|
|
2117
2117
|
async function runInstall(packageManager, cwd) {
|
|
2118
2118
|
const installArgsMap = {
|
|
2119
2119
|
npm: ["install"],
|
|
@@ -2494,7 +2494,7 @@ var NexTCLICommand = class _NexTCLICommand extends Command {
|
|
|
2494
2494
|
|
|
2495
2495
|
// src/cli.ts
|
|
2496
2496
|
var program = new NexTCLICommand();
|
|
2497
|
-
program.name("nextcli").description("Scaffold outsource-ready Next.js projects").version("0.
|
|
2497
|
+
program.name("nextcli").description("Scaffold outsource-ready Next.js projects").version("0.8.0");
|
|
2498
2498
|
registerCreateCommand(program);
|
|
2499
2499
|
registerAddCommand(program);
|
|
2500
2500
|
registerMigrateCommand(program);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thinhnguyencth1204/nextcli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "CLI scaffolder for outsourced Next.js projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
"build": "tsup",
|
|
16
16
|
"dev": "tsup --watch",
|
|
17
17
|
"typecheck": "tsc --noEmit",
|
|
18
|
-
"test": "bun test
|
|
19
|
-
"test:add-feature": "bun run build && bun test
|
|
18
|
+
"test": "bun test tests",
|
|
19
|
+
"test:add-feature": "bun run build && bun test tests/core",
|
|
20
|
+
"test:rich-text": "bun test tests/templates/next-base",
|
|
20
21
|
"smoke": "node dist/cli.js --help",
|
|
21
22
|
"smoke:full": "bun run build && bun run test && bun run scripts/pre-publish-smoke.ts",
|
|
22
23
|
"prepublishOnly": "npm run build"
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/node": "^22.15.29",
|
|
44
|
+
"lexical": "^0.45.0",
|
|
43
45
|
"tsup": "^8.1.0",
|
|
44
46
|
"typescript": "^5.5.4"
|
|
45
47
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { removeResource } from "@/lib/supabase/storage";
|
|
2
|
+
import {
|
|
3
|
+
isSupabaseManagedImageUrl,
|
|
4
|
+
syncRemovedRichTextImages,
|
|
5
|
+
type RemoveManagedImageFn,
|
|
6
|
+
} from "@/lib/rich-text";
|
|
7
|
+
import type { SerializedEditorState } from "lexical";
|
|
8
|
+
|
|
9
|
+
export const removeSupabaseManagedImage: RemoveManagedImageFn = async (
|
|
10
|
+
_url,
|
|
11
|
+
ref,
|
|
12
|
+
) => {
|
|
13
|
+
await removeResource(ref.path, ref.bucket);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Deletes Supabase storage objects for images removed from rich text content.
|
|
18
|
+
* Only URLs belonging to this project's configured Supabase bucket are removed.
|
|
19
|
+
*/
|
|
20
|
+
export async function syncRemovedSupabaseRichTextImages(
|
|
21
|
+
previous: SerializedEditorState | null | undefined,
|
|
22
|
+
next: SerializedEditorState | null | undefined,
|
|
23
|
+
) {
|
|
24
|
+
return syncRemovedRichTextImages(previous, next, {
|
|
25
|
+
isManagedUrl: isSupabaseManagedImageUrl,
|
|
26
|
+
removeManagedImage: removeSupabaseManagedImage,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -17,6 +17,7 @@ Generated by NexTCLI. Folders marked **(module)** appear only when that add-on i
|
|
|
17
17
|
| ------------- | --------------------------------------- |
|
|
18
18
|
| `layout.tsx` | Root layout, metadata from `branding` |
|
|
19
19
|
| `page.tsx` | Welcome landing page |
|
|
20
|
+
| `blog-demo/` | Rich text create/edit/read demo |
|
|
20
21
|
| `globals.css` | Design tokens (`nextcli:theme` markers) |
|
|
21
22
|
|
|
22
23
|
## `src/config/`
|
|
@@ -27,27 +28,37 @@ Generated by NexTCLI. Folders marked **(module)** appear only when that add-on i
|
|
|
27
28
|
|
|
28
29
|
## `src/components/`
|
|
29
30
|
|
|
30
|
-
| Path | Purpose
|
|
31
|
-
| ------------------- |
|
|
32
|
-
| `branding/logo.tsx` | Logo + project name
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
31
|
+
| Path | Purpose |
|
|
32
|
+
| ------------------- | --------------------------------------- |
|
|
33
|
+
| `branding/logo.tsx` | Logo + project name |
|
|
34
|
+
| `rich-text/` | Lexical editor adapters, renderer, demo |
|
|
35
|
+
| `ui/` | shadcn-style primitives |
|
|
36
|
+
| `providers/` | Theme provider |
|
|
37
|
+
|
|
38
|
+
## `src/lib/rich-text/` (base)
|
|
39
|
+
|
|
40
|
+
| Path | Purpose |
|
|
41
|
+
| -------------------------- | ---------------------------------------------------- |
|
|
42
|
+
| `image-urls.ts` | Extract image URLs from Lexical JSON |
|
|
43
|
+
| `supabase-url.ts` | Map Supabase public URLs to storage paths |
|
|
44
|
+
| `sync-removed-images.ts` | Lifecycle helper for removed images |
|
|
45
|
+
| `default-image-removal.ts` | No-op remover (swap when `supabase` module is added) |
|
|
35
46
|
|
|
36
47
|
## Optional modules (via `nextcli add module`)
|
|
37
48
|
|
|
38
|
-
| Module | Adds
|
|
39
|
-
| ------------------- |
|
|
40
|
-
| `database` | Prisma schema, client, `DATABASE_URL`, db scripts
|
|
41
|
-
| `supabase` | Supabase browser client + Storage helpers
|
|
42
|
-
| `auth` | Better Auth, sign-in pages, user APIs, bootstrap admin
|
|
43
|
-
| `api` | Axios client, API envelope helpers, React Query provider
|
|
44
|
-
| `i18n` | next-intl config, messages, locale switcher
|
|
45
|
-
| `dashboard` | Protected dashboard shell, sidebar, data-table UI
|
|
46
|
-
| `example` | Starter CRUD demo feature + `Example` Prisma model
|
|
47
|
-
| `chat` | Chat routes, hooks, Prisma chat models (+ auto deps)
|
|
48
|
-
| `supabase-realtime` | Realtime channel helpers (+ auto `supabase`)
|
|
49
|
-
| `seo` | robots/sitemap/JSON-LD helpers
|
|
50
|
-
| `email` | `src/lib/email/*`, `src/emails/*` (provider: SMTP or Resend)
|
|
49
|
+
| Module | Adds |
|
|
50
|
+
| ------------------- | --------------------------------------------------------------------- |
|
|
51
|
+
| `database` | Prisma schema, client, `DATABASE_URL`, db scripts |
|
|
52
|
+
| `supabase` | Supabase browser client + Storage helpers + `rich-text-image-sync.ts` |
|
|
53
|
+
| `auth` | Better Auth, sign-in pages, user APIs, bootstrap admin |
|
|
54
|
+
| `api` | Axios client, API envelope helpers, React Query provider |
|
|
55
|
+
| `i18n` | next-intl config, messages, locale switcher |
|
|
56
|
+
| `dashboard` | Protected dashboard shell, sidebar, data-table UI |
|
|
57
|
+
| `example` | Starter CRUD demo feature + `Example` Prisma model |
|
|
58
|
+
| `chat` | Chat routes, hooks, Prisma chat models (+ auto deps) |
|
|
59
|
+
| `supabase-realtime` | Realtime channel helpers (+ auto `supabase`) |
|
|
60
|
+
| `seo` | robots/sitemap/JSON-LD helpers |
|
|
61
|
+
| `email` | `src/lib/email/*`, `src/emails/*` (provider: SMTP or Resend) |
|
|
51
62
|
|
|
52
63
|
Module **env variables** and where to find them: see `SETUP.md` → **Optional module environment**.
|
|
53
64
|
|