@epilot/entity-client 7.1.1 → 7.2.0-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.2",
3
3
  "info": {
4
4
  "title": "Entity API",
5
- "version": "2.8.0",
5
+ "version": "2.9.0",
6
6
  "description": "Flexible data layer for epilot Entities.\n\nUse this API configure and access your business objects like Contacts, Opportunities and Products.\n\n[Feature Documentation](https://docs.epilot.io/docs/entities/flexible-entities)\n"
7
7
  },
8
8
  "tags": [
@@ -1428,6 +1428,9 @@
1428
1428
  "schema": {
1429
1429
  "$ref": "#/components/schemas/FieldsParam"
1430
1430
  }
1431
+ },
1432
+ {
1433
+ "$ref": "#/components/parameters/ApplyChangesetsQueryParam"
1431
1434
  }
1432
1435
  ],
1433
1436
  "responses": {
@@ -1619,6 +1622,9 @@
1619
1622
  },
1620
1623
  {
1621
1624
  "$ref": "#/components/parameters/ValidateEntityQueryParam"
1625
+ },
1626
+ {
1627
+ "$ref": "#/components/parameters/DirectQueryParam"
1622
1628
  }
1623
1629
  ],
1624
1630
  "requestBody": {
@@ -1682,6 +1688,9 @@
1682
1688
  },
1683
1689
  {
1684
1690
  "$ref": "#/components/parameters/ValidateEntityQueryParam"
1691
+ },
1692
+ {
1693
+ "$ref": "#/components/parameters/DirectQueryParam"
1685
1694
  }
1686
1695
  ],
1687
1696
  "requestBody": {
@@ -1881,7 +1890,7 @@
1881
1890
  "post": {
1882
1891
  "operationId": "createActivity",
1883
1892
  "summary": "createActivity",
1884
- "description": "Create an activity that can be displayed in activity feeds.\n\n- All activites are published as events on the event bus\n- Entity mutations are always part of an activity\n",
1893
+ "description": "Create an activity that can be displayed in activity feeds.\n\n- All activites are published as events on the event bus\n- Entity mutations are always part of an activity\n- When more than 10 entities are passed, the first 10 are attached synchronously and the rest are processed asynchronously to avoid DynamoDB throttling\n",
1885
1894
  "tags": [
1886
1895
  "Activity"
1887
1896
  ],
@@ -2023,6 +2032,138 @@
2023
2032
  }
2024
2033
  }
2025
2034
  },
