@epilot/app-client 0.12.8 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- (()=>{"use strict";var e={330:function(e,r,t){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(r,"__esModule",{value:!0});var p=n(t(466));r.default=p.default},466:e=>{e.exports=JSON.parse('{"openapi":"3.1.0","info":{"title":"","version":""},"servers":[{"url":"https://app.sls.epilot.io"}],"paths":{"/v1/public/app/{appId}/components/{componentId}":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the app configuration to install"},{"name":"componentId","in":"path","required":true,"description":"ID of the component to retrieve"}],"get":{"operationId":"getPublicFacingComponent","responses":{}}},"/v1/app-configurations":{"get":{"operationId":"listConfigurations","parameters":[{"name":"page","in":"query"},{"name":"pageSize","in":"query"}],"responses":{}},"post":{"operationId":"createConfiguration","requestBody":{"$ref":"#/components/requestBodies/CreateConfigRequest"},"responses":{}}},"/v1/app-configurations/public":{"get":{"operationId":"listPublicConfigurations","parameters":[{"name":"page","in":"query"},{"name":"pageSize","in":"query"}],"responses":{}}},"/v1/app-configurations/public/{appId}":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the app configuration to install"}],"get":{"operationId":"getPublicConfiguration","parameters":[{"name":"version","in":"query"}],"responses":{}}},"/v1/app-configurations/{appId}":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the app configuration"}],"get":{"operationId":"getConfiguration","parameters":[{"name":"version","in":"query"}],"responses":{}},"patch":{"operationId":"patchMetadata","requestBody":{"$ref":"#/components/requestBodies/PatchConfigMetadataRequest"},"responses":{}},"delete":{"operationId":"deleteConfiguration","responses":{}}},"/v1/app-configurations/{appId}/events":{"post":{"operationId":"queryEvents","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"required":true,"content":{"application/json":{}}},"responses":{}}},"/v1/app-configurations/{appId}/bundle":{"post":{"operationId":"createBundleUploadUrl","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/CreateBundlePresignedRequest"},"responses":{}}},"/v1/app-configurations/{appId}/zip":{"post":{"operationId":"createZipUploadUrl","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"content":{"application/json":{}}},"responses":{}}},"/v1/app-configurations/{appId}/logo":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the app configuration"}],"post":{"operationId":"createLogoUploadUrl","requestBody":{"$ref":"#/components/requestBodies/CreateLogoPresignedRequest"},"responses":{}},"delete":{"operationId":"deleteLogo","responses":{}}},"/v1/app-configurations/{appId}/versions":{"get":{"operationId":"listVersions","parameters":[{"name":"appId","in":"path","required":true},{"name":"page","in":"query"},{"name":"pageSize","in":"query"}],"responses":{}}},"/v1/app-configurations/{appId}/versions/{version}":{"get":{"operationId":"getVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"responses":{}},"delete":{"operationId":"deleteVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"responses":{}},"patch":{"operationId":"patchVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/PatchVersionRequest"},"responses":{}}},"/v1/app-configurations/{appId}/versions/{version}/review":{"get":{"operationId":"getReview","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"responses":{}},"post":{"operationId":"createReview","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/CreateReviewRequest"},"responses":{}}},"/v1/app-configurations/{appId}/versions/{version}/components":{"post":{"operationId":"createComponent","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/UpsertComponentRequest"},"responses":{}}},"/v1/app-configurations/{appId}/versions/{version}/components/{componentId}":{"patch":{"operationId":"patchComponent","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true},{"name":"componentId","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/UpsertComponentRequest"},"responses":{}},"delete":{"operationId":"deleteComponent","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true},{"name":"componentId","in":"path","required":true}],"responses":{}}},"/v1/app-configurations/{appId}/versions/{sourceVersion}/clone-to/{targetVersion}":{"post":{"operationId":"cloneVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"sourceVersion","in":"path","required":true},{"name":"targetVersion","in":"path","required":true}],"responses":{}}},"/v1/app":{"get":{"operationId":"listInstallations","parameters":[{"name":"componentType","in":"query"},{"name":"enabled","in":"query"},{"name":"page","in":"query"},{"name":"pageSize","in":"query"}],"responses":{}}},"/v1/app/{appId}":{"get":{"operationId":"getInstallation","parameters":[{"name":"appId","in":"path","required":true}],"responses":{}},"post":{"operationId":"install","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/InstallRequest"},"responses":{}},"patch":{"operationId":"patchInstallation","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/InstallRequest"},"responses":{}},"delete":{"operationId":"uninstall","parameters":[{"name":"appId","in":"path","required":true}],"responses":{}}},"/v1/app/{appId}/promote-to/{version}":{"post":{"operationId":"promoteVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"responses":{}}},"/v1/app-events":{"post":{"operationId":"ingestEvent","requestBody":{"required":true,"content":{"application/json":{}}},"responses":{}}},"/v1/public/app/{appId}/proxy/{proxyName}/{path}":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the installed app"},{"name":"proxyName","in":"path","required":true,"description":"Name of the proxy target as defined in the app manifest"},{"name":"path","in":"path","required":true,"description":"Path to forward to the proxy target"}],"get":{"operationId":"publicProxyGet","responses":{}},"post":{"operationId":"publicProxyPost","requestBody":{"content":{"application/json":{}}},"responses":{}}}},"components":{"requestBodies":{"CreateReviewRequest":{"required":true,"content":{"application/json":{}}},"CreateLogoPresignedRequest":{"required":true,"content":{"application/json":{}}},"CreateBundlePresignedRequest":{"required":true,"content":{"application/json":{}}},"PatchConfigMetadataRequest":{"required":true,"content":{"application/json":{}}},"PatchVersionRequest":{"required":true,"content":{"application/json":{}}},"UpsertComponentRequest":{"required":true,"content":{"application/json":{}}},"CreateConfigRequest":{"required":true,"content":{"application/json":{}}},"InstallRequest":{"content":{"application/json":{}}}}}}')}},r={},t=function t(n){var p=r[n];if(void 0!==p)return p.exports;var o=r[n]={exports:{}};return e[n].call(o.exports,o,o.exports,t),o.exports}(330),n=exports;for(var p in t)n[p]=t[p];t.__esModule&&Object.defineProperty(n,"__esModule",{value:!0})})();
1
+ (()=>{"use strict";var e={330(e,r,t){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(r,"__esModule",{value:!0});var p=n(t(466));r.default=p.default},466(e){e.exports=JSON.parse('{"openapi":"3.1.0","info":{"title":"","version":""},"servers":[{"url":"https://app.sls.epilot.io"}],"paths":{"/v1/public/app/{appId}/components/{componentId}":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the app configuration to install"},{"name":"componentId","in":"path","required":true,"description":"ID of the component to retrieve"}],"get":{"operationId":"getPublicFacingComponent","responses":{}}},"/v1/app-configurations":{"get":{"operationId":"listConfigurations","parameters":[{"name":"page","in":"query"},{"name":"pageSize","in":"query"}],"responses":{}},"post":{"operationId":"createConfiguration","requestBody":{"$ref":"#/components/requestBodies/CreateConfigRequest"},"responses":{}}},"/v1/app-configurations/public":{"get":{"operationId":"listPublicConfigurations","parameters":[{"name":"page","in":"query"},{"name":"pageSize","in":"query"}],"responses":{}}},"/v1/app-configurations/public/{appId}":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the app configuration to install"}],"get":{"operationId":"getPublicConfiguration","parameters":[{"name":"version","in":"query"}],"responses":{}}},"/v1/app-configurations/{appId}":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the app configuration"}],"get":{"operationId":"getConfiguration","parameters":[{"name":"version","in":"query"}],"responses":{}},"patch":{"operationId":"patchMetadata","requestBody":{"$ref":"#/components/requestBodies/PatchConfigMetadataRequest"},"responses":{}},"delete":{"operationId":"deleteConfiguration","responses":{}}},"/v1/app-configurations/{appId}/events":{"post":{"operationId":"queryEvents","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"required":true,"content":{"application/json":{}}},"responses":{}}},"/v1/app-configurations/{appId}/bundle":{"post":{"operationId":"createBundleUploadUrl","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/CreateBundlePresignedRequest"},"responses":{}}},"/v1/app-configurations/{appId}/zip":{"post":{"operationId":"createZipUploadUrl","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"content":{"application/json":{}}},"responses":{}}},"/v1/app-configurations/{appId}/logo":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the app configuration"}],"post":{"operationId":"createLogoUploadUrl","requestBody":{"$ref":"#/components/requestBodies/CreateLogoPresignedRequest"},"responses":{}},"delete":{"operationId":"deleteLogo","responses":{}}},"/v1/app-configurations/{appId}/versions":{"get":{"operationId":"listVersions","parameters":[{"name":"appId","in":"path","required":true},{"name":"page","in":"query"},{"name":"pageSize","in":"query"}],"responses":{}}},"/v1/app-configurations/{appId}/versions/{version}":{"get":{"operationId":"getVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"responses":{}},"delete":{"operationId":"deleteVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"responses":{}},"patch":{"operationId":"patchVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/PatchVersionRequest"},"responses":{}}},"/v1/app-configurations/{appId}/versions/{version}/review":{"get":{"operationId":"getReview","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"responses":{}},"post":{"operationId":"createReview","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/CreateReviewRequest"},"responses":{}}},"/v1/app-configurations/{appId}/versions/{version}/components":{"post":{"operationId":"createComponent","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/UpsertComponentRequest"},"responses":{}}},"/v1/app-configurations/{appId}/versions/{version}/components/{componentId}":{"patch":{"operationId":"patchComponent","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true},{"name":"componentId","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/UpsertComponentRequest"},"responses":{}},"delete":{"operationId":"deleteComponent","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true},{"name":"componentId","in":"path","required":true}],"responses":{}}},"/v1/app-configurations/{appId}/versions/{sourceVersion}/clone-to/{targetVersion}":{"post":{"operationId":"cloneVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"sourceVersion","in":"path","required":true},{"name":"targetVersion","in":"path","required":true}],"responses":{}}},"/v1/app":{"get":{"operationId":"listInstallations","parameters":[{"name":"componentType","in":"query"},{"name":"enabled","in":"query"},{"name":"page","in":"query"},{"name":"pageSize","in":"query"}],"responses":{}}},"/v1/app/{appId}":{"get":{"operationId":"getInstallation","parameters":[{"name":"appId","in":"path","required":true}],"responses":{}},"post":{"operationId":"install","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/InstallRequest"},"responses":{}},"patch":{"operationId":"patchInstallation","parameters":[{"name":"appId","in":"path","required":true}],"requestBody":{"$ref":"#/components/requestBodies/InstallRequest"},"responses":{}},"delete":{"operationId":"uninstall","parameters":[{"name":"appId","in":"path","required":true}],"responses":{}}},"/v1/app/{appId}/promote-to/{version}":{"post":{"operationId":"promoteVersion","parameters":[{"name":"appId","in":"path","required":true},{"name":"version","in":"path","required":true}],"responses":{}}},"/v1/app-events":{"post":{"operationId":"ingestEvent","requestBody":{"required":true,"content":{"application/json":{}}},"responses":{}}},"/v1/public/app/{appId}/proxy/{proxyName}/{path}":{"parameters":[{"name":"appId","in":"path","required":true,"description":"ID of the installed app"},{"name":"proxyName","in":"path","required":true,"description":"Name of the proxy target as defined in the app manifest"},{"name":"path","in":"path","required":true,"description":"Path to forward to the proxy target"}],"get":{"operationId":"publicProxyGet","responses":{}},"post":{"operationId":"publicProxyPost","requestBody":{"content":{"application/json":{}}},"responses":{}}}},"components":{"requestBodies":{"CreateReviewRequest":{"required":true,"content":{"application/json":{}}},"CreateLogoPresignedRequest":{"required":true,"content":{"application/json":{}}},"CreateBundlePresignedRequest":{"required":true,"content":{"application/json":{}}},"PatchConfigMetadataRequest":{"required":true,"content":{"application/json":{}}},"PatchVersionRequest":{"required":true,"content":{"application/json":{}}},"UpsertComponentRequest":{"required":true,"content":{"application/json":{}}},"CreateConfigRequest":{"required":true,"content":{"application/json":{}}},"InstallRequest":{"content":{"application/json":{}}}}}}')}},r={},t=function t(n){var p=r[n];if(void 0!==p)return p.exports;var o=r[n]={exports:{}};return e[n].call(o.exports,o,o.exports,t),o.exports}(330),n=exports;for(var p in t)n[p]=t[p];t.__esModule&&Object.defineProperty(n,"__esModule",{value:!0})})();
package/dist/openapi.d.ts CHANGED
@@ -1338,15 +1338,44 @@ declare namespace Components {
1338
1338
  events?: NotificationEvent[];
1339
1339
  }
