create-aphex 0.1.3 → 0.2.1
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/dist/index.js +9 -88
- package/package.json +4 -4
- package/templates/base/.dockerignore +0 -44
- package/templates/base/.env.example +0 -38
- package/templates/base/CHANGELOG.md +0 -124
- package/templates/base/Dockerfile +0 -69
- package/templates/base/README.md +0 -147
- package/templates/base/aphex.config.ts +0 -45
- package/templates/base/docker-compose.yml +0 -31
- package/templates/base/drizzle/0000_tiny_redwing.sql +0 -226
- package/templates/base/drizzle/meta/0000_snapshot.json +0 -1379
- package/templates/base/drizzle/meta/_journal.json +0 -13
- package/templates/base/drizzle.config.ts +0 -17
- package/templates/base/package.json +0 -81
- package/templates/base/prod.docker-compose.yml +0 -61
- package/templates/base/src/app.css +0 -32
- package/templates/base/src/app.d.ts +0 -26
- package/templates/base/src/app.html +0 -11
- package/templates/base/src/hooks.server.ts +0 -52
- package/templates/base/src/lib/assets/favicon.svg +0 -5
- package/templates/base/src/lib/auth-client.ts +0 -19
- package/templates/base/src/lib/index.ts +0 -1
- package/templates/base/src/lib/schemaTypes/index.ts +0 -11
- package/templates/base/src/lib/schemaTypes/post.ts +0 -47
- package/templates/base/src/lib/server/auth/better-auth/instance.ts +0 -183
- package/templates/base/src/lib/server/auth/index.ts +0 -25
- package/templates/base/src/lib/server/auth/instance.ts +0 -7
- package/templates/base/src/lib/server/auth/service.ts +0 -486
- package/templates/base/src/lib/server/cache/index.ts +0 -10
- package/templates/base/src/lib/server/db/auth-schema.ts +0 -86
- package/templates/base/src/lib/server/db/cms-schema.ts +0 -23
- package/templates/base/src/lib/server/db/index.ts +0 -55
- package/templates/base/src/lib/server/db/schema.ts +0 -3
- package/templates/base/src/lib/server/email/components/EmailLayout.svelte +0 -24
- package/templates/base/src/lib/server/email/components/EmailVerification.svelte +0 -26
- package/templates/base/src/lib/server/email/components/Invitation.svelte +0 -30
- package/templates/base/src/lib/server/email/components/PasswordReset.svelte +0 -28
- package/templates/base/src/lib/server/email/index.ts +0 -28
- package/templates/base/src/lib/server/email/invitation-hook.ts +0 -56
- package/templates/base/src/lib/server/email/renderer.ts +0 -13
- package/templates/base/src/lib/server/email/templates/email-verification.ts +0 -8
- package/templates/base/src/lib/server/email/templates/invitation.ts +0 -8
- package/templates/base/src/lib/server/email/templates/password-reset.ts +0 -7
- package/templates/base/src/lib/server/services/organization.ts +0 -68
- package/templates/base/src/lib/server/storage/index.ts +0 -28
- package/templates/base/src/lib/stores/activeTab.svelte.ts +0 -14
- package/templates/base/src/lib/utils/imageBuilder.ts +0 -3
- package/templates/base/src/lib/utils/slug.ts +0 -33
- package/templates/base/src/routes/(protected)/admin/+layout.server.ts +0 -86
- package/templates/base/src/routes/(protected)/admin/+layout.svelte +0 -78
- package/templates/base/src/routes/(protected)/admin/+page.server.ts +0 -60
- package/templates/base/src/routes/(protected)/admin/+page.svelte +0 -34
- package/templates/base/src/routes/(protected)/admin/organizations/+page.server.ts +0 -39
- package/templates/base/src/routes/(protected)/admin/organizations/+page.svelte +0 -31
- package/templates/base/src/routes/(protected)/admin/organizations/_components/CreateOrganization.svelte +0 -141
- package/templates/base/src/routes/(protected)/admin/organizations/_components/OrganizationsList.svelte +0 -102
- package/templates/base/src/routes/(protected)/admin/settings/+layout.server.ts +0 -42
- package/templates/base/src/routes/(protected)/admin/settings/+layout.svelte +0 -116
- package/templates/base/src/routes/(protected)/admin/settings/+page.server.ts +0 -16
- package/templates/base/src/routes/(protected)/admin/settings/+page.svelte +0 -32
- package/templates/base/src/routes/(protected)/admin/settings/_components/AccountSettings.svelte +0 -177
- package/templates/base/src/routes/(protected)/admin/settings/_components/ApiKeysSettings.svelte +0 -472
- package/templates/base/src/routes/(protected)/admin/settings/_components/OrganizationsSettings.svelte +0 -182
- package/templates/base/src/routes/(protected)/admin/settings/account/+page.server.ts +0 -25
- package/templates/base/src/routes/(protected)/admin/settings/account/+page.svelte +0 -23
- package/templates/base/src/routes/(protected)/admin/settings/api-keys/+page.server.ts +0 -54
- package/templates/base/src/routes/(protected)/admin/settings/api-keys/+page.svelte +0 -14
- package/templates/base/src/routes/(protected)/admin/settings/members/+page.server.ts +0 -31
- package/templates/base/src/routes/(protected)/admin/settings/members/+page.svelte +0 -338
- package/templates/base/src/routes/(protected)/admin/settings/roles/+page.server.ts +0 -17
- package/templates/base/src/routes/(protected)/admin/settings/roles/+page.svelte +0 -339
- package/templates/base/src/routes/+layout.svelte +0 -12
- package/templates/base/src/routes/+page.svelte +0 -2
- package/templates/base/src/routes/api/[...slug]/+server.ts +0 -35
- package/templates/base/src/routes/api/instance-settings/+server.ts +0 -70
- package/templates/base/src/routes/api/invitations/+server.ts +0 -54
- package/templates/base/src/routes/api/invitations/[id]/accept/+server.ts +0 -54
- package/templates/base/src/routes/api/invitations/[id]/reject/+server.ts +0 -49
- package/templates/base/src/routes/api/settings/api-keys/+server.ts +0 -57
- package/templates/base/src/routes/api/settings/api-keys/[id]/+server.ts +0 -53
- package/templates/base/src/routes/god-mode/+layout.server.ts +0 -32
- package/templates/base/src/routes/god-mode/+layout.svelte +0 -155
- package/templates/base/src/routes/god-mode/+page.server.ts +0 -10
- package/templates/base/src/routes/god-mode/+page.svelte +0 -32
- package/templates/base/src/routes/god-mode/_components/CreateOrganization.svelte +0 -141
- package/templates/base/src/routes/god-mode/_components/OrganizationsList.svelte +0 -169
- package/templates/base/src/routes/god-mode/organizations/+page.server.ts +0 -43
- package/templates/base/src/routes/god-mode/organizations/+page.svelte +0 -74
- package/templates/base/src/routes/invitations/+page.server.ts +0 -48
- package/templates/base/src/routes/invitations/+page.svelte +0 -264
- package/templates/base/src/routes/invite/[token]/+page.server.ts +0 -59
- package/templates/base/src/routes/invite/[token]/+page.svelte +0 -109
- package/templates/base/src/routes/login/+page.server.ts +0 -14
- package/templates/base/src/routes/login/+page.svelte +0 -332
- package/templates/base/src/routes/media/[id]/[filename]/+server.ts +0 -3
- package/templates/base/src/routes/reset-password/[token]/+page.server.ts +0 -15
- package/templates/base/src/routes/reset-password/[token]/+page.svelte +0 -179
- package/templates/base/src/routes/verify-email/+page.svelte +0 -41
- package/templates/base/static/images/aphex-darkmode.png +0 -0
- package/templates/base/static/images/aphex-lightmode.png +0 -0
- package/templates/base/static/robots.txt +0 -3
- package/templates/base/svelte.config.js +0 -19
- package/templates/base/tsconfig.json +0 -20
- package/templates/base/vite.config.ts +0 -146
package/dist/index.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as p from '@clack/prompts';
|
|
3
|
-
import { existsSync,
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync, copyFileSync } from 'fs';
|
|
4
4
|
import { join, resolve } from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import { dirname } from 'path';
|
|
7
5
|
import pc from 'picocolors';
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const templates = ['base'];
|
|
6
|
+
import { downloadTemplate } from 'giget';
|
|
7
|
+
const TEMPLATE_REPO = process.env.APHEX_TEMPLATE || 'github:IcelandicIcecream/aphex-base';
|
|
11
8
|
async function main() {
|
|
12
9
|
console.clear();
|
|
13
10
|
p.intro(pc.bgCyan(pc.black(' create-aphex ')));
|
|
14
11
|
const options = {
|
|
15
12
|
projectName: '',
|
|
16
|
-
template: 'base',
|
|
17
13
|
targetDir: ''
|
|
18
14
|
};
|
|
19
|
-
// Get project name
|
|
20
15
|
const projectName = await p.text({
|
|
21
16
|
message: 'What is your project name?',
|
|
22
17
|
placeholder: 'my-aphex-project',
|
|
@@ -34,7 +29,6 @@ async function main() {
|
|
|
34
29
|
}
|
|
35
30
|
options.projectName = projectName;
|
|
36
31
|
options.targetDir = resolve(process.cwd(), options.projectName);
|
|
37
|
-
// Check if directory already exists
|
|
38
32
|
if (existsSync(options.targetDir)) {
|
|
39
33
|
const shouldOverwrite = await p.confirm({
|
|
40
34
|
message: `Directory ${pc.cyan(options.projectName)} already exists. Overwrite?`,
|
|
@@ -45,61 +39,28 @@ async function main() {
|
|
|
45
39
|
process.exit(0);
|
|
46
40
|
}
|
|
47
41
|
}
|
|
48
|
-
options.template = 'base';
|
|
49
|
-
// Start scaffolding
|
|
50
42
|
const spinner = p.spinner();
|
|
51
|
-
spinner.start(
|
|
43
|
+
spinner.start(`Fetching template from ${TEMPLATE_REPO}...`);
|
|
52
44
|
try {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
throw new Error('Could not find templates directory');
|
|
58
|
-
}
|
|
59
|
-
const templatePath = join(templatesDir, options.template);
|
|
60
|
-
if (!existsSync(templatePath)) {
|
|
61
|
-
throw new Error(`Template "${options.template}" not found`);
|
|
62
|
-
}
|
|
63
|
-
// Create target directory
|
|
64
|
-
mkdirSync(options.targetDir, { recursive: true });
|
|
65
|
-
// Copy template files
|
|
66
|
-
cpSync(templatePath, options.targetDir, { recursive: true });
|
|
67
|
-
// Update package.json with project name and resolve workspace: references
|
|
45
|
+
await downloadTemplate(TEMPLATE_REPO, {
|
|
46
|
+
dir: options.targetDir,
|
|
47
|
+
force: true
|
|
48
|
+
});
|
|
68
49
|
const packageJsonPath = join(options.targetDir, 'package.json');
|
|
69
50
|
if (existsSync(packageJsonPath)) {
|
|
70
51
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
71
52
|
packageJson.name = options.projectName;
|
|
72
|
-
// Replace workspace:* references with actual package versions
|
|
73
|
-
for (const depType of ['dependencies', 'devDependencies']) {
|
|
74
|
-
const deps = packageJson[depType];
|
|
75
|
-
if (!deps)
|
|
76
|
-
continue;
|
|
77
|
-
for (const [name, version] of Object.entries(deps)) {
|
|
78
|
-
if (typeof version === 'string' && version.startsWith('workspace:')) {
|
|
79
|
-
// Look up the actual version from the package in the monorepo
|
|
80
|
-
const pkgDir = findPackageDir(templatesDir, name);
|
|
81
|
-
if (pkgDir) {
|
|
82
|
-
const pkgJson = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf-8'));
|
|
83
|
-
deps[name] = `^${pkgJson.version}`;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Remove private flag and workspace-specific fields
|
|
89
53
|
delete packageJson.private;
|
|
90
54
|
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, '\t') + '\n');
|
|
91
55
|
}
|
|
92
|
-
// Create .env from .env.example if it doesn't exist
|
|
93
56
|
const envPath = join(options.targetDir, '.env');
|
|
94
57
|
const envExamplePath = join(options.targetDir, '.env.example');
|
|
95
58
|
if (!existsSync(envPath) && existsSync(envExamplePath)) {
|
|
96
|
-
|
|
59
|
+
copyFileSync(envExamplePath, envPath);
|
|
97
60
|
}
|
|
98
61
|
spinner.stop('Project created successfully!');
|
|
99
|
-
// Show next steps
|
|
100
62
|
const nextSteps = [
|
|
101
63
|
`cd ${options.projectName}`,
|
|
102
|
-
'cp .env.example .env',
|
|
103
64
|
'pnpm install',
|
|
104
65
|
'pnpm db:start',
|
|
105
66
|
'pnpm db:push',
|
|
@@ -114,46 +75,6 @@ async function main() {
|
|
|
114
75
|
process.exit(1);
|
|
115
76
|
}
|
|
116
77
|
}
|
|
117
|
-
function findPackageDir(templatesDir, packageName) {
|
|
118
|
-
// Templates sit alongside packages/ in the monorepo, or the packages
|
|
119
|
-
// are bundled relative to the templates dir in the npm package
|
|
120
|
-
const possibleRoots = [
|
|
121
|
-
resolve(templatesDir, '..'), // monorepo root (templates/ -> ../)
|
|
122
|
-
resolve(templatesDir, '../..') // npm package (dist/templates -> ../../)
|
|
123
|
-
];
|
|
124
|
-
for (const root of possibleRoots) {
|
|
125
|
-
const packagesDir = join(root, 'packages');
|
|
126
|
-
if (!existsSync(packagesDir))
|
|
127
|
-
continue;
|
|
128
|
-
for (const dir of readdirSync(packagesDir)) {
|
|
129
|
-
const pkgJsonPath = join(packagesDir, dir, 'package.json');
|
|
130
|
-
if (existsSync(pkgJsonPath)) {
|
|
131
|
-
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
132
|
-
if (pkgJson.name === packageName) {
|
|
133
|
-
return join(packagesDir, dir);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
function findTemplatesDir() {
|
|
141
|
-
// Try different possible locations for the templates directory
|
|
142
|
-
const possiblePaths = [
|
|
143
|
-
// When installed via npm/npx (templates are bundled in package)
|
|
144
|
-
resolve(__dirname, '../templates'),
|
|
145
|
-
// When running from built dist in package
|
|
146
|
-
resolve(__dirname, '../../templates'),
|
|
147
|
-
// When running from source in monorepo
|
|
148
|
-
resolve(__dirname, '../../../templates')
|
|
149
|
-
];
|
|
150
|
-
for (const path of possiblePaths) {
|
|
151
|
-
if (existsSync(path)) {
|
|
152
|
-
return path;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
78
|
main().catch((error) => {
|
|
158
79
|
console.error('Error:', error);
|
|
159
80
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-aphex",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Scaffold a new Aphex CMS project — invoked via `pnpm create aphex`",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"provenance": true
|
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
"create-aphex": "./dist/index.js"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
|
-
"dist"
|
|
19
|
-
"templates"
|
|
18
|
+
"dist"
|
|
20
19
|
],
|
|
21
20
|
"keywords": [
|
|
22
21
|
"aphex",
|
|
@@ -29,6 +28,7 @@
|
|
|
29
28
|
"license": "MIT",
|
|
30
29
|
"dependencies": {
|
|
31
30
|
"@clack/prompts": "^0.11.0",
|
|
31
|
+
"giget": "^2.0.0",
|
|
32
32
|
"picocolors": "^1.1.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
"typescript": "^5.9.3"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
|
-
"build": "
|
|
39
|
+
"build": "tsc"
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Build artifacts
|
|
2
|
-
build
|
|
3
|
-
node_modules
|
|
4
|
-
.svelte-kit
|
|
5
|
-
dist
|
|
6
|
-
|
|
7
|
-
# Environment files
|
|
8
|
-
.env
|
|
9
|
-
.env.*
|
|
10
|
-
!.env.example
|
|
11
|
-
!.env.docker
|
|
12
|
-
|
|
13
|
-
# OS files
|
|
14
|
-
.DS_Store
|
|
15
|
-
Thumbs.db
|
|
16
|
-
|
|
17
|
-
# Logs
|
|
18
|
-
*.log
|
|
19
|
-
npm-debug.log*
|
|
20
|
-
yarn-debug.log*
|
|
21
|
-
yarn-error.log*
|
|
22
|
-
pnpm-debug.log*
|
|
23
|
-
|
|
24
|
-
# Storage
|
|
25
|
-
storage/assets/
|
|
26
|
-
|
|
27
|
-
# IDE
|
|
28
|
-
.vscode
|
|
29
|
-
.idea
|
|
30
|
-
*.swp
|
|
31
|
-
*.swo
|
|
32
|
-
|
|
33
|
-
# Documentation
|
|
34
|
-
README.md
|
|
35
|
-
CONTRIBUTING.md
|
|
36
|
-
LICENSE
|
|
37
|
-
|
|
38
|
-
# Git
|
|
39
|
-
.git
|
|
40
|
-
.gitignore
|
|
41
|
-
|
|
42
|
-
# Testing
|
|
43
|
-
coverage
|
|
44
|
-
.nyc_output
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# ============================
|
|
2
|
-
# Database Configuration
|
|
3
|
-
# ============================
|
|
4
|
-
|
|
5
|
-
## Option (1): Using a full DATABASE_URL
|
|
6
|
-
## -------------------------------------
|
|
7
|
-
DATABASE_URL="postgres://root:mysecretpassword@localhost:5432/local"
|
|
8
|
-
|
|
9
|
-
## Option (2): Using individual connection settings
|
|
10
|
-
## -----------------------------------------------
|
|
11
|
-
## Uncomment and set these if not using DATABASE_URL
|
|
12
|
-
# PG_HOST=localhost
|
|
13
|
-
# PG_PORT=5432
|
|
14
|
-
# PG_USER=root
|
|
15
|
-
# PG_PASSWORD=mysecretpassword
|
|
16
|
-
# PG_DATABASE=local
|
|
17
|
-
|
|
18
|
-
# ============================
|
|
19
|
-
# Auth Configuration
|
|
20
|
-
# ============================
|
|
21
|
-
# BETTER_AUTH_SECRET / BETTER_AUTH_URL also work for backwards compatibility
|
|
22
|
-
BETTER_AUTH_SECRET=your-secret-key-here-change-in-production
|
|
23
|
-
BETTER_AUTH_URL=http://localhost:5173
|
|
24
|
-
AUTH_TRUSTED_ORIGINS=http://localhost:5173
|
|
25
|
-
|
|
26
|
-
# ============================
|
|
27
|
-
# Resend Email Configuration (optional)
|
|
28
|
-
# ============================
|
|
29
|
-
RESEND_API_KEY=re_your_api_key_here
|
|
30
|
-
|
|
31
|
-
# ============================
|
|
32
|
-
# S3_COMPATIBLE CONFIGURATION (optional)
|
|
33
|
-
# ============================
|
|
34
|
-
R2_ENDPOINT=
|
|
35
|
-
R2_ACCESS_KEY_ID=
|
|
36
|
-
R2_SECRET_ACCESS_KEY=
|
|
37
|
-
R2_BUCKET=
|
|
38
|
-
R2_PUBLIC_URL=
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
**Heads up:** This project was scaffolded from `@aphexcms/base` `v0.0.3`.
|
|
3
|
-
When upgrading, read `CHANGELOG.md` in the template repo for notes on
|
|
4
|
-
what changed upstream and which files you may want to port into your
|
|
5
|
-
customized project.
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# AphexCMS Template Changelog
|
|
9
|
-
|
|
10
|
-
Notes for users upgrading an existing project scaffolded from this template.
|
|
11
|
-
Because the template is meant to be customized, changes here are **not**
|
|
12
|
-
automatically applied to your project — this file describes what changed
|
|
13
|
-
upstream so you can cherry-pick the bits you care about.
|
|
14
|
-
|
|
15
|
-
Format: each entry lists the files touched and a one-line reason. Use
|
|
16
|
-
`git diff` against the mirror repo (`IcelandicIcecream/aphex-base`) at the
|
|
17
|
-
tag matching the version you started from to see the exact changes.
|
|
18
|
-
|
|
19
|
-
## Unreleased
|
|
20
|
-
|
|
21
|
-
## 0.0.4
|
|
22
|
-
- pass authorised origins from .env into better auth to handle csrf
|
|
23
|
-
- preload dayjs for better UX when going into a fresh studio
|
|
24
|
-
- disallow admins from changing themselves to owners and kicking out original owners
|
|
25
|
-
|
|
26
|
-
## 0.0.3
|
|
27
|
-
- **feat(api): move invitation email-wrap into `aphex.config.ts → api`**
|
|
28
|
-
- Deleted: `src/routes/api/organizations/invitations/+server.ts` —
|
|
29
|
-
the SK shim that wrapped the built-in invite handler to send email.
|
|
30
|
-
- Added: `src/lib/server/email/invitation-hook.ts` — same logic, now a
|
|
31
|
-
Hono middleware registered via `config.api`. Runs BEFORE built-in
|
|
32
|
-
routes mount (Hono is registration-order-strict, so middleware needs
|
|
33
|
-
to register first to wrap a downstream handler).
|
|
34
|
-
- `aphex.config.ts` now passes `api: (app) => registerInvitationEmailHook(app)`.
|
|
35
|
-
- Why: lets us drop the last invitation-related entry from
|
|
36
|
-
`routes-exports.ts` and the matching SK route file in cms-core. The
|
|
37
|
-
only remaining `routes-exports` entry is `serveAssetCDN` (CDN URLs
|
|
38
|
-
live outside `/api` so can't move onto the catch-all).
|
|
39
|
-
- Upgrade: copy `src/lib/server/email/invitation-hook.ts` and the new
|
|
40
|
-
`api:` block in `aphex.config.ts`; delete your old
|
|
41
|
-
`src/routes/api/organizations/invitations/+server.ts`.
|
|
42
|
-
|
|
43
|
-
- **feat(api): replace per-endpoint `+server.ts` shims with a single Hono catch-all**
|
|
44
|
-
- Added: `src/routes/api/[...slug]/+server.ts` — forwards any unmatched
|
|
45
|
-
`/api/**` request to the Aphex Hono app on `event.locals.aphexCMS.apiApp`.
|
|
46
|
-
- Deleted (24 files) — all CMS-feature shims that just re-exported handlers
|
|
47
|
-
from `@aphexcms/cms-core/server`. They're now served by the catch-all:
|
|
48
|
-
- `src/routes/api/{schemas,documents,assets,organizations,roles,user}/+server.ts`
|
|
49
|
-
- `src/routes/api/schemas/[type]/+server.ts`
|
|
50
|
-
- `src/routes/api/documents/{query,[id]}/+server.ts`
|
|
51
|
-
- `src/routes/api/documents/[id]/{publish,versions}/+server.ts`
|
|
52
|
-
- `src/routes/api/documents/[id]/versions/[version]/+server.ts`
|
|
53
|
-
- `src/routes/api/documents/[id]/versions/[version]/restore/+server.ts`
|
|
54
|
-
- `src/routes/api/assets/{bulk,[id]}/+server.ts`
|
|
55
|
-
- `src/routes/api/assets/[id]/references/+server.ts`
|
|
56
|
-
- `src/routes/api/assets/references/counts/+server.ts`
|
|
57
|
-
- `src/routes/api/organizations/{switch,members,[id]}/+server.ts`
|
|
58
|
-
- `src/routes/api/roles/[name]/+server.ts`
|
|
59
|
-
- `src/routes/api/user/{cms-preference,reset-password,request-password-reset}/+server.ts`
|
|
60
|
-
- Kept (studio-locals — your own endpoints): `instance-settings`,
|
|
61
|
-
`invitations`, `invitations/[id]/{accept,reject}`,
|
|
62
|
-
`organizations/invitations`, `settings/api-keys`, `settings/api-keys/[id]`.
|
|
63
|
-
- Why: SvelteKit prefers specific routes over the catch-all, so any
|
|
64
|
-
`+server.ts` you keep wins. Custom endpoints can still go in
|
|
65
|
-
`src/routes/**/+server.ts` as before, OR be registered onto the Hono
|
|
66
|
-
app via `aphex.config.ts → api: (app) => { app.post(...) }`.
|
|
67
|
-
- Upgrade: copy `src/routes/api/[...slug]/+server.ts` from the template,
|
|
68
|
-
then delete any of the 24 shims you haven't customized. If you
|
|
69
|
-
customized one, leave it — it'll continue to win over the catch-all.
|
|
70
|
-
|
|
71
|
-
## 0.0.2
|
|
72
|
-
|
|
73
|
-
- **chore(deps): bump `@aphexcms/cms-core` to `^2.1.2` and `@aphexcms/ui` to `^0.3.4`**
|
|
74
|
-
- Fixes ESM resolution of the `schema-context.svelte` rune module
|
|
75
|
-
(`ERR_MODULE_NOT_FOUND`) and adds the `svelte` export condition on
|
|
76
|
-
subpath exports (`/client`, `/server`, `/schema`, `/routes/*`, etc.) so
|
|
77
|
-
SvelteKit's Vite plugin claims them instead of Node's default loader
|
|
78
|
-
trying to import raw `.svelte` files (`ERR_UNKNOWN_FILE_EXTENSION`).
|
|
79
|
-
- No source changes required in the template — reinstall to pick it up.
|
|
80
|
-
|
|
81
|
-
- **chore(styles): drop `@import '@aphexcms/ui/themes/aphex'` from `src/app.css`**
|
|
82
|
-
- The `@aphexcms/ui/themes/aphex` theme file was removed from
|
|
83
|
-
`@aphexcms/ui@0.3.4`. If you kept that import in your own `app.css`,
|
|
84
|
-
delete the line when you upgrade or the build will fail to resolve it.
|
|
85
|
-
|
|
86
|
-
- **fix(admin): delete-asset modal + document-editor header + boolean autosave**
|
|
87
|
-
- All three fixes live in `@aphexcms/cms-core`; upgrading the dep is enough.
|
|
88
|
-
- Long asset filenames no longer stretch the delete confirm dialog.
|
|
89
|
-
- Document editor top-row actions are vertically centered.
|
|
90
|
-
- Autosave compares against an initial-defaults snapshot — unchecking a
|
|
91
|
-
boolean now saves, and fields with `initialValue: true` no longer
|
|
92
|
-
auto-create an empty doc on mount.
|
|
93
|
-
|
|
94
|
-
- **chore(drizzle): regenerate initial migration**
|
|
95
|
-
- `drizzle/0000_tiny_redwing.sql`, `drizzle/meta/0000_snapshot.json`, `drizzle/meta/_journal.json`
|
|
96
|
-
- Template migration was stale vs. the current schema (missing
|
|
97
|
-
`cms_document_versions`, `cms_instance_settings`, `cms_roles`, the
|
|
98
|
-
`version_event` enum, and the `unpublished` document status).
|
|
99
|
-
- If you've already run `db:push` against your project DB you're fine;
|
|
100
|
-
users starting fresh from this template will now get the full schema.
|
|
101
|
-
|
|
102
|
-
- **chore(admin): comment out `<PermissionsDebug />`**
|
|
103
|
-
- `src/routes/(protected)/admin/+layout.svelte`
|
|
104
|
-
- Debug overlay disabled by default in the shipped template.
|
|
105
|
-
|
|
106
|
-
<!--
|
|
107
|
-
Example entry:
|
|
108
|
-
|
|
109
|
-
- **fix(members): reject self-invitation and duplicate members**
|
|
110
|
-
- `src/routes/(protected)/admin/settings/members/+page.svelte`
|
|
111
|
-
- Handled server-side in cms-core; UI unchanged. Safe to skip if you
|
|
112
|
-
haven't customized the invite flow.
|
|
113
|
-
|
|
114
|
-
- **feat(versions): add document versions API routes**
|
|
115
|
-
- `src/routes/api/documents/[id]/versions/+server.ts`
|
|
116
|
-
- `src/routes/api/documents/[id]/versions/[version]/+server.ts`
|
|
117
|
-
- `src/routes/api/documents/[id]/versions/[version]/restore/+server.ts`
|
|
118
|
-
- Clean re-exports from `@aphexcms/cms-core/server`. Port these over to
|
|
119
|
-
get version history in your admin UI.
|
|
120
|
-
-->
|
|
121
|
-
|
|
122
|
-
## 0.0.1
|
|
123
|
-
|
|
124
|
-
- Initial template.
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Build stage
|
|
2
|
-
FROM node:20-alpine AS builder
|
|
3
|
-
|
|
4
|
-
# Install pnpm
|
|
5
|
-
RUN npm install -g pnpm
|
|
6
|
-
|
|
7
|
-
WORKDIR /app
|
|
8
|
-
|
|
9
|
-
# Copy workspace files
|
|
10
|
-
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
|
11
|
-
COPY turbo.json ./
|
|
12
|
-
COPY tsconfig.json ./
|
|
13
|
-
|
|
14
|
-
# Copy all packages and apps
|
|
15
|
-
COPY packages ./packages
|
|
16
|
-
COPY apps/studio ./apps/studio
|
|
17
|
-
|
|
18
|
-
# Install dependencies
|
|
19
|
-
RUN pnpm install --frozen-lockfile
|
|
20
|
-
|
|
21
|
-
# Build arguments for environment variables needed at build time
|
|
22
|
-
ARG ACCESS_API_KEY
|
|
23
|
-
ARG GITHUB_TOKEN
|
|
24
|
-
ARG RESEND_API_KEY
|
|
25
|
-
ARG AUTH_SECRET
|
|
26
|
-
ARG AUTH_URL
|
|
27
|
-
ARG DATABASE_URL
|
|
28
|
-
|
|
29
|
-
# Set as environment variables for the build
|
|
30
|
-
ENV ACCESS_API_KEY=$ACCESS_API_KEY
|
|
31
|
-
ENV GITHUB_TOKEN=$GITHUB_TOKEN
|
|
32
|
-
ENV RESEND_API_KEY=$RESEND_API_KEY
|
|
33
|
-
ENV AUTH_SECRET=$AUTH_SECRET
|
|
34
|
-
ENV AUTH_URL=$AUTH_URL
|
|
35
|
-
ENV DATABASE_URL=$DATABASE_URL
|
|
36
|
-
|
|
37
|
-
# Build the application
|
|
38
|
-
WORKDIR /app/apps/studio
|
|
39
|
-
RUN pnpm build
|
|
40
|
-
|
|
41
|
-
# Production stage
|
|
42
|
-
FROM node:20-alpine AS runner
|
|
43
|
-
|
|
44
|
-
# Copy workspace root files first
|
|
45
|
-
COPY --from=builder /app/package.json /app/package.json
|
|
46
|
-
COPY --from=builder /app/pnpm-workspace.yaml /app/pnpm-workspace.yaml
|
|
47
|
-
COPY --from=builder /app/node_modules /app/node_modules
|
|
48
|
-
COPY --from=builder /app/packages /app/packages
|
|
49
|
-
|
|
50
|
-
# Set working directory for the app
|
|
51
|
-
WORKDIR /app/apps/studio
|
|
52
|
-
|
|
53
|
-
# Copy studio app files
|
|
54
|
-
COPY --from=builder /app/apps/studio/build ./build
|
|
55
|
-
COPY --from=builder /app/apps/studio/package.json ./package.json
|
|
56
|
-
COPY --from=builder /app/apps/studio/node_modules ./node_modules
|
|
57
|
-
COPY --from=builder /app/apps/studio/drizzle ./drizzle
|
|
58
|
-
COPY --from=builder /app/apps/studio/drizzle.config.ts ./drizzle.config.ts
|
|
59
|
-
|
|
60
|
-
# Expose port
|
|
61
|
-
EXPOSE 3000
|
|
62
|
-
|
|
63
|
-
# Set environment to production
|
|
64
|
-
ENV NODE_ENV=production
|
|
65
|
-
ENV PORT=3000
|
|
66
|
-
ENV NODE_PATH=/app/node_modules
|
|
67
|
-
|
|
68
|
-
# Start the application
|
|
69
|
-
CMD ["node", "build"]
|
package/templates/base/README.md
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# Aphex CMS
|
|
2
|
-
|
|
3
|
-
A clean starting point for building with Aphex CMS. No example schemas — just the wiring.
|
|
4
|
-
|
|
5
|
-
> This directory is mirrored to [**IcelandicIcecream/aphex-base**](https://github.com/IcelandicIcecream/aphex-base) on every change, so you can clone it directly as a standalone project:
|
|
6
|
-
>
|
|
7
|
-
> ```bash
|
|
8
|
-
> git clone https://github.com/IcelandicIcecream/aphex-base my-app
|
|
9
|
-
> cd my-app && pnpm install
|
|
10
|
-
> ```
|
|
11
|
-
>
|
|
12
|
-
> Or scaffold via the CLI: `pnpm aphex create`.
|
|
13
|
-
|
|
14
|
-
## Getting Started
|
|
15
|
-
|
|
16
|
-
### 1. Install Dependencies
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
pnpm install
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### 2. Set Up Environment Variables
|
|
23
|
-
|
|
24
|
-
Copy the example file and update as needed:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
cp .env.example .env
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### 3. Start PostgreSQL Database
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
pnpm db:start
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### 4. Run Database Migrations
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
pnpm db:migrate
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### 5. Start Development Server
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
pnpm dev
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Your application will be available at `http://localhost:5173`
|
|
49
|
-
|
|
50
|
-
### 6. First Login
|
|
51
|
-
|
|
52
|
-
1. Go to `http://localhost:5173/login`
|
|
53
|
-
2. Sign up with your email and password — the first user automatically becomes the super admin with a default organization
|
|
54
|
-
3. Access God Mode at `/god-mode` for instance-level administration
|
|
55
|
-
|
|
56
|
-
## Defining Content Schemas
|
|
57
|
-
|
|
58
|
-
Add your content schemas in `src/lib/schemaTypes/`. Two types are available:
|
|
59
|
-
|
|
60
|
-
- **`document`** — Top-level entities (e.g. Page, Post, Product)
|
|
61
|
-
- **`object`** — Reusable nested structures (e.g. SEO, Hero)
|
|
62
|
-
|
|
63
|
-
Example:
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
// src/lib/schemaTypes/post.ts
|
|
67
|
-
import type { SchemaType } from '@aphexcms/cms-core';
|
|
68
|
-
|
|
69
|
-
const post: SchemaType = {
|
|
70
|
-
type: 'document',
|
|
71
|
-
name: 'post',
|
|
72
|
-
title: 'Post',
|
|
73
|
-
fields: [
|
|
74
|
-
{
|
|
75
|
-
name: 'title',
|
|
76
|
-
type: 'string',
|
|
77
|
-
title: 'Title',
|
|
78
|
-
validation: (Rule) => Rule.required()
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: 'slug',
|
|
82
|
-
type: 'slug',
|
|
83
|
-
title: 'Slug',
|
|
84
|
-
source: 'title'
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
name: 'body',
|
|
88
|
-
type: 'text',
|
|
89
|
-
title: 'Body'
|
|
90
|
-
}
|
|
91
|
-
]
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export default post;
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Then register it in `src/lib/schemaTypes/index.ts`:
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
import post from './post.js';
|
|
101
|
-
|
|
102
|
-
export const schemaTypes = [post];
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Available field types: `string`, `text`, `number`, `boolean`, `slug`, `image`, `date`, `datetime`, `url`, `array`, `object`, `reference`
|
|
106
|
-
|
|
107
|
-
## Available Scripts
|
|
108
|
-
|
|
109
|
-
- `pnpm dev` — Start the development server
|
|
110
|
-
- `pnpm build` — Build for production
|
|
111
|
-
- `pnpm preview` — Preview production build
|
|
112
|
-
- `pnpm db:start` — Start PostgreSQL via Docker
|
|
113
|
-
- `pnpm db:migrate` — Run database migrations
|
|
114
|
-
- `pnpm db:push` — Push schema changes (dev only)
|
|
115
|
-
- `pnpm db:generate` — Generate migration files
|
|
116
|
-
- `pnpm db:studio` — Open Drizzle Studio
|
|
117
|
-
|
|
118
|
-
## Project Structure
|
|
119
|
-
|
|
120
|
-
```
|
|
121
|
-
.
|
|
122
|
-
├── src/
|
|
123
|
-
│ ├── lib/
|
|
124
|
-
│ │ ├── server/
|
|
125
|
-
│ │ │ ├── auth/ # Authentication (Better Auth)
|
|
126
|
-
│ │ │ ├── db/ # Database connection and schema
|
|
127
|
-
│ │ │ ├── email/ # Email templates and adapter
|
|
128
|
-
│ │ │ ├── services/ # Business logic
|
|
129
|
-
│ │ │ └── storage/ # File storage adapter
|
|
130
|
-
│ │ ├── schemaTypes/ # Your content type definitions
|
|
131
|
-
│ │ └── utils/ # Utility functions
|
|
132
|
-
│ └── routes/
|
|
133
|
-
│ ├── (protected)/admin/ # Admin panel
|
|
134
|
-
│ ├── api/ # API endpoints
|
|
135
|
-
│ ├── god-mode/ # Super admin panel
|
|
136
|
-
│ └── login/ # Authentication
|
|
137
|
-
├── aphex.config.ts # CMS configuration
|
|
138
|
-
├── drizzle/ # Database migrations
|
|
139
|
-
└── docker-compose.yml # PostgreSQL setup
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Learn More
|
|
143
|
-
|
|
144
|
-
- [Aphex CMS](https://github.com/IcelandicIcecream/aphex)
|
|
145
|
-
- [SvelteKit](https://kit.svelte.dev)
|
|
146
|
-
- [Drizzle ORM](https://orm.drizzle.team)
|
|
147
|
-
- [Better Auth](https://better-auth.com)
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// Aphex CMS Configuration
|
|
2
|
-
// This file defines the CMS configuration for your application
|
|
3
|
-
import { createCMSConfig } from '@aphexcms/cms-core/server';
|
|
4
|
-
import { schemaTypes } from './src/lib/schemaTypes/index.js';
|
|
5
|
-
import { authProvider } from './src/lib/server/auth';
|
|
6
|
-
import { db } from './src/lib/server/db';
|
|
7
|
-
import { email } from './src/lib/server/email';
|
|
8
|
-
import { registerInvitationEmailHook } from './src/lib/server/email/invitation-hook';
|
|
9
|
-
import { storageAdapter } from './src/lib/server/storage';
|
|
10
|
-
import { cacheAdapter } from './src/lib/server/cache';
|
|
11
|
-
|
|
12
|
-
export default createCMSConfig({
|
|
13
|
-
schemaTypes,
|
|
14
|
-
|
|
15
|
-
// Provide the shared database and storage adapter instances directly.
|
|
16
|
-
// These are created once in their respective /lib/server/.. files.
|
|
17
|
-
database: db,
|
|
18
|
-
storage: storageAdapter,
|
|
19
|
-
email,
|
|
20
|
-
cache: cacheAdapter,
|
|
21
|
-
|
|
22
|
-
auth: {
|
|
23
|
-
provider: authProvider,
|
|
24
|
-
loginUrl: '/login' // Redirect here when unauthenticated
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
// GraphQL is built-in and enabled by default.
|
|
28
|
-
// Set to false to disable, or pass config: { defaultPerspective: 'draft', path: '/api/graphql' }
|
|
29
|
-
graphql: {
|
|
30
|
-
defaultPerspective: 'draft',
|
|
31
|
-
path: '/api/aphex-graphql'
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
customization: {
|
|
35
|
-
branding: {
|
|
36
|
-
title: 'Aphex'
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
// Wrap built-in handlers with side effects (e.g. send the invitation
|
|
41
|
-
// email after the invite is created). Runs BEFORE built-in routes mount.
|
|
42
|
-
api: (app) => {
|
|
43
|
-
registerInvitationEmailHook(app);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
db:
|
|
3
|
-
image: postgres:18
|
|
4
|
-
restart: always
|
|
5
|
-
env_file:
|
|
6
|
-
- .env
|
|
7
|
-
ports:
|
|
8
|
-
- ${PG_PORT:-5432}:5432
|
|
9
|
-
environment:
|
|
10
|
-
POSTGRES_USER: ${PG_USER:-root}
|
|
11
|
-
POSTGRES_PASSWORD: ${PG_PASSWORD:-mysecretpassword}
|
|
12
|
-
POSTGRES_DB: ${PG_DATABASE:-local}
|
|
13
|
-
volumes:
|
|
14
|
-
- pgdata:/var/lib/postgresql
|
|
15
|
-
|
|
16
|
-
mailpit:
|
|
17
|
-
image: axllent/mailpit
|
|
18
|
-
ports:
|
|
19
|
-
- 8025:8025
|
|
20
|
-
- 1025:1025
|
|
21
|
-
environment:
|
|
22
|
-
MP_MAX_MESSAGES: 5000
|
|
23
|
-
MP_DATABASE: /data/mailpit.db
|
|
24
|
-
MP_SMTP_AUTH_ACCEPT_ANY: 1
|
|
25
|
-
MP_SMTP_AUTH_ALLOW_INSECURE: 1
|
|
26
|
-
volumes:
|
|
27
|
-
- mailpit_data:/data
|
|
28
|
-
|
|
29
|
-
volumes:
|
|
30
|
-
pgdata:
|
|
31
|
-
mailpit_data:
|