dzql 0.5.33 → 0.6.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.
Files changed (150) hide show
  1. package/.env.sample +28 -0
  2. package/compose.yml +28 -0
  3. package/dist/client/index.ts +1 -0
  4. package/dist/client/stores/useMyProfileStore.ts +114 -0
  5. package/dist/client/stores/useOrgDashboardStore.ts +131 -0
  6. package/dist/client/stores/useVenueDetailStore.ts +117 -0
  7. package/dist/client/ws.ts +716 -0
  8. package/dist/db/migrations/000_core.sql +92 -0
  9. package/dist/db/migrations/20251229T212912022Z_schema.sql +3020 -0
  10. package/dist/db/migrations/20251229T212912022Z_subscribables.sql +371 -0
  11. package/dist/runtime/manifest.json +1562 -0
  12. package/docs/README.md +293 -36
  13. package/docs/feature-requests/applyPatch-bug-report.md +85 -0
  14. package/docs/feature-requests/connection-ready-profile.md +57 -0
  15. package/docs/feature-requests/hidden-bug-report.md +111 -0
  16. package/docs/feature-requests/hidden-fields-subscribables.md +34 -0
  17. package/docs/feature-requests/subscribable-param-key-bug.md +38 -0
  18. package/docs/feature-requests/todo.md +146 -0
  19. package/docs/for_ai.md +641 -0
  20. package/docs/project-setup.md +432 -0
  21. package/examples/blog.ts +50 -0
  22. package/examples/invalid.ts +18 -0
  23. package/examples/venues.js +485 -0
  24. package/package.json +23 -60
  25. package/src/cli/codegen/client.ts +99 -0
  26. package/src/cli/codegen/manifest.ts +95 -0
  27. package/src/cli/codegen/pinia.ts +174 -0
  28. package/src/cli/codegen/realtime.ts +58 -0
  29. package/src/cli/codegen/sql.ts +698 -0
  30. package/src/cli/codegen/subscribable_sql.ts +547 -0
  31. package/src/cli/codegen/subscribable_store.ts +184 -0
  32. package/src/cli/codegen/types.ts +142 -0
  33. package/src/cli/compiler/analyzer.ts +52 -0
  34. package/src/cli/compiler/graph_rules.ts +251 -0
  35. package/src/cli/compiler/ir.ts +233 -0
  36. package/src/cli/compiler/loader.ts +132 -0
  37. package/src/cli/compiler/permissions.ts +227 -0
  38. package/src/cli/index.ts +164 -0
  39. package/src/client/index.ts +1 -0
  40. package/src/client/ws.ts +286 -0
  41. package/src/create/.env.example +8 -0
  42. package/src/create/README.md +101 -0
  43. package/src/create/compose.yml +14 -0
  44. package/src/create/domain.ts +153 -0
  45. package/src/create/package.json +24 -0
  46. package/src/create/server.ts +18 -0
  47. package/src/create/setup.sh +11 -0
  48. package/src/create/tsconfig.json +15 -0
  49. package/src/runtime/auth.ts +39 -0
  50. package/src/runtime/db.ts +33 -0
  51. package/src/runtime/errors.ts +51 -0
  52. package/src/runtime/index.ts +98 -0
  53. package/src/runtime/js_functions.ts +63 -0
  54. package/src/runtime/manifest_loader.ts +29 -0
  55. package/src/runtime/namespace.ts +483 -0
  56. package/src/runtime/server.ts +87 -0
  57. package/src/runtime/ws.ts +197 -0
  58. package/src/shared/ir.ts +197 -0
  59. package/tests/client.test.ts +38 -0
  60. package/tests/codegen.test.ts +71 -0
  61. package/tests/compiler.test.ts +45 -0
  62. package/tests/graph_rules.test.ts +173 -0
  63. package/tests/integration/db.test.ts +174 -0
  64. package/tests/integration/e2e.test.ts +65 -0
  65. package/tests/integration/features.test.ts +922 -0
  66. package/tests/integration/full_stack.test.ts +262 -0
  67. package/tests/integration/setup.ts +45 -0
  68. package/tests/ir.test.ts +32 -0
  69. package/tests/namespace.test.ts +395 -0
  70. package/tests/permissions.test.ts +55 -0
  71. package/tests/pinia.test.ts +48 -0
  72. package/tests/realtime.test.ts +22 -0
  73. package/tests/runtime.test.ts +80 -0
  74. package/tests/subscribable_gen.test.ts +72 -0
  75. package/tests/subscribable_reactivity.test.ts +258 -0
  76. package/tests/venues_gen.test.ts +25 -0
  77. package/tsconfig.json +20 -0
  78. package/tsconfig.tsbuildinfo +1 -0
  79. package/README.md +0 -90
  80. package/bin/cli.js +0 -727
  81. package/docs/compiler/ADVANCED_FILTERS.md +0 -183
  82. package/docs/compiler/CODING_STANDARDS.md +0 -415
  83. package/docs/compiler/COMPARISON.md +0 -673
  84. package/docs/compiler/QUICKSTART.md +0 -326
  85. package/docs/compiler/README.md +0 -134
  86. package/docs/examples/README.md +0 -38
  87. package/docs/examples/blog.sql +0 -160
  88. package/docs/examples/venue-detail-simple.sql +0 -8
  89. package/docs/examples/venue-detail-subscribable.sql +0 -45
  90. package/docs/for-ai/claude-guide.md +0 -1210
  91. package/docs/getting-started/quickstart.md +0 -125
  92. package/docs/getting-started/subscriptions-quick-start.md +0 -203
  93. package/docs/getting-started/tutorial.md +0 -1104
  94. package/docs/guides/atomic-updates.md +0 -299
  95. package/docs/guides/client-stores.md +0 -730
  96. package/docs/guides/composite-primary-keys.md +0 -158
  97. package/docs/guides/custom-functions.md +0 -362
  98. package/docs/guides/drop-semantics.md +0 -554
  99. package/docs/guides/field-defaults.md +0 -240
  100. package/docs/guides/interpreter-vs-compiler.md +0 -237
  101. package/docs/guides/many-to-many.md +0 -929
  102. package/docs/guides/subscriptions.md +0 -537
  103. package/docs/reference/api.md +0 -1373
  104. package/docs/reference/client.md +0 -224
  105. package/src/client/stores/index.js +0 -8
  106. package/src/client/stores/useAppStore.js +0 -285
  107. package/src/client/stores/useWsStore.js +0 -289
  108. package/src/client/ws.js +0 -762
  109. package/src/compiler/cli/compile-example.js +0 -33
  110. package/src/compiler/cli/compile-subscribable.js +0 -43
  111. package/src/compiler/cli/debug-compile.js +0 -44
  112. package/src/compiler/cli/debug-parse.js +0 -26
  113. package/src/compiler/cli/debug-path-parser.js +0 -18
  114. package/src/compiler/cli/debug-subscribable-parser.js +0 -21
  115. package/src/compiler/cli/index.js +0 -174
  116. package/src/compiler/codegen/auth-codegen.js +0 -153
  117. package/src/compiler/codegen/drop-semantics-codegen.js +0 -553
  118. package/src/compiler/codegen/graph-rules-codegen.js +0 -450
  119. package/src/compiler/codegen/notification-codegen.js +0 -232
  120. package/src/compiler/codegen/operation-codegen.js +0 -1382
  121. package/src/compiler/codegen/permission-codegen.js +0 -318
  122. package/src/compiler/codegen/subscribable-codegen.js +0 -827
  123. package/src/compiler/compiler.js +0 -371
  124. package/src/compiler/index.js +0 -11
  125. package/src/compiler/parser/entity-parser.js +0 -440
  126. package/src/compiler/parser/path-parser.js +0 -290
  127. package/src/compiler/parser/subscribable-parser.js +0 -244
  128. package/src/database/dzql-core.sql +0 -161
  129. package/src/database/migrations/001_schema.sql +0 -60
  130. package/src/database/migrations/002_functions.sql +0 -890
  131. package/src/database/migrations/003_operations.sql +0 -1135
  132. package/src/database/migrations/004_search.sql +0 -581
  133. package/src/database/migrations/005_entities.sql +0 -730
  134. package/src/database/migrations/006_auth.sql +0 -94
  135. package/src/database/migrations/007_events.sql +0 -133
  136. package/src/database/migrations/008_hello.sql +0 -18
  137. package/src/database/migrations/008a_meta.sql +0 -172
  138. package/src/database/migrations/009_subscriptions.sql +0 -240
  139. package/src/database/migrations/010_atomic_updates.sql +0 -157
  140. package/src/database/migrations/010_fix_m2m_events.sql +0 -94
  141. package/src/index.js +0 -40
  142. package/src/server/api.js +0 -9
  143. package/src/server/db.js +0 -442
  144. package/src/server/index.js +0 -317
  145. package/src/server/logger.js +0 -259
  146. package/src/server/mcp.js +0 -594
  147. package/src/server/meta-route.js +0 -251
  148. package/src/server/namespace.js +0 -292
  149. package/src/server/subscriptions.js +0 -351
  150. package/src/server/ws.js +0 -573