1340
1340
  export type NotificationEvent = "app.installed" | "app.uninstalled";
1341
+ /**
1342
+ * One declared field inside a `type: object` option. Fields are primitives — object nesting
1343
+ * is not supported.
1344
+ *
1345
+ */
1346
+ export interface ObjectField {
1347
+ /**
1348
+ * Unique identifier for this field within the parent object.
1349
+ */
1350
+ key: string;
1351
+ /**
1352
+ * Human-readable label for the field.
1353
+ */
1354
+ label?: string;
1355
+ /**
1356
+ * Detailed description of what this field is for.
1357
+ */
1358
+ description?: string;
1359
+ /**
1360
+ * Flag to indicate if this field must be filled.
1361
+ */
1362
+ required?: boolean;
1363
+ /**
1364
+ * Primitive type of this field.
1365
+ */
1366
+ type: "text" | "number" | "boolean" | "secret";
1367
+ }
1341
1368
  export interface Option {
1342
1369
  /**
1343
1370
  * Key matching a config_option from the component
1344
1371
  */
1345
1372
  key: string;
1346
1373
  /**
1347
- * The configured value for this option
1374
+ * The configured value for this option. Shape depends on the matching component option's
1375
+ * `type` and `repeatable` (see `Options.value`).
1376
+ *
1348
1377
  */
1349
- value: string | boolean | number;
1378
+ value: any;
1350
1379
  }
