@softr/sdk 0.0.27 → 0.0.29

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/dist/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { version } from "./package.js";
3
+ import { fetchSoftrEnvInput, metadataSourceFromEnv } from "./codegen/fetch-metadata.js";
3
4
  import { renderSoftrEnv } from "./codegen/softr-env.js";
4
5
  import { writeFileSync } from "node:fs";
5
6
  import path from "node:path";
@@ -7,7 +8,7 @@ import path from "node:path";
7
8
  //#region src/cli.ts
8
9
  const OUTPUT = "softr-env.d.ts";
9
10
  async function generate() {
10
- writeFileSync(path.resolve(process.cwd(), OUTPUT), renderSoftrEnv(await getMetadata(), version), "utf8");
11
+ writeFileSync(path.resolve(process.cwd(), OUTPUT), renderSoftrEnv(await fetchSoftrEnvInput(metadataSourceFromEnv()), version), "utf8");
11
12
  console.log(`[softr] wrote ${OUTPUT}`);
12
13
  }
13
14
  const [command] = process.argv.slice(2);
@@ -17,623 +18,6 @@ else {
17
18
  console.error("usage: softr-sdk generate");
18
19
  process.exit(1);
19
20
  }
20
- async function getMetadata() {
21
- return {
22
- userGroupIds: ["8f2b1c04-6d3a-4e58-9a71-c05e3b8d7f12", "3d9e7a56-1b84-42cf-8e0d-64a1f7c92b30"],
23
- datasources: [{
24
- "id": "FrkQIVpeTtfJDT",
25
- "name": "Cafes",
26
- "primaryFieldId": "9QrOA",
27
- "fields": [
28
- {
29
- "id": "9QrOA",
30
- "name": "Name",
31
- "type": "SINGLE_LINE_TEXT",
32
- "options": {
33
- "minLength": 0,
34
- "maxLength": 1024
35
- },
36
- "allowMultipleEntries": false,
37
- "readonly": false,
38
- "required": false,
39
- "createOnly": false,
40
- "defaultValue": null
41
- },
42
- {
43
- "id": "hIpjI",
44
- "name": "Description",
45
- "type": "LONG_TEXT",
46
- "options": { "type": "TEXT" },
47
- "allowMultipleEntries": false,
48
- "readonly": false,
49
- "required": false,
50
- "createOnly": false,
51
- "defaultValue": null
52
- },
53
- {
54
- "id": "r10tX",
55
- "name": "Status",
56
- "type": "SELECT",
57
- "options": {
58
- "allowToAddNewChoice": true,
59
- "filters": null,
60
- "choices": [
61
- {
62
- "id": "5db958e7-eacd-41ff-8e96-dffa73fbc06d",
63
- "label": "Todo",
64
- "color": "#386af5"
65
- },
66
- {
67
- "id": "fccba54c-8ba2-43b9-8dcc-0b551fe54ff2",
68
- "label": "In progress",
69
- "color": "#f53878"
70
- },
71
- {
72
- "id": "003d330c-6691-4327-85f4-d8cd55c12ab7",
73
- "label": "Done",
74
- "color": "#ef5f00"
75
- }
76
- ]
77
- },
78
- "allowMultipleEntries": false,
79
- "readonly": false,
80
- "required": false,
81
- "createOnly": false,
82
- "defaultValue": null
83
- },
84
- {
85
- "id": "pPOt7",
86
- "name": "AI Summary",
87
- "type": "LONG_TEXT",
88
- "options": { "type": "TEXT" },
89
- "allowMultipleEntries": false,
90
- "readonly": false,
91
- "required": false,
92
- "createOnly": false,
93
- "defaultValue": null,
94
- "aiOnly": true
95
- },
96
- {
97
- "id": "rsww5",
98
- "name": "Coffee Category",
99
- "type": "SELECT",
100
- "options": {
101
- "allowToAddNewChoice": true,
102
- "filters": null,
103
- "choices": [
104
- {
105
- "id": "79176278-98e4-4980-b6c7-8adc7bd10943",
106
- "label": "Espresso",
107
- "color": "#6F4E37"
108
- },
109
- {
110
- "id": "69fdef18-e778-455b-86a7-ddf9d39c8890",
111
- "label": "Filter",
112
- "color": "#C19A6B"
113
- },
114
- {
115
- "id": "a419b11c-c2d7-4bcf-9f1d-19c48ff04942",
116
- "label": "Cold Brew",
117
- "color": "#2F4858"
118
- },
119
- {
120
- "id": "a4d45385-ef7d-4817-97c0-50e7db429665",
121
- "label": "Tea",
122
- "color": "#2E7D32"
123
- },
124
- {
125
- "id": "ae47ba65-d40b-468f-ad7e-ef87860bbef9",
126
- "label": "Pastry",
127
- "color": "#D97706"
128
- }
129
- ]
130
- },
131
- "allowMultipleEntries": false,
132
- "readonly": false,
133
- "required": false,
134
- "createOnly": false,
135
- "defaultValue": null
136
- },
137
- {
138
- "id": "obZYH",
139
- "name": "Tags",
140
- "type": "SELECT",
141
- "options": {
142
- "allowToAddNewChoice": true,
143
- "filters": null,
144
- "choices": [
145
- {
146
- "id": "fddfc32f-3c29-484f-b922-943ad13323eb",
147
- "label": "Seasonal",
148
- "color": "#F59E0B"
149
- },
150
- {
151
- "id": "2a0288c2-b115-40ce-b83b-02242d0a9db3",
152
- "label": "Signature",
153
- "color": "#7C3AED"
154
- },
155
- {
156
- "id": "d40016c8-d689-4607-9ea7-70ef9684739d",
157
- "label": "Decaf",
158
- "color": "#64748B"
159
- },
160
- {
161
- "id": "0e1ba286-9fc4-4d24-a81f-d94a504ea025",
162
- "label": "Vegan",
163
- "color": "#16A34A"
164
- },
165
- {
166
- "id": "983e1d1f-44f5-422f-a414-c8d223da47d1",
167
- "label": "Gluten-free",
168
- "color": "#0EA5E9"
169
- }
170
- ]
171
- },
172
- "allowMultipleEntries": true,
173
- "readonly": false,
174
- "required": false,
175
- "createOnly": false,
176
- "defaultValue": null
177
- },
178
- {
179
- "id": "DnKHg",
180
- "name": "Available Today",
181
- "type": "CHECKBOX",
182
- "options": {},
183
- "allowMultipleEntries": false,
184
- "readonly": false,
185
- "required": false,
186
- "createOnly": false,
187
- "defaultValue": null
188
- },
189
- {
190
- "id": "TRrfv",
191
- "name": "Price",
192
- "type": "CURRENCY",
193
- "options": {
194
- "precision": 2,
195
- "min": 0,
196
- "max": null,
197
- "isoCode": "USD",
198
- "customSymbol": "$",
199
- "showAs": "SYMBOL",
200
- "showThousandSeparator": true,
201
- "thousandSeparatorLocale": "DEFAULT",
202
- "largeNumberAbbreviation": "NONE",
203
- "symbolOrCodePosition": "BEFORE"
204
- },
205
- "allowMultipleEntries": false,
206
- "readonly": false,
207
- "required": false,
208
- "createOnly": false,
209
- "defaultValue": null
210
- },
211
- {
212
- "id": "b1ShI",
213
- "name": "Discount %",
214
- "type": "PERCENT",
215
- "options": {
216
- "precision": 0,
217
- "min": 0,
218
- "max": 100,
219
- "showThousandSeparator": false,
220
- "thousandSeparatorLocale": "DEFAULT",
221
- "progressBarColor": "#6F4E37",
222
- "showNumber": true,
223
- "showAs": "PROGRESS_BAR"
224
- },
225
- "allowMultipleEntries": false,
226
- "readonly": false,
227
- "required": false,
228
- "createOnly": false,
229
- "defaultValue": null
230
- },
231
- {
232
- "id": "HgvTD",
233
- "name": "Prep Time",
234
- "type": "DURATION",
235
- "options": { "format": "hours_minutes" },
236
- "allowMultipleEntries": false,
237
- "readonly": false,
238
- "required": false,
239
- "createOnly": false,
240
- "defaultValue": null
241
- },
242
- {
243
- "id": "OOtnV",
244
- "name": "Customer Rating",
245
- "type": "RATING",
246
- "options": { "max": 5 },
247
- "allowMultipleEntries": false,
248
- "readonly": false,
249
- "required": false,
250
- "createOnly": false,
251
- "defaultValue": null
252
- },
253
- {
254
- "id": "sXpEY",
255
- "name": "Roast Progress",
256
- "type": "PROGRESS",
257
- "options": null,
258
- "allowMultipleEntries": false,
259
- "readonly": false,
260
- "required": false,
261
- "createOnly": false,
262
- "defaultValue": null
263
- },
264
- {
265
- "id": "1G3aA",
266
- "name": "Launch Date",
267
- "type": "DATETIME",
268
- "options": {
269
- "precision": "DATE",
270
- "useRelativeDatetimeFormat": false,
271
- "timezoneType": "LOCAL",
272
- "timezone": null,
273
- "format": null
274
- },
275
- "allowMultipleEntries": false,
276
- "readonly": false,
277
- "required": false,
278
- "createOnly": false,
279
- "defaultValue": null
280
- },
281
- {
282
- "id": "jNi5x",
283
- "name": "Menu URL",
284
- "type": "URL",
285
- "options": {},
286
- "allowMultipleEntries": false,
287
- "readonly": false,
288
- "required": false,
289
- "createOnly": false,
290
- "defaultValue": null
291
- },
292
- {
293
- "id": "NRq3e",
294
- "name": "Supplier Email",
295
- "type": "EMAIL",
296
- "options": {},
297
- "allowMultipleEntries": false,
298
- "readonly": false,
299
- "required": false,
300
- "createOnly": false,
301
- "defaultValue": null
302
- },
303
- {
304
- "id": "lJ06U",
305
- "name": "Supplier Phone",
306
- "type": "PHONE",
307
- "options": {},
308
- "allowMultipleEntries": false,
309
- "readonly": false,
310
- "required": false,
311
- "createOnly": false,
312
- "defaultValue": null
313
- },
314
- {
315
- "id": "3vzVE",
316
- "name": "Roastery Address",
317
- "type": "ADDRESS",
318
- "options": {},
319
- "allowMultipleEntries": false,
320
- "readonly": false,
321
- "required": false,
322
- "createOnly": false,
323
- "defaultValue": null
324
- },
325
- {
326
- "id": "5aV34",
327
- "name": "Product Photo",
328
- "type": "ATTACHMENT",
329
- "options": {
330
- "showAs": "PREVIEW",
331
- "inferredFileType": "IMAGE",
332
- "enableFileLinkExpiration": true,
333
- "fileLinkExpirationValue": 1,
334
- "fileLinkExpirationUnit": "HOURS"
335
- },
336
- "allowMultipleEntries": false,
337
- "readonly": false,
338
- "required": false,
339
- "createOnly": false,
340
- "defaultValue": null
341
- },
342
- {
343
- "id": "0VNXa",
344
- "name": "Barista",
345
- "type": "USER",
346
- "options": {},
347
- "allowMultipleEntries": false,
348
- "readonly": false,
349
- "required": false,
350
- "createOnly": false,
351
- "defaultValue": null
352
- },
353
- {
354
- "id": "xVag5",
355
- "name": "Order Link",
356
- "type": "BUTTON",
357
- "options": {},
358
- "allowMultipleEntries": false,
359
- "readonly": false,
360
- "required": false,
361
- "createOnly": false,
362
- "defaultValue": null
363
- },
364
- {
365
- "id": "NniWf",
366
- "name": "Supplier",
367
- "type": "LINKED_RECORD",
368
- "options": {
369
- "linkedTableId": "vEhur4KK25b1NF",
370
- "category": null,
371
- "relationshipName": null
372
- },
373
- "allowMultipleEntries": false,
374
- "readonly": false,
375
- "required": false,
376
- "createOnly": false,
377
- "defaultValue": null
378
- },
379
- {
380
- "id": "z0COG",
381
- "name": "Supplier Email (Lookup)",
382
- "type": "LOOKUP",
383
- "options": {
384
- "linkedRecordFieldId": "NniWf",
385
- "lookupFieldId": "W2kQG",
386
- "returnedField": {
387
- "type": "EMAIL",
388
- "options": {}
389
- }
390
- },
391
- "allowMultipleEntries": false,
392
- "readonly": true,
393
- "required": false,
394
- "createOnly": false,
395
- "defaultValue": null
396
- },
397
- {
398
- "id": "y2qDf",
399
- "name": "Origin Location",
400
- "type": "ADDRESS",
401
- "options": {},
402
- "allowMultipleEntries": false,
403
- "readonly": false,
404
- "required": false,
405
- "createOnly": false,
406
- "defaultValue": null
407
- },
408
- {
409
- "id": "ub7Gi",
410
- "name": "Drink Display Name",
411
- "type": "FORMULA",
412
- "options": {
413
- "formula": "IF({Coffee Category}, {Name} & \" (\" & {Coffee Category} & \")\", {Name})",
414
- "referencedFieldIds": ["9QrOA", "rsww5"],
415
- "returnedField": {
416
- "type": "SINGLE_LINE_TEXT",
417
- "options": {
418
- "minLength": 0,
419
- "maxLength": 1024
420
- }
421
- },
422
- "valid": true
423
- },
424
- "allowMultipleEntries": false,
425
- "readonly": true,
426
- "required": false,
427
- "createOnly": false,
428
- "defaultValue": null
429
- },
430
- {
431
- "id": "x8ENy",
432
- "name": "Final Price",
433
- "type": "FORMULA",
434
- "options": {
435
- "formula": "{Price} * (1 - IF({Discount %} = BLANK(), 0, {Discount %} / 100))",
436
- "referencedFieldIds": ["TRrfv", "b1ShI"],
437
- "returnedField": {
438
- "type": "CURRENCY",
439
- "options": {
440
- "precision": 2,
441
- "min": null,
442
- "max": null,
443
- "isoCode": "USD",
444
- "customSymbol": "$",
445
- "showAs": "SYMBOL",
446
- "showThousandSeparator": true,
447
- "thousandSeparatorLocale": "DEFAULT",
448
- "largeNumberAbbreviation": "NONE",
449
- "symbolOrCodePosition": "BEFORE"
450
- }
451
- },
452
- "valid": true
453
- },
454
- "allowMultipleEntries": false,
455
- "readonly": true,
456
- "required": false,
457
- "createOnly": false,
458
- "defaultValue": null
459
- },
460
- {
461
- "id": "Fnxlk",
462
- "name": "Prep Time (mins)",
463
- "type": "FORMULA",
464
- "options": {
465
- "formula": "ROUND({Prep Time} / 60, 0)",
466
- "referencedFieldIds": ["HgvTD"],
467
- "returnedField": {
468
- "type": "NUMBER",
469
- "options": {
470
- "precision": 0,
471
- "min": null,
472
- "max": null,
473
- "showThousandSeparator": true,
474
- "thousandSeparatorLocale": "DEFAULT",
475
- "largeNumberAbbreviation": "NONE",
476
- "prefix": null,
477
- "suffix": null
478
- }
479
- },
480
- "valid": true
481
- },
482
- "allowMultipleEntries": false,
483
- "readonly": true,
484
- "required": false,
485
- "createOnly": false,
486
- "defaultValue": null
487
- },
488
- {
489
- "id": "CXfMR",
490
- "name": "Is Premium",
491
- "type": "FORMULA",
492
- "options": {
493
- "formula": "OR({Price} > 6, {Customer Rating} = 5)",
494
- "referencedFieldIds": ["OOtnV", "TRrfv"],
495
- "returnedField": {
496
- "type": "SINGLE_LINE_TEXT",
497
- "options": {
498
- "minLength": 0,
499
- "maxLength": 1024
500
- }
501
- },
502
- "valid": true
503
- },
504
- "allowMultipleEntries": false,
505
- "readonly": true,
506
- "required": false,
507
- "createOnly": false,
508
- "defaultValue": null
509
- },
510
- {
511
- "id": "FpC7H",
512
- "name": "Launch Month",
513
- "type": "FORMULA",
514
- "options": {
515
- "formula": "DATETIME_FORMAT({Launch Date}, \"yyyy-MM\")",
516
- "referencedFieldIds": ["1G3aA"],
517
- "returnedField": {
518
- "type": "SINGLE_LINE_TEXT",
519
- "options": {
520
- "minLength": 0,
521
- "maxLength": 1024
522
- }
523
- },
524
- "valid": true
525
- },
526
- "allowMultipleEntries": false,
527
- "readonly": true,
528
- "required": false,
529
- "createOnly": false,
530
- "defaultValue": null
531
- },
532
- {
533
- "id": "yiEpo",
534
- "name": "Tagline",
535
- "type": "FORMULA",
536
- "options": {
537
- "formula": "IF(\n Tags,\n \"Try our \" & {Tags} & \" \" & {Name} & \"!\",\n \"Try our \" & {Name} & \"!\"\n)",
538
- "referencedFieldIds": ["9QrOA", "obZYH"],
539
- "returnedField": {
540
- "type": "SINGLE_LINE_TEXT",
541
- "options": {
542
- "minLength": 0,
543
- "maxLength": 1024
544
- }
545
- },
546
- "valid": true
547
- },
548
- "allowMultipleEntries": false,
549
- "readonly": true,
550
- "required": false,
551
- "createOnly": false,
552
- "defaultValue": null
553
- }
554
- ]
555
- }, {
556
- "id": "vEhur4KK25b1NF",
557
- "name": "Suppliers",
558
- "primaryFieldId": "LmeiI",
559
- "fields": [
560
- {
561
- "id": "LmeiI",
562
- "name": "Name",
563
- "type": "SINGLE_LINE_TEXT",
564
- "options": {
565
- "minLength": 0,
566
- "maxLength": 1024
567
- },
568
- "allowMultipleEntries": false,
569
- "readonly": false,
570
- "required": true,
571
- "createOnly": false,
572
- "defaultValue": null
573
- },
574
- {
575
- "id": "W2kQG",
576
- "name": "Email",
577
- "type": "EMAIL",
578
- "options": {},
579
- "allowMultipleEntries": false,
580
- "readonly": false,
581
- "required": false,
582
- "createOnly": false,
583
- "defaultValue": null
584
- },
585
- {
586
- "id": "xbWGH",
587
- "name": "Phone",
588
- "type": "PHONE",
589
- "options": {},
590
- "allowMultipleEntries": false,
591
- "readonly": false,
592
- "required": false,
593
- "createOnly": false,
594
- "defaultValue": null
595
- },
596
- {
597
- "id": "gy9xg",
598
- "name": "Tier",
599
- "type": "NUMBER",
600
- "options": { "precision": 0 },
601
- "allowMultipleEntries": false,
602
- "readonly": false,
603
- "required": false,
604
- "createOnly": true,
605
- "defaultValue": null
606
- },
607
- {
608
- "id": "pDvjG",
609
- "name": "Score",
610
- "type": "NUMBER",
611
- "options": { "precision": 1 },
612
- "allowMultipleEntries": false,
613
- "readonly": false,
614
- "required": false,
615
- "createOnly": false,
616
- "defaultValue": null
617
- },
618
- {
619
- "id": "xYAXG",
620
- "name": "Cafes",
621
- "type": "LINKED_RECORD",
622
- "options": {
623
- "linkedTableId": "FrkQIVpeTtfJDT",
624
- "category": null,
625
- "relationshipName": null
626
- },
627
- "allowMultipleEntries": true,
628
- "readonly": false,
629
- "required": false,
630
- "createOnly": false,
631
- "defaultValue": null
632
- }
633
- ]
634
- }]
635
- };
636
- }
637
21
 