2035
+ "/v1/entity/{slug}/{id}/changesets/{attribute}:apply": {
2036
+ "post": {
2037
+ "operationId": "applyChangeset",
2038
+ "summary": "applyChangeset",
2039
+ "description": "Applies the proposed value from a pending changeset to the entity attribute\nand removes the changeset. Used for human approval of pending changes.\n",
2040
+ "tags": [
2041
+ "Entities"
2042
+ ],
2043
+ "parameters": [
2044
+ {
2045
+ "$ref": "#/components/parameters/EntitySlugPathParam"
2046
+ },
2047
+ {
2048
+ "$ref": "#/components/parameters/EntityIdPathParam"
2049
+ },
2050
+ {
2051
+ "in": "path",
2052
+ "name": "attribute",
2053
+ "required": true,
2054
+ "description": "Attribute name of the changeset to apply",
2055
+ "schema": {
2056
+ "type": "string"
2057
+ }
2058
+ }
2059
+ ],
2060
+ "responses": {
2061
+ "200": {
2062
+ "description": "Changeset applied successfully — returns updated entity",
2063
+ "content": {
2064
+ "application/json": {
2065
+ "schema": {
2066
+ "$ref": "#/components/schemas/EntityItem"
2067
+ }
2068
+ }
2069
+ }
2070
+ },
2071
+ "404": {
2072
+ "$ref": "#/components/responses/NotFoundError"
2073
+ }
2074
+ }
2075
+ }
2076
+ },
2077
+ "/v1/entity/{slug}/{id}/changesets/{attribute}:dismiss": {
2078
+ "post": {
2079
+ "operationId": "dismissChangeset",
2080
+ "summary": "dismissChangeset",
2081
+ "description": "Removes a pending changeset without applying it. The attribute value remains unchanged.\n",
2082
+ "tags": [
2083
+ "Entities"
2084
+ ],
2085
+ "parameters": [
2086
+ {
2087
+ "$ref": "#/components/parameters/EntitySlugPathParam"
2088
+ },
2089
+ {
2090
+ "$ref": "#/components/parameters/EntityIdPathParam"
2091
+ },
2092
+ {
2093
+ "in": "path",
2094
+ "name": "attribute",
2095
+ "required": true,
2096
+ "description": "Attribute name of the changeset to dismiss",
2097
+ "schema": {
2098
+ "type": "string"
2099
+ }
2100
+ }
2101
+ ],
2102
+ "requestBody": {
2103
+ "content": {
2104
+ "application/json": {
2105
+ "schema": {
2106
+ "type": "object",
2107
+ "properties": {
2108
+ "reason": {
2109
+ "type": "string",
2110
+ "description": "Optional reason for dismissing the changeset"
2111
+ }
2112
+ }
2113
+ }
2114
+ }
2115
+ }
2116
+ },
2117
+ "responses": {
2118
+ "200": {
2119
+ "description": "Changeset dismissed successfully — returns updated entity",
2120
+ "content": {
2121
+ "application/json": {
2122
+ "schema": {
2123
+ "$ref": "#/components/schemas/EntityItem"
2124
+ }
2125
+ }
2126
+ }
2127
+ },
2128
+ "404": {
2129
+ "$ref": "#/components/responses/NotFoundError"
2130
+ }
2131
+ }
2132
+ }
2133
+ },
2134
+ "/v1/entity/{slug}/{id}/changesets": {
2135
+ "get": {
2136
+ "operationId": "listChangesets",
2137
+ "summary": "listChangesets",
2138
+ "description": "Returns all pending changesets for an entity.",
2139
+ "tags": [
2140
+ "Entities"
2141
+ ],
2142
+ "parameters": [
2143
+ {
2144
+ "$ref": "#/components/parameters/EntitySlugPathParam"
2145
+ },
2146
+ {
2147
+ "$ref": "#/components/parameters/EntityIdPathParam"
2148
+ }
2149
+ ],
2150
+ "responses": {
2151
+ "200": {
2152
+ "description": "Pending changesets for the entity",
2153
+ "content": {
2154
+ "application/json": {
2155
+ "schema": {
2156
+ "$ref": "#/components/schemas/ChangesetMap"
2157
+ }
2158
+ }
2159
+ }
2160
+ },
2161
+ "404": {
2162
+ "$ref": "#/components/responses/NotFoundError"
2163
+ }
2164
+ }
2165
+ }
2166
+ },
2026
2167
  "/v1/entity/{slug}/{id}/activity": {
2027
2168
  "get": {
2028
2169
  "operationId": "getEntityActivityFeed",
@@ -3704,7 +3845,7 @@
3704
3845
  "description": "ISO 8601 timestamp to filter jobs created after this time (e.g., 2023-01-01T00:00:00Z).",
3705
3846
  "type": "string",
3706
3847
  "format": "date-time",
3707
- "example": "2023-01-01T00:00:00.000Z"
3848
+ "example": "2023-01-01T00:00:00Z"
3708
3849
  }
3709
3850
  },
3710
3851
  {
@@ -4935,6 +5076,16 @@
4935
5076
  "type": "string"
4936
5077
  }
4937
5078
  },
5079
+ "_manifest": {
5080
+ "type": "array",
5081
+ "description": "Manifest ID used to create the schema",
5082
+ "items": {
5083
+ "type": "string",
5084
+ "format": "uuid",
5085
+ "example": "123e4567-e89b-12d3-a456-426614174000"
5086
+ },
5087
+ "nullable": true
5088
+ },
4938
5089
  "explicit_search_mappings": {
4939
5090
  "$ref": "#/components/schemas/SearchMappings"
4940
5091
  },
@@ -5487,6 +5638,20 @@
5487
5638
  },
