@crossdelta/platform-sdk 0.10.1 → 0.11.1

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,97 @@
1
+ # Testing Guidelines
2
+
3
+ ## 🚨 CRITICAL: bun:test Only
4
+
5
+ ```ts
6
+ // ✅ CORRECT
7
+ import { describe, expect, it } from 'bun:test'
8
+
9
+ // ❌ WRONG - do NOT use
10
+ jest.mock(...) // Jest doesn't work
11
+ jest.unstable_mockModule() // Jest doesn't work
12
+ vi.mock(...) // Vitest doesn't work
13
+ ```
14
+
15
+ ---
16
+
17
+ ## What to Test
18
+
19
+ - Test ONLY use-cases (not handlers)
20
+ - No mocking - use dependency injection
21
+
22
+ ```ts
23
+ import { describe, expect, it } from 'bun:test'
24
+ import { processOrder } from './process-order.use-case'
25
+
26
+ describe('processOrder', () => {
27
+ it('processes order', async () => {
28
+ const store = new Map()
29
+ await processOrder({ orderId: '123', total: 100 }, store)
30
+ expect(store.has('123')).toBe(true)
31
+ })
32
+
33
+ it('throws on missing data', async () => {
34
+ await expect(processOrder(null as any, new Map())).rejects.toThrow()
35
+ })
36
+ })
37
+ ```
38
+
39
+ ---
40
+
41
+ ## External Services & Config
42
+
43
+ Use dependency injection, not mocking:
44
+
45
+ ```ts
46
+ // ✅ Use-case accepts dependencies
47
+ export const sendPush = async (
48
+ data: PushData,
49
+ config: { instanceId: string }
50
+ ) => {
51
+ if (!config.instanceId) throw new Error('Missing instanceId')
52
+ }
53
+
54
+ // ✅ Test with fake/config
55
+ it('throws on missing config', async () => {
56
+ await expect(sendPush({}, { instanceId: '' })).rejects.toThrow()
57
+ })
58
+ ```
59
+
60
+ ---
61
+
62
+ ## ❌ WRONG patterns (NEVER use these)
63
+
64
+ ```ts
65
+ // process.env manipulation
66
+ beforeEach(() => { process.env.X = 'test' })
67
+ afterEach(() => { process.env = env })
68
+
69
+ // @ts-ignore for mocking
70
+ // @ts-ignore
71
+ svc.beams = new FakeBeams()
72
+
73
+ // Jest/Vitest mocking
74
+ jest.mock(...)
75
+ vi.mock(...)
76
+
77
+ // Dynamic imports for error testing
78
+ await expect(import('./module')).rejects.toThrow()
79
+ ```
80
+
81
+ ---
82
+
83
+ ## NestJS Services
84
+
85
+ For NestJS: extract business logic into pure functions, test those:
86
+
87
+ ```ts
88
+ // ✅ Extract testable logic from service
89
+ export const validateConfig = (config: { id: string }) => {
90
+ if (!config.id) throw new Error('Missing id')
91
+ }
92
+
93
+ // ✅ Test the extracted function
94
+ it('validates config', () => {
95
+ expect(() => validateConfig({ id: '' })).toThrow()
96
+ })
97
+ ```
@@ -1,10 +1,3 @@
1
1
  {
2
- "extends": ["../../biome.json"],
3
- "linter": {
4
- "rules": {
5
- "style": {
6
- "useImportType": "off"
7
- }
8
- }
9
- }
2
+ "extends": ["../../biome.json"]
10
3
  }
@@ -20,7 +20,8 @@
20
20
  "recommended": true,
21
21
  "useAsConstAssertion": "warn",
22
22
  "noUselessElse": "error",
23
- "useConst": "error"
23
+ "useConst": "error",
24
+ "useImportType": "off"
24
25
  },
25
26
  "complexity": {
26
27
  "recommended": true,
@@ -37,7 +37,7 @@
37
37
  }
