@jigx/core-sdk 1.2.0-next.3 → 1.2.0-next.5

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.
@@ -13,7 +13,10 @@
13
13
  complex UI
14
14
  code: |2-
15
15
  // Main expense management application
16
- const app = new ApplicationBuilder({ name: 'expense-management', title: 'Expense Management' }).with({ category: 'business' })
16
+ const app = new ApplicationBuilder({
17
+ name: 'expense-management',
18
+ title: 'Expense Management',
19
+ }).with({ category: 'business' })
17
20
  // Main dashboard screen with complex component hierarchy
18
21
  const homeScreen = app.addScreen.default({
19
22
  screenId: 'home',
@@ -21,7 +24,11 @@
21
24
  })
22
25
  // REST function for fetching expense receipts with pagination
23
26
  const restGetExpenseReceipt = app.addFunction
24
- .rest({ functionId: 'rest-get-expense-receipt', method: 'GET', url: 'https://{acumaticaurl}ExpenseReceipt' })
27
+ .rest({
28
+ functionId: 'rest-get-expense-receipt',
29
+ method: 'GET',
30
+ url: 'https://{acumaticaurl}ExpenseReceipt',
31
+ })
25
32
  .records('=$.data')
26
33
  .forRowsWithMatchingIds(true)
27
34
  .outputTransform(`=`, {
@@ -355,7 +362,11 @@
355
362
  code: |-
356
363
  // Function with pagination support
357
364
  const fn = app.addFunction
358
- .rest({ functionId: 'rest-get-expense-receipt', method: 'GET', url: 'https://{acumaticaurl}ExpenseReceipt' })
365
+ .rest({
366
+ functionId: 'rest-get-expense-receipt',
367
+ method: 'GET',
368
+ url: 'https://{acumaticaurl}ExpenseReceipt',
369
+ })
359
370
  .records('=$.data')
360
371
  .forRowsWithMatchingIds(true)
361
372
  .outputTransform(`=`, {
@@ -443,7 +454,9 @@
443
454
  // Create database tables
444
455
  app.addDatabase.default.table('sales', 'inventory', 'customers')
445
456
  // Create datasources
446
- app.addDatasource.sqlite({ datasourceId: 'sales-summary', provider: 'dynamic' }).entity('default/sales').query(`
457
+ app.addDatasource
458
+ .sqlite({ datasourceId: 'sales-summary', provider: 'dynamic' })
459
+ .entity('default/sales').query(`
447
460
  SELECT
448
461
  id,
449
462
  json_extract(data, '$.date') as date,
@@ -453,7 +466,9 @@
453
466
  WHERE json_extract(data, '$.date') >= date('now', '-30 days')
454
467
  ORDER BY json_extract(data, '$.date') DESC
455
468
  `)
456
- app.addDatasource.sqlite({ datasourceId: 'low-inventory', provider: 'dynamic' }).entity('default/inventory').query(`
469
+ app.addDatasource
470
+ .sqlite({ datasourceId: 'low-inventory', provider: 'dynamic' })
471
+ .entity('default/inventory').query(`
457
472
  SELECT
458
473
  id,
459
474
  json_extract(data, '$.name') as name,
@@ -521,7 +536,9 @@
521
536
  in joins
522
537
  code: |-
523
538
  // 1. Declare entities in datasource
524
- app.addDatasource.sqlite({ datasourceId: 'customers', provider: 'local' }).entities('customers', 'products') // Must match table names used in query
539
+ app.addDatasource
540
+ .sqlite({ datasourceId: 'customers', provider: 'local' })
541
+ .entities('customers', 'products') // Must match table names used in query
525
542
  // 2. Ensure tables exist in database
526
543
  app.addDatabase.default
527
544
  - id: rest-function-integration-example
@@ -609,7 +626,12 @@
609
626
  code: |-
610
627
  // SOAP function for web service integration
611
628
  const weatherFunction = app.addFunction
612
- .soap({ functionId: 'get-weather', connection: 'weather-service', method: 'GetWeather', wsdl: 'https://weather.com/wsdl' })
629
+ .soap({
630
+ functionId: 'get-weather',
631
+ connection: 'weather-service',
632
+ method: 'GetWeather',
633
+ wsdl: 'https://weather.com/wsdl',
634
+ })
613
635
  .outputTransform('$.Temperature')
614
636
  weatherFunction.params
615
637
  .body('city', 'London')
@@ -634,7 +656,8 @@
634
656
  code: |-
635
657
  // SQL function for database queries
636
658
  const app = new ApplicationBuilder({ name: 'sql-function-example' })
637
- const getCustomersFunction = app.addFunction.sql({ functionId: 'get-customers', connection: 'mydb' })
659
+ const getCustomersFunction = app.addFunction
660
+ .sql({ functionId: 'get-customers', connection: 'mydb' })
638
661
  .sql('SELECT * FROM customers WHERE active = @active AND region = @region')
639
662
  getCustomersFunction.params
640
663
  .input('$active', 'boolean', { value: true })
@@ -648,7 +671,8 @@
648
671
  "SELECT id, data FROM [default/customers] ORDER BY json_extract(data, '$.created_at') DESC",
649
672
  )
650
673
  // Stored procedure SQL functions
651
- const updateCustomerFunction = app.addFunction.sql({ functionId: 'update-customer', connection: 'mydb', method: 'execute' })
674
+ const updateCustomerFunction = app.addFunction
675
+ .sql({ functionId: 'update-customer', connection: 'mydb', method: 'execute' })
652
676
  .sql('sp_UpdateCustomer', 'procedure')
653
677
  updateCustomerFunction.params
654
678
  .input('$customerId', 'number', { value: 123 })
@@ -678,7 +702,10 @@
678
702
  datasource.query(`SELECT id, data FROM [default/products]`)
679
703
  // Query patterns based on datasource naming:
680
704
  // Single record - inferred from "customer", "get-customer", "customer-by-name"
681
- const singleCustomer = app.addDatasource.sqlite({ datasourceId: 'customer-by-name', provider: 'local' })
705
+ const singleCustomer = app.addDatasource.sqlite({
706
+ datasourceId: 'customer-by-name',
707
+ provider: 'local',
708
+ })
682
709
  singleCustomer.entity('default/customers')
683
710
  singleCustomer.query(`
684
711
  SELECT cus.id,
@@ -689,7 +716,10 @@
689
716
  `)
690
717
  singleCustomer.queryParameter('name', '=@ctx.jig.inputs.customerName')
691
718
  // List records - inferred from "products", "all-products", "product-list"
692
- const productList = app.addDatasource.sqlite({ datasourceId: 'product-list', provider: 'local' })
719
+ const productList = app.addDatasource.sqlite({
720
+ datasourceId: 'product-list',
721
+ provider: 'local',
722
+ })
693
723
  productList.entity('default/products')
694
724
  productList.query(`
695
725
  SELECT prd.id,
@@ -701,7 +731,10 @@
701
731
  ORDER BY json_extract(prd.data, '$.name')
702
732
  `)
703
733
  // Sorted records - inferred from "contacts-sorted-by-name"
704
- const sortedContacts = app.addDatasource.sqlite({ datasourceId: 'contacts-by-last-login', provider: 'local' })
734
+ const sortedContacts = app.addDatasource.sqlite({
735
+ datasourceId: 'contacts-by-last-login',
736
+ provider: 'local',
737
+ })
705
738
  sortedContacts.entity('default/contacts')
706
739
  sortedContacts.query(`
707
740
  SELECT con.id,
@@ -720,7 +753,10 @@
720
753
  FROM [default/parts] AS prt
721
754
  `)
722
755
  // Complex joins with parameters
723
- const customerOrders = app.addDatasource.sqlite({ datasourceId: 'customer-orders', provider: 'dynamic' })
756
+ const customerOrders = app.addDatasource.sqlite({
757
+ datasourceId: 'customer-orders',
758
+ provider: 'dynamic',
759
+ })
724
760
  customerOrders.entity('default/customers')
725
761
  customerOrders.entity('default/orders')
726
762
  customerOrders.query(`
@@ -959,8 +995,14 @@
959
995
  customerInfo.addControl
960
996
  .entityField({ label: 'Name', value: '=@ctx.datasources.customer-detail.data.name' }) // Direct access, no [0]
961
997
  .with({ style: { isPrimary: true } })
962
- customerInfo.addControl.entityField({ label: 'Email', value: '=@ctx.datasources.customer-detail.data.email' })
963
- customerInfo.addControl.entityField({ label: 'Phone', value: '=@ctx.datasources.customer-detail.data.phone' })
998
+ customerInfo.addControl.entityField({
999
+ label: 'Email',
1000
+ value: '=@ctx.datasources.customer-detail.data.email',
1001
+ })
1002
+ customerInfo.addControl.entityField({
1003
+ label: 'Phone',
1004
+ value: '=@ctx.datasources.customer-detail.data.phone',
1005
+ })
964
1006
  customerInfo.addControl.entityField({
965
1007
  label: 'Address',
966
1008
  value:
@@ -1082,8 +1124,9 @@
1082
1124
  helperText: 'Between $1 and $10,000',
1083
1125
  })
1084
1126
  // Create datasource for validation errors (simulated)
1085
- app.addDatasource.sqlite({ datasourceId: 'validation-errors', provider: 'local' }).entity('default/validation-errors')
1086
- .query(`
1127
+ app.addDatasource
1128
+ .sqlite({ datasourceId: 'validation-errors', provider: 'local' })
1129
+ .entity('default/validation-errors').query(`
1087
1130
  SELECT
1088
1131
  id,
1089
1132
  json_extract(data, '$.field') as field,
@@ -1131,7 +1174,11 @@
1131
1174
  external sources on-demand or scheduled
1132
1175
  code: |-
1133
1176
  // 1. REST function to provide data
1134
- const getUsersApi = app.addFunction.rest({ functionId: 'get-users-api', method: 'GET', url: 'https://api.company.com/users' })
1177
+ const getUsersApi = app.addFunction.rest({
1178
+ functionId: 'get-users-api',
1179
+ method: 'GET',
1180
+ url: 'https://api.company.com/users',
1181
+ })
1135
1182
  getUsersApi.params.header('Authorization', 'Bearer =@ctx.solution.state.apiToken')
1136
1183
  getUsersApi.json()
1137
1184
  getUsersApi.records('=$.data.users')
@@ -1139,7 +1186,10 @@
1139
1186
  const usersData = app.addDatasource.sqlite({ datasourceId: 'users', provider: 'dynamic' })
1140
1187
  usersData.entity('default/users')
1141
1188
  // 3. SQL function for complex data processing
1142
- const getSalesMetrics = app.addFunction.sql({ functionId: 'sales-metrics', connection: 'analytics-db' })
1189
+ const getSalesMetrics = app.addFunction.sql({
1190
+ functionId: 'sales-metrics',
1191
+ connection: 'analytics-db',
1192
+ })
1143
1193
  getSalesMetrics.providerQuery(`
1144
1194
  SELECT
1145
1195
  region,
@@ -1155,14 +1205,24 @@
1155
1205
  value: '=@ctx.jig.inputs.dateRange.start',
1156
1206
  })
1157
1207
  // 4. Function-driven datasource with SQL function
1158
- const salesData = app.addDatasource.sqlite({ datasourceId: 'sales-metrics', provider: 'dynamic' })
1208
+ const salesData = app.addDatasource.sqlite({
1209
+ datasourceId: 'sales-metrics',
1210
+ provider: 'dynamic',
1211
+ })
1159
1212
  salesData.entity('default/sales')
1160
1213
  // 5. Multiple REST endpoints combined
1161
- const getInventoryApi = app.addFunction.rest({ functionId: 'inventory-api', method: 'GET', url: 'https://api.inventory.com/items' })
1214
+ const getInventoryApi = app.addFunction.rest({
1215
+ functionId: 'inventory-api',
1216
+ method: 'GET',
1217
+ url: 'https://api.inventory.com/items',
1218
+ })
1162
1219
  getInventoryApi.params.query('status', { value: 'active', type: 'string' })
1163
1220
  getInventoryApi.params.header('API-Key', '=@ctx.solution.state.inventoryKey')
1164
1221
  getInventoryApi.json()
1165
- const inventoryData = app.addDatasource.sqlite({ datasourceId: 'inventory', provider: 'dynamic' })
1222
+ const inventoryData = app.addDatasource.sqlite({
1223
+ datasourceId: 'inventory',
1224
+ provider: 'dynamic',
1225
+ })
1166
1226
  inventoryData.entity('default/inventory')
1167
1227
  - id: entity-sync-and-queue-management-example
1168
1228
  name: Entity Sync and Queue Management
@@ -1356,7 +1416,9 @@
1356
1416
  automatically when connection is restored
1357
1417
  code: |2-
1358
1418
  // Configure datasource with offline support
1359
- app.addDatasource.sqlite({ datasourceId: 'customers', provider: 'local' }).entity('default/customers').query(`
1419
+ app.addDatasource
1420
+ .sqlite({ datasourceId: 'customers', provider: 'local' })
1421
+ .entity('default/customers').query(`
1360
1422
  SELECT id, data FROM [default/customers]
1361
1423
  WHERE json_extract(data, '$.active') = true
1362
1424
  ORDER BY json_extract(data, '$.lastModified') DESC
@@ -1819,7 +1881,9 @@
1819
1881
  navigates to detail screen. Demonstrates master-detail pattern in Jigx"
1820
1882
  code: |2-
1821
1883
  // Create datasource for students
1822
- app.addDatasource.sqlite({ datasourceId: 'students', provider: 'dynamic' }).entity('default/students').query(`
1884
+ app.addDatasource
1885
+ .sqlite({ datasourceId: 'students', provider: 'dynamic' })
1886
+ .entity('default/students').query(`
1823
1887
  SELECT
1824
1888
  id,
1825
1889
  json_extract(data, '$.firstName') as firstName,
@@ -2015,11 +2079,14 @@
2015
2079
  value: '=@ctx.jig.inputs.city',
2016
2080
  })
2017
2081
  // Dropdown with static datasource
2018
- app.addDatasource.static({ datasourceId: 'us-states', data: [
2019
- { id: 'WA', state: 'Washington' },
2020
- { id: 'CA', state: 'California' },
2021
- { id: 'NY', state: 'New York' },
2022
- ] })
2082
+ app.addDatasource.static({
2083
+ datasourceId: 'us-states',
2084
+ data: [
2085
+ { id: 'WA', state: 'Washington' },
2086
+ { id: 'CA', state: 'California' },
2087
+ { id: 'NY', state: 'New York' },
2088
+ ],
2089
+ })
2023
2090
  const stateDropdown = step2Screen.addControl.dropdown({
2024
2091
  instanceId: 'state',
2025
2092
  label: 'State',
@@ -2125,7 +2192,9 @@
2125
2192
  alerts"
2126
2193
  code: |2-
2127
2194
  // Auto-refreshing datasource
2128
- app.addDatasource.sqlite({ datasourceId: 'system-status', provider: 'dynamic' }).entity('default/status').query(`
2195
+ app.addDatasource
2196
+ .sqlite({ datasourceId: 'system-status', provider: 'dynamic' })
2197
+ .entity('default/status').query(`
2129
2198
  SELECT
2130
2199
  id,
2131
2200
  json_extract(data, '$.health') as health,
@@ -2433,7 +2502,9 @@
2433
2502
  tabs and widget grid. Support conditional display based on user roles
2434
2503
  code: |-
2435
2504
  // Configure home hub
2436
- const app = new ApplicationBuilder({ name: 'my-app', title: 'My Business App' }).with({ category: 'business' })
2505
+ const app = new ApplicationBuilder({ name: 'my-app', title: 'My Business App' }).with({
2506
+ category: 'business',
2507
+ })
2437
2508
  // Add home hub with navigation tabs
2438
2509
  app.addTab({ screenId: 'dashboard', icon: 'home', label: 'Dashboard' })
2439
2510
  app.addTab({ screenId: 'tasks', icon: 'task-checklist', label: 'Tasks' })
@@ -2453,7 +2524,7 @@
2453
2524
  data
2454
2525
  code: |-
2455
2526
  // Widget with navigation
2456
- const screen = app.addScreen.staticGrid({ screenId: 'grid-1', title: 'Static Grid', })
2527
+ const screen = app.addScreen.staticGrid({ screenId: 'grid-1', title: 'Static Grid' })
2457
2528
  // Add a grid item
2458
2529
  screen.addControl.gridItem().addControl.widget().screenId('some-jig-id')
2459
2530
  - id: widget-grid-configuration-example
@@ -2470,7 +2541,7 @@
2470
2541
  different widget sizes and conditional display. Enable navigation and data
2471
2542
  binding
2472
2543
  code: |-
2473
- const screen = app.addScreen.staticGrid({ screenId: 'grid-1', title: 'Static Grid', })
2544
+ const screen = app.addScreen.staticGrid({ screenId: 'grid-1', title: 'Static Grid' })
2474
2545
  // Add a grid item
2475
2546
  screen.addControl
2476
2547
  .gridItem()
@@ -2670,7 +2741,9 @@
2670
2741
  authentication requirements. Support deep linking with parameters
2671
2742
  code: |2-
2672
2743
  // Create datasource for navigation items
2673
- app.addDatasource.sqlite({ datasourceId: 'nav-items', provider: 'local' }).entity('default/nav-items').query(`
2744
+ app.addDatasource
2745
+ .sqlite({ datasourceId: 'nav-items', provider: 'local' })
2746
+ .entity('default/nav-items').query(`
2674
2747
  SELECT
2675
2748
  id,
2676
2749
  json_extract(data, '$.title') as title,
@@ -2693,7 +2766,7 @@
2693
2766
  listItem.subtitle('=@ctx.current.item.type')
2694
2767
  // Conditional navigation based on item type
2695
2768
  const buttons = screen.bottomPanel({ numberOfVisibleActions: 1 })
2696
- const navButton = buttons.add.list({ concurrency: 'sequential', title: 'Navigate' })
2769
+ const navButton = buttons.add.list({ concurrency: 'sequential', title: 'Navigate' })
2697
2770
  // Check if external URL
2698
2771
  navButton.actions.openUrl({
2699
2772
  instanceId: 'open-external',
@@ -2808,8 +2881,8 @@
2808
2881
  // Common date formats
2809
2882
  .value('=$fromMillis($now(), "[Y]-[M01]-[D01]")') // 2024-03-15
2810
2883
  .value('=$fromMillis($now(), "[D] [MNn] [Y]")') // 15 Mar 2024
2811
- .value('=$fromMillis($now(), "[h]:[m01] [P]")') // 3:45 PM
2812
- .value(`=(
2884
+ // 3:45 PM
2885
+ .value('=$fromMillis($now(), "[h]:[m01] [P]")').value(`=(
2813
2886
  $diff := $now() - @ctx.jig.inputs.timestamp;
2814
2887
  $days := $floor($diff / 86400000);
2815
2888
  $hours := $floor($diff / 3600000);
@@ -3976,7 +4049,10 @@
3976
4049
  intermediate results. Improve readability and debugging
3977
4050
  code: |-
3978
4051
  // Instead of one massive expression, use state
3979
- const actions = screen.onFocus.list({ concurrency: 'sequential', instanceId: 'simplify-logic' }).actions
4052
+ const actions = screen.onFocus.list({
4053
+ concurrency: 'sequential',
4054
+ instanceId: 'simplify-logic',
4055
+ }).actions
3980
4056
  actions.setScreenState({
3981
4057
  instanceId: 'filter-items',
3982
4058
  keys: {
@@ -4005,15 +4081,17 @@
4005
4081
  related fields
4006
4082
  code: |2-
4007
4083
  // Create datasources for countries and states
4008
- const countries = app.addDatasource.sqlite({ datasourceId: 'countries', provider: 'local' }).entity('default/countries')
4009
- .query(`
4084
+ const countries = app.addDatasource
4085
+ .sqlite({ datasourceId: 'countries', provider: 'local' })
4086
+ .entity('default/countries').query(`
4010
4087
  SELECT
4011
4088
  id,
4012
4089
  json_extract(data, '$.name') as name,
4013
4090
  json_extract(data, '$.code') as code
4014
4091
  FROM [default/countries]
4015
4092
  `)
4016
- app.addDatasource.sqlite({ datasourceId: 'states', provider: 'local' }).entity('default/states').query(`
4093
+ app.addDatasource.sqlite({ datasourceId: 'states', provider: 'local' }).entity('default/states')
4094
+ .query(`
4017
4095
  SELECT
4018
4096
  id,
4019
4097
  json_extract(data, '$.name') as name,
@@ -4304,7 +4382,7 @@
4304
4382
  code: |-
4305
4383
  // Example: One button that does multiple things
4306
4384
  const buttons = screen.bottomPanel({ numberOfVisibleActions: 1 })
4307
- const actionList = buttons.add.list({ concurrency: 'sequential', title: 'Save and Close' })
4385
+ const actionList = buttons.add.list({ concurrency: 'sequential', title: 'Save and Close' })
4308
4386
  const sequentialActions = actionList.actions
4309
4387
  sequentialActions
4310
4388
  .executeEntity({ instanceId: 'create-customer' })
@@ -4408,7 +4486,10 @@
4408
4486
  code: |-
4409
4487
  // 1. Sequential workflow for order processing (order matters)
4410
4488
  const orderActions = orderScreen.bottomPanel({ numberOfVisibleActions: 2 })
4411
- const processOrder = orderActions.add.list({ concurrency: 'sequential', title: 'Process Order' })
4489
+ const processOrder = orderActions.add.list({
4490
+ concurrency: 'sequential',
4491
+ title: 'Process Order',
4492
+ })
4412
4493
  const sequentialActions = processOrder.actions
4413
4494
  // Execute in order: validate → save → update status → notify
4414
4495
  sequentialActions
@@ -4445,7 +4526,10 @@
4445
4526
  },
4446
4527
  })
4447
4528
  // 2. Parallel batch operations for analytics (order doesn't matter)
4448
- const analyticsActions = orderActions.add.list({ concurrency: 'parallel', title: 'Track Analytics' })
4529
+ const analyticsActions = orderActions.add.list({
4530
+ concurrency: 'parallel',
4531
+ title: 'Track Analytics',
4532
+ })
4449
4533
  const parallelActions = analyticsActions.actions
4450
4534
  // Execute simultaneously: user activity + system metrics + performance data
4451
4535
  parallelActions
@@ -4479,7 +4563,7 @@
4479
4563
  // These action lists execute automatically during app lifecycle events (onLoad, onFocus, onRefresh)
4480
4564
  // Use app.onLoad.list({ concurrency: 'sequential' }) or app.onLoad.list({ concurrency: 'parallel' }) for background workflow orchestration
4481
4565
  // 3. Application-level sequential sync on startup
4482
- const appSync = app.onLoad.list({ concurrency: 'sequential', instanceId: 'app-startup-sync' })
4566
+ const appSync = app.onLoad.list({ concurrency: 'sequential', instanceId: 'app-startup-sync' })
4483
4567
  const syncActions = appSync.actions
4484
4568
  // Sync critical data first, then secondary data
4485
4569
  syncActions
@@ -4508,7 +4592,8 @@
4508
4592
  // More examples of user-triggered action lists with conditional logic
4509
4593
  // 4. Conditional action list for error handling
4510
4594
  const recoveryActions = errorScreen.bottomPanel({ numberOfVisibleActions: 1 })
4511
- const retryWorkflow = recoveryActions.add.list({ concurrency: 'sequential',
4595
+ const retryWorkflow = recoveryActions.add.list({
4596
+ concurrency: 'sequential',
4512
4597
  title: 'Retry Operation',
4513
4598
  when: '=@ctx.response.status >= 500',
4514
4599
  })
@@ -5030,7 +5115,10 @@
5030
5115
  // These actions execute automatically during app lifecycle events (onLoad, onFocus, onRefresh)
5031
5116
  // Use app.onLoad.list({ concurrency: 'sequential' }).actions.deleteSyncScope() for background scope cleanup
5032
5117
  // 3. Background sync scope management
5033
- const appActions = app.onLoad.list({ concurrency: 'sequential', instanceId: 'sync-scope-cleanup' }).actions
5118
+ const appActions = app.onLoad.list({
5119
+ concurrency: 'sequential',
5120
+ instanceId: 'sync-scope-cleanup',
5121
+ }).actions
5034
5122
  // Auto-cleanup on app start
5035
5123
  appActions.deleteSyncScope({
5036
5124
  itemId: 'auto-cleanup-temp',
@@ -5115,7 +5203,10 @@
5115
5203
  // These actions execute automatically during app lifecycle events (onLoad, onFocus, onRefresh)
5116
5204
  // Use app.onLoad.list({ concurrency: 'sequential' }).actions.deleteSyncStatus() for background status management
5117
5205
  // 3. Background sync status management
5118
- const appActions = app.onLoad.list({ concurrency: 'sequential', instanceId: 'cleanup-status' }).actions
5206
+ const appActions = app.onLoad.list({
5207
+ concurrency: 'sequential',
5208
+ instanceId: 'cleanup-status',
5209
+ }).actions
5119
5210
  // Auto-cleanup old statuses
5120
5211
  appActions.deleteSyncStatus({
5121
5212
  itemId: 'cleanup-old-statuses',
@@ -7624,7 +7715,7 @@
7624
7715
  when: '=@ctx.solution.state.hasTimeSensitiveFailures',
7625
7716
  })
7626
7717
  // Screen-level retry on focus
7627
- const screenActions = errorDashboard.onFocus.list({ concurrency: 'parallel', }).actions
7718
+ const screenActions = errorDashboard.onFocus.list({ concurrency: 'parallel' }).actions
7628
7719
  // Retry on screen focus
7629
7720
  screenActions.retryQueueCommand({
7630
7721
  commandId: 'focus-retry-failed',
@@ -7815,7 +7906,8 @@
7815
7906
  instanceId: 'track-app-start',
7816
7907
  keys: {
7817
7908
  lastAppStart: '=$now()',
7818
- appStartCount: '=(@ctx.solution.state.appStartCount ? @ctx.solution.state.appStartCount : 0) + 1',
7909
+ appStartCount:
7910
+ '=(@ctx.solution.state.appStartCount ? @ctx.solution.state.appStartCount : 0) + 1',
7819
7911
  },
7820
7912
  })
7821
7913
  // Initialize default state
@@ -7842,7 +7934,8 @@
7842
7934
  instanceId: 'cleanup-on-refresh',
7843
7935
  keys: {
7844
7936
  lastRefreshTime: '=$now()',
7845
- refreshCount: '=(@ctx.solution.state.refreshCount ? @ctx.solution.state.refreshCount : 0) + 1',
7937
+ refreshCount:
7938
+ '=(@ctx.solution.state.refreshCount ? @ctx.solution.state.refreshCount : 0) + 1',
7846
7939
  },
7847
7940
  })
7848
7941
  - id: action.action.set-screen-state
@@ -7895,7 +7988,8 @@
7895
7988
  instanceId: 'track-interaction',
7896
7989
  keys: {
7897
7990
  lastAction: '=@ctx.solution.state.lastAction',
7898
- interactionCount: '=(@ctx.jig.state.interactionCount ? @ctx.jig.state.interactionCount : 0) + 1',
7991
+ interactionCount:
7992
+ '=(@ctx.jig.state.interactionCount ? @ctx.jig.state.interactionCount : 0) + 1',
7899
7993
  sessionTime: '=Date.now() - @ctx.jig.state.sessionStart',
7900
7994
  },
7901
7995
  })
@@ -8947,7 +9041,8 @@
8947
9041
  - icon
8948
9042
  description: Create parallel action list button with icon and primary styling
8949
9043
  code: |-
8950
- const parallel = screen.bottomPanel().add.list({ concurrency: 'parallel',
9044
+ const parallel = screen.bottomPanel().add.list({
9045
+ concurrency: 'parallel',
8951
9046
  title: 'Execute Actions',
8952
9047
  icon: 'play',
8953
9048
  isPrimary: true,
@@ -8964,10 +9059,9 @@
8964
9059
  - sequential
8965
9060
  description: Execute navigation action sequentially in background workflow
8966
9061
  code: |-
8967
- const sequential = screen.bottomPanel().add.list({ concurrency: 'sequential',
8968
- title: 'Test Action List',
8969
- instanceId: 'list-1',
8970
- })
9062
+ const sequential = screen
9063
+ .bottomPanel()
9064
+ .add.list({ concurrency: 'sequential', title: 'Test Action List', instanceId: 'list-1' })
8971
9065
  sequential.actions.goto({ linkTo: 'home' })
8972
9066
  - id: action-list-example-2
8973
9067
  name: Action List Sequential Execution Mode (background)
@@ -8981,7 +9075,8 @@
8981
9075
  - conditional
8982
9076
  description: Execute actions sequentially with conditional when expression
8983
9077
  code: |-
8984
- const sequential = screen.bottomPanel().add.list({ concurrency: 'sequential',
9078
+ const sequential = screen.bottomPanel().add.list({
9079
+ concurrency: 'sequential',
8985
9080
  title: 'Sequential Actions',
8986
9081
  when: '=@ctx.jig.state.canExecute',
8987
9082
  })
@@ -8997,7 +9092,9 @@
8997
9092
  - parallel
8998
9093
  description: Execute multiple actions simultaneously in parallel mode
8999
9094
  code: |-
9000
- const parallel = screen.bottomPanel().add.list({ concurrency: 'parallel', title: 'Test Action List' })
9095
+ const parallel = screen
9096
+ .bottomPanel()
9097
+ .add.list({ concurrency: 'parallel', title: 'Test Action List' })
9001
9098
  parallel.actions.goto({ linkTo: 'home' })
9002
9099
  - id: clear-queue.button-example-1
9003
9100
  name: Clear Queue Button (button)
@@ -20487,8 +20584,10 @@
20487
20584
  categorization and metadata
20488
20585
  code: |-
20489
20586
  // Basic application setup with metadata
20490
- const customerApp = new ApplicationBuilder({ name: 'customer-management', title: 'Customer Management' })
20491
- .with({ category: 'business', description: 'Complete CRM solution for field sales teams' })
20587
+ const customerApp = new ApplicationBuilder({
20588
+ name: 'customer-management',
20589
+ title: 'Customer Management',
20590
+ }).with({ category: 'business', description: 'Complete CRM solution for field sales teams' })
20492
20591
  // Configure database tables for offline storage
20493
20592
  customerApp.addDatabase.default
20494
20593
  .table('customers', 'orders', 'products')
@@ -20573,8 +20672,10 @@
20573
20672
  action: 'sync-customers',
20574
20673
  })
20575
20674
  // E-commerce application example
20576
- const ecommerceApp = new ApplicationBuilder({ name: 'mobile-store', title: 'Mobile Store' })
20577
- .with({ category: 'sales', description: 'Mobile shopping application with product catalog' })
20675
+ const ecommerceApp = new ApplicationBuilder({
20676
+ name: 'mobile-store',
20677
+ title: 'Mobile Store',
20678
+ }).with({ category: 'sales', description: 'Mobile shopping application with product catalog' })
20578
20679
  // Product catalog database
20579
20680
  ecommerceApp.addDatabase.default
20580
20681
  .table('products', 'categories', 'cart')
@@ -20636,8 +20737,9 @@
20636
20737
  application state. Use CTX helpers for building expressions with proper
20637
20738
  syntax and validation
20638
20739
  code: |-
20639
- const contextApp = new ApplicationBuilder({ name: 'context-demo', title: 'Context Demo' })
20640
- .with({ category: 'business', description: 'Demonstrates context and state management patterns' })
20740
+ const contextApp = new ApplicationBuilder({ name: 'context-demo', title: 'Context Demo' }).with(
20741
+ { category: 'business', description: 'Demonstrates context and state management patterns' },
20742
+ )
20641
20743
  // Setup application state and expressions
20642
20744
  contextApp.expression('userRole', '=@ctx.solution.state.userRole')
20643
20745
  contextApp.expression('isLoggedIn', '=@ctx.solution.state.isLoggedIn')
@@ -20655,11 +20757,14 @@
20655
20757
  .query(
20656
20758
  "SELECT id, json_extract(data, '$.message') AS message, json_extract(data, '$.read') AS read FROM [default/notifications]",
20657
20759
  )
20658
- contextApp.addDatasource.static({ datasourceId: 'settings', data: [
20659
- { key: 'theme', value: 'dark' },
20660
- { key: 'language', value: 'en' },
20661
- { key: 'notifications', value: true },
20662
- ] })
20760
+ contextApp.addDatasource.static({
20761
+ datasourceId: 'settings',
20762
+ data: [
20763
+ { key: 'theme', value: 'dark' },
20764
+ { key: 'language', value: 'en' },
20765
+ { key: 'notifications', value: true },
20766
+ ],
20767
+ })
20663
20768
  // Create screens that demonstrate context usage
20664
20769
  const dashboard = contextApp.addScreen.default({
20665
20770
  screenId: 'dashboard',
@@ -20709,7 +20814,10 @@
20709
20814
  value: '=@ctx.datasources.settings[key = "language"].value',
20710
20815
  })
20711
20816
  // Advanced context usage examples
20712
- const advancedApp = new ApplicationBuilder({ name: 'advanced-context', title: 'Advanced Context' }).with({ category: 'analytics' })
20817
+ const advancedApp = new ApplicationBuilder({
20818
+ name: 'advanced-context',
20819
+ title: 'Advanced Context',
20820
+ }).with({ category: 'analytics' })
20713
20821
  // Complex expression using multiple context sources
20714
20822
  advancedApp.expression(
20715
20823
  'userStatus',
@@ -20724,7 +20832,11 @@
20724
20832
  ']',
20725
20833
  )
20726
20834
  // Function call with context parameters
20727
- advancedApp.addFunction.rest({ functionId: 'user-data', method: 'GET', url: 'https://api.example.com/users' })
20835
+ advancedApp.addFunction.rest({
20836
+ functionId: 'user-data',
20837
+ method: 'GET',
20838
+ url: 'https://api.example.com/users',
20839
+ })
20728
20840
  advancedApp.expression('userData', '=@ctx.datasources.userData')
20729
20841
  // Screen with complex state management
20730
20842
  const analyticsScreen = advancedApp.addScreen.default({
@@ -20765,15 +20877,20 @@
20765
20877
  visibility
20766
20878
  code: |-
20767
20879
  // Basic tab navigation setup
20768
- const businessApp = new ApplicationBuilder({ name: 'business-dashboard', title: 'Business Dashboard' })
20769
- .with({ category: 'business', description: 'Complete business management application' })
20880
+ const businessApp = new ApplicationBuilder({
20881
+ name: 'business-dashboard',
20882
+ title: 'Business Dashboard',
20883
+ }).with({ category: 'business', description: 'Complete business management application' })
20770
20884
  // Core navigation tabs with icons and labels
20771
20885
  businessApp.addTab({ screenId: 'home', icon: 'home', label: 'Dashboard' })
20772
20886
  businessApp.addTab({ screenId: 'customers', icon: 'multiple-users-3', label: 'Customers' })
20773
20887
  businessApp.addTab({ screenId: 'orders', icon: 'shopping-cart', label: 'Orders' })
20774
20888
  businessApp.addTab({ screenId: 'reports', icon: 'analytics-graph-bar', label: 'Reports' })
20775
20889
  // Advanced tab configuration with badges and conditions
20776
- const messagingApp = new ApplicationBuilder({ name: 'team-messenger', title: 'Team Messenger' }).with({ category: 'communications' })
20890
+ const messagingApp = new ApplicationBuilder({
20891
+ name: 'team-messenger',
20892
+ title: 'Team Messenger',
20893
+ }).with({ category: 'communications' })
20777
20894
  // Message tab with unread count badge
20778
20895
  messagingApp.addTab({
20779
20896
  screenId: 'messages',
@@ -20798,7 +20915,9 @@
20798
20915
  when: '=@ctx.solution.state.user.role = "admin"',
20799
20916
  })
20800
20917
  // E-commerce app with dynamic badges
20801
- const shopApp = new ApplicationBuilder({ name: 'mobile-shop', title: 'Mobile Shop' }).with({ category: 'sales' })
20918
+ const shopApp = new ApplicationBuilder({ name: 'mobile-shop', title: 'Mobile Shop' }).with({
20919
+ category: 'sales',
20920
+ })
20802
20921
  // Product catalog tab
20803
20922
  shopApp.addTab({ screenId: 'catalog', icon: 'grid-layout-module-1', label: 'Products' })
20804
20923
  // Shopping cart with item count
@@ -20820,7 +20939,9 @@
20820
20939
  // Account tab
20821
20940
  shopApp.addTab({ screenId: 'account', icon: 'single-man-circle', label: 'Account' })
20822
20941
  // Field service app with status-based badges
20823
- const fieldApp = new ApplicationBuilder({ name: 'field-service', title: 'Field Service' }).with({ category: 'field-services' })
20942
+ const fieldApp = new ApplicationBuilder({ name: 'field-service', title: 'Field Service' }).with(
20943
+ { category: 'field-services' },
20944
+ )
20824
20945
  // Tasks tab with priority count
20825
20946
  fieldApp.addTab({
20826
20947
  screenId: 'tasks',
@@ -20950,7 +21071,10 @@
20950
21071
  - category
20951
21072
  - description
20952
21073
  description: Create basic business application with title, category, and description
20953
- code: ".with({ category: 'business', description: 'A test application' })"
21074
+ code: |2-
21075
+ category: 'business',
21076
+ description: 'A test application',
21077
+ })
20954
21078
  - id: application-example-2
20955
21079
  name: Application with Tab Navigation Configuration
20956
21080
  category: application
@@ -21009,7 +21133,10 @@
21009
21133
  description: Build complete application with database tables, SQLite datasource,
21010
21134
  and REST function
21011
21135
  code: |-
21012
- const app: ApplicationBuilder = new ApplicationBuilder({ name: 'complete-app', title: 'Complete App' })
21136
+ const app: ApplicationBuilder = new ApplicationBuilder({
21137
+ name: 'complete-app',
21138
+ title: 'Complete App',
21139
+ })
21013
21140
  // Use the application's bound factories
21014
21141
  app.addDatabase.default.table('users').table('orders')
21015
21142
  app.addDatasource
@@ -21048,8 +21175,12 @@
21048
21175
  - build
21049
21176
  - properties
21050
21177
  description: Create application with description property for app metadata
21051
- code: "const app = new ApplicationBuilder({ name: 'descriptive-app', title:
21052
- 'Descriptive App', description: 'App with detailed description' })"
21178
+ code: |-
21179
+ const app = new ApplicationBuilder({
21180
+ name: 'descriptive-app',
21181
+ title: 'Descriptive App',
21182
+ description: 'App with detailed description',
21183
+ })
21053
21184
  - id: component.jc.left-right.element-1
21054
21185
  name: Left-Side Element Components
21055
21186
  category: component
@@ -23174,11 +23305,14 @@
23174
23305
  .title('=@ctx.current.item.name')
23175
23306
  .value('=@ctx.current.item.id')
23176
23307
  // 2. Choice field with static datasource
23177
- app.addDatasource.static({ datasourceId: 'task-priorities', data: [
23178
- { id: 'low', name: 'Low Priority', color: 'green' },
23179
- { id: 'medium', name: 'Medium Priority', color: 'yellow' },
23180
- { id: 'high', name: 'High Priority', color: 'red' },
23181
- ] })
23308
+ app.addDatasource.static({
23309
+ datasourceId: 'task-priorities',
23310
+ data: [
23311
+ { id: 'low', name: 'Low Priority', color: 'green' },
23312
+ { id: 'medium', name: 'Medium Priority', color: 'yellow' },
23313
+ { id: 'high', name: 'High Priority', color: 'red' },
23314
+ ],
23315
+ })
23182
23316
  const priorityForm = screen.addControl.form({ instanceId: 'priority-form' })
23183
23317
  const priorityChoice = priorityForm.addControl.choiceField({
23184
23318
  instanceId: 'priority-field',
@@ -23378,27 +23512,30 @@
23378
23512
  })
23379
23513
  // 1. Payment method selector (single choice with icons)
23380
23514
  const paymentForm = screen.addControl.form({ instanceId: 'payment' })
23381
- app.addDatasource.static({ datasourceId: 'payment-methods', data: [
23382
- {
23383
- id: 'credit',
23384
- name: 'Credit Card',
23385
- icon: 'credit-card',
23386
- description: 'Visa, MasterCard, Amex',
23387
- },
23388
- {
23389
- id: 'debit',
23390
- name: 'Debit Card',
23391
- icon: 'credit-card-payment',
23392
- description: 'Direct bank payment',
23393
- },
23394
- {
23395
- id: 'paypal',
23396
- name: 'PayPal',
23397
- icon: 'payment-paypal-logo',
23398
- description: 'PayPal account',
23399
- },
23400
- { id: 'apple', name: 'Apple Pay', icon: 'apple', description: 'Touch ID payment' },
23401
- ] })
23515
+ app.addDatasource.static({
23516
+ datasourceId: 'payment-methods',
23517
+ data: [
23518
+ {
23519
+ id: 'credit',
23520
+ name: 'Credit Card',
23521
+ icon: 'credit-card',
23522
+ description: 'Visa, MasterCard, Amex',
23523
+ },
23524
+ {
23525
+ id: 'debit',
23526
+ name: 'Debit Card',
23527
+ icon: 'credit-card-payment',
23528
+ description: 'Direct bank payment',
23529
+ },
23530
+ {
23531
+ id: 'paypal',
23532
+ name: 'PayPal',
23533
+ icon: 'payment-paypal-logo',
23534
+ description: 'PayPal account',
23535
+ },
23536
+ { id: 'apple', name: 'Apple Pay', icon: 'apple', description: 'Touch ID payment' },
23537
+ ],
23538
+ })
23402
23539
  const paymentMethod = paymentForm.addControl.choiceField({
23403
23540
  instanceId: 'payment-method',
23404
23541
  label: 'Payment Method',
@@ -23452,13 +23589,16 @@
23452
23589
  })
23453
23590
  // 3. Size selection with custom layout
23454
23591
  const sizeForm = screen.addControl.form({ instanceId: 'sizing' })
23455
- app.addDatasource.static({ datasourceId: 'sizes', data: [
23456
- { code: 'XS', label: 'Extra Small', available: true },
23457
- { code: 'S', label: 'Small', available: true },
23458
- { code: 'M', label: 'Medium', available: true },
23459
- { code: 'L', label: 'Large', available: false },
23460
- { code: 'XL', label: 'Extra Large', available: true },
23461
- ] })
23592
+ app.addDatasource.static({
23593
+ datasourceId: 'sizes',
23594
+ data: [
23595
+ { code: 'XS', label: 'Extra Small', available: true },
23596
+ { code: 'S', label: 'Small', available: true },
23597
+ { code: 'M', label: 'Medium', available: true },
23598
+ { code: 'L', label: 'Large', available: false },
23599
+ { code: 'XL', label: 'Extra Large', available: true },
23600
+ ],
23601
+ })
23462
23602
  const sizeChoice = sizeForm.addControl.choiceField({
23463
23603
  instanceId: 'size',
23464
23604
  label: 'Size',
@@ -23515,12 +23655,15 @@
23515
23655
  eligibilityCheck: true,
23516
23656
  })
23517
23657
  // Priority level with business constraints
23518
- app.addDatasource.static({ datasourceId: 'priority-levels', data: [
23519
- { level: 'low', name: 'Low Priority', cost: 0 },
23520
- { level: 'normal', name: 'Normal Priority', cost: 10 },
23521
- { level: 'high', name: 'High Priority', cost: 25 },
23522
- { level: 'urgent', name: 'Urgent Priority', cost: 50 },
23523
- ] })
23658
+ app.addDatasource.static({
23659
+ datasourceId: 'priority-levels',
23660
+ data: [
23661
+ { level: 'low', name: 'Low Priority', cost: 0 },
23662
+ { level: 'normal', name: 'Normal Priority', cost: 10 },
23663
+ { level: 'high', name: 'High Priority', cost: 25 },
23664
+ { level: 'urgent', name: 'Urgent Priority', cost: 50 },
23665
+ ],
23666
+ })
23524
23667
  const priorityChoice = planForm.addControl.choiceField({
23525
23668
  instanceId: 'priority-level',
23526
23669
  label: 'Priority Level',
@@ -23608,13 +23751,16 @@
23608
23751
  .title('=@ctx.current.item.name')
23609
23752
  .value('=@ctx.current.item.id')
23610
23753
  // Survey question with conditional follow-up
23611
- app.addDatasource.static({ datasourceId: 'satisfaction-ratings', data: [
23612
- { rating: 1, label: 'Very Dissatisfied', followUp: true },
23613
- { rating: 2, label: 'Dissatisfied', followUp: true },
23614
- { rating: 3, label: 'Neutral', followUp: false },
23615
- { rating: 4, label: 'Satisfied', followUp: false },
23616
- { rating: 5, label: 'Very Satisfied', followUp: false },
23617
- ] })
23754
+ app.addDatasource.static({
23755
+ datasourceId: 'satisfaction-ratings',
23756
+ data: [
23757
+ { rating: 1, label: 'Very Dissatisfied', followUp: true },
23758
+ { rating: 2, label: 'Dissatisfied', followUp: true },
23759
+ { rating: 3, label: 'Neutral', followUp: false },
23760
+ { rating: 4, label: 'Satisfied', followUp: false },
23761
+ { rating: 5, label: 'Very Satisfied', followUp: false },
23762
+ ],
23763
+ })
23618
23764
  const surveyChoice = configForm.addControl.choiceField({
23619
23765
  instanceId: 'satisfaction',
23620
23766
  label: 'How satisfied are you with our service?',
@@ -23629,12 +23775,15 @@
23629
23775
  .title('=@ctx.current.item.label')
23630
23776
  .value('=@ctx.current.item.rating')
23631
23777
  // Accessibility preferences
23632
- app.addDatasource.static({ datasourceId: 'accessibility-features', data: [
23633
- { feature: 'high-contrast', name: 'High Contrast Mode' },
23634
- { feature: 'large-text', name: 'Large Text' },
23635
- { feature: 'screen-reader', name: 'Screen Reader Support' },
23636
- { feature: 'reduced-motion', name: 'Reduced Motion' },
23637
- ] })
23778
+ app.addDatasource.static({
23779
+ datasourceId: 'accessibility-features',
23780
+ data: [
23781
+ { feature: 'high-contrast', name: 'High Contrast Mode' },
23782
+ { feature: 'large-text', name: 'Large Text' },
23783
+ { feature: 'screen-reader', name: 'Screen Reader Support' },
23784
+ { feature: 'reduced-motion', name: 'Reduced Motion' },
23785
+ ],
23786
+ })
23638
23787
  const accessibilityChoice = configForm.addControl.choiceField({
23639
23788
  instanceId: 'accessibility',
23640
23789
  isMultiple: true,
@@ -24563,11 +24712,14 @@
24563
24712
  .subtitle('=@ctx.current.item.description')
24564
24713
  // 2. Dropdown with icon elements
24565
24714
  const priorityForm = screen.addControl.form({ instanceId: 'priority-form' })
24566
- app.addDatasource.static({ datasourceId: 'task-priorities', data: [
24567
- { id: 'low', name: 'Low Priority', icon: 'arrow-down', color: 'green' },
24568
- { id: 'medium', name: 'Medium Priority', icon: 'minus', color: 'yellow' },
24569
- { id: 'high', name: 'High Priority', icon: 'arrow-up', color: 'red' },
24570
- ] })
24715
+ app.addDatasource.static({
24716
+ datasourceId: 'task-priorities',
24717
+ data: [
24718
+ { id: 'low', name: 'Low Priority', icon: 'arrow-down', color: 'green' },
24719
+ { id: 'medium', name: 'Medium Priority', icon: 'minus', color: 'yellow' },
24720
+ { id: 'high', name: 'High Priority', icon: 'arrow-up', color: 'red' },
24721
+ ],
24722
+ })
24571
24723
  const priorityDropdown = priorityForm.addControl.dropdown({
24572
24724
  instanceId: 'priority-dropdown',
24573
24725
  label: 'Task Priority',
@@ -24873,12 +25025,15 @@
24873
25025
  // Icon with color coding for skill category
24874
25026
  .leftElement.icon('=@ctx.current.item.categoryIcon')
24875
25027
  // 3. Project priority with static datasource and time estimates
24876
- app.addDatasource.static({ datasourceId: 'project-priorities', data: [
24877
- { id: 'urgent', display: 'Urgent', sla: '2 hours', color: 'negative', impact: 'critical' },
24878
- { id: 'high', display: 'High Priority', sla: '1 day', color: 'warning', impact: 'major' },
24879
- { id: 'normal', display: 'Normal', sla: '3 days', color: 'primary', impact: 'moderate' },
24880
- { id: 'low', display: 'Low Priority', sla: '1 week', color: 'neutral', impact: 'minor' },
24881
- ] })
25028
+ app.addDatasource.static({
25029
+ datasourceId: 'project-priorities',
25030
+ data: [
25031
+ { id: 'urgent', display: 'Urgent', sla: '2 hours', color: 'negative', impact: 'critical' },
25032
+ { id: 'high', display: 'High Priority', sla: '1 day', color: 'warning', impact: 'major' },
25033
+ { id: 'normal', display: 'Normal', sla: '3 days', color: 'primary', impact: 'moderate' },
25034
+ { id: 'low', display: 'Low Priority', sla: '1 week', color: 'neutral', impact: 'minor' },
25035
+ ],
25036
+ })
24882
25037
  const priorityDropdown = form.addControl.dropdown({
24883
25038
  instanceId: 'priority',
24884
25039
  isRequired: true,
@@ -24962,11 +25117,14 @@
24962
25117
  screenId: 'dropdown-test',
24963
25118
  title: 'Dropdown Test',
24964
25119
  })
24965
- app.addDatasource.static({ datasourceId: 'test-options', data: [
24966
- { title: 'Option 1', value: 'option1' },
24967
- { title: 'Option 2', value: 'option2' },
24968
- { title: 'Option 3', value: 'option3' },
24969
- ] })
25120
+ app.addDatasource.static({
25121
+ datasourceId: 'test-options',
25122
+ data: [
25123
+ { title: 'Option 1', value: 'option1' },
25124
+ { title: 'Option 2', value: 'option2' },
25125
+ { title: 'Option 3', value: 'option3' },
25126
+ ],
25127
+ })
24970
25128
  const dropdown = form.addControl.dropdown({
24971
25129
  instanceId: 'test-dropdown',
24972
25130
  isMultiple: true,
@@ -25030,10 +25188,13 @@
25030
25188
  screenId: 'inline-test',
25031
25189
  title: 'Inline Test',
25032
25190
  })
25033
- app.addDatasource.static({ datasourceId: 'inline-options', data: [
25034
- { id: 1, name: 'Option 1', active: true },
25035
- { id: 2, name: 'Option 2', active: false },
25036
- ] })
25191
+ app.addDatasource.static({
25192
+ datasourceId: 'inline-options',
25193
+ data: [
25194
+ { id: 1, name: 'Option 1', active: true },
25195
+ { id: 2, name: 'Option 2', active: false },
25196
+ ],
25197
+ })
25037
25198
  const inlineDropdown = form.addControl.dropdown({
25038
25199
  instanceId: 'inline',
25039
25200
  when: '=@ctx.solution.state.canSelect',
@@ -25643,7 +25804,11 @@
25643
25804
  const statusSection = screen.addControl.section({ instanceId: 'system-status' })
25644
25805
  const statusEntity = statusSection.addControl.entity({ instanceId: 'status-entity' })
25645
25806
  statusEntity.addControl
25646
- .entityField({ instanceId: 'server-status', label: 'Server Status', value: '=@ctx.jig.inputs.status' })
25807
+ .entityField({
25808
+ instanceId: 'server-status',
25809
+ label: 'Server Status',
25810
+ value: '=@ctx.jig.inputs.status',
25811
+ })
25647
25812
  .with({
25648
25813
  style: {
25649
25814
  isPositive: '=@ctx.jig.inputs.status = "Online"',
@@ -25755,7 +25920,10 @@
25755
25920
  label: 'Total Revenue',
25756
25921
  value: '="$" & $string(@ctx.jig.inputs.totalRevenue)',
25757
25922
  })
25758
- .with({ style: { isPrimary: true, isPositive: '=@ctx.jig.inputs.revenueGrowth > 0' }, rightIcon: 'arrow-up' })
25923
+ .with({
25924
+ style: { isPrimary: true, isPositive: '=@ctx.jig.inputs.revenueGrowth > 0' },
25925
+ rightIcon: 'arrow-up',
25926
+ })
25759
25927
  financialEntity.addControl.entityField({
25760
25928
  instanceId: 'profit-margin',
25761
25929
  label: 'Profit Margin',
@@ -25908,7 +26076,11 @@
25908
26076
  rightIcon: 'hash',
25909
26077
  })
25910
26078
  productEntity.addControl
25911
- .entityField({ instanceId: 'price', label: 'Price', value: '="$" & @ctx.entity.product.price' })
26079
+ .entityField({
26080
+ instanceId: 'price',
26081
+ label: 'Price',
26082
+ value: '="$" & @ctx.entity.product.price',
26083
+ })
25912
26084
  .with({ style: { isPositive: '=@ctx.entity.product.onSale' }, rightIcon: 'money-atm' })
25913
26085
  productEntity.addControl.entityField({
25914
26086
  instanceId: 'availability',
@@ -26038,7 +26210,8 @@
26038
26210
  value: '=@ctx.entity.device.batteryLevel & "%"',
26039
26211
  style: {
26040
26212
  isPositive: '=@ctx.entity.device.batteryLevel > 50',
26041
- isWarning: '=@ctx.entity.device.batteryLevel > 20 and @ctx.entity.device.batteryLevel <= 50',
26213
+ isWarning:
26214
+ '=@ctx.entity.device.batteryLevel > 20 and @ctx.entity.device.batteryLevel <= 50',
26042
26215
  isNegative: '=@ctx.entity.device.batteryLevel <= 20',
26043
26216
  },
26044
26217
  rightIcon: 'battery-full',
@@ -26119,7 +26292,8 @@
26119
26292
  value: '=@ctx.entity.customer.healthScore & "/100"',
26120
26293
  style: {
26121
26294
  isPositive: '=@ctx.entity.customer.healthScore >= 80',
26122
- isWarning: '=@ctx.entity.customer.healthScore >= 60 and @ctx.entity.customer.healthScore < 80',
26295
+ isWarning:
26296
+ '=@ctx.entity.customer.healthScore >= 60 and @ctx.entity.customer.healthScore < 80',
26123
26297
  isNegative: '=@ctx.entity.customer.healthScore < 60',
26124
26298
  },
26125
26299
  rightIcon: 'gift-heart',
@@ -26890,12 +27064,10 @@
26890
27064
  value: '=@ctx.jig.state.price',
26891
27065
  format: { numberStyle: 'currency', currency: 'USD' },
26892
27066
  })
26893
- app.addDatasource.static({ datasourceId: 'product-categories', data: [
26894
- { name: 'Electronics' },
26895
- { name: 'Clothing' },
26896
- { name: 'Books' },
26897
- { name: 'Home' },
26898
- ] })
27067
+ app.addDatasource.static({
27068
+ datasourceId: 'product-categories',
27069
+ data: [{ name: 'Electronics' }, { name: 'Clothing' }, { name: 'Books' }, { name: 'Home' }],
27070
+ })
26899
27071
  productRow.addControl
26900
27072
  .dropdown({
26901
27073
  instanceId: 'category',
@@ -27084,11 +27256,14 @@
27084
27256
  const settingsForm = screen.addControl.form({ instanceId: 'app-settings' })
27085
27257
  const appearanceSection = settingsForm.addControl.section({ instanceId: 'appearance' })
27086
27258
  appearanceSection.title('Appearance')
27087
- app.addDatasource.static({ datasourceId: 'themes', data: [
27088
- { label: 'Light', value: 'light' },
27089
- { label: 'Dark', value: 'dark' },
27090
- { label: 'Auto', value: 'auto' },
27091
- ] })
27259
+ app.addDatasource.static({
27260
+ datasourceId: 'themes',
27261
+ data: [
27262
+ { label: 'Light', value: 'light' },
27263
+ { label: 'Dark', value: 'dark' },
27264
+ { label: 'Auto', value: 'auto' },
27265
+ ],
27266
+ })
27092
27267
  const themeDropdown = appearanceSection.addControl.dropdown({
27093
27268
  instanceId: 'theme',
27094
27269
  label: 'Theme',
@@ -27147,12 +27322,15 @@
27147
27322
  errorText: 'Please enter a valid email address',
27148
27323
  })
27149
27324
  // Dropdown with validation
27150
- app.addDatasource.static({ datasourceId: 'priorities', data: [
27151
- { label: 'Low', value: 'low' },
27152
- { label: 'Normal', value: 'normal' },
27153
- { label: 'High', value: 'high' },
27154
- { label: 'Urgent', value: 'urgent' },
27155
- ] })
27325
+ app.addDatasource.static({
27326
+ datasourceId: 'priorities',
27327
+ data: [
27328
+ { label: 'Low', value: 'low' },
27329
+ { label: 'Normal', value: 'normal' },
27330
+ { label: 'High', value: 'high' },
27331
+ { label: 'Urgent', value: 'urgent' },
27332
+ ],
27333
+ })
27156
27334
  const priorityDropdown = contactForm.addControl.dropdown({
27157
27335
  instanceId: 'priority',
27158
27336
  isRequired: true,
@@ -27193,11 +27371,14 @@
27193
27371
  isDiscardChangesAlertEnabled: false,
27194
27372
  })
27195
27373
  // Account type selector affects other fields
27196
- app.addDatasource.static({ datasourceId: 'account-types', data: [
27197
- { label: 'Personal', value: 'personal' },
27198
- { label: 'Business', value: 'business' },
27199
- { label: 'Enterprise', value: 'enterprise' },
27200
- ] })
27374
+ app.addDatasource.static({
27375
+ datasourceId: 'account-types',
27376
+ data: [
27377
+ { label: 'Personal', value: 'personal' },
27378
+ { label: 'Business', value: 'business' },
27379
+ { label: 'Enterprise', value: 'enterprise' },
27380
+ ],
27381
+ })
27201
27382
  const accountTypeDropdown = dynamicForm.addControl.dropdown({
27202
27383
  instanceId: 'account-type',
27203
27384
  isRequired: true,
@@ -27554,7 +27735,10 @@
27554
27735
  .interactiveImageItem({
27555
27736
  instanceId: 'room-marker',
27556
27737
  title: '=@ctx.current.item.roomName',
27557
- percentageCoordinates: { x: '=@ctx.current.item.xPercent', y: '=@ctx.current.item.yPercent' },
27738
+ percentageCoordinates: {
27739
+ x: '=@ctx.current.item.xPercent',
27740
+ y: '=@ctx.current.item.yPercent',
27741
+ },
27558
27742
  })
27559
27743
  .with({ color: '=@ctx.current.item.statusColor' })
27560
27744
  roomItem.onPress.goto({
@@ -27650,7 +27834,10 @@
27650
27834
  .interactiveImageItem({
27651
27835
  instanceId: 'store-marker',
27652
27836
  groupId: '=@ctx.current.item.category',
27653
- percentageCoordinates: { x: '=@ctx.current.item.locationX', y: '=@ctx.current.item.locationY' },
27837
+ percentageCoordinates: {
27838
+ x: '=@ctx.current.item.locationX',
27839
+ y: '=@ctx.current.item.locationY',
27840
+ },
27654
27841
  })
27655
27842
  .with({ title: '=@ctx.current.item.storeName' })
27656
27843
  storeItem.onPress.goto({
@@ -27687,7 +27874,9 @@
27687
27874
  title: '=@ctx.current.item.departmentName',
27688
27875
  groupId: '=@ctx.current.item.zone',
27689
27876
  })
27690
- .with({ percentageCoordinates: { x: '=@ctx.current.item.coordX', y: '=@ctx.current.item.coordY' } })
27877
+ .with({
27878
+ percentageCoordinates: { x: '=@ctx.current.item.coordX', y: '=@ctx.current.item.coordY' },
27879
+ })
27691
27880
  departmentItem.onPress
27692
27881
  .executeEntity({ instanceId: 'show-department-info' })
27693
27882
  .dynamicData('default/departments', 'update')
@@ -27764,7 +27953,10 @@
27764
27953
  instanceId: 'sensor-marker',
27765
27954
  title: '=@ctx.current.item.sensorId',
27766
27955
  groupId: '=@ctx.current.item.sensorType',
27767
- percentageCoordinates: { x: '=@ctx.current.item.positionX', y: '=@ctx.current.item.positionY' },
27956
+ percentageCoordinates: {
27957
+ x: '=@ctx.current.item.positionX',
27958
+ y: '=@ctx.current.item.positionY',
27959
+ },
27768
27960
  color:
27769
27961
  "=@ctx.current.item.alertLevel = 'critical' ? 'negative' : (@ctx.current.item.alertLevel = 'warning' ? 'warning' : 'positive')",
27770
27962
  })
@@ -27863,10 +28055,12 @@
27863
28055
  })
27864
28056
  const locationHeader = locationScreen.header()
27865
28057
  locationHeader.with({ height: 'small' })
27866
- locationHeader.addControl.location({ instanceId: 'header-map' }).with({ viewPoint:{
27867
- latitude: 40.7128,
27868
- longitude: -74.006,
27869
- }})
28058
+ locationHeader.addControl.location({ instanceId: 'header-map' }).with({
28059
+ viewPoint: {
28060
+ latitude: 40.7128,
28061
+ longitude: -74.006,
28062
+ },
28063
+ })
27870
28064
  locationHeader.actions.goBack({ title: 'Back' })
27871
28065
  locationHeader.actions.openUrl({
27872
28066
  title: 'Directions',
@@ -27879,12 +28073,10 @@
27879
28073
  })
27880
28074
  const videoHeader = videoScreen.header()
27881
28075
  videoHeader.with({ height: 'medium' })
27882
- videoHeader.addControl
27883
- .videoPlayer({ instanceId: 'header-video' })
27884
- .with({
27885
- url: '=@ctx.solution.state.media.headerVideoUrl',
27886
- title: '=@ctx.solution.state.media.videoTitle',
27887
- })
28076
+ videoHeader.addControl.videoPlayer({ instanceId: 'header-video' }).with({
28077
+ url: '=@ctx.solution.state.media.headerVideoUrl',
28078
+ title: '=@ctx.solution.state.media.videoTitle',
28079
+ })
27888
28080
  videoHeader.actions.goto({ title: 'Full Video', linkTo: 'video-screen' })
27889
28081
  // 4. Action screen with multiple actions
27890
28082
  const actionScreen = app.addScreen.default({
@@ -27927,10 +28119,12 @@
27927
28119
  })
27928
28120
  const venueHeader = venueScreen.header()
27929
28121
  venueHeader.with({ height: 'medium' })
27930
- venueHeader.addControl.location({ instanceId: 'venue-location' }).with({ viewPoint:{
27931
- latitude: '=@ctx.solution.state.venue.coordinates.latitude',
27932
- longitude: '=@ctx.solution.state.venue.coordinates.longitude',
27933
- }})
28122
+ venueHeader.addControl.location({ instanceId: 'venue-location' }).with({
28123
+ viewPoint: {
28124
+ latitude: '=@ctx.solution.state.venue.coordinates.latitude',
28125
+ longitude: '=@ctx.solution.state.venue.coordinates.longitude',
28126
+ },
28127
+ })
27934
28128
  venueHeader.actions.goBack({ title: 'Back to List' })
27935
28129
  venueHeader.actions.openUrl({
27936
28130
  title: 'Get Directions',
@@ -27944,12 +28138,10 @@
27944
28138
  })
27945
28139
  const galleryHeader = galleryScreen.header()
27946
28140
  galleryHeader.with({ height: 'medium' })
27947
- galleryHeader.addControl
27948
- .videoPlayer({ instanceId: 'gallery-preview' })
27949
- .with({
27950
- url: '=@ctx.solution.state.gallery.featuredVideoUrl',
27951
- title: '=@ctx.solution.state.gallery.videoTitle',
27952
- })
28141
+ galleryHeader.addControl.videoPlayer({ instanceId: 'gallery-preview' }).with({
28142
+ url: '=@ctx.solution.state.gallery.featuredVideoUrl',
28143
+ title: '=@ctx.solution.state.gallery.videoTitle',
28144
+ })
27953
28145
  galleryHeader.actions.goBack({ title: 'Back to Gallery' })
27954
28146
  galleryHeader.actions.goto({ title: 'Full Screen', linkTo: 'fullscreen-video' })
27955
28147
  // Dashboard header with branding
@@ -28019,10 +28211,12 @@
28019
28211
  })
28020
28212
  const mapHeader = mapScreen.header()
28021
28213
  mapHeader.with({ height: 'medium' })
28022
- mapHeader.addControl.location({ instanceId: 'main-location' }).with({ viewPoint:{
28023
- latitude: '=@ctx.solution.state.userLocation.latitude',
28024
- longitude: '=@ctx.solution.state.userLocation.longitude',
28025
- }})
28214
+ mapHeader.addControl.location({ instanceId: 'main-location' }).with({
28215
+ viewPoint: {
28216
+ latitude: '=@ctx.solution.state.userLocation.latitude',
28217
+ longitude: '=@ctx.solution.state.userLocation.longitude',
28218
+ },
28219
+ })
28026
28220
  mapHeader.actions.goBack({ title: 'Back' })
28027
28221
  mapHeader.actions.goto({ title: 'Nearby', linkTo: 'nearby-screen' })
28028
28222
  // Media header for entertainment apps
@@ -28032,12 +28226,10 @@
28032
28226
  })
28033
28227
  const mediaHeader = mediaScreen.header()
28034
28228
  mediaHeader.with({ height: 'medium' })
28035
- mediaHeader.addControl
28036
- .videoPlayer({ instanceId: 'featured-content' })
28037
- .with({
28038
- url: '=@ctx.solution.state.media.featuredVideoUrl',
28039
- title: '=@ctx.solution.state.media.videoTitle',
28040
- })
28229
+ mediaHeader.addControl.videoPlayer({ instanceId: 'featured-content' }).with({
28230
+ url: '=@ctx.solution.state.media.featuredVideoUrl',
28231
+ title: '=@ctx.solution.state.media.videoTitle',
28232
+ })
28041
28233
  mediaHeader.actions.goBack({ title: 'Back to Library' })
28042
28234
  mediaHeader.actions.goto({ title: 'Related Content', linkTo: 'related-screen' })
28043
28235
  // Minimal header for form screens
@@ -29051,7 +29243,8 @@
29051
29243
  })
29052
29244
  vehicleMarker.addIcon({
29053
29245
  icon: "=@ctx.current.item.vehicleType = 'truck' ? 'truck' : 'car'",
29054
- color: "=@ctx.current.item.status = 'active' ? 'positive' : (@ctx.current.item.status = 'maintenance' ? 'warning' : 'negative')",
29246
+ color:
29247
+ "=@ctx.current.item.status = 'active' ? 'positive' : (@ctx.current.item.status = 'maintenance' ? 'warning' : 'negative')",
29055
29248
  })
29056
29249
  // Field service territories
29057
29250
  const serviceSection = screen.addControl.section({ instanceId: 'service-territories' })
@@ -29075,7 +29268,8 @@
29075
29268
  })
29076
29269
  appointmentMarker.addIcon({
29077
29270
  icon: "=@ctx.current.item.priority = 'urgent' ? 'alert' : 'wrench'",
29078
- color: "=@ctx.current.item.status = 'scheduled' ? 'color1' : (@ctx.current.item.status = 'in-progress' ? 'warning' : 'positive')",
29271
+ color:
29272
+ "=@ctx.current.item.status = 'scheduled' ? 'color1' : (@ctx.current.item.status = 'in-progress' ? 'warning' : 'positive')",
29079
29273
  })
29080
29274
  // Emergency response system
29081
29275
  const emergencySection = screen.addControl.section({ instanceId: 'emergency-response' })
@@ -29101,7 +29295,8 @@
29101
29295
  })
29102
29296
  incidentMarker.addIcon({
29103
29297
  icon: "=@ctx.current.item.severity = 'critical' ? 'alert-triangle' : 'information-circle'",
29104
- color: "=@ctx.current.item.severity = 'critical' ? 'negative' : (@ctx.current.item.severity = 'high' ? 'warning' : 'positive')",
29298
+ color:
29299
+ "=@ctx.current.item.severity = 'critical' ? 'negative' : (@ctx.current.item.severity = 'high' ? 'warning' : 'positive')",
29105
29300
  })
29106
29301
  // Asset tracking with geofencing
29107
29302
  const assetSection = screen.addControl.section({ instanceId: 'asset-tracking' })
@@ -29160,18 +29355,16 @@
29160
29355
  .dynamicData('default/selected_locations', 'update')
29161
29356
  // Location-aware content
29162
29357
  const contentSection = screen.addControl.section({ instanceId: 'location-content' })
29163
- const contextMap = contentSection.addControl
29164
- .location({ instanceId: 'contextual-map' })
29165
- .with({
29166
- markersData: '=@ctx.datasources.nearby_points_of_interest',
29167
- viewPoint: {
29168
- latitude: '=@ctx.solution.state.userLatitude',
29169
- longitude: '=@ctx.solution.state.userLongitude',
29170
- zoomLevel: '=@ctx.solution.state.preferredZoom',
29171
- centerPosition: 'middle',
29172
- isFollowUserLocationEnabled: '=@ctx.solution.state.trackUserMovement',
29173
- },
29174
- })
29358
+ const contextMap = contentSection.addControl.location({ instanceId: 'contextual-map' }).with({
29359
+ markersData: '=@ctx.datasources.nearby_points_of_interest',
29360
+ viewPoint: {
29361
+ latitude: '=@ctx.solution.state.userLatitude',
29362
+ longitude: '=@ctx.solution.state.userLongitude',
29363
+ zoomLevel: '=@ctx.solution.state.preferredZoom',
29364
+ centerPosition: 'middle',
29365
+ isFollowUserLocationEnabled: '=@ctx.solution.state.trackUserMovement',
29366
+ },
29367
+ })
29175
29368
  const poiMarker = contextMap.addControl.markerItem({
29176
29369
  instanceId: 'poi-marker',
29177
29370
  latitude: '=@ctx.current.item.position.lat',
@@ -29203,7 +29396,8 @@
29203
29396
  })
29204
29397
  comparisonMarker.addIcon({
29205
29398
  icon: "=@ctx.current.item.isSelected ? 'check-circle' : 'circle'",
29206
- color: "=@ctx.current.item.rank <= 3 ? 'positive' : (@ctx.current.item.rank <= 6 ? 'warning' : 'color2')",
29399
+ color:
29400
+ "=@ctx.current.item.rank <= 3 ? 'positive' : (@ctx.current.item.rank <= 6 ? 'warning' : 'color2')",
29207
29401
  })
29208
29402
  // Dynamic location clustering
29209
29403
  const clusterSection = screen.addControl.section({ instanceId: 'location-clusters' })
@@ -29230,7 +29424,8 @@
29230
29424
  })
29231
29425
  clusterMarker.addIcon({
29232
29426
  icon: "=@ctx.current.item.count > 10 ? 'layers' : 'pin-map'",
29233
- color: "=@ctx.current.item.density = 'high' ? 'negative' : (@ctx.current.item.density = 'medium' ? 'warning' : 'positive')",
29427
+ color:
29428
+ "=@ctx.current.item.density = 'high' ? 'negative' : (@ctx.current.item.density = 'medium' ? 'warning' : 'positive')",
29234
29429
  })
29235
29430
  - id: component.component.marker-item-1
29236
29431
  name: Map Marker Component
@@ -29270,7 +29465,9 @@
29270
29465
  latitude: '=@ctx.current.item.latitude',
29271
29466
  longitude: '=@ctx.current.item.longitude',
29272
29467
  })
29273
- .with({ radius: { value: '=@ctx.current.item.serviceRadius', unit: 'miles', color: 'positive' } })
29468
+ .with({
29469
+ radius: { value: '=@ctx.current.item.serviceRadius', unit: 'miles', color: 'positive' },
29470
+ })
29274
29471
  customerMarker.addIcon({ icon: '=@ctx.current.item.markerIcon' })
29275
29472
  - id: component.component.marker-item-2
29276
29473
  name: Advanced Marker Configurations
@@ -29306,7 +29503,14 @@
29306
29503
  latitude: '=@ctx.current.item.centerLat',
29307
29504
  longitude: '=@ctx.current.item.centerLng',
29308
29505
  })
29309
- .with({ radius: { value: '=@ctx.current.item.coverageRadius', unit: 'meters', color: '=(@ctx.current.item.isActive) ? "positive" : "neutral"', isEnabled: '=@ctx.current.item.showCoverage' } })
29506
+ .with({
29507
+ radius: {
29508
+ value: '=@ctx.current.item.coverageRadius',
29509
+ unit: 'meters',
29510
+ color: '=(@ctx.current.item.isActive) ? "positive" : "neutral"',
29511
+ isEnabled: '=@ctx.current.item.showCoverage',
29512
+ },
29513
+ })
29310
29514
  dynamicZone.addIcon({ icon: '=@ctx.current.item.zoneType' })
29311
29515
  - id: component.component.marker-item-3
29312
29516
  name: Marker Builder Patterns
@@ -31154,11 +31358,13 @@
31154
31358
  .with({
31155
31359
  left: {
31156
31360
  title: 'Last Month',
31157
- subtitle: '=@ctx.current.item.metrics.previousMonth.value & @ctx.current.item.metrics.unit',
31361
+ subtitle:
31362
+ '=@ctx.current.item.metrics.previousMonth.value & @ctx.current.item.metrics.unit',
31158
31363
  },
31159
31364
  right: {
31160
31365
  title: 'This Month',
31161
- subtitle: '=@ctx.current.item.metrics.currentMonth.value & @ctx.current.item.metrics.unit',
31366
+ subtitle:
31367
+ '=@ctx.current.item.metrics.currentMonth.value & @ctx.current.item.metrics.unit',
31162
31368
  },
31163
31369
  })
31164
31370
  performanceStage.onPress.goto({
@@ -34033,10 +34239,13 @@
34033
34239
  description: Create choice field item referencing a static datasource with
34034
34240
  dynamic title expressions
34035
34241
  code: |-
34036
- app.addDatasource.static({ datasourceId: 'inline-options', data: [
34037
- { id: 'x', label: 'X' },
34038
- { id: 'y', label: 'Y' },
34039
- ] })
34242
+ app.addDatasource.static({
34243
+ datasourceId: 'inline-options',
34244
+ data: [
34245
+ { id: 'x', label: 'X' },
34246
+ { id: 'y', label: 'Y' },
34247
+ ],
34248
+ })
34040
34249
  const choices = screen.addControl.choiceField({
34041
34250
  instanceId: 'inline-choices',
34042
34251
  data: '=@ctx.datasources.inline-options',
@@ -34117,10 +34326,13 @@
34117
34326
  - options
34118
34327
  description: Create choice field referencing a static datasource
34119
34328
  code: |-
34120
- app.addDatasource.static({ datasourceId: 'choice-options', data: [
34121
- { id: 'a', label: 'A' },
34122
- { id: 'b', label: 'B' },
34123
- ] })
34329
+ app.addDatasource.static({
34330
+ datasourceId: 'choice-options',
34331
+ data: [
34332
+ { id: 'a', label: 'A' },
34333
+ { id: 'b', label: 'B' },
34334
+ ],
34335
+ })
34124
34336
  const choices = screen.addControl.choiceField({
34125
34337
  instanceId: 'inline-choices',
34126
34338
  label: 'Inline',
@@ -34608,11 +34820,14 @@
34608
34820
  - required
34609
34821
  description: Create required country dropdown referencing a static datasource
34610
34822
  code: |-
34611
- app.addDatasource.static({ datasourceId: 'countries', data: [
34612
- { countryCode: 'US', countryName: 'United States' },
34613
- { countryCode: 'CA', countryName: 'Canada' },
34614
- { countryCode: 'MX', countryName: 'Mexico' },
34615
- ] })
34823
+ app.addDatasource.static({
34824
+ datasourceId: 'countries',
34825
+ data: [
34826
+ { countryCode: 'US', countryName: 'United States' },
34827
+ { countryCode: 'CA', countryName: 'Canada' },
34828
+ { countryCode: 'MX', countryName: 'Mexico' },
34829
+ ],
34830
+ })
34616
34831
  const dropdown = screen.addControl.dropdown({
34617
34832
  instanceId: 'country-select',
34618
34833
  isRequired: true,
@@ -34794,7 +35009,11 @@
34794
35009
  user profile display
34795
35010
  code: |-
34796
35011
  const userEntity = screen.addControl.entity()
34797
- userEntity.addControl.entityField({ instanceId: 'name-field', label: 'Name', value: 'John Doe' })
35012
+ userEntity.addControl.entityField({
35013
+ instanceId: 'name-field',
35014
+ label: 'Name',
35015
+ value: 'John Doe',
35016
+ })
34798
35017
  userEntity.addControl
34799
35018
  .entityField({ instanceId: 'email-field', label: 'Email' })
34800
35019
  .with({ value: 'john@example.com' })
@@ -34816,11 +35035,19 @@
34816
35035
  instanceId: 'product-entity',
34817
35036
  isCompact: true,
34818
35037
  })
34819
- productEntity.addControl.entityField({ instanceId: 'product-name', label: 'Product Name', value: 'Laptop' })
35038
+ productEntity.addControl.entityField({
35039
+ instanceId: 'product-name',
35040
+ label: 'Product Name',
35041
+ value: 'Laptop',
35042
+ })
34820
35043
  productEntity.addControl
34821
35044
  .entityField({ instanceId: 'product-price', label: 'Price' })
34822
35045
  .with({ value: '$999.99' })
34823
- productEntity.addControl.entityField({ instanceId: 'product-stock', label: 'In Stock', value: 'Yes' })
35046
+ productEntity.addControl.entityField({
35047
+ instanceId: 'product-stock',
35048
+ label: 'In Stock',
35049
+ value: 'Yes',
35050
+ })
34824
35051
  - id: jc.event-example-1
34825
35052
  name: Team Meeting Event with Full Details
34826
35053
  category: component
@@ -36274,7 +36501,10 @@
36274
36501
  },
36275
36502
  markersData: '=@ctx.datasources.locations',
36276
36503
  })
36277
- .with({ isShowUserLocationEnabled: '=@ctx.jig.state.map.showUser', paths: '=@ctx.datasources.routes' })
36504
+ .with({
36505
+ isShowUserLocationEnabled: '=@ctx.jig.state.map.showUser',
36506
+ paths: '=@ctx.datasources.routes',
36507
+ })
36278
36508
  - id: jc.location-example-8
36279
36509
  name: Location Maps with Different Radius Unit Types
36280
36510
  category: component
@@ -37802,7 +38032,10 @@
37802
38032
  sync across devices and users
37803
38033
  code: |-
37804
38034
  // Dynamic SQLite datasource - synced across devices for collaborative data
37805
- const customerData = app.addDatasource.sqlite({ datasourceId: 'customers', provider: 'dynamic' })
38035
+ const customerData = app.addDatasource.sqlite({
38036
+ datasourceId: 'customers',
38037
+ provider: 'dynamic',
38038
+ })
37806
38039
  customerData.entity('default/customers')
37807
38040
  customerData.query(`
37808
38041
  SELECT
@@ -37834,7 +38067,10 @@
37834
38067
  orderData.queryParameter('minAmount', 100)
37835
38068
  orderData.queryParameter('maxResults', 50)
37836
38069
  // Multiple entities with relationships
37837
- const inventoryData = app.addDatasource.sqlite({ datasourceId: 'inventory', provider: 'dynamic' })
38070
+ const inventoryData = app.addDatasource.sqlite({
38071
+ datasourceId: 'inventory',
38072
+ provider: 'dynamic',
38073
+ })
37838
38074
  inventoryData.entity('default/products')
37839
38075
  inventoryData.entity('default/categories')
37840
38076
  inventoryData.query(`
@@ -37850,7 +38086,10 @@
37850
38086
  WHERE json_extract(p.data, '$.active') = true
37851
38087
  `)
37852
38088
  // Single document mode - for detail views and singleton data
37853
- const customerDetail = app.addDatasource.sqlite({ datasourceId: 'customer-detail', provider: 'dynamic' })
38089
+ const customerDetail = app.addDatasource.sqlite({
38090
+ datasourceId: 'customer-detail',
38091
+ provider: 'dynamic',
38092
+ })
37854
38093
  customerDetail.entity('default/customers')
37855
38094
  customerDetail.query(`
37856
38095
  SELECT
@@ -37866,7 +38105,10 @@
37866
38105
  customerDetail.jsonProperties('data')
37867
38106
  customerDetail.isDocument(true) // Returns single document instead of array
37868
38107
  // Dashboard statistics - single aggregated row
37869
- const dashboardStats = app.addDatasource.sqlite({ datasourceId: 'dashboard-stats', provider: 'dynamic' })
38108
+ const dashboardStats = app.addDatasource.sqlite({
38109
+ datasourceId: 'dashboard-stats',
38110
+ provider: 'dynamic',
38111
+ })
37870
38112
  dashboardStats.entity('default/orders')
37871
38113
  dashboardStats.query(`
37872
38114
  SELECT
@@ -37895,7 +38137,10 @@
37895
38137
  device-specific information
37896
38138
  code: |-
37897
38139
  // Local SQLite datasource - device-only storage for preferences and temporary data
37898
- const userPrefs = app.addDatasource.sqlite({ datasourceId: 'user-preferences', provider: 'local' })
38140
+ const userPrefs = app.addDatasource.sqlite({
38141
+ datasourceId: 'user-preferences',
38142
+ provider: 'local',
38143
+ })
37899
38144
  userPrefs.entity('preferences')
37900
38145
  userPrefs.query(`
37901
38146
  SELECT
@@ -37922,7 +38167,10 @@
37922
38167
  `)
37923
38168
  localCache.queryParameter('currentTime', '=@ctx.solution.state.currentTimestamp')
37924
38169
  // Device-specific settings and configuration
37925
- const deviceSettings = app.addDatasource.sqlite({ datasourceId: 'device-settings', provider: 'local' })
38170
+ const deviceSettings = app.addDatasource.sqlite({
38171
+ datasourceId: 'device-settings',
38172
+ provider: 'local',
38173
+ })
37926
38174
  deviceSettings.entity('settings')
37927
38175
  deviceSettings.query(`
37928
38176
  SELECT
@@ -37951,99 +38199,111 @@
37951
38199
  doesn't require database storage
37952
38200
  code: |-
37953
38201
  // Basic static datasource for dropdown options
37954
- app.addDatasource.static({ datasourceId: 'order-statuses', data: [
37955
- { id: 'pending', label: 'Pending Review', color: '#FFA500' },
37956
- { id: 'approved', label: 'Approved', color: '#28A745' },
37957
- { id: 'rejected', label: 'Rejected', color: '#DC3545' },
37958
- { id: 'processing', label: 'Processing', color: '#17A2B8' },
37959
- { id: 'completed', label: 'Completed', color: '#6F42C1' },
37960
- ] })
38202
+ app.addDatasource.static({
38203
+ datasourceId: 'order-statuses',
38204
+ data: [
38205
+ { id: 'pending', label: 'Pending Review', color: '#FFA500' },
38206
+ { id: 'approved', label: 'Approved', color: '#28A745' },
38207
+ { id: 'rejected', label: 'Rejected', color: '#DC3545' },
38208
+ { id: 'processing', label: 'Processing', color: '#17A2B8' },
38209
+ { id: 'completed', label: 'Completed', color: '#6F42C1' },
38210
+ ],
38211
+ })
37961
38212
  // Configuration options for app settings
37962
- app.addDatasource.static({ datasourceId: 'theme-options', data: [
37963
- {
37964
- id: 'light',
37965
- name: 'Light Theme',
37966
- description: 'Clean bright interface',
37967
- primaryColor: '#007BFF',
37968
- backgroundColor: '#FFFFFF',
37969
- },
37970
- {
37971
- id: 'dark',
37972
- name: 'Dark Theme',
37973
- description: 'Easy on the eyes',
37974
- primaryColor: '#BB86FC',
37975
- backgroundColor: '#121212',
37976
- },
37977
- {
37978
- id: 'auto',
37979
- name: 'System Default',
37980
- description: 'Follows device setting',
37981
- primaryColor: '#6C757D',
37982
- backgroundColor: 'auto',
37983
- },
37984
- ] })
38213
+ app.addDatasource.static({
38214
+ datasourceId: 'theme-options',
38215
+ data: [
38216
+ {
38217
+ id: 'light',
38218
+ name: 'Light Theme',
38219
+ description: 'Clean bright interface',
38220
+ primaryColor: '#007BFF',
38221
+ backgroundColor: '#FFFFFF',
38222
+ },
38223
+ {
38224
+ id: 'dark',
38225
+ name: 'Dark Theme',
38226
+ description: 'Easy on the eyes',
38227
+ primaryColor: '#BB86FC',
38228
+ backgroundColor: '#121212',
38229
+ },
38230
+ {
38231
+ id: 'auto',
38232
+ name: 'System Default',
38233
+ description: 'Follows device setting',
38234
+ primaryColor: '#6C757D',
38235
+ backgroundColor: 'auto',
38236
+ },
38237
+ ],
38238
+ })
37985
38239
  // Complex lookup data with nested properties
37986
- app.addDatasource.static({ datasourceId: 'countries', data: [
37987
- {
37988
- id: 'us',
37989
- name: 'United States',
37990
- code: 'US',
37991
- currency: { symbol: '$', code: 'USD' },
37992
- regions: [
37993
- { id: 'north', name: 'North' },
37994
- { id: 'south', name: 'South' },
37995
- { id: 'east', name: 'East' },
37996
- { id: 'west', name: 'West' },
37997
- ],
37998
- },
37999
- {
38000
- id: 'uk',
38001
- name: 'United Kingdom',
38002
- code: 'GB',
38003
- currency: { symbol: '£', code: 'GBP' },
38004
- regions: [
38005
- { id: 'england', name: 'England' },
38006
- { id: 'scotland', name: 'Scotland' },
38007
- { id: 'wales', name: 'Wales' },
38008
- { id: 'ni', name: 'Northern Ireland' },
38009
- ],
38010
- },
38011
- ] })
38240
+ app.addDatasource.static({
38241
+ datasourceId: 'countries',
38242
+ data: [
38243
+ {
38244
+ id: 'us',
38245
+ name: 'United States',
38246
+ code: 'US',
38247
+ currency: { symbol: '$', code: 'USD' },
38248
+ regions: [
38249
+ { id: 'north', name: 'North' },
38250
+ { id: 'south', name: 'South' },
38251
+ { id: 'east', name: 'East' },
38252
+ { id: 'west', name: 'West' },
38253
+ ],
38254
+ },
38255
+ {
38256
+ id: 'uk',
38257
+ name: 'United Kingdom',
38258
+ code: 'GB',
38259
+ currency: { symbol: '£', code: 'GBP' },
38260
+ regions: [
38261
+ { id: 'england', name: 'England' },
38262
+ { id: 'scotland', name: 'Scotland' },
38263
+ { id: 'wales', name: 'Wales' },
38264
+ { id: 'ni', name: 'Northern Ireland' },
38265
+ ],
38266
+ },
38267
+ ],
38268
+ })
38012
38269
  // Priority levels for task management
38013
- app.addDatasource.static({ datasourceId: 'priority-levels', data: [
38014
- {
38015
- id: 1,
38016
- name: 'Low',
38017
- color: '#28A745',
38018
- description: 'Nice to have',
38019
- urgencyScore: 1,
38020
- escalationDays: 30,
38021
- },
38022
- {
38023
- id: 2,
38024
- name: 'Medium',
38025
- color: '#FFC107',
38026
- description: 'Should be addressed',
38027
- urgencyScore: 5,
38028
- escalationDays: 7,
38029
- },
38030
- {
38031
- id: 3,
38032
- name: 'High',
38033
- color: '#FD7E14',
38034
- description: 'Important issue',
38035
- urgencyScore: 8,
38036
- escalationDays: 2,
38037
- },
38038
- {
38039
- id: 4,
38040
- name: 'Critical',
38041
- color: '#DC3545',
38042
- description: 'Immediate attention required',
38043
- urgencyScore: 10,
38044
- escalationDays: 0,
38045
- },
38046
- ] })
38270
+ app.addDatasource.static({
38271
+ datasourceId: 'priority-levels',
38272
+ data: [
38273
+ {
38274
+ id: 1,
38275
+ name: 'Low',
38276
+ color: '#28A745',
38277
+ description: 'Nice to have',
38278
+ urgencyScore: 1,
38279
+ escalationDays: 30,
38280
+ },
38281
+ {
38282
+ id: 2,
38283
+ name: 'Medium',
38284
+ color: '#FFC107',
38285
+ description: 'Should be addressed',
38286
+ urgencyScore: 5,
38287
+ escalationDays: 7,
38288
+ },
38289
+ {
38290
+ id: 3,
38291
+ name: 'High',
38292
+ color: '#FD7E14',
38293
+ description: 'Important issue',
38294
+ urgencyScore: 8,
38295
+ escalationDays: 2,
38296
+ },
38297
+ {
38298
+ id: 4,
38299
+ name: 'Critical',
38300
+ color: '#DC3545',
38301
+ description: 'Immediate attention required',
38302
+ urgencyScore: 10,
38303
+ escalationDays: 0,
38304
+ },
38305
+ ],
38306
+ })
38047
38307
  - id: datasource.datasource.system
38048
38308
  name: System Datasource Configuration
38049
38309
  category: datasource
@@ -38240,8 +38500,10 @@
38240
38500
  - entity
38241
38501
  - object-form
38242
38502
  description: Use entity({ entity }) to emit the explicit object shape for a table
38243
- code: "app.addDatasource.sqlite({ datasourceId: 'test-ds', provider: 'local'
38244
- }).entity({ entity: 'customers' })"
38503
+ code: |-
38504
+ app.addDatasource
38505
+ .sqlite({ datasourceId: 'test-ds', provider: 'local' })
38506
+ .entity({ entity: 'customers' })
38245
38507
  - id: datasource.sqlite-example-7
38246
38508
  name: SQLite Datasource Entity with Sync Function
38247
38509
  category: datasource
@@ -38273,8 +38535,10 @@
38273
38535
  - external
38274
38536
  description: Use entityPackaged(name, packageName) to reference a table from an
38275
38537
  external package
38276
- code: "app.addDatasource.sqlite({ datasourceId: 'test-ds', provider: 'local'
38277
- }).entityPackaged('users', 'erp')"
38538
+ code: |-
38539
+ app.addDatasource
38540
+ .sqlite({ datasourceId: 'test-ds', provider: 'local' })
38541
+ .entityPackaged('users', 'erp')
38278
38542
  - id: datasource.static-example-1
38279
38543
  name: Static Datasource with Color Objects
38280
38544
  category: datasource
@@ -38326,10 +38590,13 @@
38326
38590
  - properties
38327
38591
  description: Store color data with name and hex value properties
38328
38592
  code: |-
38329
- app.addDatasource.static({ datasourceId: 'colors', data: [
38330
- { name: 'Red', value: '#FF0000' },
38331
- { name: 'Green', value: '#00FF00' },
38332
- ] })
38593
+ app.addDatasource.static({
38594
+ datasourceId: 'colors',
38595
+ data: [
38596
+ { name: 'Red', value: '#FF0000' },
38597
+ { name: 'Green', value: '#00FF00' },
38598
+ ],
38599
+ })
38333
38600
  - id: datasource.static-example-5
38334
38601
  name: Static Datasource with Number Array
38335
38602
  category: datasource
@@ -38355,8 +38622,10 @@
38355
38622
  - comma-delimiter
38356
38623
  description: Parse comma-separated priority values into array using default
38357
38624
  comma delimiter
38358
- code: "app.addDatasource.static({ datasourceId: 'priorities', data: []
38359
- }).csv('urgent, high, medium, low')"
38625
+ code: |-
38626
+ app.addDatasource
38627
+ .static({ datasourceId: 'priorities', data: [] })
38628
+ .csv('urgent, high, medium, low')
38360
38629
  - id: datasource.static-example-7
38361
38630
  name: Static Datasource with Pipe-Delimited CSV Colors
38362
38631
  category: datasource
@@ -38368,8 +38637,10 @@
38368
38637
  - whitespace
38369
38638
  - colors
38370
38639
  description: Parse pipe-delimited color values with automatic whitespace trimming
38371
- code: "app.addDatasource.static({ datasourceId: 'colors', data: [] }).csv(' red
38372
- | green | blue ', '|')"
38640
+ code: |-
38641
+ app.addDatasource
38642
+ .static({ datasourceId: 'colors', data: [] })
38643
+ .csv(' red | green | blue ', '|')
38373
38644
  - id: datasource.static-example-8
38374
38645
  name: Static Datasource with JSON Array Parsing
38375
38646
  category: datasource
@@ -38394,8 +38665,10 @@
38394
38665
  - key-value-pairs
38395
38666
  - configuration
38396
38667
  description: Convert JSON configuration object to key-value pair array
38397
- code: "app.addDatasource.static({ datasourceId: 'config', data: []
38398
- }).json('{\"debug\": true, \"port\": 3000}')"
38668
+ code: |-
38669
+ app.addDatasource
38670
+ .static({ datasourceId: 'config', data: [] })
38671
+ .json('{"debug": true, "port": 3000}')
38399
38672
  - id: datasource.system-example-1
38400
38673
  name: System Datasource for Feature Flags
38401
38674
  category: datasource
@@ -38458,7 +38731,11 @@
38458
38731
  managing continuation tokens for REST APIs
38459
38732
  code: |-
38460
38733
  // 1. Basic REST function with simple pagination
38461
- const getUsersFunction = app.addFunction.rest({ functionId: 'get-users', method: 'GET', url: 'https://api.example.com/users' })
38734
+ const getUsersFunction = app.addFunction.rest({
38735
+ functionId: 'get-users',
38736
+ method: 'GET',
38737
+ url: 'https://api.example.com/users',
38738
+ })
38462
38739
  getUsersFunction.params.query('page', { value: 1, type: 'number' })
38463
38740
  getUsersFunction.params.header('Authorization', 'Bearer token123')
38464
38741
  getUsersFunction.json()
@@ -38468,7 +38745,11 @@
38468
38745
  usersContinuation.when('=$.hasMore')
38469
38746
  usersContinuation.url('=$.nextPageUrl')
38470
38747
  // 2. Microsoft Graph API with OAuth continuation
38471
- const getGraphUsers = app.addFunction.rest({ functionId: 'get-graph-users', method: 'GET', url: 'https://graph.microsoft.com/v1.0/users' })
38748
+ const getGraphUsers = app.addFunction.rest({
38749
+ functionId: 'get-graph-users',
38750
+ method: 'GET',
38751
+ url: 'https://graph.microsoft.com/v1.0/users',
38752
+ })
38472
38753
  getGraphUsers.params.header('Authorization', '=@ctx.solution.state.user.graphToken')
38473
38754
  getGraphUsers.json()
38474
38755
  getGraphUsers.records('=$.value')
@@ -38477,7 +38758,11 @@
38477
38758
  graphContinuation.when('=$."@odata.nextLink"')
38478
38759
  graphContinuation.url('=$."@odata.nextLink"')
38479
38760
  // 3. Advanced pagination with cursor-based continuation
38480
- const searchCustomers = app.addFunction.rest({ functionId: 'search-customers', method: 'POST', url: 'https://api.crm.com/customers/search' })
38761
+ const searchCustomers = app.addFunction.rest({
38762
+ functionId: 'search-customers',
38763
+ method: 'POST',
38764
+ url: 'https://api.crm.com/customers/search',
38765
+ })
38481
38766
  searchCustomers.params.body('query', { name: 'John', active: true })
38482
38767
  searchCustomers.params.header('API-Key', '=@ctx.solution.state.crmApiKey')
38483
38768
  searchCustomers.json()
@@ -38489,7 +38774,11 @@
38489
38774
  '=@ctx.solution.state.apiUrl & "/customers/search?cursor=" & $.pagination.nextCursor',
38490
38775
  )
38491
38776
  // 4. Pagination with dynamic parameter updates
38492
- const getOrderHistory = app.addFunction.rest({ functionId: 'get-order-history', method: 'GET', url: 'https://api.orders.com/history' })
38777
+ const getOrderHistory = app.addFunction.rest({
38778
+ functionId: 'get-order-history',
38779
+ method: 'GET',
38780
+ url: 'https://api.orders.com/history',
38781
+ })
38493
38782
  getOrderHistory.params.query('limit', { value: 100, type: 'number' })
38494
38783
  getOrderHistory.params.query('offset', { value: 0, type: 'number' })
38495
38784
  getOrderHistory.params.header('X-API-Key', '=@ctx.solution.state.ordersApiKey')
@@ -38502,7 +38791,11 @@
38502
38791
  '=@ctx.solution.state.ordersUrl & "/history?offset=" & ($.offset + $.limit) & "&limit=" & $.limit',
38503
38792
  )
38504
38793
  // 5. Complex continuation with authentication renewal
38505
- const syncInventory = app.addFunction.rest({ functionId: 'sync-inventory', method: 'GET', url: 'https://api.inventory.com/items' })
38794
+ const syncInventory = app.addFunction.rest({
38795
+ functionId: 'sync-inventory',
38796
+ method: 'GET',
38797
+ url: 'https://api.inventory.com/items',
38798
+ })
38506
38799
  syncInventory.params.header('Authorization', 'Bearer =@ctx.solution.state.inventoryToken')
38507
38800
  syncInventory.params.query('pageSize', { value: 50, type: 'number' })
38508
38801
  syncInventory.json()
@@ -38527,14 +38820,22 @@
38527
38820
  PUT, DELETE methods with full parameter and header control
38528
38821
  code: |-
38529
38822
  // 1. Basic GET request with authentication
38530
- const getUsersFunction = app.addFunction.rest({ functionId: 'get-users', method: 'GET', url: 'https://api.example.com/users' })
38823
+ const getUsersFunction = app.addFunction.rest({
38824
+ functionId: 'get-users',
38825
+ method: 'GET',
38826
+ url: 'https://api.example.com/users',
38827
+ })
38531
38828
  getUsersFunction.json()
38532
38829
  getUsersFunction.params
38533
38830
  .header('Authorization', 'Bearer =@ctx.solution.state.auth.token')
38534
38831
  .query('page', { type: 'number', value: 1 })
38535
38832
  .query('limit', { type: 'number', value: 10 })
38536
38833
  // 2. POST request with body data and API key
38537
- const createUserFunction = app.addFunction.rest({ functionId: 'create-user', method: 'POST', url: 'https://api.example.com/users' })
38834
+ const createUserFunction = app.addFunction.rest({
38835
+ functionId: 'create-user',
38836
+ method: 'POST',
38837
+ url: 'https://api.example.com/users',
38838
+ })
38538
38839
  createUserFunction.json()
38539
38840
  createUserFunction.params.apiKey('=@ctx.solution.state.settings.apiKey').body('user', {
38540
38841
  name: '=@ctx.components.name.state.value',
@@ -38542,7 +38843,11 @@
38542
38843
  department: '=@ctx.solution.state.user.department',
38543
38844
  })
38544
38845
  // 3. Advanced configuration with output transformation and entity storage
38545
- const getProductsFunction = app.addFunction.rest({ functionId: 'get-products', method: 'GET', url: 'https://api.example.com/products' })
38846
+ const getProductsFunction = app.addFunction.rest({
38847
+ functionId: 'get-products',
38848
+ method: 'GET',
38849
+ url: 'https://api.example.com/products',
38850
+ })
38546
38851
  getProductsFunction.json().outputTransform('$.data.products').entity('default/products')
38547
38852
  getProductsFunction.params
38548
38853
  .header('X-API-Version', '2.0')
@@ -38565,7 +38870,11 @@
38565
38870
  response strategies
38566
38871
  code: |-
38567
38872
  // 1. Function with comprehensive error handling
38568
- const syncDataFunction = app.addFunction.rest({ functionId: 'sync-data', method: 'POST', url: 'https://api.example.com/sync' })
38873
+ const syncDataFunction = app.addFunction.rest({
38874
+ functionId: 'sync-data',
38875
+ method: 'POST',
38876
+ url: 'https://api.example.com/sync',
38877
+ })
38569
38878
  syncDataFunction.json()
38570
38879
  syncDataFunction.params.bearer('=@ctx.auth.accessToken').body('data', '=@ctx.pendingSync.data')
38571
38880
  // Server error with retry
@@ -38598,7 +38907,11 @@
38598
38907
  .icon('lock')
38599
38908
  .notification(true)
38600
38909
  // 2. Function with data conversion and error handling
38601
- const uploadImageFunction = app.addFunction.rest({ functionId: 'upload-image', method: 'POST', url: 'https://api.example.com/upload' })
38910
+ const uploadImageFunction = app.addFunction.rest({
38911
+ functionId: 'upload-image',
38912
+ method: 'POST',
38913
+ url: 'https://api.example.com/upload',
38914
+ })
38602
38915
  uploadImageFunction.json().base64ToUri('image', 'uploaded-image.jpg')
38603
38916
  uploadImageFunction.params
38604
38917
  .header('Content-Type', 'application/json')
@@ -38633,7 +38946,11 @@
38633
38946
  for mobile-optimized performance
38634
38947
  code: |-
38635
38948
  // 1. Paginated API with continuation logic
38636
- const getOrdersFunction = app.addFunction.rest({ functionId: 'get-orders', method: 'GET', url: 'https://api.example.com/orders' })
38949
+ const getOrdersFunction = app.addFunction.rest({
38950
+ functionId: 'get-orders',
38951
+ method: 'GET',
38952
+ url: 'https://api.example.com/orders',
38953
+ })
38637
38954
  getOrdersFunction.json().outputTransform('$.orders').entity('default/orders')
38638
38955
  getOrdersFunction.params
38639
38956
  .header('Authorization', 'Bearer =@ctx.solution.state.auth.token')
@@ -38642,7 +38959,11 @@
38642
38959
  // Continuation for next page
38643
38960
  getOrdersFunction.continuation.when('=$.hasMore').url('=$.nextPageUrl')
38644
38961
  // 2. Function with file conversion and row filtering
38645
- const getCustomersFunction = app.addFunction.rest({ functionId: 'get-customers', method: 'GET', url: 'https://api.example.com/customers' })
38962
+ const getCustomersFunction = app.addFunction.rest({
38963
+ functionId: 'get-customers',
38964
+ method: 'GET',
38965
+ url: 'https://api.example.com/customers',
38966
+ })
38646
38967
  getCustomersFunction
38647
38968
  .json()
38648
38969
  .outputTransform('$.data.customers')
@@ -38654,7 +38975,11 @@
38654
38975
  .query('includeInactive', { type: 'boolean', value: false })
38655
38976
  .query('fields', { value: 'id,name,email,profileImage,status,lastLoginDays' })
38656
38977
  // 3. Bulk data processing with transformation
38657
- const getAnalyticsFunction = app.addFunction.rest({ functionId: 'get-analytics', method: 'GET', url: 'https://api.example.com/analytics' })
38978
+ const getAnalyticsFunction = app.addFunction.rest({
38979
+ functionId: 'get-analytics',
38980
+ method: 'GET',
38981
+ url: 'https://api.example.com/analytics',
38982
+ })
38658
38983
  getAnalyticsFunction.json().outputTransform('$.metrics')
38659
38984
  getAnalyticsFunction.params
38660
38985
  .query('dateFrom', { value: '=@ctx.jig.state.filter.startDate' })
@@ -38677,14 +39002,24 @@
38677
39002
  construction, authentication, and XML response parsing
38678
39003
  code: |-
38679
39004
  // 1. Basic SOAP service call with authentication
38680
- const getUserDetailsFunction = app.addFunction.soap({ functionId: 'get-user-details', connection: 'legacy-service', method: 'GetUserDetails', wsdl: 'https://legacy-api.company.com/UserService.wsdl' })
39005
+ const getUserDetailsFunction = app.addFunction.soap({
39006
+ functionId: 'get-user-details',
39007
+ connection: 'legacy-service',
39008
+ method: 'GetUserDetails',
39009
+ wsdl: 'https://legacy-api.company.com/UserService.wsdl',
39010
+ })
38681
39011
  getUserDetailsFunction.params
38682
39012
  .header('SOAPAction', 'GetUserDetails')
38683
39013
  .header('Authorization', 'Basic =@ctx.solution.state.auth.basicToken')
38684
39014
  .body('UserId', '=@ctx.user.id')
38685
39015
  .body('IncludeDetails', true)
38686
39016
  // 2. SOAP service with complex parameters
38687
- const createOrderFunction = app.addFunction.soap({ functionId: 'create-order', connection: 'erp-service', method: 'CreateOrder', wsdl: 'https://erp.company.com/OrderService.wsdl' })
39017
+ const createOrderFunction = app.addFunction.soap({
39018
+ functionId: 'create-order',
39019
+ connection: 'erp-service',
39020
+ method: 'CreateOrder',
39021
+ wsdl: 'https://erp.company.com/OrderService.wsdl',
39022
+ })
38688
39023
  createOrderFunction.params
38689
39024
  .header('SOAPAction', 'CreateOrder')
38690
39025
  .header('X-API-Key', '=@ctx.solution.state.settings.erpApiKey')
@@ -38696,7 +39031,12 @@
38696
39031
  PaymentMethod: '=@ctx.jig.inputs.payment.method',
38697
39032
  })
38698
39033
  // 3. SOAP service with output transformation
38699
- const getInventoryFunction = app.addFunction.soap({ functionId: 'get-inventory', connection: 'wms-service', method: 'GetInventoryStatus', wsdl: 'https://wms.company.com/InventoryService.wsdl' })
39034
+ const getInventoryFunction = app.addFunction.soap({
39035
+ functionId: 'get-inventory',
39036
+ connection: 'wms-service',
39037
+ method: 'GetInventoryStatus',
39038
+ wsdl: 'https://wms.company.com/InventoryService.wsdl',
39039
+ })
38700
39040
  getInventoryFunction
38701
39041
  .outputTransform('$.Body.GetInventoryStatusResponse.InventoryItems.Item')
38702
39042
  .entity('inventory')
@@ -38721,7 +39061,12 @@
38721
39061
  authentication errors, and enterprise messaging patterns
38722
39062
  code: |-
38723
39063
  // 1. Enterprise service with comprehensive error handling
38724
- const syncEmployeeDataFunction = app.addFunction.soap({ functionId: 'sync-employee-data', connection: 'hr-service', method: 'SyncEmployeeData', wsdl: 'https://hr.company.com/EmployeeService.wsdl' })
39064
+ const syncEmployeeDataFunction = app.addFunction.soap({
39065
+ functionId: 'sync-employee-data',
39066
+ connection: 'hr-service',
39067
+ method: 'SyncEmployeeData',
39068
+ wsdl: 'https://hr.company.com/EmployeeService.wsdl',
39069
+ })
38725
39070
  syncEmployeeDataFunction.params
38726
39071
  .header('SOAPAction', 'SyncEmployeeData')
38727
39072
  .header('Authorization', 'Bearer =@ctx.solution.state.auth.enterpriseToken')
@@ -38754,7 +39099,12 @@
38754
39099
  maxRetries: 2,
38755
39100
  })
38756
39101
  // 2. Legacy financial system integration
38757
- const processPaymentFunction = app.addFunction.soap({ functionId: 'process-payment', connection: 'finance-service', method: 'ProcessPayment', wsdl: 'https://finance.company.com/PaymentService.wsdl' })
39102
+ const processPaymentFunction = app.addFunction.soap({
39103
+ functionId: 'process-payment',
39104
+ connection: 'finance-service',
39105
+ method: 'ProcessPayment',
39106
+ wsdl: 'https://finance.company.com/PaymentService.wsdl',
39107
+ })
38758
39108
  processPaymentFunction.params
38759
39109
  .header('SOAPAction', 'ProcessPayment')
38760
39110
  .header('X-System-Id', 'MOBILE_APP')
@@ -38794,7 +39144,12 @@
38794
39144
  integration, and enterprise data patterns
38795
39145
  code: |-
38796
39146
  // 1. Multi-step customer onboarding workflow
38797
- const initiateCustomerOnboardingFunction = app.addFunction.soap({ functionId: 'initiate-customer-onboarding', connection: 'crm-service', method: 'InitiateOnboarding', wsdl: 'https://crm.company.com/OnboardingService.wsdl' })
39147
+ const initiateCustomerOnboardingFunction = app.addFunction.soap({
39148
+ functionId: 'initiate-customer-onboarding',
39149
+ connection: 'crm-service',
39150
+ method: 'InitiateOnboarding',
39151
+ wsdl: 'https://crm.company.com/OnboardingService.wsdl',
39152
+ })
38798
39153
  initiateCustomerOnboardingFunction.outputTransform(
38799
39154
  '$.Body.InitiateOnboardingResponse.OnboardingProcess',
38800
39155
  )
@@ -38817,7 +39172,12 @@
38817
39172
  ReferralSource: '=@ctx.jig.inputs.referral.source',
38818
39173
  })
38819
39174
  // 2. Document processing and approval workflow
38820
- const submitDocumentForApprovalFunction = app.addFunction.soap({ functionId: 'submit-document-approval', connection: 'workflow-service', method: 'SubmitForApproval', wsdl: 'https://workflow.company.com/ApprovalService.wsdl' })
39175
+ const submitDocumentForApprovalFunction = app.addFunction.soap({
39176
+ functionId: 'submit-document-approval',
39177
+ connection: 'workflow-service',
39178
+ method: 'SubmitForApproval',
39179
+ wsdl: 'https://workflow.company.com/ApprovalService.wsdl',
39180
+ })
38821
39181
  submitDocumentForApprovalFunction.base64ToUri('documentContent', 'document.pdf')
38822
39182
  submitDocumentForApprovalFunction.params
38823
39183
  .header('SOAPAction', 'SubmitForApproval')
@@ -38834,7 +39194,12 @@
38834
39194
  },
38835
39195
  })
