@positronic/cloudflare 0.0.2

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.
@@ -0,0 +1,135 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ env,
4
+ createExecutionContext,
5
+ waitOnExecutionContext,
6
+ } from 'cloudflare:test';
7
+ import worker from '../src/index';
8
+ import { testStatus, resources, brains, schedules } from '@positronic/spec';
9
+
10
+ describe('Positronic Spec', () => {
11
+ // Helper function to create fetch wrapper for Cloudflare workers
12
+ const createFetch = () => async (request: Request) => {
13
+ const context = createExecutionContext();
14
+ const response = await worker.fetch(request, env, context);
15
+ await waitOnExecutionContext(context);
16
+ return response;
17
+ };
18
+
19
+ it('passes status endpoint test', async () => {
20
+ const result = await testStatus(createFetch());
21
+ expect(result).toBe(true);
22
+ });
23
+
24
+ describe('Resources', () => {
25
+ it('passes GET /resources test', async () => {
26
+ const result = await resources.list(createFetch());
27
+ expect(result).toBe(true);
28
+ });
29
+
30
+ it('passes POST /resources test', async () => {
31
+ const result = await resources.upload(createFetch());
32
+ expect(result).toBe(true);
33
+ });
34
+
35
+ it('passes DELETE /resources/:key test', async () => {
36
+ // First upload a resource to delete
37
+ await resources.upload(createFetch());
38
+
39
+ // Then delete it
40
+ const result = await resources.delete(createFetch(), 'test-resource.txt');
41
+ expect(result).toBe(true);
42
+ });
43
+
44
+ it('passes DELETE /resources test', async () => {
45
+ const result = await resources.deleteAll(createFetch());
46
+ expect(result).toBe(true);
47
+ });
48
+
49
+ it('passes POST /resources/presigned-link test', async () => {
50
+ const result = await resources.generatePresignedLink(createFetch());
51
+ expect(result).toBe(true);
52
+ });
53
+ });
54
+
55
+ describe('Brains', () => {
56
+ it('passes GET /brains test', async () => {
57
+ const result = await brains.list(createFetch());
58
+ expect(result).toBe(true);
59
+ });
60
+
61
+ it('passes GET /brains/:brainName test', async () => {
62
+ const result = await brains.show(createFetch(), 'basic-brain');
63
+ expect(result).toBe(true);
64
+ });
65
+
66
+ it('passes POST /brains/runs test', async () => {
67
+ const brainRunId = await brains.run(createFetch(), 'basic-brain');
68
+ expect(brainRunId).toBeTruthy();
69
+ expect(typeof brainRunId).toBe('string');
70
+ });
71
+
72
+ it('passes POST /brains/runs with non-existent brain test (404)', async () => {
73
+ const result = await brains.runNotFound(createFetch(), 'non-existent-brain');
74
+ expect(result).toBe(true);
75
+ });
76
+
77
+ it('passes GET /brains/runs/:runId/watch test', async () => {
78
+ // First create a brain run
79
+ const brainRunId = await brains.run(createFetch(), 'basic-brain');
80
+ expect(brainRunId).toBeTruthy();
81
+
82
+ // Then test watching it
83
+ const result = await brains.watch(createFetch(), brainRunId!);
84
+ expect(result).toBe(true);
85
+ });
86
+
87
+ it('passes GET /brains/:brainName/history test', async () => {
88
+ // Just test that the endpoint exists and returns the right structure
89
+ // Don't create a run first to avoid storage issues
90
+ const result = await brains.history(createFetch(), 'basic-brain', 5);
91
+ expect(result).toBe(true);
92
+ });
93
+
94
+ it('passes GET /brains/watch test', async () => {
95
+ const result = await brains.watchAll(createFetch());
96
+ expect(result).toBe(true);
97
+ });
98
+ });
99
+
100
+ describe('Schedules', () => {
101
+ it('passes POST /brains/schedules test', async () => {
102
+ const scheduleId = await schedules.create(
103
+ createFetch(),
104
+ 'basic-brain',
105
+ '0 3 * * *'
106
+ );
107
+ expect(scheduleId).toBeTruthy();
108
+ expect(typeof scheduleId).toBe('string');
109
+ });
110
+
111
+ it('passes GET /brains/schedules test', async () => {
112
+ const result = await schedules.list(createFetch());
113
+ expect(result).toBe(true);
114
+ });
115
+
116
+ it('passes DELETE /brains/schedules/:scheduleId test', async () => {
117
+ // First create a schedule
118
+ const scheduleId = await schedules.create(
119
+ createFetch(),
120
+ 'basic-brain',
121
+ '0 3 * * *'
122
+ );
123
+ expect(scheduleId).toBeTruthy();
124
+
125
+ // Then delete it
126
+ const result = await schedules.delete(createFetch(), scheduleId!);
127
+ expect(result).toBe(true);
128
+ });
129
+
130
+ it('passes GET /brains/schedules/runs test', async () => {
131
+ const result = await schedules.runs(createFetch());
132
+ expect(result).toBe(true);
133
+ });
134
+ });
135
+ });
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "types": ["../worker-configuration.d.ts", "@cloudflare/vitest-pool-workers"]
5
+ },
6
+ "include": ["./**/*.ts"]
7
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "include": ["**/*"],
3
+ "compilerOptions": {
4
+ "types": ["./worker-configuration.d.ts", "@cloudflare/vitest-pool-workers"],
5
+ "target": "es2021",
6
+ "lib": ["es2021"],
7
+ "jsx": "react-jsx",
8
+ "module": "es2022",
9
+ "moduleResolution": "bundler",
10
+ "resolveJsonModule": true,
11
+ "allowJs": true,
12
+ "checkJs": false,
13
+ "noEmit": true,
14
+ "isolatedModules": true,
15
+ "allowSyntheticDefaultImports": true,
16
+ "forceConsistentCasingInFileNames": true,
17
+ "strict": true,
18
+ "skipLibCheck": true
19
+ }
20
+ }
@@ -0,0 +1,12 @@
1
+ import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config';
2
+
3
+ export default defineWorkersConfig({
4
+ test: {
5
+ poolOptions: {
6
+ workers: {
7
+ wrangler: { configPath: './wrangler.jsonc' },
8
+ // Reverted: Removed explicit miniflare block
9
+ },
10
+ },
11
+ },
12
+ });
@@ -0,0 +1,53 @@
1
+ /**
2
+ * For more details on how to configure Wrangler, refer to:
3
+ * https://developers.cloudflare.com/workers/wrangler/configuration/
4
+ */
5
+ {
6
+ "$schema": "node_modules/wrangler/config-schema.json",
7
+ "name": "test-project",
8
+ "main": "src/index.ts",
9
+ "compatibility_date": "2025-04-04",
10
+ "compatibility_flags": [
11
+ "nodejs_compat",
12
+ "nodejs_compat_populate_process_env"
13
+ ],
14
+ "migrations": [
15
+ {
16
+ "tag": "v1",
17
+ "new_sqlite_classes": ["BrainRunnerDO", "MonitorDO", "ScheduleDO"]
18
+ }
19
+ ],
20
+ "durable_objects": {
21
+ "bindings": [
22
+ {
23
+ "class_name": "BrainRunnerDO",
24
+ "name": "BRAIN_RUNNER_DO"
25
+ },
26
+ {
27
+ "class_name": "MonitorDO",
28
+ "name": "MONITOR_DO"
29
+ },
30
+ {
31
+ "class_name": "ScheduleDO",
32
+ "name": "SCHEDULE_DO"
33
+ }
34
+ ]
35
+ },
36
+ "vars": {
37
+ "IS_TEST": "true",
38
+ "NODE_ENV": "development"
39
+ },
40
+ "r2_buckets": [
41
+ {
42
+ "binding": "TEST_RESOURCES_BUCKET",
43
+ "bucket_name": "positronic-test-resources"
44
+ },
45
+ {
46
+ "binding": "RESOURCES_BUCKET",
47
+ "bucket_name": "positronic-test-resources"
48
+ }
49
+ ],
50
+ "observability": {
51
+ "enabled": true
52
+ }
53
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": "./src",
5
+ "emitDeclarationOnly": true,
6
+ "declarationDir": "./dist/types",
7
+ "types": ["@cloudflare/workers-types", "node"]
8
+ },
9
+ "include": ["**/*"],
10
+ "exclude": ["dist", "node_modules", "**/*.test.ts", "test-project"]
11
+ }