dzql 0.3.6 → 0.4.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/bin/cli.js CHANGED
@@ -186,8 +186,7 @@ CREATE TABLE IF NOT EXISTS dzql.events (
186
186
  table_name text NOT NULL,
187
187
  op text NOT NULL,
188
188
  pk jsonb NOT NULL,
189
- before jsonb,
190
- after jsonb,
189
+ data jsonb,
191
190
  user_id int,
192
191
  notify_users int[],
193
192
  at timestamptz DEFAULT now()
@@ -206,9 +205,7 @@ BEGIN
206
205
  'table', NEW.table_name,
207
206
  'op', NEW.op,
208
207
  'pk', NEW.pk,
209
- 'data', COALESCE(NEW.after, NEW.before),
210
- 'before', NEW.before,
211
- 'after', NEW.after,
208
+ 'data', NEW.data,
212
209
  'user_id', NEW.user_id,
213
210
  'at', NEW.at,
214
211
  'notify_users', NEW.notify_users
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dzql",
3
- "version": "0.3.6",
3
+ "version": "0.4.0",
4
4
  "description": "PostgreSQL-powered framework with zero boilerplate CRUD operations and real-time WebSocket synchronization",
5
5
  "type": "module",
6
6
  "main": "src/server/index.js",
@@ -11,7 +11,8 @@
11
11
  "./client/templates": "./src/client/templates/App.vue",
12
12
  "./server": "./src/server/index.js",
13
13
  "./db": "./src/server/db.js",
14
- "./compiler": "./src/compiler/index.js"
14
+ "./compiler": "./src/compiler/index.js",
15
+ "./namespace": "./src/server/namespace.js"
15
16
  },