38836
39196
  // 3. Complex reporting service with aggregated data
38837
- const generateComplianceReportFunction = app.addFunction.soap({ functionId: 'generate-compliance-report', connection: 'compliance-service', method: 'GenerateComplianceReport', wsdl: 'https://compliance.company.com/ReportingService.wsdl' })
39197
+ const generateComplianceReportFunction = app.addFunction.soap({
39198
+ functionId: 'generate-compliance-report',
39199
+ connection: 'compliance-service',
39200
+ method: 'GenerateComplianceReport',
39201
+ wsdl: 'https://compliance.company.com/ReportingService.wsdl',
39202
+ })
38838
39203
  generateComplianceReportFunction.outputTransform(
38839
39204
  '$.Body.GenerateComplianceReportResponse.ReportData.Sections',
38840
39205
  )
@@ -38873,7 +39238,10 @@
38873
39238
  input/output parameters
38874
39239
  code: |-
38875
39240
  // 1. Basic SELECT query with parameters
38876
- const getCustomersFunction = app.addFunction.sql({ functionId: 'get-customers', connection: 'customerDb' })
39241
+ const getCustomersFunction = app.addFunction.sql({
39242
+ functionId: 'get-customers',
39243
+ connection: 'customerDb',
39244
+ })
38877
39245
  getCustomersFunction
