create-surf-app 0.1.14 → 0.1.16
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/{chunk-53EUQV7R.js → chunk-MJDS5WZH.js} +6 -8
- package/dist/cli.js +1 -3
- package/dist/index.js +1 -1
- package/dist/templates/default/CLAUDE.md +75 -31
- package/dist/templates/default/backend/db/schema.js +8 -20
- package/dist/templates/default/backend/eslint.config.mjs +1 -1
- package/dist/templates/default/backend/package.json +2 -16
- package/dist/templates/default/backend/routes/.gitkeep +1 -0
- package/dist/templates/default/backend/server.js +2 -444
- package/package.json +1 -1
- package/dist/templates/default/backend/db/index.js +0 -23
- package/dist/templates/default/backend/lib/db.js +0 -67
- package/dist/templates/default/backend/routes/proxy.js +0 -66
- package/dist/templates/mini-surf/CLAUDE.md +0 -88
- package/dist/templates/mini-surf/backend/db/schema.js +0 -8
- package/dist/templates/mini-surf/backend/eslint.config.mjs +0 -21
- package/dist/templates/mini-surf/backend/package.json +0 -12
- package/dist/templates/mini-surf/backend/routes/.gitkeep +0 -0
- package/dist/templates/mini-surf/backend/server.js +0 -2
- package/dist/templates/mini-surf/frontend/components.json +0 -17
- package/dist/templates/mini-surf/frontend/eslint.config.js +0 -42
- package/dist/templates/mini-surf/frontend/index.html +0 -43
- package/dist/templates/mini-surf/frontend/package.json +0 -73
- package/dist/templates/mini-surf/frontend/src/App.tsx +0 -18
- package/dist/templates/mini-surf/frontend/src/entry-client.tsx +0 -109
- package/dist/templates/mini-surf/frontend/src/entry-server.tsx +0 -13
- package/dist/templates/mini-surf/frontend/src/index.css +0 -4
- package/dist/templates/mini-surf/frontend/src/vite-env.d.ts +0 -1
- package/dist/templates/mini-surf/frontend/tsconfig.json +0 -19
- package/dist/templates/mini-surf/frontend/vite.config.ts +0 -25
|
@@ -5,10 +5,8 @@ import path from "path";
|
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
6
|
var DEFAULT_FRONTEND_PORT = "5173";
|
|
7
7
|
var DEFAULT_BACKEND_PORT = "3001";
|
|
8
|
-
var DEFAULT_TEMPLATE = "default";
|
|
9
8
|
async function createSurfApp({
|
|
10
9
|
projectName = ".",
|
|
11
|
-
templateName = DEFAULT_TEMPLATE,
|
|
12
10
|
frontendPort = process.env.VITE_PORT || DEFAULT_FRONTEND_PORT,
|
|
13
11
|
backendPort = process.env.VITE_BACKEND_PORT || DEFAULT_BACKEND_PORT,
|
|
14
12
|
previewBase = process.env.VITE_BASE,
|
|
@@ -18,9 +16,9 @@ async function createSurfApp({
|
|
|
18
16
|
const name = path.basename(root);
|
|
19
17
|
const validatedFrontendPort = validatePort("frontend", frontendPort);
|
|
20
18
|
const validatedBackendPort = validatePort("backend", backendPort);
|
|
21
|
-
const templateDir = resolveTemplateDir(
|
|
19
|
+
const templateDir = resolveTemplateDir();
|
|
22
20
|
logger(`
|
|
23
|
-
Creating Surf app in ${root}
|
|
21
|
+
Creating Surf app in ${root}
|
|
24
22
|
`);
|
|
25
23
|
fs.mkdirSync(root, { recursive: true });
|
|
26
24
|
copyDir(templateDir, root, root, logger);
|
|
@@ -42,16 +40,16 @@ Done! Next steps:
|
|
|
42
40
|
`);
|
|
43
41
|
return root;
|
|
44
42
|
}
|
|
45
|
-
function resolveTemplateDir(
|
|
43
|
+
function resolveTemplateDir() {
|
|
46
44
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
47
45
|
const candidates = [
|
|
48
|
-
path.join(here, "templates",
|
|
49
|
-
path.join(here, "..", "templates",
|
|
46
|
+
path.join(here, "templates", "default"),
|
|
47
|
+
path.join(here, "..", "templates", "default")
|
|
50
48
|
];
|
|
51
49
|
for (const candidate of candidates) {
|
|
52
50
|
if (fs.existsSync(candidate)) return candidate;
|
|
53
51
|
}
|
|
54
|
-
throw new Error(`Could not find template
|
|
52
|
+
throw new Error(`Could not find default template near ${here}`);
|
|
55
53
|
}
|
|
56
54
|
function copyDir(src, dest, root, logger) {
|
|
57
55
|
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
createSurfApp
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MJDS5WZH.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
var VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
8
|
-
"--template",
|
|
9
8
|
"--frontend-port",
|
|
10
9
|
"--backend-port",
|
|
11
10
|
"--preview-base"
|
|
@@ -35,7 +34,6 @@ function parseCliArgs(args) {
|
|
|
35
34
|
}
|
|
36
35
|
return {
|
|
37
36
|
projectName: positionalArgs[0] || ".",
|
|
38
|
-
templateName: getFlag(args, "--template"),
|
|
39
37
|
frontendPort: getFlag(args, "--frontend-port"),
|
|
40
38
|
backendPort: getFlag(args, "--backend-port"),
|
|
41
39
|
previewBase: getFlag(args, "--preview-base")
|
package/dist/index.js
CHANGED
|
@@ -1,44 +1,88 @@
|
|
|
1
|
-
# Project
|
|
1
|
+
# Project
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Built with [Surf SDK](https://github.com/cyberconnecthq/urania/tree/main/packages/sdk).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- `.env` files — managed by the system; editing causes Vite restart & preview downtime.
|
|
7
|
-
- `entry-client.tsx` `notifyParentReady` / `data-surf-placeholder` — hosting app depends on these.
|
|
8
|
-
## npm install Rules
|
|
5
|
+
## Imports from @surf-ai/sdk
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
- Running `npm install` on pre-installed packages corrupts the node_modules tmpfs mount, kills the Vite dev server, and causes 5+ minute preview downtime (white screen).
|
|
12
|
-
- Only `npm install` packages that are NOT in package.json. When in doubt, read `frontend/package.json` first.
|
|
7
|
+
Everything comes from `@surf-ai/sdk`. Do NOT create local utility files for these.
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
**Frontend (`@surf-ai/sdk/react`):**
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **200-line limit** — split components exceeding 200 lines into sub-components.
|
|
11
|
+
```tsx
|
|
12
|
+
import { useMarketPrice, useTokenHolders } from "@surf-ai/sdk/react"; // data hooks
|
|
13
|
+
```
|
|
20
14
|
|
|
21
|
-
|
|
15
|
+
**Backend (`@surf-ai/sdk/server`):**
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
```js
|
|
18
|
+
const { dataApi } = require("@surf-ai/sdk/server");
|
|
19
|
+
const data = await dataApi.market.price({ symbol: "BTC" });
|
|
20
|
+
const holders = await dataApi.token.holders({
|
|
21
|
+
address: "0x...",
|
|
22
|
+
chain: "ethereum",
|
|
23
|
+
});
|
|
24
|
+
// Escape hatch for new endpoints:
|
|
25
|
+
const raw = await dataApi.get("newcategory/endpoint", { foo: "bar" });
|
|
26
|
+
```
|
|
25
27
|
|
|
26
|
-
##
|
|
28
|
+
## Structure
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
```
|
|
31
|
+
frontend/src/App.tsx - build your UI here
|
|
32
|
+
frontend/src/components/ - add components
|
|
33
|
+
frontend/src/db/schema.ts - frontend DB schema mirror
|
|
34
|
+
backend/routes/*.js - add API routes (auto-mounted at /api/{name})
|
|
35
|
+
backend/db/schema.js - define database tables
|
|
36
|
+
```
|
|
29
37
|
|
|
30
|
-
##
|
|
38
|
+
## Built-in Endpoints (from @surf-ai/sdk/server)
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
- **Favicon** — `frontend/public/favicon.ico` is already provided; do NOT delete or overwrite it.
|
|
40
|
+
`createServer()` provides these automatically - do NOT create routes for them:
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
| Endpoint | Method | Purpose |
|
|
43
|
+
| -------------------- | ------ | ------------------------------------------------------ |
|
|
44
|
+
| `/api/health` | GET | Health check - `{ status: 'ok' }` |
|
|
45
|
+
| `/api/__sync-schema` | POST | Sync `backend/db/schema.js` tables to database |
|
|
46
|
+
| `/api/cron` | GET | List cron jobs with status and next run time |
|
|
47
|
+
| `/api/cron` | POST | Create a new cron task |
|
|
48
|
+
| `/api/cron/:id` | PATCH | Update a cron task (schedule, enabled, etc.) |
|
|
49
|
+
| `/api/cron/:id` | DELETE | Delete a cron task |
|
|
50
|
+
| `/api/cron/:id/run` | POST | Manually trigger a cron task |
|
|
51
|
+
| `/proxy/*` | ANY | Data API passthrough - `/proxy/market/price` -> hermod |
|
|
36
52
|
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
53
|
+
Auto-registered from `backend/routes/*.js`:
|
|
54
|
+
| File | Endpoint |
|
|
55
|
+
|------|----------|
|
|
56
|
+
| `routes/btc.js` | `/api/btc` |
|
|
57
|
+
| `routes/portfolio.js` | `/api/portfolio` |
|
|
58
|
+
|
|
59
|
+
## Database
|
|
60
|
+
|
|
61
|
+
Define tables in `backend/db/schema.js` using Drizzle ORM:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
const { pgTable, serial, text, timestamp } = require("drizzle-orm/pg-core");
|
|
65
|
+
exports.users = pgTable("users", {
|
|
66
|
+
id: serial("id").primaryKey(),
|
|
67
|
+
name: text("name").notNull(),
|
|
68
|
+
created_at: timestamp("created_at").defaultNow(),
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Tables are auto-created on startup and when `schema.js` changes (file watcher).
|
|
73
|
+
The agent can also call `POST /api/__sync-schema` explicitly after editing.
|
|
74
|
+
|
|
75
|
+
## Do NOT modify
|
|
76
|
+
|
|
77
|
+
- `vite.config.ts` - proxy and build config
|
|
78
|
+
- `backend/server.js` - uses @surf-ai/sdk/server
|
|
79
|
+
- `entry-client.tsx` - app bootstrap with SSR hydration
|
|
80
|
+
- `entry-server.tsx` - SSR render for deploy
|
|
81
|
+
- `index.html` - cold-start guard and Surf badge
|
|
82
|
+
- `eslint.config.*` - lint rules
|
|
83
|
+
- `index.css` - only imports, do not add styles here (use Tailwind classes)
|
|
84
|
+
|
|
85
|
+
## Rules
|
|
86
|
+
|
|
87
|
+
- Use `@surf-ai/sdk/react` hooks in frontend, `@surf-ai/sdk/server` dataApi in backend
|
|
88
|
+
- Frontend packages are pre-installed - check `package.json` before installing
|
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
* const todos = pgTable('todos', {
|
|
11
|
-
* id: serial('id').primaryKey(),
|
|
12
|
-
* title: text('title').notNull(),
|
|
13
|
-
* completed: boolean('completed').default(false),
|
|
14
|
-
* createdAt: timestamp('created_at', { withTimezone: true }).defaultNow(),
|
|
15
|
-
* });
|
|
16
|
-
*
|
|
17
|
-
* module.exports = { todos };
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
// Add your table definitions here.
|
|
1
|
+
// Define your Drizzle ORM tables here.
|
|
2
|
+
// Example:
|
|
3
|
+
// const { pgTable, serial, text, timestamp } = require('drizzle-orm/pg-core')
|
|
4
|
+
// exports.users = pgTable('users', {
|
|
5
|
+
// id: serial('id').primaryKey(),
|
|
6
|
+
// name: text('name').notNull(),
|
|
7
|
+
// created_at: timestamp('created_at').defaultNow(),
|
|
8
|
+
// })
|
|
@@ -1,26 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "0.0.0",
|
|
5
4
|
"scripts": {
|
|
6
|
-
"check": "node --check server.js && find routes lib db -type f -name '*.js' -print0 | xargs -0 -n1 node --check",
|
|
7
|
-
"lint": "eslint .",
|
|
8
5
|
"start": "node server.js",
|
|
9
|
-
"dev": "node --watch
|
|
10
|
-
"verify": "npm run lint && npm run check"
|
|
6
|
+
"dev": "node --watch server.js"
|
|
11
7
|
},
|
|
12
8
|
"dependencies": {
|
|
13
9
|
"@surf-ai/sdk": "0.1.4-beta",
|
|
14
|
-
"express": "4.22.1"
|
|
15
|
-
"cors": "2.8.6",
|
|
16
|
-
"http-proxy-middleware": "3.0.5",
|
|
17
|
-
"drizzle-orm": "0.44.7",
|
|
18
|
-
"drizzle-kit": "0.30.6",
|
|
19
|
-
"croner": "9.1.0"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@eslint/js": "9.39.4",
|
|
23
|
-
"eslint": "9.39.4",
|
|
24
|
-
"globals": "16.5.0"
|
|
10
|
+
"express": "4.22.1"
|
|
25
11
|
}
|
|
26
12
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|