5488
5639
  "has_primary": {
5489
5640
  "type": "boolean"
5641
+ },
5642
+ "edit_mode": {
5643
+ "type": "string",
5644
+ "description": "Controls how updates to this attribute are handled.\n- `direct` (default): update is applied immediately. No changeset created.\n- `external`: update creates a changeset, auto-cleared on matching external update (e.g. ERP inbound sync via ?direct=true).\n- `approval`: update creates a changeset, requires explicit human approval.\n",
5645
+ "enum": [
5646
+ "direct",
5647
+ "external",
5648
+ "approval"
5649
+ ],
5650
+ "default": "direct"
5651
+ },
5652
+ "edit_mode_config": {
5653
+ "$ref": "#/components/schemas/EditModeConfig",
5654
+ "description": "Configuration for non-direct edit modes. Required when edit_mode is external or approval with fuzzy match strategy."
5490
5655
  }
5491
5656
  },
5492
5657
  "required": [
@@ -6544,6 +6709,11 @@
6544
6709
  "type": "boolean",
6545
6710
  "description": "Whether this column is required for each row",
6546
6711
  "default": false
6712
+ },
6713
+ "bold": {
6714
+ "type": "boolean",
6715
+ "description": "When true, the row is rendered in bold (only applies in transposed mode)",
6716
+ "default": false
6547
6717
  }
6548
6718
  },
6549
6719
  "required": [
@@ -6560,8 +6730,30 @@
6560
6730
  },
6561
6731
  "max_rows": {
6562
6732
  "type": "integer",
6563
- "description": "Maximum number of rows allowed",
6733
+ "description": "Maximum number of rows allowed (or maximum periods when transposed)",
6564
6734
  "minimum": 1
6735
+ },
6736
+ "transposed": {
6737
+ "type": "boolean",
6738
+ "description": "Enable transposed layout where rows become metrics and columns become periods",
6739
+ "default": false
6740
+ },
6741
+ "column_header": {
6742
+ "type": "object",
6743
+ "description": "Configuration for column headers in transposed mode",
6744
+ "properties": {
6745
+ "template": {
6746
+ "type": "string",
6747
+ "description": "Header label pattern with {{i}} as index placeholder (e.g., \"Year {{i}}\")",
6748
+ "example": "Year {{i}}"
6749
+ },
6750
+ "start": {
6751
+ "type": "integer",
6752
+ "description": "Starting index value for the template placeholder",
6753
+ "default": 0,
6754
+ "minimum": 0
6755
+ }
6756
+ }
6565
6757
  }
6566
6758
  }
6567
6759
  }
@@ -7375,6 +7567,18 @@
7375
7567
  "example": "123e4567-e89b-12d3-a456-426614174000"
7376
7568
  },
7377
7569
  "nullable": true
7570
+ },
7571
+ "_changesets": {
7572
+ "allOf": [
7573
+ {
7574
+ "readOnly": true
7575
+ },
7576
+ {
7577
+ "$ref": "#/components/schemas/ChangesetMap"
7578
+ }
7579
+ ],
7580
+ "nullable": true,
7581
+ "description": "Pending attribute changesets for attributes configured with external or approval edit mode.\nRead-only via normal entity PATCH/PUT operations — cannot be set directly.\nUse the changeset management endpoints to apply or dismiss changesets.\n"
7378
7582
  }
7379
7583
  },
7380
7584
  "example": {
@@ -8308,6 +8512,11 @@
8308
8512
  "type": "boolean",
8309
8513
  "description": "If true, return full entity objects in entityNodes instead of just entity IDs in nodes",
8310
8514
  "default": false
8515
+ },
8516
+ "apply_changesets": {
8517
+ "type": "boolean",
8518
+ "description": "When true and hydrate is also true, entity objects in entityNodes have pending changeset proposed values applied in-place. The _changesets field is still included in the response.",
8519
+ "default": false
8311
8520
  }
8312
8521
  }
8313
8522
  },
@@ -8604,11 +8813,16 @@
8604
8813
  "float",
8605
8814
  "date",
8606
8815
  "flattened",
8607
- "nested"
8816
+ "nested",
8817
+ "object"
8608
8818
  ]
8609
8819
  },