38878
39246
  .providerQuery('SELECT * FROM customers WHERE active = @active AND region = @region')
38879
39247
  .entity('customers')
@@ -38881,7 +39249,11 @@
38881
39249
  .input('active', 'boolean', { value: true })
38882
39250
  .input('region', 'string', { value: '=@ctx.solution.state.user.region' })
38883
39251
  // 2. Stored procedure with input and output parameters
38884
- const updateCustomerFunction = app.addFunction.sql({ functionId: 'update-customer', connection: 'customerDb', method: 'execute' })
39252
+ const updateCustomerFunction = app.addFunction.sql({
39253
+ functionId: 'update-customer',
39254
+ connection: 'customerDb',
39255
+ method: 'execute',
39256
+ })
38885
39257
  updateCustomerFunction.procedure('sp_UpdateCustomer')
38886
39258
  updateCustomerFunction.params
38887
39259
  .input('customerId', 'number', { value: '=@ctx.jig.inputs.customer.id' })
@@ -38890,7 +39262,10 @@
38890
39262
  .output('result', 'string')
38891
39263
  .output('affectedRows', 'number')
38892
39264
  // 3. Complex query with data transformation
38893
- const getOrderStatsFunction = app.addFunction.sql({ functionId: 'get-order-stats', connection: 'analyticsDb' })
39265
+ const getOrderStatsFunction = app.addFunction.sql({
39266
+ functionId: 'get-order-stats',
39267
+ connection: 'analyticsDb',
39268
+ })
38894
39269
  getOrderStatsFunction.providerQuery(`
38895
39270
  SELECT
38896
39271
  customerId,
@@ -38923,7 +39298,11 @@
38923
39298
  handling of database constraints, locks, and file operations
38924
39299
  code: |-
38925
39300
  // 1. Insert operation with comprehensive error handling
38926
- const createOrderFunction = app.addFunction.sql({ functionId: 'create-order', connection: 'ordersDb', method: 'execute' })
39301
+ const createOrderFunction = app.addFunction.sql({
39302
+ functionId: 'create-order',
39303
+ connection: 'ordersDb',
39304
+ method: 'execute',
39305
+ })
38927
39306
  createOrderFunction.procedure('sp_CreateOrder')
38928
39307
  createOrderFunction.params
38929
39308
  .input('customerId', 'number', { value: '=@ctx.jig.inputs.customer.id' })
@@ -38949,7 +39328,10 @@
38949
39328
  maxRetries: 3,
38950
39329
  })
38951
39330
  // 2. Function with file conversion and row operations
38952
- const getProductsWithImagesFunction = app.addFunction.sql({ functionId: 'get-products-with-images', connection: 'catalogDb' })
39331
+ const getProductsWithImagesFunction = app.addFunction.sql({
39332
+ functionId: 'get-products-with-images',
39333
+ connection: 'catalogDb',
39334
+ })
38953
39335
  getProductsWithImagesFunction
38954
39336
  .providerQuery('SELECT * FROM products WHERE categoryId = @categoryId')
38955
39337
  .entity('products')
@@ -38959,7 +39341,11 @@
38959
39341
  value: '=@ctx.current.item.category.id',
38960
39342
  })
38961
39343
  // 3. Bulk operation with table operations and conditions
38962
- const syncInventoryFunction = app.addFunction.sql({ functionId: 'sync-inventory', connection: 'inventoryDb', method: 'execute' })
39344
+ const syncInventoryFunction = app.addFunction.sql({
39345
+ functionId: 'sync-inventory',
39346
+ connection: 'inventoryDb',
39347
+ method: 'execute',
39348
+ })
38963
39349
  syncInventoryFunction.procedure('sp_SyncInventory')
38964
39350
  syncInventoryFunction.params
38965
39351
  .input('inventoryData', 'string', { value: '=JSON.stringify(@ctx.datasources.inventory)' })
@@ -38994,17 +39380,26 @@
38994
39380
  operations
38995
39381
  code: |-
38996
39382
  // 1. Dynamic SELECT query with helper methods
38997
- const getFilteredCustomersFunction = app.addFunction.sql({ functionId: 'get-filtered-customers', connection: 'reportsDb' })
39383
+ const getFilteredCustomersFunction = app.addFunction.sql({
39384
+ functionId: 'get-filtered-customers',
39385
+ connection: 'reportsDb',
39386
+ })
38998
39387
  getFilteredCustomersFunction
38999
39388
  .select(['id', 'name', 'email', 'region', 'lastOrderDate'], 'customers', 'active = @active')
39000
39389
  .entity('customers')
39001
39390
  getFilteredCustomersFunction.params.input('active', 'boolean', { value: true })
39002
39391
  // 2. Simple SELECT ALL with conditions
39003
- const getAllProductsFunction = app.addFunction.sql({ functionId: 'get-all-products', connection: 'catalogDb' })
39392
+ const getAllProductsFunction = app.addFunction.sql({
39393
+ functionId: 'get-all-products',
39394
+ connection: 'catalogDb',
39395
+ })
39004
39396
  getAllProductsFunction.selectAll('products', 'discontinued = @discontinued').entity('products')
39005
39397
  getAllProductsFunction.params.input('discontinued', 'boolean', { value: false })
39006
39398
  // 3. Complex analytics query
39007
- const getSalesReportFunction = app.addFunction.sql({ functionId: 'get-sales-report', connection: 'analyticsDb' })
39399
+ const getSalesReportFunction = app.addFunction.sql({
39400
+ functionId: 'get-sales-report',
39401
+ connection: 'analyticsDb',
39402
+ })
39008
39403
  getSalesReportFunction.providerQuery(`
39009
39404
  WITH monthly_sales AS (
39010
39405
  SELECT
@@ -39032,7 +39427,11 @@
39032
39427
  value: '=@ctx.jig.inputs.report.startDate',
39033
39428
  })