16
17
  "files": [
17
18
  "bin/**/*.js",
@@ -0,0 +1,228 @@
1
+ import { sql, db } from "./db.js";
2
+
3
+ // Default user for CLI operations
4
+ const DEFAULT_USER_ID = 1;
5
+
6
+ /**
7
+ * Discover available entities from dzql.entities table
8
+ */
9
+ async function discoverEntities() {
10
+ const result = await sql`
11
+ SELECT table_name, label_field, searchable_fields
12
+ FROM dzql.entities
13
+ ORDER BY table_name
14
+ `;
15
+
16
+ const entities = {};
17
+ for (const row of result) {
18
+ const searchFields = row.searchable_fields?.join(", ") || "none";
19
+ entities[row.table_name] = {
20
+ label: row.label_field,
21
+ searchable: row.searchable_fields || [],
22
+ description: `Entity: ${row.table_name} (label: ${row.label_field}, searchable: ${searchFields})`,
23
+ };
24
+ }
25
+
26
+ return entities;
27
+ }
28
+
29
+ /**
30
+ * DZQL operations namespace - provides CLI-style access to DZQL operations
31
+ *
32
+ * Usage in tasks.js:
33
+ * ```js
34
+ * import { DzqlNamespace } from 'dzql/namespace';
35
+ *
36
+ * export class Tasks {
37
+ * constructor() {
38
+ * this.dzql = new DzqlNamespace();
39
+ * }
40
+ * }
41
+ * ```
42
+ */
43
+ export class DzqlNamespace {
44
+ constructor(userId = DEFAULT_USER_ID) {
45
+ this.userId = userId;
46
+ }
47
+
48
+ /** List all available entities */
49
+ async entities(c) {
50
+ try {
51
+ const entities = await discoverEntities();
52
+ console.log(JSON.stringify({ success: true, entities }, null, 2));
53
+ await sql.end();
54
+ } catch (error) {
55
+ console.error(
56
+ JSON.stringify({ success: false, error: error.message }, null, 2),
57
+ );
58
+ await sql.end();
59
+ process.exit(1);
60
+ }
61
+ }
62
+
63
+ /** Search an entity */
64
+ async search(c, entity, argsJson = "{}") {
65
+ if (!entity) {
66
+ console.error("Error: entity name required");
67
+ console.error("Usage: invokej dzql.search <entity> '<json_args>'");
68
+ console.error(
69
+ 'Example: invokej dzql.search organisations \'{"query": "test"}\'',
70
+ );
71
+ await sql.end();
72
+ process.exit(1);
73
+ }
74
+
75
+ let args;
76
+ try {
77
+ args = JSON.parse(argsJson);
78
+ } catch (e) {
79
+ console.error("Error: arguments must be valid JSON");
80
+ await sql.end();
81
+ process.exit(1);
82
+ }
83
+
84
+ try {
85
+ const result = await db.api.search[entity](args, this.userId);
86
+ console.log(JSON.stringify({ success: true, result }, null, 2));
87
+ await sql.end();
88
+ } catch (error) {
89
+ console.error(
90
+ JSON.stringify({ success: false, error: error.message }, null, 2),
91
+ );
92
+ await sql.end();
93
+ process.exit(1);
94
+ }
95
+ }
96
+
97
+ /** Get entity by ID */
98
+ async get(c, entity, argsJson = "{}") {
99
+ if (!entity) {
100
+ console.error("Error: entity name required");
101
+ console.error("Usage: invokej dzql.get <entity> '<json_args>'");
102
+ console.error("Example: invokej dzql.get venues '{\"id\": 1}'");
103
+ await sql.end();
104
+ process.exit(1);
105
+ }
106
+
107
+ let args;
108
+ try {
109
+ args = JSON.parse(argsJson);
110
+ } catch (e) {
111
+ console.error("Error: arguments must be valid JSON");
112
+ await sql.end();
113
+ process.exit(1);
114
+ }
115
+
116
+ try {
117
+ const result = await db.api.get[entity](args, this.userId);
118
+ console.log(JSON.stringify({ success: true, result }, null, 2));
119
+ await sql.end();
120
+ } catch (error) {
121
+ console.error(
122
+ JSON.stringify({ success: false, error: error.message }, null, 2),
123
+ );
124
+ await sql.end();
125
+ process.exit(1);
126
+ }
127
+ }
128
+
129
+ /** Save (create or update) entity */
130
+ async save(c, entity, argsJson = "{}") {
131
+ if (!entity) {
132
+ console.error("Error: entity name required");
133
+ console.error("Usage: invokej dzql.save <entity> '<json_args>'");
134
+ console.error(
135
+ 'Example: invokej dzql.save venues \'{"name": "Test Venue", "org_id": 1}\'',
136
+ );
137
+ await sql.end();
138
+ process.exit(1);
139
+ }
140
+
141
+ let args;
142
+ try {
143
+ args = JSON.parse(argsJson);
144
+ } catch (e) {
145
+ console.error("Error: arguments must be valid JSON");
146
+ await sql.end();
147
+ process.exit(1);
148
+ }
149
+
150
+ try {
151
+ const result = await db.api.save[entity](args, this.userId);
152
+ console.log(JSON.stringify({ success: true, result }, null, 2));
153
+ await sql.end();
154
+ } catch (error) {
155
+ console.error(
156
+ JSON.stringify({ success: false, error: error.message }, null, 2),
157
+ );
158
+ await sql.end();
159
+ process.exit(1);
160
+ }
161
+ }
162
+
163
+ /** Delete entity by ID */
164
+ async delete(c, entity, argsJson = "{}") {
165
+ if (!entity) {
166
+ console.error("Error: entity name required");
167
+ console.error("Usage: invokej dzql.delete <entity> '<json_args>'");
168
+ console.error("Example: invokej dzql.delete venues '{\"id\": 1}'");
169
+ await sql.end();
170
+ process.exit(1);
171
+ }
172
+
173
+ let args;
174
+ try {
175
+ args = JSON.parse(argsJson);
176
+ } catch (e) {
177
+ console.error("Error: arguments must be valid JSON");
178
+ await sql.end();
179
+ process.exit(1);
180
+ }
181
+
182
+ try {
183
+ const result = await db.api.delete[entity](args, this.userId);
184
+ console.log(JSON.stringify({ success: true, result }, null, 2));
185
+ await sql.end();
186
+ } catch (error) {
187
+ console.error(
188
+ JSON.stringify({ success: false, error: error.message }, null, 2),
189
+ );
190
+ await sql.end();
191
+ process.exit(1);
192
+ }
193
+ }
194
+
195
+ /** Lookup entity (for dropdowns/autocomplete) */
196
+ async lookup(c, entity, argsJson = "{}") {
197
+ if (!entity) {
198
+ console.error("Error: entity name required");
199
+ console.error("Usage: invokej dzql.lookup <entity> '<json_args>'");
200
+ console.error(
201
+ 'Example: invokej dzql.lookup organisations \'{"query": "acme"}\'',
202
+ );
203
+ await sql.end();
204
+ process.exit(1);
205
+ }
206
+
207
+ let args;
208
+ try {
209
+ args = JSON.parse(argsJson);
210
+ } catch (e) {
211
+ console.error("Error: arguments must be valid JSON");
212
+ await sql.end();
213
+ process.exit(1);
214
+ }
215
+
216
+ try {
217
+ const result = await db.api.lookup[entity](args, this.userId);
218
+ console.log(JSON.stringify({ success: true, result }, null, 2));
219
+ await sql.end();
220
+ } catch (error) {
221
+ console.error(
222
+ JSON.stringify({ success: false, error: error.message }, null, 2),
223
+ );
224
+ await sql.end();
225
+ process.exit(1);
226
+ }
227
+ }
228
+ }