dzql 0.5.33 → 0.6.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.
Files changed (142) 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 +309 -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 +653 -0
  20. package/docs/project-setup.md +456 -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 +166 -0
  39. package/src/client/index.ts +1 -0
  40. package/src/client/ws.ts +286 -0
  41. package/src/runtime/auth.ts +39 -0
  42. package/src/runtime/db.ts +33 -0
  43. package/src/runtime/errors.ts +51 -0
  44. package/src/runtime/index.ts +98 -0
  45. package/src/runtime/js_functions.ts +63 -0
  46. package/src/runtime/manifest_loader.ts +29 -0
  47. package/src/runtime/namespace.ts +483 -0
  48. package/src/runtime/server.ts +87 -0
  49. package/src/runtime/ws.ts +197 -0
  50. package/src/shared/ir.ts +197 -0
  51. package/tests/client.test.ts +38 -0
  52. package/tests/codegen.test.ts +71 -0
  53. package/tests/compiler.test.ts +45 -0
  54. package/tests/graph_rules.test.ts +173 -0
  55. package/tests/integration/db.test.ts +174 -0
  56. package/tests/integration/e2e.test.ts +65 -0
  57. package/tests/integration/features.test.ts +922 -0
  58. package/tests/integration/full_stack.test.ts +262 -0
  59. package/tests/integration/setup.ts +45 -0
  60. package/tests/ir.test.ts +32 -0
  61. package/tests/namespace.test.ts +395 -0
  62. package/tests/permissions.test.ts +55 -0
  63. package/tests/pinia.test.ts +48 -0
  64. package/tests/realtime.test.ts +22 -0
  65. package/tests/runtime.test.ts +80 -0
  66. package/tests/subscribable_gen.test.ts +72 -0
  67. package/tests/subscribable_reactivity.test.ts +258 -0
  68. package/tests/venues_gen.test.ts +25 -0
  69. package/tsconfig.json +20 -0
  70. package/tsconfig.tsbuildinfo +1 -0
  71. package/README.md +0 -90
  72. package/bin/cli.js +0 -727
  73. package/docs/compiler/ADVANCED_FILTERS.md +0 -183
  74. package/docs/compiler/CODING_STANDARDS.md +0 -415
  75. package/docs/compiler/COMPARISON.md +0 -673
  76. package/docs/compiler/QUICKSTART.md +0 -326
  77. package/docs/compiler/README.md +0 -134
  78. package/docs/examples/README.md +0 -38
  79. package/docs/examples/blog.sql +0 -160
  80. package/docs/examples/venue-detail-simple.sql +0 -8
  81. package/docs/examples/venue-detail-subscribable.sql +0 -45
  82. package/docs/for-ai/claude-guide.md +0 -1210
  83. package/docs/getting-started/quickstart.md +0 -125
  84. package/docs/getting-started/subscriptions-quick-start.md +0 -203
  85. package/docs/getting-started/tutorial.md +0 -1104
  86. package/docs/guides/atomic-updates.md +0 -299
  87. package/docs/guides/client-stores.md +0 -730
  88. package/docs/guides/composite-primary-keys.md +0 -158
  89. package/docs/guides/custom-functions.md +0 -362
  90. package/docs/guides/drop-semantics.md +0 -554
  91. package/docs/guides/field-defaults.md +0 -240
  92. package/docs/guides/interpreter-vs-compiler.md +0 -237
  93. package/docs/guides/many-to-many.md +0 -929
  94. package/docs/guides/subscriptions.md +0 -537
  95. package/docs/reference/api.md +0 -1373
  96. package/docs/reference/client.md +0 -224
  97. package/src/client/stores/index.js +0 -8
  98. package/src/client/stores/useAppStore.js +0 -285
  99. package/src/client/stores/useWsStore.js +0 -289
  100. package/src/client/ws.js +0 -762
  101. package/src/compiler/cli/compile-example.js +0 -33
  102. package/src/compiler/cli/compile-subscribable.js +0 -43
  103. package/src/compiler/cli/debug-compile.js +0 -44
  104. package/src/compiler/cli/debug-parse.js +0 -26
  105. package/src/compiler/cli/debug-path-parser.js +0 -18
  106. package/src/compiler/cli/debug-subscribable-parser.js +0 -21
  107. package/src/compiler/cli/index.js +0 -174
  108. package/src/compiler/codegen/auth-codegen.js +0 -153
  109. package/src/compiler/codegen/drop-semantics-codegen.js +0 -553
  110. package/src/compiler/codegen/graph-rules-codegen.js +0 -450
  111. package/src/compiler/codegen/notification-codegen.js +0 -232
  112. package/src/compiler/codegen/operation-codegen.js +0 -1382
  113. package/src/compiler/codegen/permission-codegen.js +0 -318
  114. package/src/compiler/codegen/subscribable-codegen.js +0 -827
  115. package/src/compiler/compiler.js +0 -371
  116. package/src/compiler/index.js +0 -11
  117. package/src/compiler/parser/entity-parser.js +0 -440
  118. package/src/compiler/parser/path-parser.js +0 -290
  119. package/src/compiler/parser/subscribable-parser.js +0 -244
  120. package/src/database/dzql-core.sql +0 -161
  121. package/src/database/migrations/001_schema.sql +0 -60
  122. package/src/database/migrations/002_functions.sql +0 -890
  123. package/src/database/migrations/003_operations.sql +0 -1135
  124. package/src/database/migrations/004_search.sql +0 -581
  125. package/src/database/migrations/005_entities.sql +0 -730
  126. package/src/database/migrations/006_auth.sql +0 -94
  127. package/src/database/migrations/007_events.sql +0 -133
  128. package/src/database/migrations/008_hello.sql +0 -18
  129. package/src/database/migrations/008a_meta.sql +0 -172
  130. package/src/database/migrations/009_subscriptions.sql +0 -240
  131. package/src/database/migrations/010_atomic_updates.sql +0 -157
  132. package/src/database/migrations/010_fix_m2m_events.sql +0 -94
  133. package/src/index.js +0 -40
  134. package/src/server/api.js +0 -9
  135. package/src/server/db.js +0 -442
  136. package/src/server/index.js +0 -317
  137. package/src/server/logger.js +0 -259
  138. package/src/server/mcp.js +0 -594
  139. package/src/server/meta-route.js +0 -251
  140. package/src/server/namespace.js +0 -292
  141. package/src/server/subscriptions.js +0 -351
  142. package/src/server/ws.js +0 -573