39034
39429
  // 4. Batch processing with file operations
39035
- const processBatchUploadsFunction = app.addFunction.sql({ functionId: 'process-batch-uploads', connection: 'processingDb', method: 'execute' })
39430
+ const processBatchUploadsFunction = app.addFunction.sql({
39431
+ functionId: 'process-batch-uploads',
39432
+ connection: 'processingDb',
39433
+ method: 'execute',
39434
+ })
39036
39435
  processBatchUploadsFunction.procedure('sp_ProcessBatch').uriToBase64('uploadFile')
39037
39436
  processBatchUploadsFunction.params
39038
39437
  .input('batchId', 'string', { value: '=@ctx.jig.inputs.batch.id' })
@@ -39053,7 +39452,11 @@
39053
39452
  result expression
39054
39453
  code: |-
39055
39454
  const app = new ApplicationBuilder({ name: 'test-app' })
39056
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/test' })
39455
+ const fn = app.addFunction.rest({
39456
+ functionId: 'test-function',
39457
+ method: 'POST',
39458
+ url: 'https://api.example.com/test',
39459
+ })
39057
39460
  fn.guard('guard-function')
39058
39461
  .parameters({
39059
39462
  accessToken: 'acuerp',
@@ -39074,7 +39477,11 @@
39074
39477
  tables with parameterized statements
39075
39478
  code: |-
39076
39479
  const app = new ApplicationBuilder({ name: 'test-app' })
39077
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/test' })
39480
+ const fn = app.addFunction.rest({
39481
+ functionId: 'test-function',
39482
+ method: 'POST',
39483
+ url: 'https://api.example.com/test',
39484
+ })
39078
39485
  const guard = fn
39079
39486
  .guard('guard-function')
39080
39487
  .parameters({ id: '=@ctx.parameters.id' })
@@ -39100,7 +39507,11 @@
39100
39507
  replace records
39101
39508
  code: |-
39102
39509
  const app = new ApplicationBuilder({ name: 'test-app' })
39103
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/test' })
39510
+ const fn = app.addFunction.rest({
39511
+ functionId: 'test-function',
39512
+ method: 'POST',
39513
+ url: 'https://api.example.com/test',
39514
+ })
39104
39515
  const guard = fn.guard('guard-function').result('=true')
39105
39516
  guard
39106
39517
  .operation()
@@ -39117,7 +39528,11 @@
39117
39528
  process response data
39118
39529
  code: |-
39119
39530
  const app = new ApplicationBuilder({ name: 'test-app' })
39120
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'GET', url: 'https://api.example.com/data' })
39531
+ const fn = app.addFunction.rest({
39532
+ functionId: 'test-function',
39533
+ method: 'GET',
39534
+ url: 'https://api.example.com/data',
39535
+ })
39121
39536
  fn.operation('=@ctx.response.body.items').upsertMerge(
39122
39537
  'items',
39123
39538
  '=$map(@ctx.response.body.items, function($v) {$merge([$v, {"Remote": true}])})',
@@ -39133,7 +39548,11 @@
39133
39548
  description: Configure function with root-level execute-sql operation to update local data
39134
39549
  code: |-
39135
39550
  const app = new ApplicationBuilder({ name: 'test-app' })
39136
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'GET', url: 'https://api.example.com/data' })
39551
+ const fn = app.addFunction.rest({
39552
+ functionId: 'test-function',
39553
+ method: 'GET',
39554
+ url: 'https://api.example.com/data',
39555
+ })
39137
39556
  fn.operation().executeSql(
39138
39557
  ['items'],
39139
39558
  'UPDATE items SET data = json_set(data, "$.Remote", false)',
@@ -39151,7 +39570,11 @@
39151
39570
  execution based on parameters
39152
39571
  code: |-
39153
39572
  const app = new ApplicationBuilder({ name: 'test-app' })
39154
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'GET', url: 'https://api.example.com/data' })
39573
+ const fn = app.addFunction.rest({
39574
+ functionId: 'test-function',
39575
+ method: 'GET',
39576
+ url: 'https://api.example.com/data',
39577
+ })
39155
39578
  fn.operation()