1351
1380
  /**
1352
1381
  * Options for the component configuration
@@ -1369,10 +1398,41 @@ declare namespace Components {
1369
1398
  */
1370
1399
  description?: string;
1371
1400
  /**
1372
- * The configured value for this option. Is only present when the component is installed.
1401
+ * When true, the configured value is an array of entries, each tagged with a stable
1402
+ * server-assigned `id`. Combine with any `type` to express "many of this thing."
1403
+ * Defaults to false.
1404
+ *
1373
1405
  */
1374
- value?: string | boolean | number;
1375
- type: "text" | "number" | "boolean" | "secret";
1406
+ repeatable?: boolean;
1407
+ /**
1408
+ * Field declarations — required when `type: object`. Each entry describes one primitive
1409
+ * sub-field of the object value. Object types may not nest (no `type: object` inside `fields`).
1410
+ *
1411
+ */
1412
+ fields?: /**
1413
+ * One declared field inside a `type: object` option. Fields are primitives — object nesting
1414
+ * is not supported.
1415
+ *
1416
+ */
1417
+ ObjectField[];
1418
+ /**
1419
+ * The configured value for this option. Shape depends on `type` and `repeatable`:
1420
+ * - primitive `type` (text/number/boolean/secret), `repeatable` false → primitive
1421
+ * - primitive `type`, `repeatable` true → array of `{id, value}` entries
1422
+ * - `type: object`, `repeatable` false → object with declared fields
1423
+ * - `type: object`, `repeatable` true → array of `{id, ...declared fields}` entries
1424
+ *
1425
+ * `id` is server-assigned and stable across edits so consumers can reference entries
1426
+ * by id rather than by index.
1427
+ *
1428
+ */
1429
+ value?: any;
1430
+ /**
1431
+ * The type of this option. `object` declares a structured value whose fields are listed
1432
+ * under `fields`. Combine with `repeatable: true` to express a list of these objects.
1433
+ *
1434
+ */
1435
+ type: "text" | "number" | "boolean" | "secret" | "object";
1376
1436
  }