8610
8820
  "fields": {
8611
8821
  "additionalProperties": true
8822
+ },
8823
+ "dynamic": {
8824
+ "type": "boolean",
8825
+ "description": "When false, prevents ES from inferring types for nested fields. Used for _changesets where values can be any type."
8612
8826
  }
8613
8827
  }
8614
8828
  }
@@ -8675,7 +8889,7 @@
8675
8889
  },
8676
8890
  "ActivityType": {
8677
8891
  "type": "string",
8678
- "description": "A type for the activity. Used to categorize activities in the activity feed and for event subscriptions.\n\nBuilt-in entity activity types (custom activities can be defined as well):\n- EntityCreated\n- EntityUpdated\n- EntityDeleted\n- EntitySoftDeleted\n- EntityRestored\n- RelationsAdded\n- RelationsRemoved\n- RelationsSoftDeleted\n- RelationsRestored\n- RelationsDeleted\n"
8892
+ "description": "A type for the activity. Used to categorize activities in the activity feed and for event subscriptions.\n\nBuilt-in entity activity types (custom activities can be defined as well):\n- EntityCreated\n- EntityUpdated\n- EntityDeleted\n- EntitySoftDeleted\n- EntityRestored\n- RelationsAdded\n- RelationsRemoved\n- RelationsSoftDeleted\n- RelationsRestored\n- RelationsDeleted\n- ChangesetCreated\n- ChangesetAutoCleared\n- ChangesetApplied\n- ChangesetDismissed\n"
8679
8893
  },
8680
8894
  "Activity": {
8681
8895
  "type": "object",
@@ -9463,6 +9677,143 @@
9463
9677
  "example": "Bad Request"
9464
9678
  }
9465
9679
  }