39156
39579
  .when('=@ctx.parameters.deleteRequired = "y"')
39157
39580
  .executeSql(['items'], 'DELETE FROM items WHERE json_extract(data, "$.Remote") is false')
@@ -39169,7 +39592,11 @@
39169
39592
  and conditional execute-sql
39170
39593
  code: |-
39171
39594
  const app = new ApplicationBuilder({ name: 'test-app' })
39172
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'GET', url: 'https://api.example.com/data' })
39595
+ const fn = app.addFunction.rest({
39596
+ functionId: 'test-function',
39597
+ method: 'GET',
39598
+ url: 'https://api.example.com/data',
39599
+ })
39173
39600
  fn.operation().upsertMerge('items', '=@ctx.response.body')
39174
39601
  fn.operation()
39175
39602
  .when('=@ctx.parameters.cleanup = true')
@@ -39224,7 +39651,11 @@
39224
39651
  values from function execution
39225
39652
  code: |-
39226
39653
  const app = new ApplicationBuilder({ name: 'test-app' })
39227
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/payment' })
39654
+ const fn = app.addFunction.rest({
39655
+ functionId: 'test-function',
39656
+ method: 'POST',
39657
+ url: 'https://api.example.com/payment',
39658
+ })
39228
39659
  fn.params
39229
39660
  .body('amount', undefined, { type: 'number', required: true })