@@ -1,157 +0,0 @@
1
- -- Migration 010: Atomic Updates for Subscribables
2
- -- Adds extract_scope_tables function and updates register_subscribable to auto-populate scope_tables
3
-
4
- -- ============================================================================
5
- -- Helper function to extract scope tables from relations
6
- -- ============================================================================
7
-
8
- CREATE OR REPLACE FUNCTION dzql.extract_scope_tables(
9
- p_root_entity TEXT,
10
- p_relations JSONB
11
- ) RETURNS TEXT[] AS $$
12
- DECLARE
13
- v_tables TEXT[];
14
- v_key TEXT;
15
- v_value JSONB;
16
- v_entity TEXT;
17
- v_nested JSONB;
18
- BEGIN
19
- -- Start with root entity (may be NULL for dashboard mode)
20
- IF p_root_entity IS NOT NULL AND p_root_entity != '' THEN
21
- v_tables := ARRAY[p_root_entity];
22
- ELSE
23
- v_tables := ARRAY[]::TEXT[];
24
- END IF;
25
-
26
- -- Return early if no relations
27
- IF p_relations IS NULL OR p_relations = '{}'::jsonb THEN
28
- RETURN v_tables;
29
- END IF;
30
-
31
- -- Iterate through relations
32
- FOR v_key, v_value IN SELECT * FROM jsonb_each(p_relations)
33
- LOOP
34
- -- Handle string relation (simple FK expansion): "org": "organisations"
35
- IF jsonb_typeof(v_value) = 'string' THEN
36
- v_entity := v_value #>> '{}';
37
- IF v_entity IS NOT NULL AND v_entity != '' THEN
38
- v_tables := array_append(v_tables, v_entity);
39
- END IF;
40
- -- Handle object relation: {"entity": "sites", "filter": "..."}
41
- ELSIF jsonb_typeof(v_value) = 'object' THEN
42
- v_entity := v_value ->> 'entity';
43
- IF v_entity IS NOT NULL AND v_entity != '' THEN
44
- v_tables := array_append(v_tables, v_entity);
45
- END IF;
46
-
47
- -- Recursively handle nested relations (include or relations)
48
- v_nested := v_value -> 'include';
49
- IF v_nested IS NOT NULL AND jsonb_typeof(v_nested) = 'object' THEN
50
- v_tables := v_tables || dzql.extract_scope_tables(NULL, v_nested);
51
- END IF;
52
-
53
- v_nested := v_value -> 'relations';
54
- IF v_nested IS NOT NULL AND jsonb_typeof(v_nested) = 'object' THEN
55
- v_tables := v_tables || dzql.extract_scope_tables(NULL, v_nested);
56
- END IF;
57
- END IF;
58
- END LOOP;
59
-
60
- -- Remove duplicates and nulls
61
- SELECT array_agg(DISTINCT t) INTO v_tables
62
- FROM unnest(v_tables) t
63
- WHERE t IS NOT NULL;
64
-
65
- RETURN COALESCE(v_tables, ARRAY[]::TEXT[]);
66
- END;
67
- $$ LANGUAGE plpgsql IMMUTABLE;
68
-
69
- COMMENT ON FUNCTION dzql.extract_scope_tables IS
70
- 'Extract all table names from a subscribable definition (root entity + all relations recursively)';
71
-
72
- -- ============================================================================
73
- -- Update register_subscribable to auto-populate scope_tables
74
- -- ============================================================================
75
-
76
- CREATE OR REPLACE FUNCTION dzql.register_subscribable(
77
- p_name TEXT,
78
- p_permission_paths JSONB,
79
- p_param_schema JSONB,
80
- p_root_entity TEXT,
81
- p_relations JSONB
82
- ) RETURNS TEXT AS $$
83
- DECLARE
84
- v_result TEXT;
85
- v_scope_tables TEXT[];
86
- BEGIN
87
- -- Validate inputs
88
- IF p_name IS NULL OR p_name = '' THEN
89
- RAISE EXCEPTION 'Subscribable name cannot be empty';
90
- END IF;
91
-
92
- -- NULL root_entity is allowed for dashboard mode (pure collections)
93
- -- But if relations is also empty, that's an error
94
- IF (p_root_entity IS NULL OR p_root_entity = '') AND
95
- (p_relations IS NULL OR p_relations = '{}'::jsonb) THEN
96
- RAISE EXCEPTION 'Subscribable must have either a root entity or relations';
97
- END IF;
98
-
99
- -- Extract scope tables from root entity and relations
100
- v_scope_tables := dzql.extract_scope_tables(p_root_entity, p_relations);
101
-
102
- -- Insert or update subscribable
103
- INSERT INTO dzql.subscribables (
104
- name,
105
- permission_paths,
106
- param_schema,
107
- root_entity,
108
- relations,
109
- scope_tables,
110
- created_at,
111
- updated_at
112
- ) VALUES (
113
- p_name,
114
- COALESCE(p_permission_paths, '{}'::jsonb),
115
- COALESCE(p_param_schema, '{}'::jsonb),
116
- NULLIF(p_root_entity, ''), -- Store empty string as NULL
117
- COALESCE(p_relations, '{}'::jsonb),
118
- v_scope_tables,
119
- NOW(),
120
- NOW()
121
- )
122
- ON CONFLICT (name) DO UPDATE SET
123
- permission_paths = EXCLUDED.permission_paths,
124
- param_schema = EXCLUDED.param_schema,
125
- root_entity = EXCLUDED.root_entity,
126
- relations = EXCLUDED.relations,
127
- scope_tables = EXCLUDED.scope_tables,
128
- updated_at = NOW();
129
-
130
- v_result := format('Subscribable "%s" registered successfully with scope tables: %s',
131
- p_name, array_to_string(v_scope_tables, ', '));
132
-
133
- RAISE NOTICE '%', v_result;
134
-
135
- RETURN v_result;
136
- END;
137
- $$ LANGUAGE plpgsql;
138
-
139
- -- ============================================================================
140
- -- Backfill existing subscribables with scope_tables
141
- -- ============================================================================
142
-
143
- UPDATE dzql.subscribables s
144
- SET scope_tables = dzql.extract_scope_tables(s.root_entity, s.relations)
145
- WHERE scope_tables = '{}' OR scope_tables IS NULL;
146
-
147
- -- ============================================================================
148
- -- Verification
149
- -- ============================================================================
150
-
151
- DO $$
152
- BEGIN
153
- RAISE NOTICE 'Migration 010: Atomic Updates - Complete';
154
- RAISE NOTICE 'Created dzql.extract_scope_tables() function';
155
- RAISE NOTICE 'Updated dzql.register_subscribable() to auto-populate scope_tables';
156
- RAISE NOTICE 'Backfilled existing subscribables';
157
- END $$;
@@ -1,94 +0,0 @@
1
- -- ============================================================================
2
- -- Migration 010: Fix M2M in Event "before" Field
3
- -- ============================================================================
4
- --
5
- -- Issue: UPDATE events don't include M2M data in the "before" field
6
- -- Root cause: l_existing_record in generic_save doesn't expand M2M relationships
7
- -- Fix: Create a helper function to expand M2M, then update generic_save to use it
8
- --
9
- -- This ensures UPDATE events have complete before/after state including M2M data
10
- -- ============================================================================
11
-
12
- DO $$ BEGIN
13
- RAISE NOTICE 'Migration 010: Fixing M2M in event before field...';
14
- END $$;
15
-
16
- -- Create helper function to expand M2M relationships for a record
17
- CREATE OR REPLACE FUNCTION dzql.expand_m2m_for_record(
18
- p_entity text,
19
- p_record jsonb,
20
- p_entity_config record,
21
- p_pk_cols text[]
22
- ) RETURNS jsonb
23
- LANGUAGE plpgsql
24
- AS $$
25
- DECLARE
26
- l_result jsonb := p_record;
27
- l_m2m_key text;
28
- l_m2m_config jsonb;
29
- l_id_field text;
30
- l_junction_table text;
31
- l_local_key text;
32
- l_foreign_key text;
33
- l_target_entity text;
34
- l_expand boolean;
35
- l_record_id text;
36
- l_id_array jsonb;
37
- l_expanded_objects jsonb;
38
- BEGIN
39
- -- Only expand if entity has M2M configuration
40
- IF p_entity_config.many_to_many IS NULL OR p_entity_config.many_to_many = '{}'::jsonb THEN
41
- RETURN l_result;
42
- END IF;
43
-
44
- -- Get the primary key value from the record
45
- l_record_id := l_result->>p_pk_cols[1]; -- Assume single PK for now
46
-
47
- IF l_record_id IS NULL THEN
48
- RETURN l_result;
49
- END IF;
50
-
51
- -- Loop through all M2M relationships
52
- FOR l_m2m_key IN SELECT jsonb_object_keys(p_entity_config.many_to_many)
53
- LOOP
54
- l_m2m_config := p_entity_config.many_to_many->l_m2m_key;
55
- l_id_field := l_m2m_config->>'id_field';
56
- l_junction_table := l_m2m_config->>'junction_table';
57
- l_local_key := l_m2m_config->>'local_key';
58
- l_foreign_key := l_m2m_config->>'foreign_key';
59
- l_target_entity := l_m2m_config->>'target_entity';
60
- l_expand := COALESCE((l_m2m_config->>'expand')::boolean, false);
61
-
62
- -- Always include array of IDs
63
- EXECUTE format('
64
- SELECT COALESCE(jsonb_agg(%I ORDER BY %I), ''[]''::jsonb)
65
- FROM %I
66
- WHERE %I = $1::int
67
- ', l_foreign_key, l_foreign_key, l_junction_table, l_local_key)
68
- INTO l_id_array
69
- USING l_record_id;
70
-
71
- l_result := l_result || jsonb_build_object(l_id_field, l_id_array);
72
-
73
- -- Conditionally include expanded objects if expand: true
74
- IF l_expand THEN
75
- EXECUTE format('
76
- SELECT COALESCE(jsonb_agg(to_jsonb(t.*) ORDER BY t.id), ''[]''::jsonb)
77
- FROM %I jt
78
- JOIN %I t ON t.id = jt.%I
79
- WHERE jt.%I = $1::int
80
- ', l_junction_table, l_target_entity, l_foreign_key, l_local_key)
81
- INTO l_expanded_objects
82
- USING l_record_id;
83
-
84
- l_result := l_result || jsonb_build_object(l_m2m_key, l_expanded_objects);
85
- END IF;
86
- END LOOP;
87
-
88
- RETURN l_result;
89
- END $$;
90
-
91
- DO $$ BEGIN
92
- RAISE NOTICE 'Migration 010: M2M expansion helper function created';
93
- RAISE NOTICE 'Note: generic_save still needs updating to use this helper - will be done in next migration';
94
- END $$;
package/src/index.js DELETED
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env bun
2
- /**
3
- * DZQL Demo Server
4
- *
5
- * Minimal example server that serves demo.html and provides WebSocket functionality.
6
- * Run with: bun packages/dzql/src/index.js
7
- */
8
-
9
- import { createServer } from './server/index.js';
10
- import { fileURLToPath } from 'url';
11
- import { dirname, join } from 'path';
12
-
13
- const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
15
-
16
- // Path to demo.html
17
- const demoPath = join(__dirname, 'client/demo.html');
18
-
19
- // Create DZQL server with demo route
20
- const app = createServer({
21
- port: 3000,
22
- routes: {
23
- '/': async () => {
24
- const file = Bun.file(demoPath);
25
- return new Response(file, {
26
- headers: { 'Content-Type': 'text/html' }
27
- });
28
- },
29
- '/demo': async () => {
30
- const file = Bun.file(demoPath);
31
- return new Response(file, {
32
- headers: { 'Content-Type': 'text/html' }
33
- });
34
- }
35
- }
36
- });
37
-
38
- console.log('🚀 DZQL Demo Server running');
39
- console.log('📝 Visit http://localhost:3000 to see the demo');
40
- console.log('🔌 WebSocket available at ws://localhost:3000/ws');
package/src/server/api.js DELETED
@@ -1,9 +0,0 @@
1
- export async function goodbye(userId, params = {}) {
2
- const { name = "World" } = params;
3
-
4
- return {
5
- message: `Goodbye, ${name}!`,
6
- from: "Bun",
7
- user_id: userId,
8
- };
9
- }