@dinoxx/dinox-cli 2.2.0 → 2.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.
Files changed (102) hide show
  1. package/README.md +17 -3
  2. package/dist/cli.js +6 -0
  3. package/dist/commands/domain/options.d.ts +10 -0
  4. package/dist/commands/domain/options.js +75 -0
  5. package/dist/commands/domain/run.d.ts +24 -0
  6. package/dist/commands/domain/run.js +137 -0
  7. package/dist/commands/gateway/index.d.ts +4 -0
  8. package/dist/commands/gateway/index.js +300 -0
  9. package/dist/commands/notes/actions.js +47 -18
  10. package/dist/commands/notes/createFromTemplate.d.ts +35 -0
  11. package/dist/commands/notes/createFromTemplate.js +58 -0
  12. package/dist/commands/notes/descriptors.js +9 -4
  13. package/dist/commands/notes/repo/read.js +4 -23
  14. package/dist/commands/notes/repo/write.d.ts +2 -0
  15. package/dist/commands/notes/repo/write.js +1 -1
  16. package/dist/commands/properties/index.d.ts +16 -0
  17. package/dist/commands/properties/index.js +640 -0
  18. package/dist/commands/properties/repo.d.ts +150 -0
  19. package/dist/commands/properties/repo.js +272 -0
  20. package/dist/commands/savedViews/fields.d.ts +28 -0
  21. package/dist/commands/savedViews/fields.js +87 -0
  22. package/dist/commands/savedViews/index.js +203 -164
  23. package/dist/commands/savedViews/model.d.ts +27 -69
  24. package/dist/commands/savedViews/model.js +63 -279
  25. package/dist/commands/savedViews/repo.d.ts +64 -62
  26. package/dist/commands/savedViews/repo.js +309 -428
  27. package/dist/commands/schema/renderSkills.js +33 -5
  28. package/dist/commands/schema/spec.js +6 -0
  29. package/dist/commands/templates/index.d.ts +4 -0
  30. package/dist/commands/templates/index.js +290 -0
  31. package/dist/commands/templates/model.d.ts +12 -34
  32. package/dist/commands/templates/model.js +39 -83
  33. package/dist/commands/templates/repo.d.ts +53 -0
  34. package/dist/commands/templates/repo.js +78 -0
  35. package/dist/config/paths.d.ts +1 -0
  36. package/dist/config/paths.js +1 -1
  37. package/dist/daemon/server.d.ts +1 -0
  38. package/dist/daemon/server.js +31 -0
  39. package/dist/gateway/adapters/acp.d.ts +42 -0
  40. package/dist/gateway/adapters/acp.js +285 -0
  41. package/dist/gateway/adapters/echo.d.ts +12 -0
  42. package/dist/gateway/adapters/echo.js +51 -0
  43. package/dist/gateway/adapters/index.d.ts +9 -0
  44. package/dist/gateway/adapters/index.js +30 -0
  45. package/dist/gateway/assistantProjection.d.ts +32 -0
  46. package/dist/gateway/assistantProjection.js +193 -0
  47. package/dist/gateway/config.d.ts +50 -0
  48. package/dist/gateway/config.js +253 -0
  49. package/dist/gateway/detect.d.ts +40 -0
  50. package/dist/gateway/detect.js +145 -0
  51. package/dist/gateway/deviceHost.d.ts +82 -0
  52. package/dist/gateway/deviceHost.js +530 -0
  53. package/dist/gateway/mcpServer.d.ts +4 -0
  54. package/dist/gateway/mcpServer.js +118 -0
  55. package/dist/gateway/protocol.d.ts +29 -0
  56. package/dist/gateway/protocol.js +127 -0
  57. package/dist/gateway/runExecutor.d.ts +67 -0
  58. package/dist/gateway/runExecutor.js +316 -0
  59. package/dist/gateway/service.d.ts +26 -0
  60. package/dist/gateway/service.js +82 -0
  61. package/dist/gateway/streamPublisher.d.ts +33 -0
  62. package/dist/gateway/streamPublisher.js +93 -0
  63. package/dist/gateway/threadStore.d.ts +157 -0
  64. package/dist/gateway/threadStore.js +430 -0
  65. package/dist/gateway/types.d.ts +117 -0
  66. package/dist/gateway/types.js +9 -0
  67. package/dist/skills/registry.js +7 -0
  68. package/dist/utils/errorCodes.d.ts +212 -0
  69. package/dist/utils/errorCodes.js +53 -0
  70. package/dist/vendor/electron/domain/note-templates.d.ts +3 -0
  71. package/dist/vendor/electron/domain/note-templates.js +232 -0
  72. package/dist/vendor/electron/domain/properties.d.ts +10 -0
  73. package/dist/vendor/electron/domain/properties.js +1549 -0
  74. package/dist/vendor/electron/domain/saved-view-analytics.d.ts +45 -0
  75. package/dist/vendor/electron/domain/saved-view-analytics.js +365 -0
  76. package/dist/vendor/electron/domain/saved-view-relative-date.d.ts +21 -0
  77. package/dist/vendor/electron/domain/saved-view-relative-date.js +153 -0
  78. package/dist/vendor/electron/domain/saved-views.d.ts +61 -0
  79. package/dist/vendor/electron/domain/saved-views.js +1120 -0
  80. package/dist/vendor/electron/rpc.d.ts +22 -0
  81. package/dist/vendor/electron/rpc.js +27 -0
  82. package/dist/vendor/electron/shared/ai-errors.d.ts +11 -0
  83. package/dist/vendor/electron/shared/ai-errors.js +107 -0
  84. package/dist/vendor/electron/shared/external-types.d.ts +20 -0
  85. package/dist/vendor/electron/shared/external-types.js +1 -0
  86. package/dist/vendor/electron/shared/index.d.ts +9 -0
  87. package/dist/vendor/electron/shared/index.js +7 -0
  88. package/dist/vendor/electron/shared/note-properties.d.ts +328 -0
  89. package/dist/vendor/electron/shared/note-properties.js +1027 -0
  90. package/dist/vendor/electron/shared/note-templates.d.ts +82 -0
  91. package/dist/vendor/electron/shared/note-templates.js +84 -0
  92. package/dist/vendor/electron/shared/powersync-read-models.d.ts +1716 -0
  93. package/dist/vendor/electron/shared/powersync-read-models.js +1 -0
  94. package/dist/vendor/electron/shared/remote-device-agent.d.ts +373 -0
  95. package/dist/vendor/electron/shared/remote-device-agent.js +191 -0
  96. package/dist/vendor/electron/shared/saved-views.d.ts +394 -0
  97. package/dist/vendor/electron/shared/saved-views.js +981 -0
  98. package/dist/vendor/electron/sql-utils.d.ts +5 -0
  99. package/dist/vendor/electron/sql-utils.js +32 -0
  100. package/package.json +10 -4
  101. package/dist/commands/savedViews/semantics.d.ts +0 -46
  102. package/dist/commands/savedViews/semantics.js +0 -738