1377
1437
  export interface OptionsRef {
1378
1438
  /**
@@ -1520,15 +1580,13 @@ declare namespace Components {
1520
1580
  * - 200 with a JSON body of shape:
1521
1581
  * {
1522
1582
  * "type_options": [
1523
- * { "id": "feed-out", "label": { "en": "Grid import" }, "aggregation_group": "grid", "statistical_method": "sum", "direction": "out", "unit": "kWh" },
1524
- * { "id": "feed-in", "label": { "en": "Feed-in" }, "aggregation_group": "grid", "statistical_method": "sum", "direction": "in", "unit": "kWh" },
1583
+ * { "id": "ht", "label": { "en": "High tariff" }, "aggregation_group": "consumption", "statistical_method": "sum", "unit": "kWh" },
1525
1584
  * ...
1526
1585
  * ],
1527
1586
  * "intervals": ["PT15M", "PT1H", "P1D", "P1M"],
1528
1587
  * "data_range": { "from": "2024-01-01T00:00:00Z", "to": "2026-05-01T00:00:00Z" }
1529
1588
  * }
1530
1589
  * Each type option carries its own `statistical_method`, which describes the method already applied to that type's data and dictates the chart shape: `sum` is rendered as a bar chart; `min`, `average`, and `max` are rendered as a line chart. A single visualization can therefore mix bar-shaped types with line-shaped types. Defaults to `sum` when omitted.
1531
- * `direction` declares whether a type adds to or subtracts from the period total: `out` is grid-to-consumer (consumption, additive); `in` is consumer-to-grid (export, subtractive). With both present in a prosumer setup the chart computes a *net* consumption per period and can flip its label to "Total production" when the result is negative. Defaults to `out` when omitted.
1532
1590
  * `aggregation_group` controls how types within a group are visually combined (depends on the per-type `statistical_method`):
1533
1591
  * - bar chart (`sum`): same-group types are stacked into a single bar (e.g. ht/nt summed into total consumption); different-group types render side-by-side.
1534
1592
  * - line chart (`min` / `average` / `max`): same-group types are rendered as an area chart; different-group types render as separate lines.
@@ -2045,15 +2103,13 @@ declare namespace Components {
2045
2103
  * - 200 with a JSON body of shape:
2046
2104
  * {
2047
2105
  * "type_options": [
2048
- * { "id": "feed-out", "label": { "en": "Grid import" }, "aggregation_group": "grid", "statistical_method": "sum", "direction": "out", "unit": "kWh" },
2049
- * { "id": "feed-in", "label": { "en": "Feed-in" }, "aggregation_group": "grid", "statistical_method": "sum", "direction": "in", "unit": "kWh" },
2106
+ * { "id": "ht", "label": { "en": "High tariff" }, "aggregation_group": "consumption", "statistical_method": "sum", "unit": "kWh" },
2050
2107
  * ...
2051
2108
  * ],
2052
2109
  * "intervals": ["PT15M", "PT1H", "P1D", "P1M"],
2053
2110
  * "data_range": { "from": "2024-01-01T00:00:00Z", "to": "2026-05-01T00:00:00Z" }
2054
2111
  * }
2055
2112
  * Each type option carries its own `statistical_method`, which describes the method already applied to that type's data and dictates the chart shape: `sum` is rendered as a bar chart; `min`, `average`, and `max` are rendered as a line chart. A single visualization can therefore mix bar-shaped types with line-shaped types. Defaults to `sum` when omitted.
2056
- * `direction` declares whether a type adds to or subtracts from the period total: `out` is grid-to-consumer (consumption, additive); `in` is consumer-to-grid (export, subtractive). With both present in a prosumer setup the chart computes a *net* consumption per period and can flip its label to "Total production" when the result is negative. Defaults to `out` when omitted.
2057
2113
  * `aggregation_group` controls how types within a group are visually combined (depends on the per-type `statistical_method`):
2058
2114
  * - bar chart (`sum`): same-group types are stacked into a single bar (e.g. ht/nt summed into total consumption); different-group types render side-by-side.
2059
2115
  * - line chart (`min` / `average` / `max`): same-group types are rendered as an area chart; different-group types render as separate lines.
@@ -3670,6 +3726,7 @@ export type JourneyBlockComponentArgs = Components.Schemas.JourneyBlockComponent
3670
3726
  export type JourneyBlockConfig = Components.Schemas.JourneyBlockConfig;
3671
3727
  export type NotificationConfig = Components.Schemas.NotificationConfig;
3672
3728
  export type NotificationEvent = Components.Schemas.NotificationEvent;
3729
+ export type ObjectField = Components.Schemas.ObjectField;
3673
3730
  export type Option = Components.Schemas.Option;
3674
3731
  export type Options = Components.Schemas.Options;
3675
3732
  export type OptionsRef = Components.Schemas.OptionsRef;
package/dist/openapi.json CHANGED
@@ -1842,13 +1842,56 @@
1842
1842
  "type": "string",
1843
1843
  "description": "Detailed description of what this configuration option does"
1844
1844
  },
1845
+ "repeatable": {
1846
+ "type": "boolean",
1847
+ "description": "When true, the configured value is an array of entries, each tagged with a stable\nserver-assigned `id`. Combine with any `type` to express \"many of this thing.\"\nDefaults to false.\n"
1848
+ },
1849
+ "fields": {
1850
+ "type": "array",
1851
+ "description": "Field declarations — required when `type: object`. Each entry describes one primitive\nsub-field of the object value. Object types may not nest (no `type: object` inside `fields`).\n",
1852
+ "items": {
1853
+ "$ref": "#/components/schemas/ObjectField"
1854
+ }
1855
+ },
1845
1856
  "value": {
1846
- "type": [
1847
- "string",
1857
+ "description": "The configured value for this option. Shape depends on `type` and `repeatable`:\n- primitive `type` (text/number/boolean/secret), `repeatable` false → primitive\n- primitive `type`, `repeatable` true → array of `{id, value}` entries\n- `type: object`, `repeatable` false → object with declared fields\n- `type: object`, `repeatable` true → array of `{id, ...declared fields}` entries\n\n`id` is server-assigned and stable across edits so consumers can reference entries\nby id rather than by index.\n"
1858
+ },
1859
+ "type": {
1860
+ "type": "string",
1861
+ "enum": [
1862
+ "text",
1863
+ "number",
1848
1864
  "boolean",
1849
- "number"
1865
+ "secret",
1866
+ "object"
1850
1867
  ],
1851
- "description": "The configured value for this option. Is only present when the component is installed."
1868
+ "description": "The type of this option. `object` declares a structured value whose fields are listed\nunder `fields`. Combine with `repeatable: true` to express a list of these objects.\n"
1869
+ }
1870
+ }
1871
+ },
1872
+ "ObjectField": {
1873
+ "type": "object",
1874
+ "description": "One declared field inside a `type: object` option. Fields are primitives — object nesting\nis not supported.\n",
1875
+ "required": [
1876
+ "key",
1877
+ "type"
1878
+ ],
1879
+ "properties": {
1880
+ "key": {
1881
+ "type": "string",
1882
+ "description": "Unique identifier for this field within the parent object."
1883
+ },
1884
+ "label": {
1885
+ "type": "string",
1886
+ "description": "Human-readable label for the field."
1887
+ },
1888
+ "description": {
1889
+ "type": "string",
1890
+ "description": "Detailed description of what this field is for."
1891
+ },
1892
+ "required": {
1893
+ "type": "boolean",
1894
+ "description": "Flag to indicate if this field must be filled."
1852
1895
  },
1853
1896
  "type": {
1854
1897
  "type": "string",
@@ -1857,7 +1900,8 @@
1857
1900
  "number",
1858
1901
  "boolean",
1859
1902
  "secret"
1860
- ]
1903
+ ],
1904
+ "description": "Primitive type of this field."
1861
1905
  }
1862
1906
  }
1863
1907
  },
@@ -1873,12 +1917,7 @@
1873
1917
  "description": "Key matching a config_option from the component"
1874
1918
  },
1875
1919
  "value": {
1876
- "type": [
1877
- "string",
1878
- "boolean",
1879
- "number"
1880
- ],
1881
- "description": "The configured value for this option"
1920
+ "description": "The configured value for this option. Shape depends on the matching component option's\n`type` and `repeatable` (see `Options.value`).\n"
1882
1921
  }
1883
1922
  }
1884
1923
  },
@@ -3252,7 +3291,7 @@
3252
3291
  "additionalProperties": false
3253
3292
  },
3254
3293
  "PortalExtensionHookVisualizationMetadata": {
3255
- "description": "Hook that returns runtime metadata describing how a visualization (consumption / price / cost chart) should be rendered for a given portal context (meter, contract, etc). It is invoked by the portal before fetching data, with the same context the data hook would receive, so that the discovery shape can vary per meter/contract. The expected response to the call is:\n - 200 with a JSON body of shape:\n {\n \"type_options\": [\n { \"id\": \"feed-out\", \"label\": { \"en\": \"Grid import\" }, \"aggregation_group\": \"grid\", \"statistical_method\": \"sum\", \"direction\": \"out\", \"unit\": \"kWh\" },\n { \"id\": \"feed-in\", \"label\": { \"en\": \"Feed-in\" }, \"aggregation_group\": \"grid\", \"statistical_method\": \"sum\", \"direction\": \"in\", \"unit\": \"kWh\" },\n ...\n ],\n \"intervals\": [\"PT15M\", \"PT1H\", \"P1D\", \"P1M\"],\n \"data_range\": { \"from\": \"2024-01-01T00:00:00Z\", \"to\": \"2026-05-01T00:00:00Z\" }\n }\n Each type option carries its own `statistical_method`, which describes the method already applied to that type's data and dictates the chart shape: `sum` is rendered as a bar chart; `min`, `average`, and `max` are rendered as a line chart. A single visualization can therefore mix bar-shaped types with line-shaped types. Defaults to `sum` when omitted.\n `direction` declares whether a type adds to or subtracts from the period total: `out` is grid-to-consumer (consumption, additive); `in` is consumer-to-grid (export, subtractive). With both present in a prosumer setup the chart computes a *net* consumption per period and can flip its label to \"Total production\" when the result is negative. Defaults to `out` when omitted.\n `aggregation_group` controls how types within a group are visually combined (depends on the per-type `statistical_method`):\n - bar chart (`sum`): same-group types are stacked into a single bar (e.g. ht/nt summed into total consumption); different-group types render side-by-side.\n - line chart (`min` / `average` / `max`): same-group types are rendered as an area chart; different-group types render as separate lines.\n All fields are optional; the consumer falls back to its defaults for whatever the hook does not return.\nThe portal looks up this hook implicitly per extension (one `visualizationMetadata` hook per extension) — there is no need for a data-retrieval hook to reference it explicitly.\n",
3294
+ "description": "Hook that returns runtime metadata describing how a visualization (consumption / price / cost chart) should be rendered for a given portal context (meter, contract, etc). It is invoked by the portal before fetching data, with the same context the data hook would receive, so that the discovery shape can vary per meter/contract. The expected response to the call is:\n - 200 with a JSON body of shape:\n {\n \"type_options\": [\n { \"id\": \"ht\", \"label\": { \"en\": \"High tariff\" }, \"aggregation_group\": \"consumption\", \"statistical_method\": \"sum\", \"unit\": \"kWh\" },\n ...\n ],\n \"intervals\": [\"PT15M\", \"PT1H\", \"P1D\", \"P1M\"],\n \"data_range\": { \"from\": \"2024-01-01T00:00:00Z\", \"to\": \"2026-05-01T00:00:00Z\" }\n }\n Each type option carries its own `statistical_method`, which describes the method already applied to that type's data and dictates the chart shape: `sum` is rendered as a bar chart; `min`, `average`, and `max` are rendered as a line chart. A single visualization can therefore mix bar-shaped types with line-shaped types. Defaults to `sum` when omitted.\n `aggregation_group` controls how types within a group are visually combined (depends on the per-type `statistical_method`):\n - bar chart (`sum`): same-group types are stacked into a single bar (e.g. ht/nt summed into total consumption); different-group types render side-by-side.\n - line chart (`min` / `average` / `max`): same-group types are rendered as an area chart; different-group types render as separate lines.\n All fields are optional; the consumer falls back to its defaults for whatever the hook does not return.\nThe portal looks up this hook implicitly per extension (one `visualizationMetadata` hook per extension) — there is no need for a data-retrieval hook to reference it explicitly.\n",
3256
3295
  "type": "object",
3257
3296
  "properties": {
3258
3297
  "id": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epilot/app-client",
3
- "version": "0.12.8",
3
+ "version": "0.13.0",
4
4
  "description": "JavaScript client library for the epilot App API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",