@softr/sdk 0.0.10 → 0.0.12

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,482 @@
1
+ //#region src/core/query.d.ts
2
+
3
+ type LogicalOperator = "AND" | "OR";
4
+ type FilterOperator = "IS" | "IS_NOT" | "EQUAL" | "NOT_EQUAL" | "IS_EMPTY" | "IS_NOT_EMPTY" | "IS_ONE_OF" | "IS_NONE_OF" | "HAS_ALL_OF" | "HAS_ONE_OF" | "HAS_NONE_OF" | "CONTAINS" | "INLINE_CONTAINS" | "GT" | "LT" | "GTE" | "LTE" | "BETWEEN" | "IS_NOT_BETWEEN" | "DOES_NOT_CONTAINS" | "STARTS_WITH" | "ENDS_WITH";
5
+ type ConditionFieldType = "TEXT" | "BOOLEAN" | "NUMERIC" | "ARRAY" | "DATE";
6
+ interface Filter {
7
+ subject: string;
8
+ operator: FilterOperator;
9
+ value?: unknown;
10
+ type: ConditionFieldType;
11
+ }
12
+ type ConstructableFilter = Filter & {
13
+ [INTERNAL_KIND]: "FILTER";
14
+ };
15
+ type ConstructableFilterGroup = {
16
+ logicalOperator: LogicalOperator;
17
+ filters: Array<ConstructableFilter | ConstructableFilterGroup>;
18
+ [INTERNAL_KIND]: "LOGICAL_GROUP";
19
+ };
20
+ interface SortingOptionItem {
21
+ sortingField: string;
22
+ sortType: "ASC" | "DESC";
23
+ }
24
+ type ConstructableOrderBy = SortingOptionItem & {
25
+ [INTERNAL_KIND]: "ORDER_BY";
26
+ };
27
+ type AnyConstructable = ConstructableFilter | ConstructableFilterGroup;
28
+ declare const INTERNAL_KIND: unique symbol;
29
+ /**
30
+ * Query builder for filter queries. This exist to alleviate the (LLM?) mental overhead. API filter schema is a bit
31
+ * verbose and confusing, even when dealing with very basic queries. So to fall into the pit of success, aim here
32
+ * is to simplify filtering as much as possible.
33
+ *
34
+ * @example
35
+ * single filter
36
+ * ```tsx
37
+ * const query = q.text("title").contains("hello");
38
+ *
39
+ * const json = buildFilterCriteria(query);
40
+ * // result
41
+ * {
42
+ * "filterCriteria": {
43
+ * "filterConditionGroup": {
44
+ * "logicalOperator": "AND"
45
+ * "filterGroups": [{
46
+ * "logicalOperator": "AND",
47
+ * "filters": [{
48
+ * "subject": "title",
49
+ * "type": "TEXT",
50
+ * "operator": "CONTAINS",
51
+ * "value": "hello"
52
+ * }],
53
+ * }]
54
+ * }
55
+ * }
56
+ * }
57
+ *
58
+ * ```
59
+ *
60
+ * @example
61
+ * combining multiple filters
62
+ * ```tsx
63
+ * const query = q.and(
64
+ * q.text("title").contains("hello"),
65
+ * q.number("views").is(100),
66
+ * q.or(
67
+ * q.text("author").is("John"),
68
+ * q.boolean("isPublished").is(true)
69
+ * )
70
+ * );
71
+ * ```
72
+ */
73
+ declare const q: {
74
+ select<T extends Record<string, string>>(mapping: T): T;
75
+ and(...filters: AnyConstructable[]): ConstructableFilterGroup;
76
+ or(...filters: AnyConstructable[]): ConstructableFilterGroup;
77
+ text(subject: string): {
78
+ is(value: string): {
79
+ operator: "IS";
80
+ value: string;
81
+ subject: string;
82
+ type: "TEXT";
83
+ [INTERNAL_KIND]: "FILTER";
84
+ };
85
+ isNot(value: string): {
86
+ operator: "IS_NOT";
87
+ value: string;
88
+ subject: string;
89
+ type: "TEXT";
90
+ [INTERNAL_KIND]: "FILTER";
91
+ };
92
+ contains(value: string): {
93
+ operator: "CONTAINS";
94
+ value: string;
95
+ subject: string;
96
+ type: "TEXT";
97
+ [INTERNAL_KIND]: "FILTER";
98
+ };
99
+ isOneOf(value: string[]): {
100
+ operator: "IS_ONE_OF";
101
+ value: string[];
102
+ subject: string;
103
+ type: "TEXT";
104
+ [INTERNAL_KIND]: "FILTER";
105
+ };
106
+ isNoneOf(value: string[]): {
107
+ operator: "IS_NONE_OF";
108
+ value: string[];
109
+ subject: string;
110
+ type: "TEXT";
111
+ [INTERNAL_KIND]: "FILTER";
112
+ };
113
+ startsWith(value: string): {
114
+ operator: "STARTS_WITH";
115
+ value: string;
116
+ subject: string;
117
+ type: "TEXT";
118
+ [INTERNAL_KIND]: "FILTER";
119
+ };
120
+ endsWith(value: string): {
121
+ operator: "ENDS_WITH";
122
+ value: string;
123
+ subject: string;
124
+ type: "TEXT";
125
+ [INTERNAL_KIND]: "FILTER";
126
+ };
127
+ hasAllOf(value: string[]): {
128
+ operator: "HAS_ALL_OF";
129
+ value: string[];
130
+ subject: string;
131
+ type: "TEXT";
132
+ [INTERNAL_KIND]: "FILTER";
133
+ };
134
+ isEmpty(): {
135
+ operator: "IS_EMPTY";
136
+ subject: string;
137
+ type: "TEXT";
138
+ [INTERNAL_KIND]: "FILTER";
139
+ };
140
+ isNotEmpty(): {
141
+ operator: "IS_NOT_EMPTY";
142
+ subject: string;
143
+ type: "TEXT";
144
+ [INTERNAL_KIND]: "FILTER";
145
+ };
146
+ };
147
+ boolean(subject: string): {
148
+ is(value: boolean): {
149
+ operator: "IS";
150
+ value: boolean;
151
+ subject: string;
152
+ type: "BOOLEAN";
153
+ [INTERNAL_KIND]: "FILTER";
154
+ };
155
+ isNot(value: boolean): {
156
+ operator: "IS_NOT";
157
+ value: boolean;
158
+ subject: string;
159
+ type: "BOOLEAN";
160
+ [INTERNAL_KIND]: "FILTER";
161
+ };
162
+ isEmpty(): {
163
+ operator: "IS_EMPTY";
164
+ subject: string;
165
+ type: "BOOLEAN";
166
+ [INTERNAL_KIND]: "FILTER";
167
+ };
168
+ isNotEmpty(): {
169
+ operator: "IS_NOT_EMPTY";
170
+ subject: string;
171
+ type: "BOOLEAN";
172
+ [INTERNAL_KIND]: "FILTER";
173
+ };
174
+ };
175
+ number(subject: string): {
176
+ is(value: number): {
177
+ operator: "IS";
178
+ value: string;
179
+ subject: string;
180
+ type: "NUMERIC";
181
+ [INTERNAL_KIND]: "FILTER";
182
+ };
183
+ isNot(value: number): {
184
+ operator: "IS_NOT";
185
+ value: string;
186
+ subject: string;
187
+ type: "NUMERIC";
188
+ [INTERNAL_KIND]: "FILTER";
189
+ };
190
+ gt(value: number): {
191
+ operator: "GT";
192
+ value: string;
193
+ subject: string;
194
+ type: "NUMERIC";
195
+ [INTERNAL_KIND]: "FILTER";
196
+ };
197
+ gte(value: number): {
198
+ operator: "GTE";
199
+ value: string;
200
+ subject: string;
201
+ type: "NUMERIC";
202
+ [INTERNAL_KIND]: "FILTER";
203
+ };
204
+ lt(value: number): {
205
+ operator: "LT";
206
+ value: string;
207
+ subject: string;
208
+ type: "NUMERIC";
209
+ [INTERNAL_KIND]: "FILTER";
210
+ };
211
+ lte(value: number): {
212
+ operator: "LTE";
213
+ value: string;
214
+ subject: string;
215
+ type: "NUMERIC";
216
+ [INTERNAL_KIND]: "FILTER";
217
+ };
218
+ between(start: number, end: number): {
219
+ operator: "BETWEEN";
220
+ value: string[];
221
+ subject: string;
222
+ type: "NUMERIC";
223
+ [INTERNAL_KIND]: "FILTER";
224
+ };
225
+ isEmpty(): {
226
+ operator: "IS_EMPTY";
227
+ subject: string;
228
+ type: "NUMERIC";
229
+ [INTERNAL_KIND]: "FILTER";
230
+ };
231
+ isNotEmpty(): {
232
+ operator: "IS_NOT_EMPTY";
233
+ subject: string;
234
+ type: "NUMERIC";
235
+ [INTERNAL_KIND]: "FILTER";
236
+ };
237
+ };
238
+ array(subject: string): {
239
+ is(value: string[]): {
240
+ operator: "IS";
241
+ value: string[];
242
+ subject: string;
243
+ type: "ARRAY";
244
+ [INTERNAL_KIND]: "FILTER";
245
+ };
246
+ isOneOf(value: string[]): {
247
+ operator: "IS_ONE_OF";
248
+ value: string[];
249
+ subject: string;
250
+ type: "ARRAY";
251
+ [INTERNAL_KIND]: "FILTER";
252
+ };
253
+ isNoneOf(value: string[]): {
254
+ operator: "IS_NONE_OF";
255
+ value: string[];
256
+ subject: string;
257
+ type: "ARRAY";
258
+ [INTERNAL_KIND]: "FILTER";
259
+ };
260
+ hasAllOf(value: string[]): {
261
+ operator: "HAS_ALL_OF";
262
+ value: string[];
263
+ subject: string;
264
+ type: "ARRAY";
265
+ [INTERNAL_KIND]: "FILTER";
266
+ };
267
+ isEmpty(): {
268
+ operator: "IS_EMPTY";
269
+ subject: string;
270
+ type: "ARRAY";
271
+ [INTERNAL_KIND]: "FILTER";
272
+ };
273
+ isNotEmpty(): {
274
+ operator: "IS_NOT_EMPTY";
275
+ subject: string;
276
+ type: "ARRAY";
277
+ [INTERNAL_KIND]: "FILTER";
278
+ };
279
+ };
280
+ date(subject: string): {
281
+ is(value: string): {
282
+ operator: "IS";
283
+ value: string;
284
+ subject: string;
285
+ type: "DATE";
286
+ [INTERNAL_KIND]: "FILTER";
287
+ };
288
+ isNot(value: string): {
289
+ operator: "IS_NOT";
290
+ value: string;
291
+ subject: string;
292
+ type: "DATE";
293
+ [INTERNAL_KIND]: "FILTER";
294
+ };
295
+ gt(value: string): {
296
+ operator: "GT";
297
+ value: string;
298
+ subject: string;
299
+ type: "DATE";
300
+ [INTERNAL_KIND]: "FILTER";
301
+ };
302
+ gte(value: string): {
303
+ operator: "GTE";
304
+ value: string;
305
+ subject: string;
306
+ type: "DATE";
307
+ [INTERNAL_KIND]: "FILTER";
308
+ };
309
+ lt(value: string): {
310
+ operator: "LT";
311
+ value: string;
312
+ subject: string;
313
+ type: "DATE";
314
+ [INTERNAL_KIND]: "FILTER";
315
+ };
316
+ lte(value: string): {
317
+ operator: "LTE";
318
+ value: string;
319
+ subject: string;
320
+ type: "DATE";
321
+ [INTERNAL_KIND]: "FILTER";
322
+ };
323
+ between(start: string, end: string): {
324
+ operator: "BETWEEN";
325
+ value: string[];
326
+ subject: string;
327
+ type: "DATE";
328
+ [INTERNAL_KIND]: "FILTER";
329
+ };
330
+ isNotBetween(start: string, end: string): {
331
+ operator: "IS_NOT_BETWEEN";
332
+ value: string[];
333
+ subject: string;
334
+ type: "DATE";
335
+ [INTERNAL_KIND]: "FILTER";
336
+ };
337
+ isEmpty(): {
338
+ operator: "IS_EMPTY";
339
+ subject: string;
340
+ type: "DATE";
341
+ [INTERNAL_KIND]: "FILTER";
342
+ };
343
+ isNotEmpty(): {
344
+ operator: "IS_NOT_EMPTY";
345
+ subject: string;
346
+ type: "DATE";
347
+ [INTERNAL_KIND]: "FILTER";
348
+ };
349
+ };
350
+ asc(subject: string): ConstructableOrderBy;
351
+ desc(subject: string): ConstructableOrderBy;
352
+ };
353
+ //#endregion
354
+ //#region src/auth/user.d.ts
355
+ /**
356
+ * Declare this interface in your app to narrow every group id the SDK takes and
357
+ * returns. Without a declaration, a group id is a plain `string`.
358
+ *
359
+ * @example
360
+ * declare module "@softr/sdk" {
361
+ * interface SoftrUserGroups {
362
+ * ids:
363
+ * | "b1f2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
364
+ * | "f9e8d7c6-5b4a-4938-8271-605f4e3d2c1b"
365
+ * }
366
+ * }
367
+ */
368
+ interface SoftrUserGroups {}
369
+ /** A Softr user group id, narrowed to your own ids if you declare {@link SoftrUserGroups}. */
370
+ type SoftrUserGroupId = SoftrUserGroups extends {
371
+ ids: infer Id extends string;
372
+ } ? Id : string;
373
+ /** The signed-in visitor. */
374
+ type User = {
375
+ id: string;
376
+ email: string;
377
+ name: string;
378
+ userGroupIds: Array<SoftrUserGroupId>;
379
+ };
380
+ //#endregion
381
+ //#region src/types.d.ts
382
+ interface SoftrUser {
383
+ id: string;
384
+ email: string;
385
+ name: string;
386
+ userGroupIds: Array<SoftrUserGroupId>;
387
+ }
388
+ interface DatasourcePermissions {
389
+ read: boolean;
390
+ create: boolean;
391
+ update: boolean;
392
+ delete: boolean;
393
+ }
394
+ interface SoftrPermissions {
395
+ datasources: Record<string, DatasourcePermissions>;
396
+ workflows: Record<string, boolean>;
397
+ }
398
+ interface SoftrMe {
399
+ user: SoftrUser | null;
400
+ permissions: SoftrPermissions;
401
+ }
402
+ type GetByIdOptions = {
403
+ id: string;
404
+ where?: never;
405
+ timeZone?: string;
406
+ };
407
+ type GetByWhereOptions = {
408
+ id?: never;
409
+ where: AnyConstructable;
410
+ timeZone?: string;
411
+ };
412
+ type GetOptions = GetByIdOptions | GetByWhereOptions;
413
+ interface ListOptions {
414
+ /**
415
+ * Maps human-readable aliases to Softr field IDs.
416
+ * When provided, returned fields are keyed by alias instead of raw field ID.
417
+ */
418
+ select?: Record<string, string>;
419
+ where?: AnyConstructable;
420
+ orderBy?: ConstructableOrderBy | ConstructableOrderBy[];
421
+ /**
422
+ * Number of records to return per page. Defaults to 20, max 100.
423
+ */
424
+ limit?: number;
425
+ /**
426
+ * Offset to start from. Pass the `nextOffset` from a previous result to paginate.
427
+ * Omit or pass `null` to start from the beginning.
428
+ */
429
+ offset?: number | null;
430
+ /** Override the timezone for this request. */
431
+ timeZone?: string;
432
+ }
433
+ interface ListResult<T = SoftrRecord> {
434
+ records: T[];
435
+ total: number;
436
+ /** Offset to pass as `offset` in the next call, or `null` when there are no more pages. */
437
+ nextOffset: number | null;
438
+ }
439
+ interface SoftrRecord {
440
+ id: string;
441
+ fields: Record<string, unknown>;
442
+ }
443
+ type AggregationFunction = 'SUM' | 'AVG' | 'MAX' | 'MIN' | 'COUNT' | 'DISTINCT';
444
+ interface MetricOptions {
445
+ select?: Record<string, string>;
446
+ where?: AnyConstructable;
447
+ aggregation: AggregationFunction;
448
+ /** Field alias (resolved via select) or raw field ID. Not required for COUNT. */
449
+ field?: string;
450
+ /** Override the timezone for this request. */
451
+ timeZone?: string;
452
+ }
453
+ interface MetricResult {
454
+ value: number | null;
455
+ executionTimestamp: Date;
456
+ }
457
+ interface ChartDataOptions {
458
+ select?: Record<string, string>;
459
+ where?: AnyConstructable;
460
+ /** Field alias (resolved via select) or raw field ID. */
461
+ groupBy: string | string[];
462
+ metrics: Record<string, {
463
+ field?: string;
464
+ aggregation: AggregationFunction;
465
+ }>;
466
+ orderBy?: ConstructableOrderBy;
467
+ /** Override the timezone for this request. */
468
+ timeZone?: string;
469
+ }
470
+ interface ChartDataResult {
471
+ data: Record<string, unknown>[];
472
+ executionTimestamp: Date;
473
+ }
474
+ interface CreateOptions {
475
+ fields: Record<string, unknown>;
476
+ }
477
+ interface UpdateOptions {
478
+ id: string;
479
+ fields: Record<string, unknown>;
480
+ }
481
+ //#endregion
482
+ export { SoftrUserGroups as _, DatasourcePermissions as a, ListResult as c, SoftrMe as d, SoftrPermissions as f, SoftrUserGroupId as g, UpdateOptions as h, CreateOptions as i, MetricOptions as l, SoftrUser as m, ChartDataOptions as n, GetOptions as o, SoftrRecord as p, ChartDataResult as r, ListOptions as s, AggregationFunction as t, MetricResult as u, User as v, q as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softr/sdk",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },