create-nextly-app 0.0.1 → 0.0.2-alpha.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/LICENSE +22 -0
- package/README.md +131 -0
- package/bin/create-nextly-app.js +3 -0
- package/dist/chunk-AYJ2RKVJ.mjs +28752 -0
- package/dist/chunk-AYJ2RKVJ.mjs.map +1 -0
- package/dist/cli.cjs +32410 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.mjs +3633 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.cjs +24776 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +69 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +83 -10
- package/templates/base/.env.example +16 -0
- package/templates/base/README.md +30 -0
- package/templates/base/eslint.config.mjs +18 -0
- package/templates/base/next.config.ts +21 -0
- package/templates/base/postcss.config.mjs +7 -0
- package/templates/base/public/file.svg +1 -0
- package/templates/base/public/globe.svg +1 -0
- package/templates/base/public/next.svg +1 -0
- package/templates/base/public/vercel.svg +1 -0
- package/templates/base/public/window.svg +1 -0
- package/templates/base/src/app/admin/[[...params]]/layout.tsx +20 -0
- package/templates/base/src/app/admin/[[...params]]/page.tsx +27 -0
- package/templates/base/src/app/admin/api/[[...params]]/route.ts +12 -0
- package/templates/base/src/app/api/health/route.ts +7 -0
- package/templates/base/src/app/api/media/[[...path]]/route.ts +34 -0
- package/templates/base/src/app/favicon.ico +0 -0
- package/templates/base/src/app/globals.css +55 -0
- package/templates/base/src/app/layout.tsx +43 -0
- package/templates/base/src/app/page.tsx +65 -0
- package/templates/base/src/types/generated/.gitkeep +0 -0
- package/templates/base/src/types/generated/nextly-types.ts +12 -0
- package/templates/base/tsconfig.json +35 -0
- package/templates/blank/.env.example +8 -0
- package/templates/blank/README.md +63 -0
- package/templates/blank/nextly.config.ts +14 -0
- package/templates/blank/src/access/README.md +22 -0
- package/templates/blank/src/app/(frontend)/page.tsx +176 -0
- package/templates/blank/src/app/globals.css +79 -0
- package/templates/blank/src/app/layout.tsx +46 -0
- package/templates/blank/src/collections/README.md +22 -0
- package/templates/blank/src/components/README.md +10 -0
- package/templates/blank/src/components/ThemeToggle.tsx +113 -0
- package/templates/blank/src/lib/README.md +15 -0
- package/templates/blank/src/singles/README.md +19 -0
- package/templates/blank/template.json +14 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project type / template selection.
|
|
3
|
+
* "blog" is the first content template added for alpha.
|
|
4
|
+
*/
|
|
5
|
+
type ProjectType = "blank" | "blog";
|
|
6
|
+
/**
|
|
7
|
+
* Schema approach selection for content templates.
|
|
8
|
+
* - code-first: Full schema definitions in nextly.config.ts (like Payload CMS)
|
|
9
|
+
* - visual: Empty config, schemas created via Admin Panel UI (like Strapi/WordPress)
|
|
10
|
+
* - both: Core schemas in code, additional schemas creatable via Admin Panel
|
|
11
|
+
*/
|
|
12
|
+
type ProjectApproach = "code-first" | "visual";
|
|
13
|
+
/**
|
|
14
|
+
* Supported database types
|
|
15
|
+
*/
|
|
16
|
+
type DatabaseType = "postgresql" | "mysql" | "sqlite";
|
|
17
|
+
/**
|
|
18
|
+
* Options for createNextly function
|
|
19
|
+
*/
|
|
20
|
+
interface CreateNextlyOptions {
|
|
21
|
+
/** Working directory (defaults to process.cwd()) */
|
|
22
|
+
cwd?: string;
|
|
23
|
+
/** Skip interactive prompts and use defaults */
|
|
24
|
+
defaults?: boolean;
|
|
25
|
+
/** Pre-selected project type / template name */
|
|
26
|
+
projectType?: ProjectType;
|
|
27
|
+
/** Pre-selected database type */
|
|
28
|
+
database?: DatabaseType;
|
|
29
|
+
/** Skip dependency installation (useful for local testing before packages are published) */
|
|
30
|
+
skipInstall?: boolean;
|
|
31
|
+
/** Use yalc for local package installation (for testing before npm publish) */
|
|
32
|
+
useYalc?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Project name derived from the CLI's positional `[directory]` argument.
|
|
35
|
+
* Must be a bare directory name (no slashes). Callers pass the basename
|
|
36
|
+
* of the user-provided argument.
|
|
37
|
+
*/
|
|
38
|
+
projectNameFromArg?: string;
|
|
39
|
+
/**
|
|
40
|
+
* When true, the CLI was invoked with "." meaning "install in current directory".
|
|
41
|
+
* Different from projectNameFromArg which creates a subdirectory.
|
|
42
|
+
*/
|
|
43
|
+
installInCwd?: boolean;
|
|
44
|
+
/** Schema approach for content templates (code-first, visual) */
|
|
45
|
+
approach?: ProjectApproach;
|
|
46
|
+
/** Path to local templates directory (for development, bypasses GitHub download) */
|
|
47
|
+
localTemplatePath?: string;
|
|
48
|
+
/** Git branch for template download from GitHub (defaults to "main") */
|
|
49
|
+
branch?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Main entry point for scaffolding Nextly in a Next.js project.
|
|
54
|
+
*
|
|
55
|
+
* Two flows:
|
|
56
|
+
* 1. Empty directory -> scaffold Next.js + install Nextly
|
|
57
|
+
* 2. Existing Next.js project -> install Nextly into it
|
|
58
|
+
*
|
|
59
|
+
* Interactive prompt order:
|
|
60
|
+
* 1. Project name (or detect existing project)
|
|
61
|
+
* 2. Template selection (blank, blog, etc.)
|
|
62
|
+
* 3. Schema approach (code-first, visual) — only for content templates
|
|
63
|
+
* 4. Demo content (yes/no) - only for content templates
|
|
64
|
+
* 5. Database selection (sqlite, postgresql, mysql)
|
|
65
|
+
* 6. Database connection string (only for postgresql/mysql)
|
|
66
|
+
*/
|
|
67
|
+
declare function createNextly(options?: CreateNextlyOptions): Promise<void>;
|
|
68
|
+
|
|
69
|
+
export { type CreateNextlyOptions, createNextly };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project type / template selection.
|
|
3
|
+
* "blog" is the first content template added for alpha.
|
|
4
|
+
*/
|
|
5
|
+
type ProjectType = "blank" | "blog";
|
|
6
|
+
/**
|
|
7
|
+
* Schema approach selection for content templates.
|
|
8
|
+
* - code-first: Full schema definitions in nextly.config.ts (like Payload CMS)
|
|
9
|
+
* - visual: Empty config, schemas created via Admin Panel UI (like Strapi/WordPress)
|
|
10
|
+
* - both: Core schemas in code, additional schemas creatable via Admin Panel
|
|
11
|
+
*/
|
|
12
|
+
type ProjectApproach = "code-first" | "visual";
|
|
13
|
+
/**
|
|
14
|
+
* Supported database types
|
|
15
|
+
*/
|
|
16
|
+
type DatabaseType = "postgresql" | "mysql" | "sqlite";
|
|
17
|
+
/**
|
|
18
|
+
* Options for createNextly function
|
|
19
|
+
*/
|
|
20
|
+
interface CreateNextlyOptions {
|
|
21
|
+
/** Working directory (defaults to process.cwd()) */
|
|
22
|
+
cwd?: string;
|
|
23
|
+
/** Skip interactive prompts and use defaults */
|
|
24
|
+
defaults?: boolean;
|
|
25
|
+
/** Pre-selected project type / template name */
|
|
26
|
+
projectType?: ProjectType;
|
|
27
|
+
/** Pre-selected database type */
|
|
28
|
+
database?: DatabaseType;
|
|
29
|
+
/** Skip dependency installation (useful for local testing before packages are published) */
|
|
30
|
+
skipInstall?: boolean;
|
|
31
|
+
/** Use yalc for local package installation (for testing before npm publish) */
|
|
32
|
+
useYalc?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Project name derived from the CLI's positional `[directory]` argument.
|
|
35
|
+
* Must be a bare directory name (no slashes). Callers pass the basename
|
|
36
|
+
* of the user-provided argument.
|
|
37
|
+
*/
|
|
38
|
+
projectNameFromArg?: string;
|
|
39
|
+
/**
|
|
40
|
+
* When true, the CLI was invoked with "." meaning "install in current directory".
|
|
41
|
+
* Different from projectNameFromArg which creates a subdirectory.
|
|
42
|
+
*/
|
|
43
|
+
installInCwd?: boolean;
|
|
44
|
+
/** Schema approach for content templates (code-first, visual) */
|
|
45
|
+
approach?: ProjectApproach;
|
|
46
|
+
/** Path to local templates directory (for development, bypasses GitHub download) */
|
|
47
|
+
localTemplatePath?: string;
|
|
48
|
+
/** Git branch for template download from GitHub (defaults to "main") */
|
|
49
|
+
branch?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Main entry point for scaffolding Nextly in a Next.js project.
|
|
54
|
+
*
|
|
55
|
+
* Two flows:
|
|
56
|
+
* 1. Empty directory -> scaffold Next.js + install Nextly
|
|
57
|
+
* 2. Existing Next.js project -> install Nextly into it
|
|
58
|
+
*
|
|
59
|
+
* Interactive prompt order:
|
|
60
|
+
* 1. Project name (or detect existing project)
|
|
61
|
+
* 2. Template selection (blank, blog, etc.)
|
|
62
|
+
* 3. Schema approach (code-first, visual) — only for content templates
|
|
63
|
+
* 4. Demo content (yes/no) - only for content templates
|
|
64
|
+
* 5. Database selection (sqlite, postgresql, mysql)
|
|
65
|
+
* 6. Database connection string (only for postgresql/mysql)
|
|
66
|
+
*/
|
|
67
|
+
declare function createNextly(options?: CreateNextlyOptions): Promise<void>;
|
|
68
|
+
|
|
69
|
+
export { type CreateNextlyOptions, createNextly };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,86 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-nextly-app",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
3
|
+
"version": "0.0.2-alpha.0",
|
|
4
|
+
"description": "CLI to scaffold Nextly in your Next.js project",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.mjs",
|
|
8
|
+
"module": "dist/index.mjs",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"bin": {
|
|
11
|
+
"create-nextly-app": "./bin/create-nextly-app.js"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.mjs",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"bin",
|
|
23
|
+
"templates"
|
|
24
|
+
],
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@clack/prompts": "^1.1.0",
|
|
27
|
+
"commander": "^14.0.2",
|
|
28
|
+
"execa": "^9.6.0",
|
|
29
|
+
"fs-extra": "^11.3.0",
|
|
30
|
+
"ora": "^9.0.0",
|
|
31
|
+
"picocolors": "^1.1.1",
|
|
32
|
+
"tar": "^7.4.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/fs-extra": "^11.0.4",
|
|
36
|
+
"@types/tar": "^6.1.13",
|
|
37
|
+
"@types/node": "^20.19.17",
|
|
38
|
+
"@vitest/coverage-v8": "^4.0.8",
|
|
39
|
+
"@vitest/ui": "^4.0.8",
|
|
40
|
+
"eslint": "^9.34.0",
|
|
41
|
+
"tsup": "^8.5.0",
|
|
42
|
+
"typescript": "^5.9.3",
|
|
43
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
44
|
+
"vitest": "^4.0.8",
|
|
45
|
+
"@nextlyhq/eslint-config": "0.0.1",
|
|
46
|
+
"@nextlyhq/telemetry": "0.0.1",
|
|
47
|
+
"@nextlyhq/tsconfig": "0.0.1"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=20.0.0"
|
|
8
51
|
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
52
|
+
"keywords": [
|
|
53
|
+
"nextly",
|
|
54
|
+
"cms",
|
|
55
|
+
"nextjs",
|
|
56
|
+
"cli",
|
|
57
|
+
"scaffold",
|
|
58
|
+
"create-nextly-app",
|
|
59
|
+
"create-app"
|
|
60
|
+
],
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "git+https://github.com/nextlyhq/nextly.git",
|
|
64
|
+
"directory": "packages/create-nextly-app"
|
|
65
|
+
},
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"access": "public",
|
|
68
|
+
"registry": "https://registry.npmjs.org/",
|
|
69
|
+
"provenance": true
|
|
70
|
+
},
|
|
71
|
+
"homepage": "https://nextlyhq.com",
|
|
72
|
+
"bugs": {
|
|
73
|
+
"url": "https://github.com/nextlyhq/nextly/issues"
|
|
74
|
+
},
|
|
75
|
+
"author": "Nextly <contact@nextlyhq.com> (https://nextlyhq.com)",
|
|
76
|
+
"scripts": {
|
|
77
|
+
"build": "tsup",
|
|
78
|
+
"dev": "tsup --watch",
|
|
79
|
+
"check-types": "tsc --noEmit",
|
|
80
|
+
"lint": "eslint . --max-warnings 0",
|
|
81
|
+
"lint:fix": "eslint . --fix",
|
|
82
|
+
"test": "vitest run --passWithNoTests",
|
|
83
|
+
"test:watch": "vitest",
|
|
84
|
+
"clean": "rimraf dist"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Nextly Configuration
|
|
2
|
+
# Generated by create-nextly-app
|
|
3
|
+
|
|
4
|
+
# Database Configuration
|
|
5
|
+
DB_DIALECT={{databaseDialect}}
|
|
6
|
+
DATABASE_URL={{databaseUrl}}
|
|
7
|
+
|
|
8
|
+
# Authentication (REQUIRED)
|
|
9
|
+
# Generate with: openssl rand -base64 32
|
|
10
|
+
NEXTLY_SECRET=change-me-generate-a-secure-secret
|
|
11
|
+
|
|
12
|
+
# Application URL
|
|
13
|
+
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
|
14
|
+
|
|
15
|
+
# Storage Configuration
|
|
16
|
+
{{storageEnvVars}}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Base template
|
|
2
|
+
|
|
3
|
+
Shared scaffolding for all `create-nextly-app` templates. The CLI applies this template first, then overlays the user-selected template (`blank`, `blog`, or future) on top.
|
|
4
|
+
|
|
5
|
+
> Not user-selectable. You will not see "base" in the CLI menu. It is always applied beneath your chosen template.
|
|
6
|
+
|
|
7
|
+
## What's in here
|
|
8
|
+
|
|
9
|
+
- Admin route handler stub (`app/admin/[[...params]]/page.tsx`)
|
|
10
|
+
- Default API handler stubs
|
|
11
|
+
- Shared styles and Tailwind preset wiring
|
|
12
|
+
- Default `tsconfig.json`, `next.config.ts`, `eslint.config.mjs`, `postcss.config.mjs`
|
|
13
|
+
|
|
14
|
+
## Maintainer notes
|
|
15
|
+
|
|
16
|
+
When editing files in `base/`, run the CLI against `--template blank` and `--template blog` locally to confirm both still scaffold cleanly:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm --filter create-nextly-app dev -- my-test \
|
|
20
|
+
--template blank \
|
|
21
|
+
--local-template ./templates \
|
|
22
|
+
--skip-install
|
|
23
|
+
|
|
24
|
+
pnpm --filter create-nextly-app dev -- my-test \
|
|
25
|
+
--template blog \
|
|
26
|
+
--local-template ./templates \
|
|
27
|
+
--skip-install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
See [CONTRIBUTING.md](../../CONTRIBUTING.md).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig, globalIgnores } from "eslint/config";
|
|
2
|
+
import nextVitals from "eslint-config-next/core-web-vitals";
|
|
3
|
+
import nextTs from "eslint-config-next/typescript";
|
|
4
|
+
|
|
5
|
+
const eslintConfig = defineConfig([
|
|
6
|
+
...nextVitals,
|
|
7
|
+
...nextTs,
|
|
8
|
+
// Override default ignores of eslint-config-next.
|
|
9
|
+
globalIgnores([
|
|
10
|
+
// Default ignores of eslint-config-next:
|
|
11
|
+
".next/**",
|
|
12
|
+
"out/**",
|
|
13
|
+
"build/**",
|
|
14
|
+
"next-env.d.ts",
|
|
15
|
+
]),
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
export default eslintConfig;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { NextConfig } from "next";
|
|
2
|
+
|
|
3
|
+
const nextConfig: NextConfig = {
|
|
4
|
+
serverExternalPackages: [
|
|
5
|
+
"nextly",
|
|
6
|
+
"@nextlyhq/adapter-drizzle",
|
|
7
|
+
"@nextlyhq/adapter-postgres",
|
|
8
|
+
"@nextlyhq/adapter-mysql",
|
|
9
|
+
"@nextlyhq/adapter-sqlite",
|
|
10
|
+
"drizzle-orm",
|
|
11
|
+
"drizzle-kit",
|
|
12
|
+
"pg",
|
|
13
|
+
"mysql2",
|
|
14
|
+
"better-sqlite3",
|
|
15
|
+
"bcryptjs",
|
|
16
|
+
"sharp",
|
|
17
|
+
"esbuild",
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default nextConfig;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getBrandingCss } from "nextly/config";
|
|
2
|
+
|
|
3
|
+
import config from "../../../../nextly.config";
|
|
4
|
+
|
|
5
|
+
const brandingCss = getBrandingCss(config.admin?.branding);
|
|
6
|
+
|
|
7
|
+
export default function AdminLayout({
|
|
8
|
+
children,
|
|
9
|
+
}: {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
}) {
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
{brandingCss && (
|
|
15
|
+
<style dangerouslySetInnerHTML={{ __html: brandingCss }} />
|
|
16
|
+
)}
|
|
17
|
+
{children}
|
|
18
|
+
</>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// Plugin-side admin imports. Every scaffold ships @nextlyhq/plugin-form-builder
|
|
4
|
+
// as a dependency (see packages/create-nextly-app utils/template.ts). These
|
|
5
|
+
// three lines register the plugin's custom admin field components and load its
|
|
6
|
+
// CSS so the Forms collection's drag-and-drop field builder and Submissions
|
|
7
|
+
// filter UI render correctly. Without them, Forms still appears in the sidebar
|
|
8
|
+
// but the builder falls back to plain JSON/text inputs.
|
|
9
|
+
import "@nextlyhq/admin/style.css";
|
|
10
|
+
import "@nextlyhq/plugin-form-builder/admin";
|
|
11
|
+
import "@nextlyhq/plugin-form-builder/styles/builder.css";
|
|
12
|
+
import "@nextlyhq/plugin-form-builder/styles/submissions-filter.css";
|
|
13
|
+
import { RootLayout, QueryProvider, ErrorBoundary } from "@nextlyhq/admin";
|
|
14
|
+
|
|
15
|
+
export default function AdminPage() {
|
|
16
|
+
return (
|
|
17
|
+
<ErrorBoundary
|
|
18
|
+
onError={(error, errorInfo) => {
|
|
19
|
+
console.error("Admin error:", error, errorInfo);
|
|
20
|
+
}}
|
|
21
|
+
>
|
|
22
|
+
<QueryProvider>
|
|
23
|
+
<RootLayout />
|
|
24
|
+
</QueryProvider>
|
|
25
|
+
</ErrorBoundary>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createDynamicHandlers } from "nextly/runtime";
|
|
2
|
+
|
|
3
|
+
import nextlyConfig from "../../../../../nextly.config";
|
|
4
|
+
|
|
5
|
+
const handlers = createDynamicHandlers({ config: nextlyConfig });
|
|
6
|
+
|
|
7
|
+
export const GET = handlers.GET;
|
|
8
|
+
export const POST = handlers.POST;
|
|
9
|
+
export const PUT = handlers.PUT;
|
|
10
|
+
export const PATCH = handlers.PATCH;
|
|
11
|
+
export const DELETE = handlers.DELETE;
|
|
12
|
+
export const OPTIONS = handlers.OPTIONS;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media API Routes (Catch-All Handler)
|
|
3
|
+
*
|
|
4
|
+
* This single route handles all media operations:
|
|
5
|
+
*
|
|
6
|
+
* Media Files:
|
|
7
|
+
* - GET /api/media - List media with pagination
|
|
8
|
+
* - POST /api/media - Upload new media file
|
|
9
|
+
* - GET /api/media/:id - Get media by ID
|
|
10
|
+
* - PATCH /api/media/:id - Update media metadata
|
|
11
|
+
* - DELETE /api/media/:id - Delete media file
|
|
12
|
+
* - PATCH /api/media/:id/move - Move media to folder
|
|
13
|
+
*
|
|
14
|
+
* Folders:
|
|
15
|
+
* - GET /api/media/folders - List folders
|
|
16
|
+
* - POST /api/media/folders - Create folder
|
|
17
|
+
* - GET /api/media/folders/:id - Get folder by ID
|
|
18
|
+
* - PATCH /api/media/folders/:id - Update folder
|
|
19
|
+
* - DELETE /api/media/folders/:id - Delete folder
|
|
20
|
+
* - GET /api/media/folders/:id/contents - Get folder contents
|
|
21
|
+
* - GET /api/media/folders/root/contents - Get root folder contents
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { createMediaHandlers } from "nextly/api/media-handlers";
|
|
25
|
+
|
|
26
|
+
import nextlyConfig from "../../../../../nextly.config";
|
|
27
|
+
|
|
28
|
+
// Pass config to ensure storage plugins work across all worker processes
|
|
29
|
+
const handlers = createMediaHandlers({ config: nextlyConfig });
|
|
30
|
+
|
|
31
|
+
export const GET = handlers.GET;
|
|
32
|
+
export const POST = handlers.POST;
|
|
33
|
+
export const PATCH = handlers.PATCH;
|
|
34
|
+
export const DELETE = handlers.DELETE;
|
|
Binary file
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
--background: #ffffff;
|
|
5
|
+
--foreground: #171717;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
@theme inline {
|
|
9
|
+
--color-background: var(--background);
|
|
10
|
+
--color-foreground: var(--foreground);
|
|
11
|
+
--font-sans: var(--font-geist-sans);
|
|
12
|
+
--font-mono: var(--font-geist-mono);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@media (prefers-color-scheme: dark) {
|
|
16
|
+
:root {
|
|
17
|
+
--background: #0a0a0a;
|
|
18
|
+
--foreground: #ededed;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
body {
|
|
23
|
+
background: var(--background);
|
|
24
|
+
color: var(--foreground);
|
|
25
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* ===============================================================
|
|
29
|
+
Accessibility baseline
|
|
30
|
+
---------------------------------------------------------------
|
|
31
|
+
Applied globally so the template passes a WCAG AA keyboard audit
|
|
32
|
+
out of the box. Adjust to match your brand.
|
|
33
|
+
=============================================================== */
|
|
34
|
+
|
|
35
|
+
/* Visible focus ring for keyboard users. `:focus-visible` only fires
|
|
36
|
+
on keyboard / programmatic focus, so clicking a button doesn't
|
|
37
|
+
show the ring but tabbing to it does. */
|
|
38
|
+
*:focus-visible {
|
|
39
|
+
outline: 2px solid currentColor;
|
|
40
|
+
outline-offset: 2px;
|
|
41
|
+
border-radius: 2px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Honor OS-level reduced-motion preference — disables hover scale,
|
|
45
|
+
transitions, and animations for users who've opted out. */
|
|
46
|
+
@media (prefers-reduced-motion: reduce) {
|
|
47
|
+
*,
|
|
48
|
+
*::before,
|
|
49
|
+
*::after {
|
|
50
|
+
animation-duration: 0.01ms !important;
|
|
51
|
+
animation-iteration-count: 1 !important;
|
|
52
|
+
transition-duration: 0.01ms !important;
|
|
53
|
+
scroll-behavior: auto !important;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { Geist, Geist_Mono } from "next/font/google";
|
|
3
|
+
import "./globals.css";
|
|
4
|
+
|
|
5
|
+
const geistSans = Geist({
|
|
6
|
+
variable: "--font-geist-sans",
|
|
7
|
+
subsets: ["latin"],
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const geistMono = Geist_Mono({
|
|
11
|
+
variable: "--font-geist-mono",
|
|
12
|
+
subsets: ["latin"],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* `metadataBase` tells Next.js how to resolve relative URLs in OpenGraph
|
|
17
|
+
* images, Twitter images, and canonical URLs. Set `NEXT_PUBLIC_SITE_URL`
|
|
18
|
+
* in your environment to your production domain (e.g.
|
|
19
|
+
* `https://yourblog.com`). The localhost fallback keeps dev working.
|
|
20
|
+
*/
|
|
21
|
+
export const metadata: Metadata = {
|
|
22
|
+
metadataBase: new URL(
|
|
23
|
+
process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000"
|
|
24
|
+
),
|
|
25
|
+
title: { default: "Nextly", template: "%s — Nextly" },
|
|
26
|
+
description: "A site built with Nextly.",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default function RootLayout({
|
|
30
|
+
children,
|
|
31
|
+
}: Readonly<{
|
|
32
|
+
children: React.ReactNode;
|
|
33
|
+
}>) {
|
|
34
|
+
return (
|
|
35
|
+
<html lang="en" suppressHydrationWarning>
|
|
36
|
+
<body
|
|
37
|
+
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
|
38
|
+
>
|
|
39
|
+
{children}
|
|
40
|
+
</body>
|
|
41
|
+
</html>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Image from "next/image";
|
|
2
|
+
|
|
3
|
+
export default function Home() {
|
|
4
|
+
return (
|
|
5
|
+
<div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
|
|
6
|
+
<main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
|
|
7
|
+
<Image
|
|
8
|
+
className="dark:invert"
|
|
9
|
+
src="/next.svg"
|
|
10
|
+
alt="Next.js logo"
|
|
11
|
+
width={100}
|
|
12
|
+
height={20}
|
|
13
|
+
priority
|
|
14
|
+
/>
|
|
15
|
+
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
|
|
16
|
+
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
|
|
17
|
+
To get started, edit the page.tsx file.
|
|
18
|
+
</h1>
|
|
19
|
+
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
|
|
20
|
+
Looking for a starting point or more instructions? Head over to{" "}
|
|
21
|
+
<a
|
|
22
|
+
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
|
23
|
+
className="font-medium text-zinc-950 dark:text-zinc-50"
|
|
24
|
+
>
|
|
25
|
+
Templates
|
|
26
|
+
</a>{" "}
|
|
27
|
+
or the{" "}
|
|
28
|
+
<a
|
|
29
|
+
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
|
30
|
+
className="font-medium text-zinc-950 dark:text-zinc-50"
|
|
31
|
+
>
|
|
32
|
+
Learning
|
|
33
|
+
</a>{" "}
|
|
34
|
+
center.
|
|
35
|
+
</p>
|
|
36
|
+
</div>
|
|
37
|
+
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
|
|
38
|
+
<a
|
|
39
|
+
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
|
|
40
|
+
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
|
41
|
+
target="_blank"
|
|
42
|
+
rel="noopener noreferrer"
|
|
43
|
+
>
|
|
44
|
+
<Image
|
|
45
|
+
className="dark:invert"
|
|
46
|
+
src="/vercel.svg"
|
|
47
|
+
alt="Vercel logomark"
|
|
48
|
+
width={16}
|
|
49
|
+
height={16}
|
|
50
|
+
/>
|
|
51
|
+
Deploy Now
|
|
52
|
+
</a>
|
|
53
|
+
<a
|
|
54
|
+
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
|
|
55
|
+
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
|
56
|
+
target="_blank"
|
|
57
|
+
rel="noopener noreferrer"
|
|
58
|
+
>
|
|
59
|
+
Documentation
|
|
60
|
+
</a>
|
|
61
|
+
</div>
|
|
62
|
+
</main>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nextly Generated Types
|
|
3
|
+
*
|
|
4
|
+
* This file will be auto-generated when you run:
|
|
5
|
+
* npx nextly dev
|
|
6
|
+
* npx nextly generate:types
|
|
7
|
+
*
|
|
8
|
+
* Do not edit this file manually - it will be overwritten.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// Types will be generated here after running nextly dev
|
|
12
|
+
export {};
|