638
22
  //#endregion
639
23
  export { };
@@ -443,7 +443,7 @@ function nameOf(datasourceId, context) {
443
443
  }
444
444
  /**
445
445
  * Always quoted, even where an identifier would do. Find All References on a field id at a
446
- * `defineAction` call site matches string literals and quoted property names, so a bare key is
446
+ * `defineQuery` call site matches string literals and quoted property names, so a bare key is
447
447
  * invisible to it and the id no longer navigates here.
448
448
  */
449
449
  function key(name) {
@@ -0,0 +1,46 @@
1
+ import { panic } from "../assertions.js";
2
+
3
+ //#region src/codegen/fetch-metadata.ts
4
+ function metadataSourceFromEnv(env = process.env) {
5
+ const missing = [
6
+ "SOFTR_STUDIO_API_URL",
7
+ "SOFTR_DATASOURCE_API_URL",
8
+ "SOFTR_APPLICATION_ID",
9
+ "SOFTR_STUDIO_TOKEN"
10
+ ].filter((name) => !env[name]?.trim());
11
+ if (missing.length > 0) panic(`Cannot read the app's schema: ${missing.join(", ")} is not set.`);
12
+ return {
13
+ studioApiUrl: withoutTrailingSlash(env.SOFTR_STUDIO_API_URL),
14
+ datasourceApiUrl: withoutTrailingSlash(env.SOFTR_DATASOURCE_API_URL),
15
+ applicationId: env.SOFTR_APPLICATION_ID,
16
+ token: env.SOFTR_STUDIO_TOKEN
17
+ };
18
+ }
19
+ async function fetchSoftrEnvInput(source) {
20
+ const { studioApiUrl, datasourceApiUrl, applicationId, token } = source;
21
+ const registered = await apiFetch(`${studioApiUrl}/v1/applications/${applicationId}/datasources`, token);
22
+ return {
23
+ datasources: await Promise.all(registered.map(async ({ name, datasource }) => {
24
+ return {
25
+ ...await apiFetch(`${datasourceApiUrl}/v1/datasource/vibe/applications/${applicationId}/datasources/${datasource.id}/metadata`, token),
26
+ id: datasource.id,
27
+ name
28
+ };
29
+ })),
30
+ userGroupIds: null
31
+ };
32
+ }
33
+ async function apiFetch(url, token) {
34
+ const response = await fetch(url, { headers: {
35
+ accept: "application/json",
36
+ Authorization: `Bearer ${token}`
37
+ } }).catch(() => panic(`Could not reach ${url}`));
38
+ if (!response.ok) panic(`${url} answered ${response.status}`);
39
+ return await response.json();
40
+ }
41
+ function withoutTrailingSlash(url) {
42
+ return url.replace(/\/+$/, "");
43
+ }
44
+
45
+ //#endregion
46
+ export { fetchSoftrEnvInput, metadataSourceFromEnv };
@@ -13,8 +13,7 @@ function renderSoftrEnv(input, sdkVersion) {
13
13
  "",
14
14
  "declare module \"@softr/sdk\" {",
15
15
  indent(interfaces),
16
- "",
17
- indent(renderUserGroups(input.userGroupIds)),
16
+ ...input.userGroupIds === null ? [] : ["", indent(renderUserGroups(input.userGroupIds))],
18
17
  "}",
19
18
  ""
20
19
  ].join("\n");