39230
39661
  .output('prePaymentTransactionId', { type: 'string', required: false })
@@ -39242,7 +39673,11 @@
39242
39673
  description: Configure guard with when condition to control when guard evaluation runs
39243
39674
  code: |-
39244
39675
  const app = new ApplicationBuilder({ name: 'test-app' })
39245
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/test' })
39676
+ const fn = app.addFunction.rest({
39677
+ functionId: 'test-function',
39678
+ method: 'POST',
39679
+ url: 'https://api.example.com/test',
39680
+ })
39246
39681
  fn.guard('guard-function').when('=@ctx.user.authenticated').result('=@ctx.guard.output.valid')
39247
39682
  - id: function.guard-example-12
39248
39683
  name: Guard with Retry and Continuation Lifecycle Options
@@ -39257,7 +39692,11 @@
39257
39692
  robust sync workflows
39258
39693
  code: |-
39259
39694
  const app = new ApplicationBuilder({ name: 'test-app' })
39260
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/test' })
39695
+ const fn = app.addFunction.rest({
39696
+ functionId: 'test-function',
39697
+ method: 'POST',
39698
+ url: 'https://api.example.com/test',
39699
+ })
39261
39700
  fn.guard('guard-function').onRetry().onContinuation().result('=@ctx.guard.output.valid')