@@ -95,6 +95,18 @@ export declare const ERROR_CODES: {
95
95
  readonly exitCode: 2;
96
96
  readonly description: "An argument or option value is invalid.";
97
97
  };
98
+ readonly INVALID_PROPERTY_DEF_CONFIG: {
99
+ readonly exitCode: 1;
100
+ readonly description: "A property definition config could not be serialized.";
101
+ };
102
+ readonly INVALID_PROPERTY_DEF_ID: {
103
+ readonly exitCode: 1;
104
+ readonly description: "A property definition id is missing or blank.";
105
+ };
106
+ readonly INVALID_PROPERTY_OPTIONS: {
107
+ readonly exitCode: 1;
108
+ readonly description: "Property options could not be serialized.";
109
+ };
98
110
  readonly INVALID_STORAGE_KEY: {
99
111
  readonly exitCode: 2;
100
112
  readonly description: "The storage object key is invalid.";
@@ -107,6 +119,22 @@ export declare const ERROR_CODES: {
107
119
  readonly exitCode: 5;
108
120
  readonly description: "The note does not exist or is deleted.";
109
121
  };
122
+ readonly NOTE_PROPERTIES_CORRUPT: {
123
+ readonly exitCode: 1;
124
+ readonly description: "The note properties JSON is corrupt and cannot be mutated safely.";
125
+ };
126
+ readonly NOTE_PROPERTIES_INVALID: {
127
+ readonly exitCode: 1;
128
+ readonly description: "The note properties mutation is invalid.";
129
+ };
130
+ readonly NOTE_PROPERTIES_MUTATION_FAILED: {
131
+ readonly exitCode: 1;
132
+ readonly description: "The note properties mutation could not be applied.";
133
+ };
134
+ readonly NOTE_PROPERTY_ORDER_STALE: {
135
+ readonly exitCode: 5;
136
+ readonly description: "The property slot order no longer matches the note; re-read and retry.";
137
+ };
110
138
  readonly NOTE_TEMPLATE_INVALID_CONTENT: {
111
139
  readonly exitCode: 1;
112
140
  readonly description: "The note template content is invalid.";
@@ -119,6 +147,10 @@ export declare const ERROR_CODES: {
119
147
  readonly exitCode: 1;
120
148
  readonly description: "A note template token is used in an invalid context.";
121
149
  };
150
+ readonly NOTE_TEMPLATE_NOT_FOUND: {
151
+ readonly exitCode: 5;
152
+ readonly description: "The note template does not exist or is deleted.";
153
+ };
122
154
  readonly NOTE_TEMPLATE_UNSUPPORTED_PROPERTY_DEF_VERSION: {
123
155
  readonly exitCode: 1;
124
156
  readonly description: "The note template property definition version is unsupported.";
@@ -135,6 +167,166 @@ export declare const ERROR_CODES: {
135
167
  readonly exitCode: 5;
136
168
  readonly description: "A safety precondition for the operation did not hold.";
137
169
  };
170
+ readonly PROPERTY_DATE_INVALID: {
171
+ readonly exitCode: 1;
172
+ readonly description: "A date property value is not a valid date.";
173
+ };
174
+ readonly PROPERTY_DEF_CONFIG_INVALID: {
175
+ readonly exitCode: 1;
176
+ readonly description: "A property definition config is invalid.";
177
+ };
178
+ readonly PROPERTY_DEF_CONFIG_TYPE_MISMATCH: {
179
+ readonly exitCode: 1;
180
+ readonly description: "A property definition config does not match the property type.";
181
+ };
182
+ readonly PROPERTY_DEF_ENSURE_FAILED: {
183
+ readonly exitCode: 1;
184
+ readonly description: "The property definition could not be created or reused.";
185
+ };
186
+ readonly PROPERTY_DEF_ENSURE_INPUT_INVALID: {
187
+ readonly exitCode: 1;
188
+ readonly description: "The property definition create input is invalid.";
189
+ };
190
+ readonly PROPERTY_DEF_NOT_FOUND: {
191
+ readonly exitCode: 5;
192
+ readonly description: "The property definition does not exist or is deleted.";
193
+ };
194
+ readonly PROPERTY_DEF_TYPE_CONFLICT: {
195
+ readonly exitCode: 5;
196
+ readonly description: "A property with this key already exists with a different type.";
197
+ };
198
+ readonly PROPERTY_DEF_TYPE_INVALID: {
199
+ readonly exitCode: 1;
200
+ readonly description: "The stored property definition type is invalid.";
201
+ };
202
+ readonly PROPERTY_FILES_INVALID: {
203
+ readonly exitCode: 1;
204
+ readonly description: "A files property value is invalid.";
205
+ };
206
+ readonly PROPERTY_LEGACY_OPTION_LABEL_INVALID: {
207
+ readonly exitCode: 1;
208
+ readonly description: "A legacy option label cannot be migrated.";
209
+ };
210
+ readonly PROPERTY_LEGACY_OPTION_NOT_PLANNED: {
211
+ readonly exitCode: 1;
212
+ readonly description: "A legacy option value was not covered by the migration plan.";
213
+ };
214
+ readonly PROPERTY_LEGACY_VALUE_INVALID: {
215
+ readonly exitCode: 1;
216
+ readonly description: "A legacy option value cannot be migrated.";
217
+ };
218
+ readonly PROPERTY_MULTI_SELECT_EMPTY: {
219
+ readonly exitCode: 1;
220
+ readonly description: "A multi-select property value is empty.";
221
+ };
222
+ readonly PROPERTY_MULTI_SELECT_LIMIT_EXCEEDED: {
223
+ readonly exitCode: 1;
224
+ readonly description: "A multi-select property value has too many selections.";
225
+ };
226
+ readonly PROPERTY_NUMBER_INVALID: {
227
+ readonly exitCode: 1;
228
+ readonly description: "A number property value is invalid or out of range.";
229
+ };
230
+ readonly PROPERTY_OPTIONS_INVALID: {
231
+ readonly exitCode: 1;
232
+ readonly description: "Stored property options are invalid.";
233
+ };
234
+ readonly PROPERTY_OPTIONS_MIGRATION_REQUIRED: {
235
+ readonly exitCode: 5;
236
+ readonly description: "Legacy property options must be migrated first (dino prop migrate-options).";
237
+ };
238
+ readonly PROPERTY_OPTIONS_TYPE_MISMATCH: {
239
+ readonly exitCode: 1;
240
+ readonly description: "Options were supplied for a property type that has none.";
241
+ };
242
+ readonly PROPERTY_OPTION_ARCHIVED: {
243
+ readonly exitCode: 5;
244
+ readonly description: "The select option is archived and cannot be assigned.";
245
+ };
246
+ readonly PROPERTY_OPTION_ID_DUPLICATE: {
247
+ readonly exitCode: 1;
248
+ readonly description: "Property options contain duplicate ids.";
249
+ };
250
+ readonly PROPERTY_OPTION_ID_UNKNOWN: {
251
+ readonly exitCode: 1;
252
+ readonly description: "A property option id does not exist on the definition.";
253
+ };
254
+ readonly PROPERTY_OPTION_LABEL_INVALID: {
255
+ readonly exitCode: 1;
256
+ readonly description: "A property option label is blank, too long, or duplicated.";
257
+ };
258
+ readonly PROPERTY_OPTION_LIMIT_EXCEEDED: {
259
+ readonly exitCode: 1;
260
+ readonly description: "The property has too many options.";
261
+ };
262
+ readonly PROPERTY_OPTION_NEW_ID_FORBIDDEN: {
263
+ readonly exitCode: 1;
264
+ readonly description: "New property options must not carry an id.";
265
+ };
266
+ readonly PROPERTY_OPTION_NOT_FOUND: {
267
+ readonly exitCode: 5;
268
+ readonly description: "The select option does not exist on a closed property.";
269
+ };
270
+ readonly PROPERTY_OPTION_REMOVAL_REQUIRES_ARCHIVE: {
271
+ readonly exitCode: 1;
272
+ readonly description: "Existing property options must be archived instead of removed.";
273
+ };
274
+ readonly PROPERTY_OPTION_REPAIR_ID_FORBIDDEN: {
275
+ readonly exitCode: 1;
276
+ readonly description: "Repair options must not carry ids.";
277
+ };
278
+ readonly PROPERTY_OPTION_SORT_RANK_EXHAUSTED: {
279
+ readonly exitCode: 1;
280
+ readonly description: "No sort rank is left for a new property option.";
281
+ };
282
+ readonly PROPERTY_OPTION_VALUE_INVALID: {
283
+ readonly exitCode: 1;
284
+ readonly description: "A select property value is invalid.";
285
+ };
286
+ readonly PROPERTY_PLACE_INVALID: {
287
+ readonly exitCode: 1;
288
+ readonly description: "A place property value is invalid.";
289
+ };
290
+ readonly PROPERTY_RELATION_EMPTY: {
291
+ readonly exitCode: 1;
292
+ readonly description: "A relation property value is empty.";
293
+ };
294
+ readonly PROPERTY_RELATION_INVALID: {
295
+ readonly exitCode: 1;
296
+ readonly description: "A relation property value references invalid notes.";
297
+ };
298
+ readonly PROPERTY_RELATION_LIMIT: {
299
+ readonly exitCode: 1;
300
+ readonly description: "A relation property value has too many notes.";
301
+ };
302
+ readonly PROPERTY_TYPE_NOT_ACTIVE: {
303
+ readonly exitCode: 1;
304
+ readonly description: "The property type is not active.";
305
+ };
306
+ readonly PROPERTY_UNIQUE_ID_CONFIG_INVALID: {
307
+ readonly exitCode: 1;
308
+ readonly description: "A unique-id property counter is invalid.";
309
+ };
310
+ readonly PROPERTY_UNIQUE_ID_INVALID: {
311
+ readonly exitCode: 1;
312
+ readonly description: "A unique-id property value is invalid.";
313
+ };
314
+ readonly PROPERTY_UNIQUE_ID_TYPE_MISMATCH: {
315
+ readonly exitCode: 1;
316
+ readonly description: "A unique-id setting was supplied for a different property type.";
317
+ };
318
+ readonly PROPERTY_URL_INVALID: {
319
+ readonly exitCode: 1;
320
+ readonly description: "A url property value is invalid.";
321
+ };
322
+ readonly PROPERTY_VALUE_INVALID: {
323
+ readonly exitCode: 1;
324
+ readonly description: "A property value does not match its definition.";
325
+ };
326
+ readonly SAVED_VIEW_FILTER_CORRUPT: {
327
+ readonly exitCode: 1;
328
+ readonly description: "A stored saved view filter is corrupt.";
329
+ };
138
330
  readonly SAVED_VIEW_FILTER_TOO_COMPLEX: {
139
331
  readonly exitCode: 1;
140
332
  readonly description: "The saved view filter exceeds supported complexity.";
@@ -147,6 +339,10 @@ export declare const ERROR_CODES: {
147
339
  readonly exitCode: 1;
148
340
  readonly description: "The saved view config is invalid.";
149
341
  };
342
+ readonly SAVED_VIEW_INVALID_CURRENT_TIME: {
343
+ readonly exitCode: 1;
344
+ readonly description: "The reference time for dynamic date filters is invalid.";
345
+ };
150
346
  readonly SAVED_VIEW_INVALID_DATE_VALUE: {
151
347
  readonly exitCode: 1;
152
348
  readonly description: "A saved view date value is not a real calendar date.";
@@ -159,10 +355,22 @@ export declare const ERROR_CODES: {
159
355
  readonly exitCode: 1;
160
356
  readonly description: "The saved view filter is invalid.";
161
357
  };
358
+ readonly SAVED_VIEW_INVALID_OPERATOR: {
359
+ readonly exitCode: 1;
360
+ readonly description: "A saved view filter operator is invalid.";
361
+ };
362
+ readonly SAVED_VIEW_INVALID_RELATIVE_DAYS: {
363
+ readonly exitCode: 1;
364
+ readonly description: "withinLastDays requires an integer day count in range.";
365
+ };
162
366
  readonly SAVED_VIEW_INVALID_ROW: {
163
367
  readonly exitCode: 1;
164
368
  readonly description: "A stored saved view row is invalid.";
165
369
  };
370
+ readonly SAVED_VIEW_INVALID_TIME_ZONE: {
371
+ readonly exitCode: 2;
372
+ readonly description: "The time zone is not a valid IANA time zone.";
373
+ };
166
374
  readonly SAVED_VIEW_NOT_FOUND: {
167
375
  readonly exitCode: 5;
168
376
  readonly description: "The saved view does not exist.";
@@ -199,6 +407,10 @@ export declare const ERROR_CODES: {
199
407
  readonly exitCode: 1;
200
408
  readonly description: "The field type cannot be sorted.";
201
409
  };
410
+ readonly SAVED_VIEW_TIME_ZONE_CONVERSION_FAILED: {
411
+ readonly exitCode: 1;
412
+ readonly description: "A dynamic date boundary could not be converted to the time zone.";
413
+ };
202
414
  readonly SAVED_VIEW_UNSUPPORTED_CONFIG_VERSION: {
203
415
  readonly exitCode: 1;
204
416
  readonly description: "The saved view config version is unsupported.";
@@ -29,23 +29,75 @@ export const ERROR_CODES = {
29
29
  DAEMON_UNREACHABLE: { exitCode: 1, description: 'The daemon socket could not be reached.' },
30
30
  INTERNAL_ERROR: { exitCode: 1, description: 'Unexpected internal error; not a DinoxError.' },
31
31
  INVALID_ARGUMENT: { exitCode: 2, description: 'An argument or option value is invalid.' },
32
+ INVALID_PROPERTY_DEF_CONFIG: { exitCode: 1, description: 'A property definition config could not be serialized.' },
33
+ INVALID_PROPERTY_DEF_ID: { exitCode: 1, description: 'A property definition id is missing or blank.' },
34
+ INVALID_PROPERTY_OPTIONS: { exitCode: 1, description: 'Property options could not be serialized.' },
32
35
  INVALID_STORAGE_KEY: { exitCode: 2, description: 'The storage object key is invalid.' },
33
36
  NOTE_INVALID_PROPERTIES: { exitCode: 1, description: 'Note properties are invalid.' },
34
37
  NOTE_NOT_FOUND: { exitCode: 5, description: 'The note does not exist or is deleted.' },
38
+ NOTE_PROPERTIES_CORRUPT: { exitCode: 1, description: 'The note properties JSON is corrupt and cannot be mutated safely.' },
39
+ NOTE_PROPERTIES_INVALID: { exitCode: 1, description: 'The note properties mutation is invalid.' },
40
+ NOTE_PROPERTIES_MUTATION_FAILED: { exitCode: 1, description: 'The note properties mutation could not be applied.' },
41
+ NOTE_PROPERTY_ORDER_STALE: { exitCode: 5, description: 'The property slot order no longer matches the note; re-read and retry.' },
35
42
  NOTE_TEMPLATE_INVALID_CONTENT: { exitCode: 1, description: 'The note template content is invalid.' },
36
43
  NOTE_TEMPLATE_INVALID_PROPERTY_DEF: { exitCode: 1, description: 'A note template property definition is invalid.' },
37
44
  NOTE_TEMPLATE_INVALID_TOKEN_CONTEXT: { exitCode: 1, description: 'A note template token is used in an invalid context.' },
45
+ NOTE_TEMPLATE_NOT_FOUND: { exitCode: 5, description: 'The note template does not exist or is deleted.' },
38
46
  NOTE_TEMPLATE_UNSUPPORTED_PROPERTY_DEF_VERSION: { exitCode: 1, description: 'The note template property definition version is unsupported.' },
39
47
  NOT_FOUND: { exitCode: 5, description: 'The requested resource was not found.' },
40
48
  POWERSYNC_OWNER_BUSY: { exitCode: 1, description: 'Another process owns the local PowerSync database.' },
41
49
  PRECONDITION_FAILED: { exitCode: 5, description: 'A safety precondition for the operation did not hold.' },
50
+ PROPERTY_DATE_INVALID: { exitCode: 1, description: 'A date property value is not a valid date.' },
51
+ PROPERTY_DEF_CONFIG_INVALID: { exitCode: 1, description: 'A property definition config is invalid.' },
52
+ PROPERTY_DEF_CONFIG_TYPE_MISMATCH: { exitCode: 1, description: 'A property definition config does not match the property type.' },
53
+ PROPERTY_DEF_ENSURE_FAILED: { exitCode: 1, description: 'The property definition could not be created or reused.' },
54
+ PROPERTY_DEF_ENSURE_INPUT_INVALID: { exitCode: 1, description: 'The property definition create input is invalid.' },
55
+ PROPERTY_DEF_NOT_FOUND: { exitCode: 5, description: 'The property definition does not exist or is deleted.' },
56
+ PROPERTY_DEF_TYPE_CONFLICT: { exitCode: 5, description: 'A property with this key already exists with a different type.' },
57
+ PROPERTY_DEF_TYPE_INVALID: { exitCode: 1, description: 'The stored property definition type is invalid.' },
58
+ PROPERTY_FILES_INVALID: { exitCode: 1, description: 'A files property value is invalid.' },
59
+ PROPERTY_LEGACY_OPTION_LABEL_INVALID: { exitCode: 1, description: 'A legacy option label cannot be migrated.' },
60
+ PROPERTY_LEGACY_OPTION_NOT_PLANNED: { exitCode: 1, description: 'A legacy option value was not covered by the migration plan.' },
61
+ PROPERTY_LEGACY_VALUE_INVALID: { exitCode: 1, description: 'A legacy option value cannot be migrated.' },
62
+ PROPERTY_MULTI_SELECT_EMPTY: { exitCode: 1, description: 'A multi-select property value is empty.' },
63
+ PROPERTY_MULTI_SELECT_LIMIT_EXCEEDED: { exitCode: 1, description: 'A multi-select property value has too many selections.' },
64
+ PROPERTY_NUMBER_INVALID: { exitCode: 1, description: 'A number property value is invalid or out of range.' },
65
+ PROPERTY_OPTIONS_INVALID: { exitCode: 1, description: 'Stored property options are invalid.' },
66
+ PROPERTY_OPTIONS_MIGRATION_REQUIRED: { exitCode: 5, description: 'Legacy property options must be migrated first (dino prop migrate-options).' },
67
+ PROPERTY_OPTIONS_TYPE_MISMATCH: { exitCode: 1, description: 'Options were supplied for a property type that has none.' },
68
+ PROPERTY_OPTION_ARCHIVED: { exitCode: 5, description: 'The select option is archived and cannot be assigned.' },
69
+ PROPERTY_OPTION_ID_DUPLICATE: { exitCode: 1, description: 'Property options contain duplicate ids.' },
70
+ PROPERTY_OPTION_ID_UNKNOWN: { exitCode: 1, description: 'A property option id does not exist on the definition.' },
71
+ PROPERTY_OPTION_LABEL_INVALID: { exitCode: 1, description: 'A property option label is blank, too long, or duplicated.' },
72
+ PROPERTY_OPTION_LIMIT_EXCEEDED: { exitCode: 1, description: 'The property has too many options.' },
73
+ PROPERTY_OPTION_NEW_ID_FORBIDDEN: { exitCode: 1, description: 'New property options must not carry an id.' },
74
+ PROPERTY_OPTION_NOT_FOUND: { exitCode: 5, description: 'The select option does not exist on a closed property.' },
75
+ PROPERTY_OPTION_REMOVAL_REQUIRES_ARCHIVE: { exitCode: 1, description: 'Existing property options must be archived instead of removed.' },
76
+ PROPERTY_OPTION_REPAIR_ID_FORBIDDEN: { exitCode: 1, description: 'Repair options must not carry ids.' },
77
+ PROPERTY_OPTION_SORT_RANK_EXHAUSTED: { exitCode: 1, description: 'No sort rank is left for a new property option.' },
78
+ PROPERTY_OPTION_VALUE_INVALID: { exitCode: 1, description: 'A select property value is invalid.' },
79
+ PROPERTY_PLACE_INVALID: { exitCode: 1, description: 'A place property value is invalid.' },
80
+ PROPERTY_RELATION_EMPTY: { exitCode: 1, description: 'A relation property value is empty.' },
81
+ PROPERTY_RELATION_INVALID: { exitCode: 1, description: 'A relation property value references invalid notes.' },
82
+ PROPERTY_RELATION_LIMIT: { exitCode: 1, description: 'A relation property value has too many notes.' },
83
+ PROPERTY_TYPE_NOT_ACTIVE: { exitCode: 1, description: 'The property type is not active.' },
84
+ PROPERTY_UNIQUE_ID_CONFIG_INVALID: { exitCode: 1, description: 'A unique-id property counter is invalid.' },
85
+ PROPERTY_UNIQUE_ID_INVALID: { exitCode: 1, description: 'A unique-id property value is invalid.' },
86
+ PROPERTY_UNIQUE_ID_TYPE_MISMATCH: { exitCode: 1, description: 'A unique-id setting was supplied for a different property type.' },
87
+ PROPERTY_URL_INVALID: { exitCode: 1, description: 'A url property value is invalid.' },
88
+ PROPERTY_VALUE_INVALID: { exitCode: 1, description: 'A property value does not match its definition.' },
89
+ SAVED_VIEW_FILTER_CORRUPT: { exitCode: 1, description: 'A stored saved view filter is corrupt.' },
42
90
  SAVED_VIEW_FILTER_TOO_COMPLEX: { exitCode: 1, description: 'The saved view filter exceeds supported complexity.' },
43
91
  SAVED_VIEW_FILTER_VALUE_REQUIRED: { exitCode: 5, description: 'A saved view filter condition is missing its value.' },
44
92
  SAVED_VIEW_INVALID_CONFIG: { exitCode: 1, description: 'The saved view config is invalid.' },
93
+ SAVED_VIEW_INVALID_CURRENT_TIME: { exitCode: 1, description: 'The reference time for dynamic date filters is invalid.' },
45
94
  SAVED_VIEW_INVALID_DATE_VALUE: { exitCode: 1, description: 'A saved view date value is not a real calendar date.' },
46
95
  SAVED_VIEW_INVALID_FIELD: { exitCode: 1, description: 'A saved view references an invalid field.' },
47
96
  SAVED_VIEW_INVALID_FILTER: { exitCode: 1, description: 'The saved view filter is invalid.' },
97
+ SAVED_VIEW_INVALID_OPERATOR: { exitCode: 1, description: 'A saved view filter operator is invalid.' },
98
+ SAVED_VIEW_INVALID_RELATIVE_DAYS: { exitCode: 1, description: 'withinLastDays requires an integer day count in range.' },
48
99
  SAVED_VIEW_INVALID_ROW: { exitCode: 1, description: 'A stored saved view row is invalid.' },
100
+ SAVED_VIEW_INVALID_TIME_ZONE: { exitCode: 2, description: 'The time zone is not a valid IANA time zone.' },
49
101
  SAVED_VIEW_NOT_FOUND: { exitCode: 5, description: 'The saved view does not exist.' },
50
102
  SAVED_VIEW_OPERATOR_TYPE_MISMATCH: { exitCode: 1, description: 'A filter operator is not valid for the field type.' },
51
103
  SAVED_VIEW_OPTION_NOT_FOUND: { exitCode: 5, description: 'A select option id referenced by the view does not exist.' },
@@ -55,6 +107,7 @@ export const ERROR_CODES = {
55
107
  SAVED_VIEW_PROPERTY_OPTIONS_INVALID: { exitCode: 1, description: 'Property options used by the view are invalid.' },
56
108
  SAVED_VIEW_PROPERTY_OPTIONS_MIGRATION_REQUIRED: { exitCode: 5, description: 'Property options need migration before use.' },
57
109
  SAVED_VIEW_SORT_TYPE_UNSUPPORTED: { exitCode: 1, description: 'The field type cannot be sorted.' },
110
+ SAVED_VIEW_TIME_ZONE_CONVERSION_FAILED: { exitCode: 1, description: 'A dynamic date boundary could not be converted to the time zone.' },
58
111
  SAVED_VIEW_UNSUPPORTED_CONFIG_VERSION: { exitCode: 1, description: 'The saved view config version is unsupported.' },
59
112
  SAVED_VIEW_UNSUPPORTED_FILTER_VERSION: { exitCode: 1, description: 'The saved view filter version is unsupported.' },
60
113
  SAVED_VIEW_UNSUPPORTED_LAYOUT: { exitCode: 1, description: 'The saved view layout is unsupported.' },
@@ -0,0 +1,3 @@
1
+ import { type CommandDefinition, type ReadModelDefinition } from "../rpc.js";
2
+ export declare function createNoteTemplateReadModels(): ReadModelDefinition[];
3
+ export declare function createNoteTemplateCommands(): CommandDefinition[];
@@ -0,0 +1,232 @@
1
+ import { isPropertyKeyValid, serializeNoteTemplatePropertyKeys, } from "../shared/index.js";
2
+ import { uuidv7 } from "uuidv7";
3
+ import { z } from "zod";
4
+ import { defineCommand, defineReadModel, } from "../rpc.js";
5
+ import { normalizeLimit } from "../sql-utils.js";
6
+ /**
7
+ * Note templates are synced rows shared with the mobile client. The electron
8
+ * side owns the `property_def` column (versioned key-list envelope); writes
9
+ * only SET the columns they change so template content/extra_data written by
10
+ * other clients is never clobbered.
11
+ */
12
+ const NOTE_TEMPLATE_TABLE = "c_note_template";
13
+ const NOTE_TEMPLATE_COLUMNS = `
14
+ id, user_id, name, content, priority, is_show, extra_data, property_def,
15
+ insert_at, update_at, is_del
16
+ `;
17
+ const PROPERTY_KEYS_INPUT = z
18
+ .array(z.string().min(1).max(64).refine(isPropertyKeyValid))
19
+ .max(50);
20
+ const NOTE_TEMPLATE_CATALOG_INPUT = z.object({
21
+ userId: z.string().trim().min(1),
22
+ limit: z.number().int().positive().max(2000).optional(),
23
+ });
24
+ const TEMPLATE_CONTENT_INPUT = z.string().max(200_000);
25
+ const NOTE_TEMPLATE_CREATE_INPUT = z.object({
26
+ userId: z.string().trim().min(1),
27
+ name: z.string().trim().min(1).max(120),
28
+ propertyKeys: PROPERTY_KEYS_INPUT,
29
+ content: TEMPLATE_CONTENT_INPUT.nullable().optional(),
30
+ updatedAt: z.string().trim().min(1).max(64),
31
+ });
32
+ const NOTE_TEMPLATE_UPDATE_INPUT = z
33
+ .object({
34
+ id: z.string().trim().min(1),
35
+ userId: z.string().trim().min(1),
36
+ name: z.string().trim().min(1).max(120).optional(),
37
+ propertyKeys: PROPERTY_KEYS_INPUT.optional(),
38
+ content: TEMPLATE_CONTENT_INPUT.nullable().optional(),
39
+ updatedAt: z.string().trim().min(1).max(64),
40
+ })
41
+ .refine((input) => input.name !== undefined ||
42
+ input.propertyKeys !== undefined ||
43
+ input.content !== undefined, {
44
+ message: "At least one note-template field must be updated",
45
+ });
46
+ const NOTE_TEMPLATE_SOFT_DELETE_INPUT = z.object({
47
+ id: z.string().trim().min(1),
48
+ userId: z.string().trim().min(1),
49
+ updatedAt: z.string().trim().min(1).max(64),
50
+ });
51
+ export function createNoteTemplateReadModels() {
52
+ return [
53
+ defineReadModel({
54
+ name: "noteTemplates.catalog",
55
+ inputSchema: NOTE_TEMPLATE_CATALOG_INPUT,
56
+ tables: () => [NOTE_TEMPLATE_TABLE],
57
+ fetch: async (db, input) => fetchNoteTemplateCatalog(db, input),
58
+ }),
59
+ ];
60
+ }
61
+ export function createNoteTemplateCommands() {
62
+ return [
63
+ defineCommand({
64
+ name: "noteTemplates.create",
65
+ inputSchema: NOTE_TEMPLATE_CREATE_INPUT,
66
+ run: async (db, input) => {
67
+ const id = await createNoteTemplate(db, input);
68
+ return { result: id, affectedTables: [NOTE_TEMPLATE_TABLE] };
69
+ },
70
+ }),
71
+ defineCommand({
72
+ name: "noteTemplates.update",
73
+ inputSchema: NOTE_TEMPLATE_UPDATE_INPUT,
74
+ run: async (db, input) => {
75
+ const changed = await updateNoteTemplate(db, input);
76
+ return {
77
+ result: changed,
78
+ affectedTables: changed ? [NOTE_TEMPLATE_TABLE] : [],
79
+ };
80
+ },
81
+ }),
82
+ defineCommand({
83
+ name: "noteTemplates.softDelete",
84
+ inputSchema: NOTE_TEMPLATE_SOFT_DELETE_INPUT,
85
+ run: async (db, input) => {
86
+ const changed = await softDeleteNoteTemplate(db, input);
87
+ return {
88
+ result: changed,
89
+ affectedTables: changed ? [NOTE_TEMPLATE_TABLE] : [],
90
+ };
91
+ },
92
+ }),
93
+ ];
94
+ }
95
+ async function fetchNoteTemplateCatalog(db, input) {
96
+ const userId = input.userId.trim();
97
+ const limit = normalizeLimit(input.limit, 500, 2000);
98
+ if (!userId)
99
+ throw new Error("Invalid note template catalog input");
100
+ if (limit <= 0)
101
+ return [];
102
+ return await db.getAll(`
103
+ SELECT ${NOTE_TEMPLATE_COLUMNS}
104
+ FROM c_note_template
105
+ WHERE user_id = ?
106
+ AND (is_del IS NULL OR is_del = 0)
107
+ ORDER BY COALESCE(priority, 0) ASC,
108
+ COALESCE(NULLIF(insert_at, ''), id) ASC,
109
+ id ASC
110
+ LIMIT ?
111
+ `, [userId, limit]);
112
+ }
113
+ function normalizeTemplateContent(content) {
114
+ if (typeof content !== "string")
115
+ return "";
116
+ return content.trim() ? content : "";
117
+ }
118
+ /**
119
+ * Templates with content are visible in the mobile template picker
120
+ * (is_show = 1); property-only templates stay hidden there (is_show = 0)
121
+ * because mobile does not render property_def yet and an empty-content
122
+ * template would produce blank notes.
123
+ */
124
+ async function createNoteTemplate(db, input) {
125
+ const userId = input.userId.trim();
126
+ const name = input.name.trim();
127
+ const updatedAt = input.updatedAt.trim();
128
+ if (!userId || !name || !updatedAt) {
129
+ throw new Error("Invalid note template create input");
130
+ }
131
+ const content = normalizeTemplateContent(input.content);
132
+ const id = uuidv7();
133
+ await db.writeTransaction(async (context) => {
134
+ await context.execute(`INSERT INTO c_note_template (
135
+ id, user_id, name, content, priority, is_show, extra_data,
136
+ property_def, insert_at, update_at, is_del
137
+ ) VALUES (?, ?, ?, ?, 0, ?, ?, ?, ?, ?, 0)
138
+ `, [
139
+ id,
140
+ userId,
141
+ name,
142
+ content,
143
+ content ? 1 : 0,
144
+ "{}",
145
+ serializeNoteTemplatePropertyKeys(input.propertyKeys),
146
+ updatedAt,
147
+ updatedAt,
148
+ ]);
149
+ });
150
+ return id;
151
+ }
152
+ async function updateNoteTemplate(db, input) {
153
+ const id = input.id.trim();
154
+ const userId = input.userId.trim();
155
+ const updatedAt = input.updatedAt.trim();
156
+ if (!id || !userId || !updatedAt) {
157
+ throw new Error("Invalid note template update input");
158
+ }
159
+ let changed = false;
160
+ await db.writeTransaction(async (context) => {
161
+ const row = await context.getOptional(`SELECT ${NOTE_TEMPLATE_COLUMNS}
162
+ FROM c_note_template
163
+ WHERE id = ?
164
+ AND user_id = ?
165
+ AND (is_del IS NULL OR is_del = 0)
166
+ LIMIT 1`, [id, userId]);
167
+ if (!row)
168
+ return;
169
+ const assignments = [];
170
+ const params = [];
171
+ if (input.name !== undefined) {
172
+ const name = input.name.trim();
173
+ if (name && name !== (row.name ?? "")) {
174
+ assignments.push("name = ?");
175
+ params.push(name);
176
+ }
177
+ }
178
+ if (input.propertyKeys !== undefined) {
179
+ const serialized = serializeNoteTemplatePropertyKeys(input.propertyKeys);
180
+ if (serialized !== (row.property_def ?? null)) {
181
+ assignments.push("property_def = ?");
182
+ params.push(serialized);
183
+ }
184
+ }
185
+ if (input.content !== undefined) {
186
+ const nextContent = normalizeTemplateContent(input.content);
187
+ const previousContent = normalizeTemplateContent(row.content);
188
+ if (nextContent !== previousContent) {
189
+ assignments.push("content = ?");
190
+ params.push(nextContent);
191
+ // Flip mobile-picker visibility only when content presence changes,
192
+ // so a manual is_show choice survives ordinary edits.
193
+ if (Boolean(nextContent) !== Boolean(previousContent)) {
194
+ assignments.push("is_show = ?");
195
+ params.push(nextContent ? 1 : 0);
196
+ }
197
+ }
198
+ }
199
+ if (assignments.length === 0)
200
+ return;
201
+ assignments.push("update_at = ?");
202
+ params.push(updatedAt, id, userId);
203
+ await context.execute(`UPDATE c_note_template
204
+ SET ${assignments.join(", ")}
205
+ WHERE id = ? AND user_id = ?`, params);
206
+ changed = true;
207
+ });
208
+ return changed;
209
+ }
210
+ async function softDeleteNoteTemplate(db, input) {
211
+ const id = input.id.trim();
212
+ const userId = input.userId.trim();
213
+ const updatedAt = input.updatedAt.trim();
214
+ if (!id || !userId || !updatedAt) {
215
+ throw new Error("Invalid note template delete input");
216
+ }
217
+ let changed = false;
218
+ await db.writeTransaction(async (context) => {
219
+ const row = await context.getOptional(`SELECT id FROM c_note_template
220
+ WHERE id = ?
221
+ AND user_id = ?
222
+ AND (is_del IS NULL OR is_del = 0)
223
+ LIMIT 1`, [id, userId]);
224
+ if (!row)
225
+ return;
226
+ await context.execute(`UPDATE c_note_template
227
+ SET is_del = 1, update_at = ?
228
+ WHERE id = ? AND user_id = ?`, [updatedAt, id, userId]);
229
+ changed = true;
230
+ });
231
+ return changed;
232
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Inputs: typed PowerSync read-model and command payloads for property definitions and note values.
3
+ * Outputs: catalog rows plus transactional definition, migration, and note-property mutations.
4
+ */
5
+ import type { PropertyDefCatalogInput, PropertyDefRow } from "../shared/index.js";
6
+ import type { AbstractPowerSyncDatabase as PowerSyncDatabase } from "@powersync/common";
7
+ import { type CommandDefinition, type ReadModelDefinition } from "../rpc.js";
8
+ export declare function createPropertyReadModels(): ReadModelDefinition[];
9
+ export declare function createPropertyCommands(): CommandDefinition[];
10
+ export declare function fetchPropertyCatalog(db: PowerSyncDatabase, input: PropertyDefCatalogInput): Promise<PropertyDefRow[]>;