kernelcms 0.1.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 +70 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +133 -0
- package/dist/chunk-O5TO5JFA.js +1181 -0
- package/dist/chunk-Z2RKB4LF.js +285 -0
- package/dist/client.d.ts +57 -0
- package/dist/client.js +61 -0
- package/dist/index-BxvPeUO2.d.ts +134 -0
- package/dist/index.d.ts +224 -0
- package/dist/index.js +90 -0
- package/dist/postgres.d.ts +21 -0
- package/dist/postgres.js +459 -0
- package/dist/server.d.ts +27 -0
- package/dist/server.js +13 -0
- package/dist/sqlite.d.ts +14 -0
- package/dist/sqlite.js +393 -0
- package/dist/types-DMOX4FIP.d.ts +310 -0
- package/package.json +72 -0
package/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# kernelcms
|
|
2
|
+
|
|
3
|
+
The TanStack-native, adapter-based, end-to-end type-safe **headless CMS** — config-as-code and fully self-hosted.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install kernelcms
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
> Requires **Node >= 22** and a **PostgreSQL** database (set `DATABASE_URL`).
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// kernel.config.ts
|
|
15
|
+
import { defineConfig } from 'kernelcms'
|
|
16
|
+
import { postgresAdapter } from 'kernelcms/postgres'
|
|
17
|
+
|
|
18
|
+
export default defineConfig({
|
|
19
|
+
secret: process.env.KERNEL_SECRET,
|
|
20
|
+
db: postgresAdapter(), // reads DATABASE_URL
|
|
21
|
+
collections: [
|
|
22
|
+
{
|
|
23
|
+
slug: 'posts',
|
|
24
|
+
access: { read: () => true },
|
|
25
|
+
fields: [
|
|
26
|
+
{ name: 'title', type: 'text', required: true },
|
|
27
|
+
{ name: 'body', type: 'richText' },
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
export DATABASE_URL="postgres://user:pass@localhost:5432/mydb"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { initKernel } from 'kernelcms'
|
|
40
|
+
import config from './kernel.config'
|
|
41
|
+
|
|
42
|
+
const kernel = await initKernel(config, { autoMigrate: true })
|
|
43
|
+
const post = await kernel.create({ collection: 'posts', data: { title: 'Hello' }, overrideAccess: true })
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Entry points
|
|
47
|
+
|
|
48
|
+
| Import | What you get |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| `kernelcms` | Config, fields, the Local API (`initKernel`), auth, access, codegen, error types |
|
|
51
|
+
| `kernelcms/postgres` | `postgresAdapter` — the default PostgreSQL adapter (pooled, concurrent transactions) |
|
|
52
|
+
| `kernelcms/sqlite` | `sqliteAdapter` — an optional `node:sqlite` adapter, handy for local dev and tests |
|
|
53
|
+
| `kernelcms/server` | `createRequestHandler`, `serve` — the REST handler + Node http adapter |
|
|
54
|
+
| `kernelcms/client` | `createClient` — a tiny typed fetch client (browser/edge/Node) |
|
|
55
|
+
|
|
56
|
+
## CLI
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx kernel migrate # create/update tables from the config
|
|
60
|
+
npx kernel seed # run the exported seed()
|
|
61
|
+
npx kernel dev # migrate + start the REST API
|
|
62
|
+
npx kernel generate:types # emit TypeScript types for the content model
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The CLI imports your `kernel.config.ts` directly — run on Node ≥ 22.6 (type
|
|
66
|
+
stripping) or point `--config` at a compiled `.js`/`.mjs`.
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
MIT
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
serve
|
|
4
|
+
} from "./chunk-Z2RKB4LF.js";
|
|
5
|
+
import {
|
|
6
|
+
generateTypes,
|
|
7
|
+
initKernel
|
|
8
|
+
} from "./chunk-O5TO5JFA.js";
|
|
9
|
+
|
|
10
|
+
// ../cli/src/index.ts
|
|
11
|
+
import { writeFileSync } from "fs";
|
|
12
|
+
import { dirname, resolve } from "path";
|
|
13
|
+
import { pathToFileURL } from "url";
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
const positionals = [];
|
|
16
|
+
const flags = {};
|
|
17
|
+
for (let i = 0; i < argv.length; i++) {
|
|
18
|
+
const arg = argv[i];
|
|
19
|
+
if (arg.startsWith("--")) {
|
|
20
|
+
const key = arg.slice(2);
|
|
21
|
+
const next = argv[i + 1];
|
|
22
|
+
if (next !== void 0 && !next.startsWith("--")) {
|
|
23
|
+
flags[key] = next;
|
|
24
|
+
i++;
|
|
25
|
+
} else {
|
|
26
|
+
flags[key] = true;
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
positionals.push(arg);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return { command: positionals[0], positionals: positionals.slice(1), flags };
|
|
33
|
+
}
|
|
34
|
+
async function loadConfig(flags) {
|
|
35
|
+
const configPath = typeof flags.config === "string" ? flags.config : "kernel.config.ts";
|
|
36
|
+
const abs = resolve(process.cwd(), configPath);
|
|
37
|
+
const mod = await import(pathToFileURL(abs).href);
|
|
38
|
+
const config = mod.default ?? mod.config;
|
|
39
|
+
if (!config) throw new Error(`No config found. Export a default config from ${configPath}.`);
|
|
40
|
+
return { config, seed: mod.seed, path: abs };
|
|
41
|
+
}
|
|
42
|
+
var HELP = `KernelCMS CLI
|
|
43
|
+
|
|
44
|
+
Usage: kernel <command> [options]
|
|
45
|
+
|
|
46
|
+
Commands:
|
|
47
|
+
migrate Create/update database tables from the config schema
|
|
48
|
+
seed Run the exported seed() function
|
|
49
|
+
generate:types Write generated TypeScript types for the content model
|
|
50
|
+
dev Migrate, then start the REST API server
|
|
51
|
+
|
|
52
|
+
Options:
|
|
53
|
+
--config <path> Path to kernel.config.ts (default: ./kernel.config.ts)
|
|
54
|
+
--port <number> Port for "dev" (default: $PORT or 3000)
|
|
55
|
+
--out <path> Output file for "generate:types"
|
|
56
|
+
`;
|
|
57
|
+
async function run(argv) {
|
|
58
|
+
const { command, flags } = parseArgs(argv);
|
|
59
|
+
switch (command) {
|
|
60
|
+
case "migrate": {
|
|
61
|
+
const { config } = await loadConfig(flags);
|
|
62
|
+
const kernel = await initKernel(config);
|
|
63
|
+
const report = await kernel.db.migrate(kernel.schema);
|
|
64
|
+
console.log(
|
|
65
|
+
`\u2713 Migration complete \u2014 ${report.createdTables.length} table(s) created, ${report.addedColumns.length} column(s) added.`
|
|
66
|
+
);
|
|
67
|
+
if (report.createdTables.length) console.log(` Created: ${report.createdTables.join(", ")}`);
|
|
68
|
+
await kernel.destroy();
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case "seed": {
|
|
72
|
+
const { config, seed } = await loadConfig(flags);
|
|
73
|
+
if (!seed) throw new Error("No `seed` export found in the config module.");
|
|
74
|
+
const kernel = await initKernel(config, { autoMigrate: true });
|
|
75
|
+
await seed(kernel);
|
|
76
|
+
console.log("\u2713 Seed complete.");
|
|
77
|
+
await kernel.destroy();
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case "generate:types":
|
|
81
|
+
case "types": {
|
|
82
|
+
const { config, path } = await loadConfig(flags);
|
|
83
|
+
const output = generateTypes({ collections: config.collections, globals: config.globals ?? [] });
|
|
84
|
+
const out = typeof flags.out === "string" ? resolve(process.cwd(), flags.out) : resolve(dirname(path), "kernel-types.ts");
|
|
85
|
+
writeFileSync(out, output, "utf8");
|
|
86
|
+
console.log(`\u2713 Types written to ${out}`);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case "dev": {
|
|
90
|
+
const { config } = await loadConfig(flags);
|
|
91
|
+
const kernel = await initKernel(config, { autoMigrate: true });
|
|
92
|
+
const port = typeof flags.port === "string" ? Number(flags.port) : Number(process.env.PORT) || 3e3;
|
|
93
|
+
const server = await serve(kernel, {
|
|
94
|
+
port,
|
|
95
|
+
apiKey: process.env.KERNEL_API_KEY,
|
|
96
|
+
cors: true
|
|
97
|
+
});
|
|
98
|
+
console.log(`
|
|
99
|
+
KernelCMS dev server`);
|
|
100
|
+
console.log(` \u279C API: ${server.url}${kernel.config.routes.api}`);
|
|
101
|
+
console.log(` \u279C Health: ${server.url}${kernel.config.routes.api}/health`);
|
|
102
|
+
console.log(` \u279C Collections: ${kernel.config.collections.map((c) => c.slug).join(", ") || "(none)"}`);
|
|
103
|
+
if (!process.env.KERNEL_API_KEY) {
|
|
104
|
+
console.log(` ! Set KERNEL_API_KEY to enable trusted writes over HTTP.`);
|
|
105
|
+
}
|
|
106
|
+
const shutdown = async () => {
|
|
107
|
+
await server.close();
|
|
108
|
+
await kernel.destroy();
|
|
109
|
+
process.exit(0);
|
|
110
|
+
};
|
|
111
|
+
process.on("SIGINT", shutdown);
|
|
112
|
+
process.on("SIGTERM", shutdown);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case void 0:
|
|
116
|
+
case "help":
|
|
117
|
+
case "--help":
|
|
118
|
+
console.log(HELP);
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
console.error(`Unknown command "${command}".
|
|
122
|
+
`);
|
|
123
|
+
console.log(HELP);
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/bin.ts
|
|
129
|
+
run(process.argv.slice(2)).catch((err) => {
|
|
130
|
+
console.error(`
|
|
131
|
+
\u2717 ${err instanceof Error ? err.message : String(err)}`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
});
|