@@ -0,0 +1,432 @@
1
+ # TZQL Project Setup Guide
2
+
3
+ Complete guide for setting up a Vue/Pinia client project with TZQL.
4
+
5
+ ## Project Structure
6
+
7
+ ```
8
+ my-app/
9
+ ├── package.json # Workspaces root
10
+ ├── bun.lock # Single lockfile
11
+ ├── domain.js # TZQL domain definition
12
+ ├── .env # Environment variables
13
+ ├── compose.yml # PostgreSQL for development
14
+ ├── generated/ # DO NOT EDIT - compiled output
15
+ │ ├── client/ # WebSocket client, Pinia stores, types
16
+ │ ├── db/migrations/ # PostgreSQL schema
17
+ │ └── runtime/ # Server manifest
18
+ ├── src/ # Vue client workspace
19
+ │ ├── package.json
20
+ │ ├── vite.config.ts
21
+ │ ├── tsconfig.app.json
22
+ │ └── src/
23
+ │ ├── main.ts
24
+ │ ├── App.vue
25
+ │ ├── composables/
26
+ │ ├── components/
27
+ │ └── views/
28
+ └── server/ # TZQL server workspace
29
+ ├── package.json
30
+ └── index.ts
31
+ ```
32
+
33
+ ## 1. Bun Workspaces
34
+
35
+ Root `package.json`:
36
+
37
+ ```json
38
+ {
39
+ "name": "my-app",
40
+ "private": true,
41
+ "workspaces": ["src", "server"],
42
+ "scripts": {
43
+ "compile": "tzql compile domain.js -o generated",
44
+ "db": "docker compose down -v && docker compose up -d",
45
+ "logs": "docker compose logs -f",
46
+ "dev": "concurrently -n server,client -c blue,green \"bun run --filter @my-app/server dev\" \"bun run --filter @my-app/client dev\""
47
+ },
48
+ "devDependencies": {
49
+ "concurrently": "^9.2.1",
50
+ "tzql": "link:tzql"
51
+ }
52
+ }
53
+ ```
54
+
55
+ Client `src/package.json`:
56
+
57
+ ```json
58
+ {
59
+ "name": "@my-app/client",
60
+ "private": true,
61
+ "type": "module",
62
+ "scripts": {
63
+ "dev": "vite",
64
+ "build": "vite build"
65
+ },
66
+ "dependencies": {
67
+ "pinia": "^3.0.4",
68
+ "vue": "^3.5.25",
69
+ "vue-router": "^4.6.3"
70
+ },
71
+ "devDependencies": {
72
+ "@vitejs/plugin-vue": "^6.0.2",
73
+ "vite": "^7.2.4",
74
+ "typescript": "~5.9.0"
75
+ }
76
+ }
77
+ ```
78
+
79
+ Server `server/package.json`:
80
+
81
+ ```json
82
+ {
83
+ "name": "@my-app/server",
84
+ "private": true,
85
+ "type": "module",
86
+ "scripts": {
87
+ "dev": "cd .. && bun run server/index.ts"
88
+ },
89
+ "dependencies": {
90
+ "tzql": "link:tzql"
91
+ }
92
+ }
93
+ ```
94
+
95
+ **Important:** The server script uses `cd ..` to run from the project root so that:
96
+ - `.env` is found (dotenv loads from `process.cwd()`)
97
+ - `MANIFEST_PATH=./generated/runtime/manifest.json` resolves correctly
98
+
99
+ Server `server/index.ts`:
100
+
101
+ ```typescript
102
+ import "tzql";
103
+ ```
104
+
105
+ ## 2. Docker Compose for PostgreSQL
106
+
107
+ `compose.yml`:
108
+
109
+ ```yaml
110
+ services:
111
+ db:
112
+ image: postgres:16-alpine
113
+ environment:
114
+ POSTGRES_USER: myapp
115
+ POSTGRES_PASSWORD: myapp
116
+ POSTGRES_DB: myapp
117
+ ports:
118
+ - "5432:5432"
119
+ volumes:
120
+ - pgdata:/var/lib/postgresql/data
121
+ - ./generated/db/migrations:/docker-entrypoint-initdb.d:ro
122
+
123
+ volumes:
124
+ pgdata:
125
+ ```
126
+
127
+ **Key:** Mount `generated/db/migrations` to `/docker-entrypoint-initdb.d` for automatic schema initialization on first run.
128
+
129
+ ## 3. Environment Variables
130
+
131
+ `.env`:
132
+
133
+ ```
134
+ # Database
135
+ DATABASE_URL=postgres://myapp:myapp@localhost:5432/myapp
136
+
137
+ # Server
138
+ PORT=3000
139
+ MANIFEST_PATH=./generated/runtime/manifest.json
140
+ JWT_SECRET=dev-secret-change-in-production
141
+
142
+ # Client (Vite)
143
+ VITE_TZQL_TOKEN_NAME=myapp_token
144
+ ```
145
+
146
+ ## 4. Vite Configuration
147
+
148
+ `src/vite.config.ts`:
149
+
150
+ ```typescript
151
+ import { fileURLToPath, URL } from 'node:url'
152
+ import { defineConfig } from 'vite'
153
+ import vue from '@vitejs/plugin-vue'
154
+
155
+ export default defineConfig({
156
+ plugins: [vue()],
157
+ resolve: {
158
+ alias: {
159
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
160
+ '@generated': fileURLToPath(new URL('../generated', import.meta.url)),
161
+ },
162
+ },
163
+ server: {
164
+ // Allow external access (for Docker-based tools like Playwright MCP)
165
+ host: '0.0.0.0',
166
+ allowedHosts: ['host.docker.internal'],
167
+
168
+ // Proxy WebSocket to TZQL server
169
+ proxy: {
170
+ '/ws': {
171
+ target: 'ws://localhost:3000',
172
+ ws: true,
173
+ },
174
+ },
175
+ },
176
+ })
177
+ ```
178
+
179
+ **Configuration explained:**
180
+
181
+ - `host: '0.0.0.0'` - Binds to all interfaces, required for Docker access
182
+ - `allowedHosts: ['host.docker.internal']` - Allows Playwright MCP (running in Docker) to connect
183
+ - `proxy: { '/ws': ... }` - Client connects to `/ws` on Vite's port, proxied to TZQL server on port 3000
184
+
185
+ **For Playwright MCP testing:** Navigate to `http://host.docker.internal:5173`
186
+
187
+ ## 5. TypeScript Path Aliases
188
+
189
+ `src/tsconfig.app.json`:
190
+
191
+ ```json
192
+ {
193
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
194
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
195
+ "compilerOptions": {
196
+ "paths": {
197
+ "@/*": ["./src/*"],
198
+ "@generated/*": ["../generated/*"]
199
+ }
200
+ }
201
+ }
202
+ ```
203
+
204
+ ## 6. Authentication Composable
205
+
206
+ `src/src/composables/useTzql.ts`:
207
+
208
+ ```typescript
209
+ import { ref } from 'vue'
210
+ import { ws } from '@generated/client'
211
+
212
+ const ready = ref(false)
213
+ const user = ref<any>(null)
214
+ const connectionError = ref<string | null>(null)
215
+
216
+ export function useTzql() {
217
+ async function connect(url?: string) {
218
+ try {
219
+ connectionError.value = null
220
+ ready.value = false
221
+
222
+ ws.onReady((profile: any) => {
223
+ if (!profile && localStorage.getItem('token')) {
224
+ localStorage.removeItem('token')
225
+ }
226
+ user.value = profile
227
+ ready.value = true
228
+ })
229
+
230
+ await ws.connect(url)
231
+ } catch (e: any) {
232
+ connectionError.value = e.message
233
+ throw e
234
+ }
235
+ }
236
+
237
+ async function login(email: string, password: string) {
238
+ const result = await ws.login({ email, password })
239
+ if (result?.user_id) {
240
+ user.value = result
241
+ }
242
+ return result
243
+ }
244
+
245
+ async function register(name: string, email: string, password: string) {
246
+ const result = await ws.register({ name, email, password })
247
+ if (result?.user_id) {
248
+ user.value = result
249
+ }
250
+ return result
251
+ }
252
+
253
+ async function logout() {
254
+ await ws.logout()
255
+ user.value = null
256
+ }
257
+
258
+ return { ws, ready, user, connectionError, connect, login, register, logout }
259
+ }
260
+ ```
261
+
262
+ ## 7. App Entry Point
263
+
264
+ `src/src/main.ts`:
265
+
266
+ ```typescript
267
+ import './assets/main.css'
268
+ import { createApp } from 'vue'
269
+ import { createPinia } from 'pinia'
270
+ import App from './App.vue'
271
+ import router from './router'
272
+ import { useTzql } from './composables/useTzql'
273
+
274
+ const app = createApp(App)
275
+ app.use(createPinia())
276
+ app.use(router)
277
+ app.mount('#app')
278
+
279
+ // Connect to TZQL server
280
+ const { connect } = useTzql()
281
+ connect()
282
+ ```
283
+
284
+ ## 8. App Component Pattern
285
+
286
+ `src/src/App.vue`:
287
+
288
+ ```vue
289
+ <script setup lang="ts">
290
+ import { useTzql } from '@/composables/useTzql'
291
+ import LoginModal from '@/components/LoginModal.vue'
292
+
293
+ const { ready, user, logout } = useTzql()
294
+ </script>
295
+
296
+ <template>
297
+ <div v-if="!ready" class="loading">Connecting...</div>
298
+ <LoginModal v-else-if="!user" />
299
+ <template v-else>
300
+ <header>
301
+ <nav>
302
+ <RouterLink to="/">Home</RouterLink>
303
+ <span>{{ user.name }}</span>
304
+ <button @click="logout">Logout</button>
305
+ </nav>
306
+ </header>
307
+ <main>
308
+ <RouterView />
309
+ </main>
310
+ </template>
311
+ </template>
312
+ ```
313
+
314
+ **Key points:**
315
+ - No router guards needed - WebSocket `connection:ready` is the source of truth
316
+ - Shows loading until connection established
317
+ - Shows login if no user, app content if authenticated
318
+ - Login/logout reactively update UI - no page reload needed
319
+
320
+ ## 9. Using Generated Stores
321
+
322
+ ```vue
323
+ <script setup lang="ts">
324
+ import { computed, watchEffect } from 'vue'
325
+ import { useRoute } from 'vue-router'
326
+ import { useTzql } from '@/composables/useTzql'
327
+ import { useVenueDetailStore } from '@generated/client/stores/useVenueDetailStore.js'
328
+
329
+ const route = useRoute()
330
+ const { ws } = useTzql()
331
+ const store = useVenueDetailStore()
332
+
333
+ const venueId = computed(() => Number(route.params.id))
334
+ const docKey = computed(() => JSON.stringify({ venue_id: venueId.value }))
335
+
336
+ // Bind to subscription when venueId changes
337
+ watchEffect(() => {
338
+ if (venueId.value) {
339
+ store.bind({ venue_id: venueId.value })
340
+ }
341
+ })
342
+
343
+ // Reactive data from store
344
+ const doc = computed(() => store.documents[docKey.value])
345
+ const loading = computed(() => !doc.value || doc.value.loading.value)
346
+ const venue = computed(() => doc.value?.data.value)
347
+ const sites = computed(() => doc.value?.data.value?.sites ?? [])
348
+
349
+ // CRUD operations
350
+ async function createSite(name: string) {
351
+ await ws.api.save_sites({ venue_id: venueId.value, name })
352
+ // No refetch needed - patch arrives via WebSocket
353
+ }
354
+
355
+ async function updateSite(id: number, name: string) {
356
+ await ws.api.save_sites({ id, venue_id: venueId.value, name })
357
+ }
358
+
359
+ async function deleteSite(id: number) {
360
+ await ws.api.delete_sites({ id })
361
+ }
362
+ </script>
363
+ ```
364
+
365
+ ## 10. CLI Database Access with invj
366
+
367
+ Create `tasks.js` in the project root to enable CLI database operations:
368
+
369
+ ```javascript
370
+ import { TzqlNamespace } from "tzql/namespace";
371
+
372
+ export class Tasks {
373
+ constructor() {
374
+ this.tzql = new TzqlNamespace();
375
+ }
376
+ }
377
+ ```
378
+
379
+ This integrates with `invj` to provide direct database access:
380
+
381
+ ```bash
382
+ # List available commands
383
+ invj -l
384
+
385
+ # Available tzql commands:
386
+ # tzql:entities - List all entities
387
+ # tzql:subscribables - List all subscribables
388
+ # tzql:functions - List all functions
389
+ # tzql:search <entity> [json] - Search records
390
+ # tzql:get <entity> [json] - Get single record
391
+ # tzql:save <entity> [json] - Create/update record
392
+ # tzql:delete <entity> [json] - Delete record
393
+ # tzql:lookup <entity> [json] - Autocomplete lookup
394
+ # tzql:call <func> [json] - Call custom function
395
+ # tzql:subscribe <name> [json] - Get subscribable data
396
+
397
+ # Examples
398
+ invj tzql:entities
399
+ invj tzql:search venues
400
+ invj tzql:search venues '{"org_id": 1}'
401
+ invj tzql:get venues '{"id": 1}'
402
+ invj tzql:save venues '{"org_id": 1, "name": "New Venue", "address": "123 Main St"}'
403
+ invj tzql:delete venues '{"id": 1}'
404
+ ```
405
+
406
+ ## Development Workflow
407
+
408
+ ```bash
409
+ # 1. Start PostgreSQL
410
+ bun run db
411
+
412
+ # 2. Compile domain (after any domain.js changes)
413
+ bun run compile
414
+
415
+ # 3. Start dev servers
416
+ bun run dev
417
+ ```
418
+
419
+ After `bun run db`, the database initializes with migrations automatically. After domain changes, run `bun run compile` then restart the server.
420
+
421
+ ## Linking TZQL for Local Development
422
+
423
+ If developing TZQL locally:
424
+
425
+ ```bash
426
+ cd /path/to/tzql
427
+ bun link
428
+
429
+ cd /path/to/my-app
430
+ # tzql is already in package.json as "link:tzql"
431
+ bun install
432
+ ```
@@ -0,0 +1,50 @@
1
+ // TZQL Entity Definition Example
2
+
3
+ export const entities = {
4
+ posts: {
5
+ schema: {
6
+ id: 'serial PRIMARY KEY',
7
+ title: 'text NOT NULL',
8
+ content: 'text',
9
+ author_id: 'int NOT NULL', // In a real app, this would reference users(id)
10
+ created_at: 'timestamptz DEFAULT now()'
11
+ },
12
+ permissions: {
13
+ view: [], // Public
14
+ create: ['@author_id == @user_id'], // Only create for self
15
+ update: ['@author_id == @user_id'], // Only owner
16
+ delete: ['@author_id == @user_id'] // Only owner
17
+ },
18
+ graphRules: {
19
+ on_create: {
20
+ actions: [
21
+ { type: 'reactor', name: 'notify_subscribers', params: { post_id: '@id' } }
22
+ ]
23
+ }
24
+ }
25
+ },
26
+ comments: {
27
+ schema: {
28
+ id: 'serial PRIMARY KEY',
29
+ post_id: 'int NOT NULL REFERENCES posts(id) ON DELETE CASCADE',
30
+ content: 'text NOT NULL',
31
+ author_id: 'int NOT NULL'
32
+ },
33
+ permissions: {
34
+ view: [],
35
+ create: [],
36
+ delete: ['@author_id == @user_id']
37
+ }
38
+ }
39
+ };
40
+
41
+ export const subscribables = {
42
+ post_detail: {
43
+ params: { post_id: 'int' },
44
+ root: { entity: 'posts', key: 'post_id' },
45
+ includes: {
46
+ comments: { entity: 'comments', filter: { post_id: '@id' } }
47
+ },
48
+ scopeTables: ['posts', 'comments']
49
+ }
50
+ };
@@ -0,0 +1,18 @@
1
+ // TZQL Entity Definition Example (INVALID)
2
+
3
+ export const entities = {
4
+ posts: {
5
+ schema: { id: 'serial PRIMARY KEY' },
6
+ permissions: {}
7
+ }
8
+ };
9
+
10
+ export const subscribables = {
11
+ broken_feed: {
12
+ params: {},
13
+ root: { entity: 'posts' },
14
+ includes: {
15
+ comments: { entity: 'missing_table' } // <--- Error: 'missing_table' does not exist
16
+ }
17
+ }
18
+ };