@celsoft/create-platform-app 0.4.0 → 0.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@celsoft/create-platform-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Create an app deployed by @celsoft/platform: npm create @celsoft/platform-app",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": { "type": "git", "url": "git+https://github.com/celsoft-com/platform.git", "directory": "packages/create-platform-app" },
|
package/template/README.md
CHANGED
|
@@ -5,13 +5,15 @@ Deployed to Cloudflare Workers with a Neon database by [@celsoft/platform](https
|
|
|
5
5
|
## First deploy
|
|
6
6
|
|
|
7
7
|
1. **Repo:** create a GitHub repo for this directory and push it.
|
|
8
|
-
2. **Tokens:** run `npx platform init`; it adds blank token entries to `.env.secrets` and stops.
|
|
8
|
+
2. **Tokens:** run `npx @celsoft/platform init`; it adds blank token entries to `.env.secrets` and stops.
|
|
9
9
|
3. **Fill:** create the tokens described in the platform's [SETUP.md](https://github.com/celsoft-com/platform/blob/main/SETUP.md) and paste them into `.env.secrets`.
|
|
10
|
-
4. **Init:** run `npx platform init` again; it stores the tokens in GitHub and writes the deploy workflow.
|
|
11
|
-
5. **
|
|
10
|
+
4. **Init:** run `npx @celsoft/platform init` again; it stores the tokens in GitHub and writes the deploy workflow.
|
|
11
|
+
5. **Migrations:** run `npx @celsoft/platform db generate`; it writes the SQL for `src/schema.ts` to `drizzle/`.
|
|
12
|
+
6. **Ship:** commit and push; main deploys to https://{{hostname}}, and every PR gets a preview.
|
|
12
13
|
|
|
13
14
|
## Your code
|
|
14
15
|
|
|
15
|
-
1. **API:** `src/worker.ts`, where `defineApp` hands each request a
|
|
16
|
+
1. **API:** `src/worker.ts`, where `defineApp` hands each request `db`, a Drizzle client typed with your tables.
|
|
16
17
|
2. **Pages:** `public/`, served as static files.
|
|
17
|
-
3. **
|
|
18
|
+
3. **Tables:** `src/schema.ts`; after changing it, run `npx @celsoft/platform db generate`, read the SQL it writes, and commit it. Each deploy applies new migrations.
|
|
19
|
+
4. **Local:** `npx @celsoft/platform dev` runs the app against its own copy of the database, generating migrations as you go.
|
package/template/package.json
CHANGED
package/template/platform.jsonc
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./node_modules/@celsoft/platform/schema.json",
|
|
3
|
-
"version": 1,
|
|
4
3
|
"name": "{{name}}",
|
|
5
4
|
"hostname": "{{hostname}}",
|
|
6
5
|
"worker": "src/worker.ts",
|
|
7
6
|
"frontend": "public",
|
|
8
7
|
"compatibilityDate": "{{compatibilityDate}}",
|
|
9
8
|
"database": {
|
|
10
|
-
"neonProject": "{{neonProject}}"
|
|
11
|
-
"migrate": "node scripts/migrate.js"
|
|
9
|
+
"neonProject": "{{neonProject}}"
|
|
12
10
|
}
|
|
13
11
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { id, timestamps } from "@celsoft/platform/schema";
|
|
2
|
+
import { pgTable, text } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
// The app's tables. After changing them, run `npx @celsoft/platform db generate` and commit drizzle/.
|
|
5
|
+
export const items = pgTable("items", {
|
|
6
|
+
id: id(),
|
|
7
|
+
name: text("name").notNull(),
|
|
8
|
+
...timestamps(),
|
|
9
|
+
});
|
package/template/src/worker.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { defineApp } from "@celsoft/platform";
|
|
2
|
+
import { desc } from "drizzle-orm";
|
|
3
|
+
import * as schema from "./schema";
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
const url = new URL(request.url);
|
|
5
|
+
const { items } = schema;
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
export default defineApp(
|
|
8
|
+
async (request, { db }) => {
|
|
9
|
+
const url = new URL(request.url);
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
if (url.pathname === "/api/items" && request.method === "GET") {
|
|
12
|
+
return Response.json(await db.select().from(items).orderBy(desc(items.createdAt)).limit(100));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return new Response("not found", { status: 404 });
|
|
16
|
+
},
|
|
17
|
+
{ schema },
|
|
18
|
+
);
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
-
import postgres from "postgres";
|
|
3
|
-
|
|
4
|
-
const dir = new URL("../migrations/", import.meta.url);
|
|
5
|
-
const sql = postgres(process.env.DATABASE_URL, { max: 1, onnotice: () => {} });
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
await sql`create table if not exists schema_migrations (name text primary key, applied_at timestamptz not null default now())`;
|
|
9
|
-
const applied = new Set((await sql`select name from schema_migrations`).map((row) => row.name));
|
|
10
|
-
const pending = (await readdir(dir)).filter((name) => name.endsWith(".sql") && !applied.has(name)).sort();
|
|
11
|
-
|
|
12
|
-
for (const name of pending) {
|
|
13
|
-
const text = await readFile(new URL(name, dir), "utf8");
|
|
14
|
-
await sql.begin(async (tx) => {
|
|
15
|
-
await tx.unsafe(text);
|
|
16
|
-
await tx`insert into schema_migrations (name) values (${name})`;
|
|
17
|
-
});
|
|
18
|
-
console.log(`applied ${name}`);
|
|
19
|
-
}
|
|
20
|
-
if (pending.length === 0) console.log("migrations up to date");
|
|
21
|
-
} finally {
|
|
22
|
-
await sql.end();
|
|
23
|
-
}
|