@aerostack/cli 1.3.5 → 1.5.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 +15 -0
- package/bin/postinstall.js +8 -39
- package/bin/run.js +85 -83
- package/package.json +16 -3
- package/templates/drizzle.config.ts +16 -0
- package/templates/package.json +23 -0
- package/templates/src/db/client.ts +12 -0
- package/templates/src/db/schema.ts +14 -0
- package/templates/src/index.ts +28 -0
- package/templates/tsconfig.json +29 -0
- package/templates/wrangler.toml +16 -0
package/README.md
CHANGED
|
@@ -29,6 +29,21 @@ npx aerostack deploy
|
|
|
29
29
|
|
|
30
30
|
The first run downloads the binary from GitHub releases. Subsequent runs use the cached binary at `~/.aerostack/bin` (shared with the curl install).
|
|
31
31
|
|
|
32
|
+
## Registry: add community functions
|
|
33
|
+
|
|
34
|
+
Install open-source functions from the Aerostack registry into your project (Cloudflare or Node.js):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx aerostack add stripe-checkout
|
|
38
|
+
npx aerostack add alice/stripe-checkout
|
|
39
|
+
npx aerostack add stripe-checkout --runtime=node
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- **Cloudflare** (default): Adds Hono + D1 adapter and wires the route. Uses Drizzle in `src/db/` when the function has a schema.
|
|
43
|
+
- **Node.js** (`--runtime=node`): Adds a Node/Express adapter. Pass your own Drizzle client (pg or sqlite) and mount the router in your app.
|
|
44
|
+
|
|
45
|
+
Functions follow the **Open Function Standard**: one portable core, multiple adapters. You can use them in any Node.js project, not only on the Aerostack platform. See `planning/OPEN_FUNCTION_STANDARD.md` for the spec.
|
|
46
|
+
|
|
32
47
|
## Uninstall
|
|
33
48
|
|
|
34
49
|
```bash
|
package/bin/postinstall.js
CHANGED
|
@@ -1,41 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// For the purpose of this edit, we'll assume `downloadBinary()` is a placeholder
|
|
11
|
-
// for the actual download logic that would be placed here.
|
|
12
|
-
try {
|
|
13
|
-
// Original download logic (placeholder, as it's not in the provided original code)
|
|
14
|
-
// If downloadBinary() is not defined, this will cause a ReferenceError.
|
|
15
|
-
// The user's instruction implies this function exists or will be added.
|
|
16
|
-
// downloadBinary(); // Uncomment and define if actual download logic is intended here
|
|
17
|
-
} catch (e) {
|
|
18
|
-
console.warn('⚠️ Aerostack CLI download failed. You may need to install it manually or check your connection.');
|
|
19
|
-
console.warn(' Details: ' + e.message);
|
|
20
|
-
// Do not exit with error, allow install to continue
|
|
21
|
-
process.exit(0);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Global install: package at prefix/node_modules/aerostack, bin at prefix/bin
|
|
25
|
-
const pkgRoot = path.resolve(__dirname, "..");
|
|
26
|
-
const prefix = path.dirname(path.dirname(pkgRoot));
|
|
27
|
-
const binDir = path.join(prefix, "bin");
|
|
28
|
-
const binPath = path.join(binDir, process.platform === "win32" ? "aerostack.cmd" : "aerostack");
|
|
29
|
-
|
|
30
|
-
if (!fs.existsSync(binDir)) return;
|
|
31
|
-
|
|
32
|
-
const pathEnv = (process.env.PATH || "").split(path.delimiter);
|
|
33
|
-
const inPath = pathEnv.some((p) => path.resolve(p) === path.resolve(binDir));
|
|
34
|
-
|
|
35
|
-
if (!inPath) {
|
|
36
|
-
console.log("\n\u001b[33mAerostack installed. Add to PATH (run once, or add to ~/.zshrc):\u001b[0m");
|
|
37
|
-
console.log(` \u001b[36mexport PATH="$PATH:${binDir}"\u001b[0m\n`);
|
|
38
|
-
console.log("Or use \u001b[32mnpx aerostack\u001b[0m (no PATH config needed).\n");
|
|
39
|
-
} else {
|
|
40
|
-
console.log("\n\u001b[32mAerostack installed. Run: aerostack --version\u001b[0m\n");
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
|
|
5
|
+
// Just a polite notice
|
|
6
|
+
const binDir = join(process.env.HOME || process.env.USERPROFILE || '.', '.aerostack', 'bin');
|
|
7
|
+
if (existsSync(binDir)) {
|
|
8
|
+
console.log(`\nAerostack is installed.`);
|
|
9
|
+
console.log(`To use the binary directly, add ${binDir} to your PATH.\n`);
|
|
41
10
|
}
|
package/bin/run.js
CHANGED
|
@@ -1,20 +1,55 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Aerostack CLI -
|
|
4
|
-
*
|
|
3
|
+
* Aerostack CLI - Hybrid Dispatcher
|
|
4
|
+
*
|
|
5
|
+
* Routes specific commands (init, add, publish, list, login) to the
|
|
6
|
+
* pure Node.js implementation (drizzle/hono support).
|
|
7
|
+
*
|
|
8
|
+
* All other commands map to the Go binary (legacy/platform).
|
|
5
9
|
*/
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
import { spawn } from 'child_process';
|
|
12
|
+
import { existsSync, mkdirSync, chmodSync, writeFileSync, rmSync, renameSync } from 'fs';
|
|
13
|
+
import { join, resolve } from 'path';
|
|
14
|
+
import { platform as getOsPlatform, arch as getOsArch, tmpdir } from 'os';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
|
|
17
|
+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
18
|
+
|
|
19
|
+
// ─── 1. Hybrid Dispatcher ──────────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
const args = process.argv.slice(2);
|
|
22
|
+
const command = args[0];
|
|
23
|
+
const NODE_COMMANDS = ['init', 'add', 'publish', 'list', 'login'];
|
|
24
|
+
|
|
25
|
+
if (command && NODE_COMMANDS.includes(command)) {
|
|
26
|
+
// Dispatch to Node.js implementation
|
|
27
|
+
import('../dist/index.js').then(m => m.run(args)).catch(err => {
|
|
28
|
+
console.error('Failed to run Node.js CLI:', err);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
});
|
|
31
|
+
} else {
|
|
32
|
+
// Dispatch to Go implementation
|
|
33
|
+
ensureBinary().then(binPath => {
|
|
34
|
+
const child = spawn(binPath, args, { stdio: 'inherit' });
|
|
35
|
+
child.on('exit', code => process.exit(code ?? 0));
|
|
36
|
+
}).catch(err => {
|
|
37
|
+
console.error('Error:', err.message);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ─── 2. Go Binary Downloader (Legacy) ──────────────────────────────────────────
|
|
10
43
|
|
|
11
44
|
const REPO = "aerostackdev/cli";
|
|
12
45
|
const BINARY = "aerostack";
|
|
13
|
-
|
|
46
|
+
// Use HOME or USERPROFILE for global install location
|
|
47
|
+
const HOME = process.env.HOME || process.env.USERPROFILE || tmpdir();
|
|
48
|
+
const INSTALL_DIR = process.env.AEROSTACK_INSTALL_DIR || join(HOME, ".aerostack", "bin");
|
|
14
49
|
|
|
15
50
|
function getPlatform() {
|
|
16
|
-
const platform =
|
|
17
|
-
const arch =
|
|
51
|
+
const platform = getOsPlatform();
|
|
52
|
+
const arch = getOsArch();
|
|
18
53
|
const map = {
|
|
19
54
|
darwin: { arm64: "darwin_arm64", x64: "darwin_amd64" },
|
|
20
55
|
linux: { arm64: "linux_arm64", x64: "linux_amd64" },
|
|
@@ -26,102 +61,69 @@ function getPlatform() {
|
|
|
26
61
|
}
|
|
27
62
|
|
|
28
63
|
async function getLatestVersion() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
64
|
+
// If we can't check, fallback or fail. Here we try checking.
|
|
65
|
+
try {
|
|
66
|
+
const res = await fetch(`https://api.github.com/repos/${REPO}/releases/latest`, {
|
|
67
|
+
headers: { "User-Agent": "aerostack-cli-npm/1.5.0" },
|
|
68
|
+
});
|
|
69
|
+
if (!res.ok) return "1.3.0"; // Fallback if rate limited
|
|
70
|
+
const data = await res.json();
|
|
71
|
+
return data.tag_name.replace(/^v/, '');
|
|
72
|
+
} catch {
|
|
73
|
+
return "1.3.0";
|
|
74
|
+
}
|
|
37
75
|
}
|
|
38
76
|
|
|
39
77
|
async function downloadBinary(version, asset) {
|
|
40
78
|
const ext = asset.startsWith("windows") ? "zip" : "tar.gz";
|
|
41
|
-
const archive = `${BINARY}
|
|
42
|
-
|
|
79
|
+
const archive = `${BINARY}_v${version}_${asset}.${ext}`; // Check github release naming convention
|
|
80
|
+
// Usually: aerostack_1.3.0_darwin_arm64.tar.gz
|
|
81
|
+
// Let's assume standard GoReleaser naming: name_version_os_arch
|
|
82
|
+
const releaseName = `${BINARY}_${version}_${asset}.${ext}`;
|
|
43
83
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
84
|
+
const url = `https://github.com/${REPO}/releases/download/v${version}/${releaseName}`;
|
|
85
|
+
const tmpDir = join(tmpdir(), `aerostack-${Date.now()}`);
|
|
86
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
87
|
+
|
|
88
|
+
const archivePath = join(tmpDir, releaseName);
|
|
89
|
+
|
|
90
|
+
console.error(`Downloading Aerostack Go Core v${version}...`);
|
|
91
|
+
const res = await fetch(url, { redirect: "follow" });
|
|
92
|
+
if (!res.ok) throw new Error(`Download failed: ${url} (${res.status})`);
|
|
47
93
|
|
|
48
|
-
const res = await fetch(url, {
|
|
49
|
-
headers: { "User-Agent": "aerostack-cli-npm/1.0" },
|
|
50
|
-
redirect: "follow",
|
|
51
|
-
});
|
|
52
|
-
if (!res.ok) throw new Error(`Download failed: ${url}`);
|
|
53
94
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
54
|
-
|
|
95
|
+
writeFileSync(archivePath, buffer);
|
|
55
96
|
|
|
56
97
|
const binDir = INSTALL_DIR;
|
|
57
|
-
|
|
58
|
-
const binPath =
|
|
98
|
+
mkdirSync(binDir, { recursive: true });
|
|
99
|
+
const binPath = join(binDir, process.platform === "win32" ? `${BINARY}.exe` : BINARY);
|
|
59
100
|
|
|
60
101
|
if (ext === "zip") {
|
|
61
|
-
const AdmZip =
|
|
102
|
+
const AdmZip = (await import("adm-zip")).default;
|
|
62
103
|
const zip = new AdmZip(archivePath);
|
|
63
104
|
zip.extractAllTo(tmpDir, true);
|
|
64
|
-
const extracted =
|
|
65
|
-
|
|
105
|
+
const extracted = join(tmpDir, `${BINARY}.exe`);
|
|
106
|
+
if (existsSync(extracted)) renameSync(extracted, binPath);
|
|
66
107
|
} else {
|
|
67
|
-
const tar =
|
|
108
|
+
const tar = (await import("tar")).default;
|
|
68
109
|
await tar.x({ file: archivePath, cwd: tmpDir });
|
|
69
|
-
|
|
110
|
+
const extracted = join(tmpDir, BINARY);
|
|
111
|
+
if (existsSync(extracted)) renameSync(extracted, binPath);
|
|
70
112
|
}
|
|
71
113
|
|
|
72
|
-
|
|
73
|
-
|
|
114
|
+
chmodSync(binPath, 0o755);
|
|
115
|
+
try { rmSync(tmpDir, { recursive: true, force: true }); } catch { }
|
|
74
116
|
return binPath;
|
|
75
117
|
}
|
|
76
118
|
|
|
77
|
-
async function getInstalledVersion(binPath) {
|
|
78
|
-
try {
|
|
79
|
-
const { execFileSync } = require("child_process");
|
|
80
|
-
const out = execFileSync(binPath, ["--version"], { encoding: "utf8" });
|
|
81
|
-
const m = out.match(/v?(\d+\.\d+\.\d+)/);
|
|
82
|
-
return m ? m[1] : null;
|
|
83
|
-
} catch {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
119
|
async function ensureBinary() {
|
|
89
|
-
const binPath =
|
|
90
|
-
const {
|
|
91
|
-
const latestVersion = await getLatestVersion();
|
|
92
|
-
|
|
93
|
-
if (fs.existsSync(binPath)) {
|
|
94
|
-
const installed = await getInstalledVersion(binPath);
|
|
95
|
-
if (installed && installed === latestVersion) return binPath;
|
|
96
|
-
if (installed) console.error(`Updating Aerostack CLI v${installed} → v${latestVersion}...`);
|
|
97
|
-
} else {
|
|
98
|
-
console.error(`Downloading Aerostack CLI v${latestVersion}...`);
|
|
99
|
-
}
|
|
120
|
+
const binPath = join(INSTALL_DIR, process.platform === "win32" ? `${BINARY}.exe` : BINARY);
|
|
121
|
+
const { arch, asset } = getPlatform();
|
|
100
122
|
|
|
101
|
-
try
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// Windows on ARM64 can run x64 binaries via emulation.
|
|
105
|
-
// If arm64 artifact is unavailable, fall back to windows_amd64.
|
|
106
|
-
if (platform === "win32" && arch === "arm64" && asset === "windows_arm64") {
|
|
107
|
-
return downloadBinary(latestVersion, "windows_amd64");
|
|
108
|
-
}
|
|
109
|
-
throw err;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
123
|
+
// For now, always try to grab latest or fallback
|
|
124
|
+
// In production we should cache version check
|
|
125
|
+
if (existsSync(binPath)) return binPath;
|
|
112
126
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const binPath = await ensureBinary();
|
|
116
|
-
const child = spawn(binPath, process.argv.slice(2), {
|
|
117
|
-
stdio: "inherit",
|
|
118
|
-
shell: false,
|
|
119
|
-
});
|
|
120
|
-
child.on("exit", (code) => process.exit(code ?? 0));
|
|
121
|
-
} catch (err) {
|
|
122
|
-
console.error("Error:", err.message);
|
|
123
|
-
process.exit(1);
|
|
124
|
-
}
|
|
127
|
+
const version = await getLatestVersion();
|
|
128
|
+
return await downloadBinary(version, asset);
|
|
125
129
|
}
|
|
126
|
-
|
|
127
|
-
main();
|
package/package.json
CHANGED
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aerostack/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Aerostack CLI - Zero-config serverless development for Cloudflare",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"files": [
|
|
6
|
-
"bin"
|
|
7
|
+
"bin",
|
|
8
|
+
"dist",
|
|
9
|
+
"templates"
|
|
7
10
|
],
|
|
8
11
|
"bin": {
|
|
9
12
|
"aerostack": "bin/run.js"
|
|
10
13
|
},
|
|
11
14
|
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
12
16
|
"postinstall": "node bin/postinstall.js",
|
|
13
17
|
"uninstall": "node bin/uninstall.js"
|
|
14
18
|
},
|
|
15
19
|
"dependencies": {
|
|
16
20
|
"adm-zip": "^0.5.16",
|
|
17
|
-
"tar": "^7.0.0"
|
|
21
|
+
"tar": "^7.0.0",
|
|
22
|
+
"chalk": "^5.3.0",
|
|
23
|
+
"ora": "^8.0.1",
|
|
24
|
+
"prompts": "^2.4.2",
|
|
25
|
+
"node-fetch": "^3.3.2"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^22.0.0",
|
|
29
|
+
"@types/prompts": "^2.4.9",
|
|
30
|
+
"typescript": "^5.9.3"
|
|
18
31
|
},
|
|
19
32
|
"keywords": [
|
|
20
33
|
"aerostack",
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineConfig } from 'drizzle-kit';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
schema: [
|
|
5
|
+
'./src/db/schema.ts', // Base/core tables
|
|
6
|
+
'./src/modules/**/schema.ts' // Auto-discover all installed module schemas
|
|
7
|
+
],
|
|
8
|
+
out: './drizzle',
|
|
9
|
+
dialect: 'sqlite',
|
|
10
|
+
driver: 'd1-http',
|
|
11
|
+
dbCredentials: {
|
|
12
|
+
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
|
|
13
|
+
databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
|
|
14
|
+
token: process.env.CLOUDFLARE_D1_TOKEN!,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": true,
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "wrangler dev",
|
|
8
|
+
"deploy": "wrangler deploy",
|
|
9
|
+
"db:push": "drizzle-kit push",
|
|
10
|
+
"db:generate": "drizzle-kit generate",
|
|
11
|
+
"db:studio": "drizzle-kit studio"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"drizzle-orm": "^0.45.1",
|
|
15
|
+
"hono": "^4.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@cloudflare/workers-types": "^4.20250219.0",
|
|
19
|
+
"drizzle-kit": "^0.31.0",
|
|
20
|
+
"typescript": "^5.9.0",
|
|
21
|
+
"wrangler": "^4.0.0"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { drizzle } from 'drizzle-orm/d1';
|
|
2
|
+
import * as schema from './schema';
|
|
3
|
+
|
|
4
|
+
export type DrizzleDB = ReturnType<typeof createDb>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a Drizzle database client bound to the Cloudflare D1 instance.
|
|
8
|
+
* Call this inside each request handler: const db = createDb(c.env.DB);
|
|
9
|
+
*/
|
|
10
|
+
export function createDb(d1: D1Database) {
|
|
11
|
+
return drizzle(d1, { schema });
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/db/schema.ts — Central Schema Hub
|
|
3
|
+
*
|
|
4
|
+
* This file re-exports all table schemas from installed modules.
|
|
5
|
+
* Drizzle uses this for type-safe query building.
|
|
6
|
+
*
|
|
7
|
+
* When you run `npx aerostack add <module>`, the module's schema
|
|
8
|
+
* is imported here automatically.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// aerostack:schema-imports — module schemas are auto-imported above this line
|
|
12
|
+
|
|
13
|
+
// Export everything for Drizzle's relational queries
|
|
14
|
+
// aerostack:schema-exports — exports are auto-added above this line
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/index.ts — Aerostack Base Project
|
|
3
|
+
*
|
|
4
|
+
* This is the main entry point for your Cloudflare Worker.
|
|
5
|
+
* Routes from installed modules are mounted here automatically
|
|
6
|
+
* when you run `npx aerostack add <function-name>`.
|
|
7
|
+
*/
|
|
8
|
+
import { Hono } from 'hono';
|
|
9
|
+
|
|
10
|
+
// ─── Module Routes ─────────────────────────────────────────────────────────────
|
|
11
|
+
// aerostack:imports — imports are auto-injected above this line
|
|
12
|
+
|
|
13
|
+
const app = new Hono<{
|
|
14
|
+
Bindings: {
|
|
15
|
+
DB: D1Database;
|
|
16
|
+
CACHE: KVNamespace;
|
|
17
|
+
AI: Ai;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
}>();
|
|
21
|
+
|
|
22
|
+
// ─── Installed Module Routes ──────────────────────────────────────────────────
|
|
23
|
+
// aerostack:routes — routes are auto-injected above this line
|
|
24
|
+
|
|
25
|
+
// ─── Health Check ─────────────────────────────────────────────────────────────
|
|
26
|
+
app.get('/health', (c) => c.json({ status: 'ok', timestamp: Date.now() }));
|
|
27
|
+
|
|
28
|
+
export default app;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": [
|
|
7
|
+
"ES2022"
|
|
8
|
+
],
|
|
9
|
+
"types": [
|
|
10
|
+
"@cloudflare/workers-types"
|
|
11
|
+
],
|
|
12
|
+
"strict": true,
|
|
13
|
+
"noEmit": true,
|
|
14
|
+
"allowImportingTsExtensions": true,
|
|
15
|
+
"paths": {
|
|
16
|
+
"@/*": [
|
|
17
|
+
"./src/*"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"include": [
|
|
22
|
+
"src",
|
|
23
|
+
"**/*.ts"
|
|
24
|
+
],
|
|
25
|
+
"exclude": [
|
|
26
|
+
"node_modules",
|
|
27
|
+
"dist"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name = "{{PROJECT_NAME}}"
|
|
2
|
+
main = "src/index.ts"
|
|
3
|
+
compatibility_date = "2025-01-01"
|
|
4
|
+
compatibility_flags = ["nodejs_compat"]
|
|
5
|
+
|
|
6
|
+
[[d1_databases]]
|
|
7
|
+
binding = "DB"
|
|
8
|
+
database_name = "{{PROJECT_NAME}}-db"
|
|
9
|
+
database_id = "YOUR_DATABASE_ID_HERE"
|
|
10
|
+
|
|
11
|
+
[[kv_namespaces]]
|
|
12
|
+
binding = "CACHE"
|
|
13
|
+
id = "YOUR_KV_ID_HERE"
|
|
14
|
+
|
|
15
|
+
[ai]
|
|
16
|
+
binding = "AI"
|