39262
39701
  - id: function.guard-example-13
39263
39702
  name: Guard with Dynamic onInitial Expression
@@ -39272,7 +39711,11 @@
39272
39711
  initial guard evaluation
39273
39712
  code: |-
39274
39713
  const app = new ApplicationBuilder({ name: 'test-app' })
39275
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/test' })
39714
+ const fn = app.addFunction.rest({
39715
+ functionId: 'test-function',
39716
+ method: 'POST',
39717
+ url: 'https://api.example.com/test',
39718
+ })
39276
39719
  fn.guard('guard-function')
39277
39720
  .onInitial('=@ctx.parameters.runGuard')
39278
39721
  .result('=@ctx.guard.output.valid')
@@ -39288,7 +39731,11 @@
39288
39731
  records in a table
39289
39732
  code: |-
39290
39733
  const app = new ApplicationBuilder({ name: 'test-app' })
39291
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'GET', url: 'https://api.example.com/data' })
39734
+ const fn = app.addFunction.rest({
39735
+ functionId: 'test-function',
39736
+ method: 'GET',
39737
+ url: 'https://api.example.com/data',
39738
+ })
39292
39739
  fn.operation('=@ctx.response.body.items').upsertReplace('items', '=@ctx.response.body.items')
39293
39740
  - id: function.guard-example-15
39294
39741
  name: Function with Find-Replace Operation for Temp ID Resolution
@@ -39303,7 +39750,11 @@
39303
39750
  server-assigned IDs across multiple tables including the command queue
39304
39751
  code: |-
39305
39752
  const app = new ApplicationBuilder({ name: 'test-app' })
39306
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/data' })
39753
+ const fn = app.addFunction.rest({
39754
+ functionId: 'test-function',
39755
+ method: 'POST',
39756
+ url: 'https://api.example.com/data',
39757
+ })
39307
39758
  fn.operation().findReplace(
39308
39759
  'temp-id-123',
39309
39760
  '=@ctx.response.body.id',
@@ -39323,7 +39774,11 @@
39323
39774
  timestamp columns for conflict resolution
39324
39775
  code: |-
39325
39776
  const app = new ApplicationBuilder({ name: 'test-app' })
39326
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'GET', url: 'https://api.example.com/data' })
39777
+ const fn = app.addFunction.rest({
39778
+ functionId: 'test-function',
39779
+ method: 'GET',
39780
+ url: 'https://api.example.com/data',
39781
+ })
39327
39782
  fn.operation('=@ctx.response.body')
39328
39783
  .upsertMerge('items', '=@ctx.response.body')
39329
39784
  .primaryKey('itemId')
@@ -39341,7 +39796,11 @@
39341
39796
  formats during sync
39342
39797
  code: |-
39343
39798
  const app = new ApplicationBuilder({ name: 'test-app' })
39344
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'GET', url: 'https://api.example.com/data' })
39799
+ const fn = app.addFunction.rest({
39800
+ functionId: 'test-function',
39801
+ method: 'GET',
39802
+ url: 'https://api.example.com/data',
39803
+ })
39345
39804
  fn.operation('=@ctx.response.body')
39346
39805
  .upsertMerge('items', '=@ctx.response.body')
39347
39806
  .conversions([{ property: 'image', from: 'base64', to: 'local-uri' }])
@@ -39358,7 +39817,11 @@
39358
39817
  failed transactions from local tables