9680
+ },
9681
+ "ChangesetCreator": {
9682
+ "type": "object",
9683
+ "description": "Identifies the actor that created the changeset.",
9684
+ "properties": {
9685
+ "type": {
9686
+ "type": "string",
9687
+ "description": "Type of actor that created the changeset",
9688
+ "enum": [
9689
+ "user",
9690
+ "portal_user",
9691
+ "api_client",
9692
+ "automation"
9693
+ ]
9694
+ },
9695
+ "id": {
9696
+ "type": "string",
9697
+ "description": "ID of the actor (user ID, portal user ID, API client ID, etc.)"
9698
+ }
9699
+ }
9700
+ },
9701
+ "Changeset": {
9702
+ "type": "object",
9703
+ "description": "A pending proposed change for a single entity attribute, awaiting external confirmation or human approval.",
9704
+ "required": [
9705
+ "proposed_value",
9706
+ "created_at",
9707
+ "edit_mode"
9708
+ ],
9709
+ "properties": {
9710
+ "proposed_value": {
9711
+ "description": "The proposed new value for the attribute. Type matches the attribute type."
9712
+ },
9713
+ "previous_value": {
9714
+ "description": "The attribute value at the time the changeset was created. Stored for reference."
9715
+ },
9716
+ "created_at": {
9717
+ "type": "string",
9718
+ "format": "date-time",
9719
+ "description": "Timestamp when the changeset was created"
9720
+ },
9721
+ "created_by": {
9722
+ "$ref": "#/components/schemas/ChangesetCreator"
9723
+ },
9724
+ "edit_mode": {
9725
+ "type": "string",
9726
+ "description": "The edit mode that triggered this changeset",
9727
+ "enum": [
9728
+ "external",
9729
+ "approval"
9730
+ ]
9731
+ },
9732
+ "match_strategy": {
9733
+ "$ref": "#/components/schemas/MatchStrategy"
9734
+ },
9735
+ "source": {
9736
+ "type": "string",
9737
+ "description": "Optional label indicating where the change originated (e.g. end_customer_portal, installer_portal, journey, automation)"
9738
+ }
9739
+ }
9740
+ },
9741
+ "ChangesetMap": {
9742
+ "type": "object",
9743
+ "description": "Map of attribute name to pending changeset. At most one changeset per attribute.",
9744
+ "additionalProperties": {
9745
+ "$ref": "#/components/schemas/Changeset"
9746
+ }
9747
+ },
9748
+ "EditModeConfig": {
9749
+ "type": "object",
9750
+ "description": "Configuration for non-direct edit modes on an entity attribute.",
9751
+ "properties": {
9752
+ "match_strategy": {
9753
+ "$ref": "#/components/schemas/MatchStrategy"
9754
+ },
9755
+ "fuzzy_config": {
9756
+ "$ref": "#/components/schemas/FuzzyConfig"
9757
+ }
9758
+ }
9759
+ },
9760
+ "FuzzyConfig": {
9761
+ "type": "object",
9762
+ "description": "Configuration for fuzzy match strategies on changeset auto-clearing.",
9763
+ "required": [
9764
+ "type"
9765
+ ],
9766
+ "properties": {
9767
+ "type": {
9768
+ "type": "string",
9769
+ "description": "Which fuzzy algorithm to apply.",
9770
+ "enum": [
9771
+ "suffix",
9772
+ "digits_only",
9773
+ "normalize_phone",
9774
+ "ignore_fields",
9775
+ "contains_entry",
9776
+ "regex"
9777
+ ]
9778
+ },
9779
+ "suffix_length": {
9780
+ "type": "integer",
9781
+ "description": "For type=suffix: number of characters to compare from end of string."
9782
+ },
9783
+ "fields_to_ignore": {
9784
+ "type": "array",
9785
+ "items": {
9786
+ "type": "string"
9787
+ },
9788
+ "description": "For type=ignore_fields: field names to exclude when comparing array entries."
9789
+ },
9790
+ "regex_flags": {
9791
+ "type": "string",
9792
+ "description": "For type=regex: flags to apply to the regex (e.g. 'i' for case-insensitive)."
9793
+ },
9794
+ "country_code": {
9795
+ "type": "string",
9796
+ "description": "For type=normalize_phone: country dialing code digits to strip (e.g. '49' for Germany). No '+' prefix."
9797
+ },
9798
+ "match_on": {
9799
+ "type": "string",
9800
+ "description": "For type=normalize_phone and type=contains_entry: attribute key(s) within array entries to compare on."
9801
+ },
9802
+ "pattern": {
9803
+ "type": "string",
9804
+ "description": "For type=regex: regular expression pattern to test the incoming value against."
9805
+ }
9806
+ }
9807
+ },
9808
+ "MatchStrategy": {
9809
+ "type": "string",
9810
+ "description": "Strategy for auto-clearing the changeset when an external update is received.\n- `exact`: The inbound value must exactly match the proposed value (deep equality).\n- `fuzzy`: The inbound value is compared using the configured fuzzy algorithm.\n- `any`: Any update to the attribute clears the changeset, regardless of value.\n",
9811
+ "enum": [
9812
+ "exact",
9813
+ "fuzzy",
9814
+ "any"
9815
+ ],
9816
+ "default": "exact"
9466
9817
  }
9467
9818
  },
9468
9819
  "parameters": {
@@ -9699,6 +10050,26 @@
9699
10050
  "default": false,
9700
10051
  "type": "boolean"
9701
10052
  }
10053
+ },
10054
+ "DirectQueryParam": {
10055
+ "name": "direct",
10056
+ "description": "When true, bypasses changeset interception and applies attribute updates directly.\nUsed by trusted integrations (e.g. ERP inbound sync) to confirm changes and auto-clear matching pending changesets.\nDefaults to false — no breaking change for existing callers.\n",
10057
+ "in": "query",
10058
+ "required": false,
10059
+ "schema": {
10060
+ "type": "boolean",
10061
+ "default": false
10062
+ }
10063
+ },
10064
+ "ApplyChangesetsQueryParam": {
10065
+ "name": "apply_changesets",
10066
+ "description": "When true, applies pending changeset proposed values in-place on the response entity.\nThe response includes both the hydrated values and the raw _changesets field.\nDoes not mutate stored data — pure read-time transform.\n",
10067
+ "in": "query",
10068
+ "required": false,
10069
+ "schema": {
10070
+ "type": "boolean",
10071
+ "default": false
10072
+ }
9702
10073
  }
9703
10074
  },
9704
10075
  "examples": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epilot/entity-client",
3
- "version": "7.1.1",
3
+ "version": "7.2.0-rc1",
4
4
  "description": "JavaScript client library for the epilot Core Entity API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",