create-cloesce 0.0.5 → 0.2.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 +1 -1
- package/templates/default/cloesce.config.ts +16 -0
- package/templates/default/package.json +2 -2
- package/templates/default/src/data/models.cloesce.ts +7 -19
- package/templates/default/src/web/index.ts +5 -5
- package/templates/default/test/weather.test.ts +5 -3
- package/templates/default/vitest.config.ts +6 -0
- package/templates/default/wrangler.jsonc +3 -0
- package/templates/default/cloesce.config.json +0 -7
- package/templates/default/wrangler.toml +0 -1
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineConfig } from "cloesce/config";
|
|
2
|
+
import { Weather } from "./src/data/models.cloesce";
|
|
3
|
+
|
|
4
|
+
const config = defineConfig({
|
|
5
|
+
srcPaths: ["./src/data"],
|
|
6
|
+
workersUrl: "http://localhost:5000/api",
|
|
7
|
+
wranglerConfigFormat: "jsonc",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// The Fluent API can be used to further configure models,
|
|
11
|
+
// for example to add a unique constraint on the Weather model:
|
|
12
|
+
config.model(Weather, builder => {
|
|
13
|
+
builder.unique("dateTime", "location");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export default config;
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "cloesce compile && wrangler build",
|
|
8
|
-
"migrate:cloesce": "cloesce migrate",
|
|
8
|
+
"migrate:cloesce": "cloesce migrate db",
|
|
9
9
|
"migrate:wrangler": "wrangler d1 migrations apply db",
|
|
10
10
|
"start:dev": "wrangler dev --port 5000",
|
|
11
11
|
"start:web": "vite",
|
|
12
12
|
"test": "vitest"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"cloesce": ">=0.
|
|
15
|
+
"cloesce": ">=0.2.2",
|
|
16
16
|
"wrangler": "^4.61.1"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Get, Post, HttpResult, Integer, Model, R2, Inject, Crud } from "cloesce/backend";
|
|
2
2
|
import { R2ObjectBody, ReadableStream } from "@cloudflare/workers-types";
|
|
3
3
|
import { Env } from "./main.cloesce";
|
|
4
4
|
|
|
5
|
-
@Model()
|
|
5
|
+
@Model("db")
|
|
6
6
|
export class Weather {
|
|
7
7
|
// Cloesce interprets this is a primary key.
|
|
8
8
|
// Optionally, decorate with @PrimaryKey
|
|
9
9
|
id: Integer;
|
|
10
10
|
|
|
11
11
|
// Foreign key to WeatherReport
|
|
12
|
-
// Optionally, decorate with @ForeignKey
|
|
12
|
+
// Optionally, decorate with @ForeignKey<WeatherReport>(wr => wr.id)
|
|
13
13
|
weatherReportId: Integer;
|
|
14
14
|
|
|
15
15
|
// Navigation property to weatherReportId
|
|
16
|
-
// Optionally, decorate with @OneToOne<Weather>(w => w.weatherReportId)
|
|
17
16
|
weatherReport: WeatherReport | undefined;
|
|
18
17
|
|
|
19
18
|
dateTime: Date;
|
|
@@ -24,18 +23,13 @@ export class Weather {
|
|
|
24
23
|
@R2("weather/photo/{id}", "bucket")
|
|
25
24
|
photo: R2ObjectBody | undefined;
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
static readonly withPhoto: IncludeTree<Weather> = {
|
|
29
|
-
photo: {}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
@POST
|
|
26
|
+
@Post()
|
|
33
27
|
async uploadPhoto(@Inject env: Env, stream: ReadableStream): Promise<HttpResult<void>> {
|
|
34
28
|
await env.bucket.put(`weather/photo/${this.id}`, stream);
|
|
35
29
|
return HttpResult.ok(200);
|
|
36
30
|
}
|
|
37
31
|
|
|
38
|
-
@
|
|
32
|
+
@Get({ includeTree: { photo: {} } })
|
|
39
33
|
downloadPhoto(): HttpResult<ReadableStream> {
|
|
40
34
|
if (!this.photo) {
|
|
41
35
|
return HttpResult.fail(404, "Photo not found");
|
|
@@ -44,7 +38,8 @@ export class Weather {
|
|
|
44
38
|
}
|
|
45
39
|
}
|
|
46
40
|
|
|
47
|
-
@
|
|
41
|
+
@Crud("GET", "SAVE", "LIST")
|
|
42
|
+
@Model("db")
|
|
48
43
|
export class WeatherReport {
|
|
49
44
|
// Cloesce assumes this is a primary key.
|
|
50
45
|
// Optionally, decorate with @PrimaryKey
|
|
@@ -54,12 +49,5 @@ export class WeatherReport {
|
|
|
54
49
|
description: string;
|
|
55
50
|
|
|
56
51
|
// Cloesce assumes this is a foreign key to Weather.weatherReportId
|
|
57
|
-
// Optionally, or if multiple FKs exist, decorate with
|
|
58
|
-
// @OneToMany<Weather>(w => w.weatherReportId)
|
|
59
52
|
weatherEntries: Weather[];
|
|
60
|
-
|
|
61
|
-
// Hydrates the weatherEntries when the client calls "withWeatherEntries"
|
|
62
|
-
static readonly withWeatherEntries: IncludeTree<WeatherReport> = {
|
|
63
|
-
weatherEntries: {}
|
|
64
|
-
}
|
|
65
53
|
}
|
|
@@ -21,7 +21,7 @@ const showResult = (outputId: string, result: any) => {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
window.listReports = async () => {
|
|
24
|
-
const result = await WeatherReport.LIST(
|
|
24
|
+
const result = await WeatherReport.LIST(null, null, null);
|
|
25
25
|
showResult('list-output', result);
|
|
26
26
|
};
|
|
27
27
|
|
|
@@ -46,7 +46,7 @@ window.addWeatherEntry = async () => {
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
const getResult = await WeatherReport.GET(reportId
|
|
49
|
+
const getResult = await WeatherReport.GET(reportId);
|
|
50
50
|
if (!getResult.ok) {
|
|
51
51
|
showResult('entry-output', getResult);
|
|
52
52
|
return;
|
|
@@ -66,7 +66,7 @@ window.addWeatherEntry = async () => {
|
|
|
66
66
|
title: report.title,
|
|
67
67
|
description: report.description,
|
|
68
68
|
weatherEntries: [...(report.weatherEntries || []), newEntry]
|
|
69
|
-
}
|
|
69
|
+
});
|
|
70
70
|
|
|
71
71
|
showResult('entry-output', result);
|
|
72
72
|
};
|
|
@@ -90,7 +90,7 @@ window.uploadPhoto = async () => {
|
|
|
90
90
|
const weather = new Weather();
|
|
91
91
|
weather.id = id;
|
|
92
92
|
|
|
93
|
-
const result = await weather.uploadPhoto(new Uint8Array(buffer)
|
|
93
|
+
const result = await weather.uploadPhoto(new Uint8Array(buffer));
|
|
94
94
|
showResult('upload-output', result);
|
|
95
95
|
};
|
|
96
96
|
|
|
@@ -104,7 +104,7 @@ window.downloadPhoto = async () => {
|
|
|
104
104
|
|
|
105
105
|
const weather = new Weather();
|
|
106
106
|
weather.id = id;
|
|
107
|
-
const result = await weather.downloadPhoto(
|
|
107
|
+
const result = await weather.downloadPhoto();
|
|
108
108
|
|
|
109
109
|
if (result.ok && result.data) {
|
|
110
110
|
const blob = await result.data.blob();
|
|
@@ -33,7 +33,10 @@ async function createTestEnv() {
|
|
|
33
33
|
"condition" text NOT NULL,
|
|
34
34
|
FOREIGN KEY ("weatherReportId") REFERENCES "WeatherReport" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
35
35
|
);
|
|
36
|
-
CREATE TABLE IF NOT EXISTS "_cloesce_tmp" (
|
|
36
|
+
CREATE TABLE IF NOT EXISTS "_cloesce_tmp" (
|
|
37
|
+
"path" text PRIMARY KEY,
|
|
38
|
+
"primary_key" text NOT NULL
|
|
39
|
+
);
|
|
37
40
|
`).run();
|
|
38
41
|
|
|
39
42
|
return { env, orm: Orm.fromEnv(env) };
|
|
@@ -65,13 +68,12 @@ describe("Miniflare Integration Tests", () => {
|
|
|
65
68
|
condition: "Sunny"
|
|
66
69
|
}]
|
|
67
70
|
},
|
|
68
|
-
WeatherReport.withWeatherEntries
|
|
69
71
|
);
|
|
70
72
|
|
|
71
73
|
await report!.weatherEntries[0].uploadPhoto(env, testData as any);
|
|
72
74
|
|
|
73
75
|
// Act
|
|
74
|
-
const weatherEntries = await orm.list(Weather
|
|
76
|
+
const weatherEntries = await orm.list(Weather);
|
|
75
77
|
const photo = weatherEntries[0].downloadPhoto();
|
|
76
78
|
|
|
77
79
|
// Assert
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
main = ".generated/workers.ts"
|