38
38
  },
39
39
  "dependencies": {
40
- "@crossdelta/cloudevents": "^0.4.23",
40
+ "@crossdelta/cloudevents": "^0.5.1",
41
41
  "@crossdelta/telemetry": "^0.1.4"
42
42
  },
43
43
  "devDependencies": {
@@ -11,7 +11,7 @@
11
11
  }
12
12
  },
13
13
  "dependencies": {
14
- "@crossdelta/cloudevents": "^0.5.0",
14
+ "@crossdelta/cloudevents": "^0.5.1",
15
15
  "zod": "^4.0.0"
16
16
  },
17
17
  "devDependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossdelta/platform-sdk",
3
- "version": "0.10.1",
3
+ "version": "0.11.1",
4
4
  "description": "Platform toolkit for event-driven microservices — keeping code and infrastructure in lockstep.",
5
5
  "keywords": [
6
6
  "cli",
@@ -49,128 +49,133 @@
49
49
  "email": "mail@hoevelmanns.io"
50
50
  },
51
51
  "generatorConfig": {
52
- "serviceTypes": {
53
- "hono": {
54
- "commandType": "hono-micro",
55
- "entryPoint": "src/index.ts",
56
- "skipFiles": [
57
- "package.json",
58
- "tsconfig.json",
59
- "Dockerfile"
60
- ]
52
+ "docs": {
53
+ "base": ["service.md", "code-style.md", "testing.md"],
54
+ "frameworks": {
55
+ "hono": {
56
+ "bun": "hono-bun.md",
57
+ "node": "hono-node.md"
61
58
  },
62
- "nest": {
63
- "commandType": "nest-micro",
64
- "entryPoint": "src/main.ts",
65
- "skipFiles": [
66
- "package.json",
67
- "tsconfig.json",
68
- "Dockerfile"
69
- ]
70
- }
59
+ "nest": "nest.md"
71
60
  }
72
61
  },
73
- "scripts": {
74
- "start:dev": "node esbuild.config.mjs --watch",
75
- "build:cli": "node esbuild.config.mjs",
76
- "build:cli:copy": "cp cli/integration.collection.json bin/integration.collection.json && rm -rf bin/templates && mkdir -p bin/templates && cp -r cli/src/commands/create/workspace/templates bin/templates/workspace && cp -r cli/src/commands/create/hono-microservice/templates bin/templates/hono-microservice && cp -r cli/src/commands/create/nest-microservice/templates bin/templates/nest-microservice && mkdir -p bin/docs/generators && cp -r docs/generators/* bin/docs/generators/",
77
- "build:schematics:transpile": "tsc --project tsconfig.schematics.json",
78
- "build:schematics:copy": "cp -R schematics/* dist/schematics && find dist/schematics -name '*.ts' -delete",
79
- "build:schematics": "npm run build:schematics:transpile && npm run build:schematics:copy",
80
- "build": "npm run build:cli && npm run build:schematics && npm run build:cli:copy",
81
- "prepublishOnly": "npm run build",
82
- "lint": "biome lint --fix",
83
- "test": "bun test",
84
- "test:watch": "bun test --watch"
85
- },
86
- "schematics": "./dist/schematics/collection.json",
87
- "esbuild": {
88
- "external": [
89
- "@crossdelta/infrastructure",
90
- "@faker-js/faker",
91
- "@inquirer/prompts",
92
- "ai",
93
- "@ai-sdk/openai",
94
- "@ai-sdk/anthropic",
95
- "vite",
96
- "handlebars",
97
- "zx",
98
- "listr2",
99
- "enquirer",
100
- "execa",
101
- "globby",
102
- "fs-extra",
103
- "chalk",
104
- "ora",
105
- "jiti",
106
- "zod",
107
- "ts-morph",
108
- "commander",
109
- "chokidar"
110
- ]
111
- },
112
- "dependencies": {
113
- "@ai-sdk/anthropic": "^2.0.53",
114
- "@ai-sdk/openai": "^2.0.79",
115
- "@angular-devkit/core": "^21.0.0",
116
- "@faker-js/faker": "^9.8.0",
117
- "@inquirer/prompts": "^7.5.0",
118
- "@listr2/prompt-adapter-enquirer": "^2.0.15",
119
- "ai": "^5.0.108",
120
- "chalk": "^5.4.1",
121
- "chokidar": "^5.0.0",
122
- "cli-table3": "^0.6.5",
123
- "commander": "^13.1.0",
124
- "dotenv": "^17.2.3",
125
- "enquirer": "^2.4.1",
126
- "execa": "^9.5.2",
127
- "fs-extra": "^11.3.0",
128
- "globby": "^14.1.0",
129
- "handlebars": "^4.7.8",
130
- "jiti": "^2.6.1",
131
- "listr2": "^8.3.2",
132
- "ora": "^8.2.0",
133
- "os": "^0.1.2",
134
- "package-up": "^5.0.0",
135
- "rimraf": "^6.1.2",
136
- "terminal-link": "^4.0.0",
137
- "ts-morph": "^27.0.0",
138
- "vite": "^6.3.4",
139
- "zod": "^3.24.3",
140
- "zx": "^8.5.3"
141
- },
142
- "peerDependencies": {
143
- "@crossdelta/cloudevents": "*",
144
- "@crossdelta/infrastructure": "*",
145
- "@nestjs/schematics": "^11.0.5",
146
- "turbo": "^2.0.0"
147
- },
148
- "peerDependenciesMeta": {
149
- "@crossdelta/cloudevents": {
150
- "optional": true
151
- },
152
- "@crossdelta/infrastructure": {
153
- "optional": true
62
+ "serviceTypes": {
63
+ "hono": {
64
+ "commandType": "hono-micro",
65
+ "entryPoint": "src/index.ts",
66
+ "skipFiles": [
67
+ "package.json",
68
+ "tsconfig.json",
69
+ "Dockerfile"
70
+ ]
154
71
  },
155
- "@nestjs/schematics": {
156
- "optional": true
157
- },
158
- "turbo": {
159
- "optional": true
72
+ "nest": {
73
+ "commandType": "nest-micro",
74
+ "entryPoint": "src/main.ts",
75
+ "skipFiles": [
76
+ "package.json",
77
+ "tsconfig.json",
78
+ "Dockerfile"
79
+ ]
160
80
  }
81
+ }
82
+ },
83
+ "scripts": {
84
+ "start:dev": "node esbuild.config.mjs --watch",
85
+ "build:cli": "node esbuild.config.mjs",
86
+ "build:cli:copy": "cp cli/integration.collection.json bin/integration.collection.json && rm -rf bin/templates && mkdir -p bin/templates && cp -r cli/src/commands/create/workspace/templates bin/templates/workspace && cp -r cli/src/commands/create/hono-microservice/templates bin/templates/hono-microservice && cp -r cli/src/commands/create/nest-microservice/templates bin/templates/nest-microservice && mkdir -p bin/docs/generators && cp -r docs/generators/* bin/docs/generators/",
87
+ "build:schematics:transpile": "tsc --project tsconfig.schematics.json",
88
+ "build:schematics:copy": "cp -R schematics/* dist/schematics && find dist/schematics -name '*.ts' -delete",
89
+ "build:schematics": "npm run build:schematics:transpile && npm run build:schematics:copy",
90
+ "build": "npm run build:cli && npm run build:schematics && npm run build:cli:copy",
91
+ "prepublishOnly": "npm run build",
92
+ "lint": "biome lint --fix",
93
+ "test": "bun test",
94
+ "test:watch": "bun test --watch"
95
+ },
96
+ "schematics": "./dist/schematics/collection.json",
97
+ "esbuild": {
98
+ "external": [
99
+ "@crossdelta/infrastructure",
100
+ "@faker-js/faker",
101
+ "@inquirer/prompts",
102
+ "ai",
103
+ "@ai-sdk/openai",
104
+ "@ai-sdk/anthropic",
105
+ "handlebars",
106
+ "listr2",
107
+ "enquirer",
108
+ "execa",
109
+ "globby",
110
+ "fs-extra",
111
+ "chalk",
112
+ "ora",
113
+ "jiti",
114
+ "zod",
115
+ "ts-morph",
116
+ "commander",
117
+ "chokidar"
118
+ ]
119
+ },
120
+ "dependencies": {
121
+ "@ai-sdk/anthropic": "^2.0.53",
122
+ "@ai-sdk/openai": "^2.0.79",
123
+ "@angular-devkit/core": "^21.0.0",
124
+ "@faker-js/faker": "^9.8.0",
125
+ "@inquirer/prompts": "^7.5.0",
126
+ "@listr2/prompt-adapter-enquirer": "^2.0.15",
127
+ "ai": "^5.0.108",
128
+ "chalk": "^5.4.1",
129
+ "chokidar": "^5.0.0",
130
+ "cli-table3": "^0.6.5",
131
+ "commander": "^13.1.0",
132
+ "dotenv": "^17.2.3",
133
+ "enquirer": "^2.4.1",
134
+ "execa": "^9.5.2",
135
+ "fs-extra": "^11.3.0",
136
+ "globby": "^14.1.0",
137
+ "handlebars": "^4.7.8",
138
+ "jiti": "^2.6.1",
139
+ "listr2": "^8.3.2",
140
+ "ora": "^8.2.0",
141
+ "package-up": "^5.0.0",
142
+ "rimraf": "^6.1.2",
143
+ "terminal-link": "^4.0.0",
144
+ "ts-morph": "^27.0.0",
145
+ "zod": "^3.24.3"
146
+ },
147
+ "peerDependencies": {
148
+ "@crossdelta/cloudevents": "*",
149
+ "@crossdelta/infrastructure": "*",
150
+ "@nestjs/schematics": "^11.0.5",
151
+ "turbo": "^2.0.0"
152
+ },
153
+ "peerDependenciesMeta": {
154
+ "@crossdelta/cloudevents": {
155
+ "optional": true
156
+ },
157
+ "@crossdelta/infrastructure": {
158
+ "optional": true
161
159
  },
162
- "devDependencies": {
163
- "@angular-devkit/core": "^21.0.0",
164
- "@angular-devkit/schematics": "^21.0.0",
165
- "@angular-devkit/schematics-cli": "^19.2.10",
166
- "@eslint/js": "^9.22.0",
167
- "@nestjs/schematics": "^11.0.9",
168
- "@types/fs-extra": "^11.0.4",
169
- "bun-types": "^1.3.4",
170
- "comment-json": "^4.4.1",
171
- "esbuild": "^0.25.3",
172
- "eslint": "^9.25.1",
173
- "typescript": "^5.8.3",
174
- "typescript-eslint": "^8.31.1"
160
+ "@nestjs/schematics": {
161
+ "optional": true
162
+ },
163
+ "turbo": {
164
+ "optional": true
175
165
  }
166
+ },
167
+ "devDependencies": {
168
+ "@angular-devkit/core": "^21.0.0",
169
+ "@angular-devkit/schematics": "^21.0.0",
170
+ "@angular-devkit/schematics-cli": "^19.2.10",
171
+ "@eslint/js": "^9.22.0",
172
+ "@nestjs/schematics": "^11.0.9",
173
+ "@types/fs-extra": "^11.0.4",
174
+ "bun-types": "^1.3.4",
175
+ "comment-json": "^4.4.1",
176
+ "esbuild": "^0.25.3",
177
+ "eslint": "^9.25.1",
178
+ "typescript": "^5.8.3",
179
+ "typescript-eslint": "^8.31.1"
180
+ }
176
181
  }