39359
39818
  code: |-
39360
39819
  const app = new ApplicationBuilder({ name: 'test-app' })
39361
- const fn = app.addFunction.rest({ functionId: 'test-function', method: 'POST', url: 'https://api.example.com/payment' })
39820
+ const fn = app.addFunction.rest({
39821
+ functionId: 'test-function',
39822
+ method: 'POST',
39823
+ url: 'https://api.example.com/payment',
39824
+ })
39362
39825
  fn.error('=@ctx.response.status = 500')
39363
39826
  .operation('=@ctx.response.body')
39364
39827
  .executeSql(
@@ -39407,7 +39870,11 @@
39407
39870
  starting_after parameter and bearer token authentication
39408
39871
  code: |-
39409
39872
  const fn = app.addFunction
39410
- .rest({ functionId: 'stripe-api', method: 'GET', url: 'https://api.stripe.com/v1/customers' })
39873
+ .rest({
39874
+ functionId: 'stripe-api',
39875
+ method: 'GET',
39876
+ url: 'https://api.stripe.com/v1/customers',
39877
+ })
39411
39878
  .json()
39412
39879
  .bearerToken('=@ctx.solution.state.stripeApiKey')
39413
39880
  fn.params.query('limit', { value: 100 })
@@ -39476,7 +39943,11 @@
39476
39943
  notifications, data transformation, operations and retry logic
39477
39944
  code: |-
39478
39945
  const app = new ApplicationBuilder({ name: 'test-application' })
39479
- const fn = app.addFunction.rest({ functionId: 'comprehensive-api', method: 'GET', url: 'https://api.example.com/data' })
39946
+ const fn = app.addFunction.rest({
39947
+ functionId: 'comprehensive-api',
39948
+ method: 'GET',
39949
+ url: 'https://api.example.com/data',
39950
+ })
39480
39951
  const errorHandler = fn
39481
39952
  .error('=@ctx.response.status >= 500')
39482
39953
  .title('Request Failed')
@@ -39508,7 +39979,11 @@
39508
39979
  conditions and retry strategies
39509
39980
  code: |-
39510
39981
  const app = new ApplicationBuilder({ name: 'test-application' })
39511
- const fn = app.addFunction.rest({ functionId: 'api-with-errors', method: 'GET', url: 'https://api.example.com/data' })
39982
+ const fn = app.addFunction.rest({
39983
+ functionId: 'api-with-errors',
39984
+ method: 'GET',
39985
+ url: 'https://api.example.com/data',
39986
+ })
39512
39987
  fn.error(true).title('Default Error')
39513
39988
  fn.error('=@ctx.response.status = 404').title('Not Found')
39514
39989
  fn.error('=@ctx.response.status >= 500').title('Server Error').retry({ delay: 5000 })
@@ -39567,7 +40042,11 @@
39567
40042
  description: Configure REST function pagination with continuation expressions
39568
40043
  for hasNext and nextUrl
39569
40044
  code: |-
39570
- const fn = app.addFunction.rest({ functionId: 'list-items', method: 'GET', url: 'https://api.example.com/items' })
40045
+ const fn = app.addFunction.rest({
40046
+ functionId: 'list-items',
40047
+ method: 'GET',
40048
+ url: 'https://api.example.com/items',
40049
+ })
39571
40050
  fn.continuation.when(toExpression('=$.hasNext')).url(toExpression('=$.nextUrl'))
39572
40051
  - id: function.rest-example-3
39573
40052
  name: REST Function with Entity Storage and Data Conversions
@@ -39584,7 +40063,11 @@
39584
40063
  from base64 to buffer and local URI
39585
40064
  code: |-
39586
40065
  app.addFunction
39587
- .rest({ functionId: 'get-products', method: 'GET', url: 'https://api.example.com/products' })
40066
+ .rest({
40067
+ functionId: 'get-products',
40068
+ method: 'GET',
40069
+ url: 'https://api.example.com/products',
40070
+ })
39588
40071
  .entity('default/products')
39589
40072
  .conversion('price', 'base64', 'buffer')
39590
40073
  .conversion('image', 'base64', 'local-uri', 'product-image.jpg')
@@ -39684,7 +40167,12 @@
39684
40167
  parameters and output transformation
39685
40168
  code: |-
39686
40169
  const fn = app.addFunction
39687
- .soap({ functionId: 'get-weather', connection: 'weather-service', method: 'GetWeather', wsdl: 'https://weather.com/wsdl' })
40170
+ .soap({
40171
+ functionId: 'get-weather',
40172
+ connection: 'weather-service',
40173
+ method: 'GetWeather',
40174
+ wsdl: 'https://weather.com/wsdl',
40175
+ })
39688
40176
  .outputTransform('$.Temperature')
39689
40177
  fn.params.body('city', 'London').header('apiKey', 'secret-key')
39690
40178
  - id: function.soap-example-2
@@ -39701,7 +40189,12 @@
39701
40189
  storage for order processing
39702
40190
  code: |-
39703
40191
  app.addFunction
39704
- .soap({ functionId: 'create-order', connection: 'order-service', method: 'CreateOrder', wsdl: 'https://orders.com/wsdl' })
40192
+ .soap({
40193
+ functionId: 'create-order',
40194
+ connection: 'order-service',
40195
+ method: 'CreateOrder',
40196
+ wsdl: 'https://orders.com/wsdl',
40197
+ })
39705
40198
  .inputTransform('="123"')
39706
40199
  .entity('orders')
39707
40200
  - id: function.soap-example-3
@@ -39719,7 +40212,12 @@
39719
40212
  conversions for thumbnails and source images
39720
40213
  code: |-
39721
40214
  const fn = app.addFunction
39722
- .soap({ functionId: 'process-image', connection: 'image-service', method: 'ProcessImage', wsdl: 'https://image.com/wsdl' })
40215
+ .soap({
40216
+ functionId: 'process-image',
40217
+ connection: 'image-service',
40218
+ method: 'ProcessImage',
40219
+ wsdl: 'https://image.com/wsdl',
40220
+ })
39723
40221
  .base64ToUri('thumbnail', 'thumb.jpg')
39724
40222
  .uriToBase64('source')
39725
40223
  fn.params.body('image', '=@ctx.solution.state.imageData')
@@ -39738,7 +40236,12 @@
39738
40236
  SOAP faults and network timeouts with retry logic
39739
40237
  code: |-
39740
40238
  const fn = app.addFunction
39741
- .soap({ functionId: 'weather-api', connection: 'weather-service', method: 'GetWeatherForecast', wsdl: 'https://weather.example.com/service?wsdl' })
40239
+ .soap({
40240
+ functionId: 'weather-api',
40241
+ connection: 'weather-service',
40242
+ method: 'GetWeatherForecast',
40243
+ wsdl: 'https://weather.example.com/service?wsdl',
40244
+ })
39742
40245
  .outputTransform('$.GetWeatherForecastResult')
39743
40246
  fn.params
39744
40247
  .body('city', '=@ctx.jig.inputs.location.city')
@@ -39775,7 +40278,8 @@
39775
40278
  description: Create SQL query function for customers with boolean parameter and
39776
40279
  entity storage
39777
40280
  code: |-
39778
- const fn = app.addFunction.sql({ functionId: 'get-customers', connection: 'mydb' })
40281
+ const fn = app.addFunction
40282
+ .sql({ functionId: 'get-customers', connection: 'mydb' })
39779
40283
  .sql('SELECT * FROM customers WHERE active = @active')
39780
40284
  fn.params.input('$active', 'boolean', { value: true })
39781
40285
  fn.entity('customers')
@@ -39792,7 +40296,8 @@
39792
40296
  description: Configure SQL function to execute stored procedure with input and
39793
40297
  output parameters for customer updates
39794
40298
  code: |-
39795
- const fn = app.addFunction.sql({ functionId: 'update-customer', connection: 'mydb', method: 'execute' })
40299
+ const fn = app.addFunction
40300
+ .sql({ functionId: 'update-customer', connection: 'mydb', method: 'execute' })
39796
40301
  .sql('sp_UpdateCustomer', 'procedure')
39797
40302
  fn.params
39798
40303
  .input('$customerId', 'number', { value: 123 })
@@ -39811,7 +40316,8 @@
39811
40316
  description: Generate SQL function with select helper for specific columns and
39812
40317
  active status filter
39813
40318
  code: |-
39814
- const fn = app.addFunction.sql({ functionId: 'get-customers', connection: 'mydb' })
40319
+ const fn = app.addFunction
40320
+ .sql({ functionId: 'get-customers', connection: 'mydb' })
39815
40321
  .select(['id', 'name', 'email'], 'customers', 'active = @active')
39816
40322
  fn.params.input('active', 'boolean', { value: true })
39817
40323
  - id: function.sql-example-4
@@ -39825,8 +40331,10 @@
39825
40331
  - no-where-clause
39826
40332
  description: Generate SQL function with select all helper to retrieve all
39827
40333
  products without filtering
39828
- code: "app.addFunction.sql({ functionId: 'get-all-products', connection: 'mydb'
39829
- }).selectAll('products')"
40334
+ code: |-
40335
+ app.addFunction
40336
+ .sql({ functionId: 'get-all-products', connection: 'mydb' })
40337
+ .selectAll('products')
39830
40338
  - id: function.sql-example-5
39831
40339
  name: SQL Function with Select All Helper and WHERE Clause Filter
39832
40340
  category: function
@@ -39840,7 +40348,8 @@
39840
40348
  description: Generate SQL function with select all helper and status parameter
39841
40349
  for active product filtering
39842
40350
  code: |-
39843
- const fn = app.addFunction.sql({ functionId: 'get-active-products', connection: 'mydb' })
40351
+ const fn = app.addFunction
40352
+ .sql({ functionId: 'get-active-products', connection: 'mydb' })
39844
40353
  .selectAll('products', 'status = @status')
39845
40354
  fn.params.input('status', 'string', { value: 'active' })
39846
40355
  - id: function.sql-example-6
@@ -39858,7 +40367,8 @@
39858
40367
  description: Configure SQL order sync function with comprehensive database error
39859
40368
  handling including constraint violations, lock errors and retry logic
39860
40369
  code: |-
39861
- const fn = app.addFunction.sql({ functionId: 'sync-orders', connection: 'orders_db' })
40370
+ const fn = app.addFunction
40371
+ .sql({ functionId: 'sync-orders', connection: 'orders_db' })
39862
40372
  .sql(
39863
40373
  'INSERT INTO orders (id, customer_id, total, status) VALUES (@id, @customer_id, @total, @status)',
39864
40374
  )
@@ -39922,7 +40432,11 @@
39922
40432
  description: Configure REST function header using branded ParameterName type
39923
40433
  code: |-
39924
40434
  const paramName = toParameterName('apiKey')
39925
- const builder = app.addFunction.rest({ functionId: 'test', method: 'GET', url: 'https://api.test.com' })
40435
+ const builder = app.addFunction.rest({
40436
+ functionId: 'test',
40437
+ method: 'GET',
40438
+ url: 'https://api.test.com',
40439
+ })
39926
40440
  // Should not throw with valid parameter name
39927
40441
  builder.params.header(paramName, 'secret')
39928
40442
  - id: function-example-3
@@ -39943,7 +40457,11 @@
39943
40457
  dependencies, and continuation support using config object
39944
40458
  code: |-
39945
40459
  const app = new ApplicationBuilder({ name: 'test-application' })
39946
- const fn = app.addFunction.rest({ functionId: 'config-query', method: 'GET', url: 'https://api.test.com' })
40460
+ const fn = app.addFunction.rest({
40461
+ functionId: 'config-query',
40462
+ method: 'GET',
40463
+ url: 'https://api.test.com',
40464
+ })
39947
40465
  fn.query('items', {
39948
40466
  statement: 'SELECT * FROM items WHERE active = 1',
39949
40467
  resultType: 'records',
@@ -39967,7 +40485,11 @@
39967
40485
  and scalar/record result type
39968
40486
  code: |-
39969
40487
  const app = new ApplicationBuilder({ name: 'test-application' })
39970
- const fn = app.addFunction.rest({ functionId: 'param-config-query', method: 'GET', url: 'https://api.test.com' })
40488
+ const fn = app.addFunction.rest({
40489
+ functionId: 'param-config-query',
40490
+ method: 'GET',
40491
+ url: 'https://api.test.com',
40492
+ })
39971
40493
  fn.query('lookup', {
39972
40494
  statement: 'SELECT * FROM items WHERE id = @id',
39973
40495
  parameters: { id: '=@ctx.user.id' },
@@ -39984,7 +40506,11 @@
39984
40506
  description: Set output expression to control what the function returns to its caller
39985
40507
  code: |-
39986
40508
  const app = new ApplicationBuilder({ name: 'test-application' })
39987
- const fn = app.addFunction.rest({ functionId: 'output-fn', method: 'GET', url: 'https://api.test.com' })
40509
+ const fn = app.addFunction.rest({
40510
+ functionId: 'output-fn',
40511
+ method: 'GET',
40512
+ url: 'https://api.test.com',
40513
+ })
39988
40514
  fn.output('=@ctx.response.body.result')
39989
40515
  - id: screen.bottom-sheet-example-1
39990
40516
  name: Bottom Sheet with Child Screens
@@ -40643,7 +41169,7 @@
40643
41169
  template component
40644
41170
  code: |-
40645
41171
  const dynamicGridScreen = app.addScreen
40646
- .dynamicGrid({ screenId: 'grid-1', title: 'Dynamic Grid', })
41172
+ .dynamicGrid({ screenId: 'grid-1', title: 'Dynamic Grid' })
40647
41173
  .data('=@ctx.datasources.dynamic')
40648
41174
  // Add required item template
40649
41175
  dynamicGridScreen.addControl.gridItem({ instanceId: 'item-1', size: '1x1' })
@@ -40663,7 +41189,7 @@
40663
41189
  subtitle for dynamic content
40664
41190
  code: |-
40665
41191
  const dynamicGridWithWidget = app.addScreen
40666
- .dynamicGrid({ screenId: 'dynamic-widget-test', title: 'Widget Test', })
41192
+ .dynamicGrid({ screenId: 'dynamic-widget-test', title: 'Widget Test' })
40667
41193
  .data('=@ctx.datasources.items') // Add required data
40668
41194
  // Add required item template
40669
41195
  dynamicGridWithWidget.addControl.gridItem({ instanceId: 'item-1', size: '1x1' })
@@ -40685,7 +41211,7 @@
40685
41211
  data-bound items
40686
41212
  code: |-
40687
41213
  const screen = app.addScreen
40688
- .dynamicGrid({ screenId: 'dynamic-item-test', title: 'Item Test', })
41214
+ .dynamicGrid({ screenId: 'dynamic-item-test', title: 'Item Test' })
40689
41215
  .data('=@ctx.datasources.items') // Add required data
40690
41216
  screen.addControl.gridItem()
40691
41217
  - id: screen.grid-dynamic-example-4
@@ -40703,7 +41229,7 @@
40703
41229
  line chart series data
40704
41230
  code: |-
40705
41231
  const dynamicGridWithChart = app.addScreen
40706
- .dynamicGrid({ screenId: 'dg', title: 'Dynamic Grid', })
41232
+ .dynamicGrid({ screenId: 'dg', title: 'Dynamic Grid' })
40707
41233
  .data('=@ctx.datasources.items') // Add required data
40708
41234
  // Add item template and widget
40709
41235
  dynamicGridWithChart.addControl.gridItem()
@@ -41579,7 +42105,7 @@
41579
42105
  from solution state
41580
42106
  code: |-
41581
42107
  const gridWithDynamicSummary = app.addScreen
41582
- .dynamicGrid({ screenId: 'dynamic-summary-test', title: 'Dynamic Summary', })
42108
+ .dynamicGrid({ screenId: 'dynamic-summary-test', title: 'Dynamic Summary' })
41583
42109
  .data('=@ctx.datasources.items')
41584
42110
  gridWithDynamicSummary.addControl.gridItem({ size: '1x1' })
41585
42111
  gridWithDynamicSummary.summary().addControl.default({
@@ -42023,7 +42549,9 @@
42023
42549
  concurrency: 'parallel',
42024
42550
  instanceId: 'load-data',
42025
42551
  })
42026
- const ds = screen.addDatasource.sqlite({ datasourceId: 'preferences', provider: 'local' }).entity('default/notifications')
42552
+ const ds = screen.addDatasource
42553
+ .sqlite({ datasourceId: 'preferences', provider: 'local' })
42554
+ .entity('default/notifications')
42027
42555
  onFocusAction.actions
42028
42556
  .executeEntity({ instanceId: 'load-notifications' })
42029
42557
  .dynamicData('default/notifications', 'update')
@@ -42690,7 +43218,11 @@
42690
43218
  productPreview.title('Product Showcase')
42691
43219
  productPreview.subtitle('Browse our product collection')
42692
43220
  const productEntity = productPreview.addControl.entity({ instanceId: 'product-preview' })
42693
- productEntity.addControl.entityField({ instanceId: 'name', label: 'Product Name', value: 'Premium Widget' })
43221
+ productEntity.addControl.entityField({
43222
+ instanceId: 'name',
43223
+ label: 'Product Name',
43224
+ value: 'Premium Widget',
43225
+ })
42694
43226
  productEntity.addControl.entityField({ instanceId: 'price', label: 'Price', value: '$99.99' })
42695
43227
  // Dashboard screen with compact preview
42696
43228
  const dashboard = app.addScreen.default({
@@ -44329,7 +44861,14 @@
44329
44861
  instanceId: 'office-marker',
44330
44862
  address: '=@ctx.current.item.address',
44331
44863
  })
44332
- officeMarker.with({ radius: { value: 0.5, unit: 'kilometers', color: 'primary', isEnabled: '=@ctx.current.item.showCoverage' } })
44864
+ officeMarker.with({
44865
+ radius: {
44866
+ value: 0.5,
44867
+ unit: 'kilometers',
44868
+ color: 'primary',
44869
+ isEnabled: '=@ctx.current.item.showCoverage',
44870
+ },
44871
+ })
44333
44872
  officeMarker.addIcon({ icon: 'office-building-tall-1', color: 'info' })
44334
44873
  // Create grid to display widgets (custom/static mode for map dashboard)
44335
44874
  const staticGrid = screen.addControl.grid()