n8n-nodes-lifespace 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -62,11 +62,19 @@ The token is shown only when it is created or rotated. Store it in n8n immediate
62
62
 
63
63
  A **LifeSpace Trigger** additionally uses a **LifeSpace Webhook Signing** credential containing the endpoint-scoped HMAC signing secret. This is deliberately separate from the API credential: the Service API Token authenticates outbound n8n → LifeSpace calls, while the signing secret verifies inbound LifeSpace → n8n deliveries and rotates with its Webhook Endpoint. The Trigger still reuses the LifeSpace API credential for Space/Record Type discovery, so API context is not duplicated.
64
64
 
65
- Runtime Discovery determines which Spaces, Record Types, fields, queries, Actions and relation lookup capabilities the current API credential can use. Execution authorization is still enforced by LifeSpace from the current principal, credential scope, Application × Model Access and current Space/Data Grant authority.
65
+ Runtime Discovery determines which Spaces, Record Types, fields, queries, Actions and relation lookup capabilities the current API credential can use. The adapter starts from the compact current-principal inventory, then loads static semantic detail only for the selected Space/Record Type. Relation target lookup remains lazy and field-scoped. Execution authorization is still enforced by LifeSpace from the current principal, credential scope, Application × Model Access and current Space/Data Grant authority.
66
+
67
+ ## Generated Record UX
68
+
69
+ Create/Update keep scalar fields in n8n Resource Mapper while using native n8n controls for LifeSpace calendar-date fields and supported relations. Single relations use a selector; multi-relations use multi-select. List / Query offers typed filter variants for text, enum, boolean, number, date/time and authorized relations, while retaining the raw legacy filter as an expression/compatibility escape hatch.
70
+
71
+ The node displays the authorized human-readable `spaceName` when present while continuing to submit the stable `spc_*` ID.
72
+
73
+ Calendar-backed models use canonical `capabilityBindings.calendar` field roles instead of Event-specific field names. Date-only values are normalized to `YYYY-MM-DD`, and contradictory all-day/timed state is rejected locally before the mutation request while Core remains the final validation authority.
66
74
 
67
75
  ## LifeSpace contract compatibility
68
76
 
69
- This package follows the current LifeSpace Core Kernel `0.23.0` contract family.
77
+ This package follows the current LifeSpace Core Kernel `0.31.0` contract family. It consumes Runtime/Discovery semantics only; Eventing configuration and webhook delivery semantics are owned independently by Integration/Eventing `0.1.0`.
70
78
 
71
79
  The UX depends on these Kernel capabilities:
72
80
 
@@ -75,7 +83,27 @@ The UX depends on these Kernel capabilities:
75
83
  - `0.20.0`: Action semantic input separated from optimistic-concurrency metadata;
76
84
  - `0.21.0`: invitation-token transport hardening retained by the current baseline;
77
85
  - `0.22.0`: authoritative field `title` metadata plus ordered repeatable Generic Query sort metadata;
78
- - `0.23.0`: authorized source-field-aware Relation Target Lookup for `person` / `person_list` fields.
86
+ - `0.23.0`: authorized source-field-aware Relation Target Lookup for `person` / `person_list` fields;
87
+ - `0.24.0`: authorized human-readable `spaceName` projection while `spaceId` remains stable;
88
+ - `0.25.0`: bounded Capability field-role bindings, beginning with Calendar;
89
+ - `0.26.0`: progressively loadable single-model static semantic detail;
90
+ - `0.27.0`: compact current-principal inventory that de-duplicates model semantics from Space visibility edges;
91
+ - `0.28.0`: bounded batch Reference Resolution for relation IDs;
92
+ - `0.29.0`: canonical ordinary-record `referenceLabel` semantics plus `record` / `record_list` lookup and resolution;
93
+ - `0.30.0`: explicit paginated Change History collection and Model Control Plane ownership split;
94
+ - `0.31.0`: Integration/Eventing wire representation moves to the independent Integration/Eventing `0.1.0` contract while Core remains the Runtime authority.
95
+
96
+ The adapter prefers the `0.27+` progressive flow:
97
+
98
+ ```text
99
+ GET /me/_discovery/inventory
100
+ -> choose current Space / Record Type
101
+ -> GET /spaces/{spaceId}/_discovery/models/{modelKey}
102
+ -> relation target lookup / reference resolution only when needed
103
+ -> canonical Runtime request
104
+ ```
105
+
106
+ The legacy aggregate `GET /me/_discovery` remains an intentional compatibility fallback. Neither cached Discovery nor relation lookup is treated as authorization proof; every mutation still goes through canonical LifeSpace Runtime enforcement.
79
107
 
80
108
  Ordinary Record CRUD/Action routes remain model-contract surfaces derived from published Model Definitions; the n8n adapter does not maintain a second copy of those schemas.
81
109
 
@@ -98,7 +126,7 @@ The same applies to ordinary values such as Record ID, Search, Filter Value, Ret
98
126
  Two boundaries are intentional:
99
127
 
100
128
  - **Resource** and **Operation** are structural node controls and do not accept expressions because they determine which parameter schema and execution path the node has.
101
- - **Fields** and **Action Input** use n8n's `resourceMapper`. The mapper container is structural, but each generated field value inside it remains expression-capable. This includes relation-backed field values: the UI can offer authorized Person options while an expression can still supply a stable Person ID or ID list.
129
+ - **Fields** and **Action Input** use n8n's `resourceMapper`. The mapper container is structural, but each generated field value inside it remains expression-capable. This includes relation-backed field values: the UI can offer authorized options while an expression can still supply a stable relation ID or ID list.
102
130
 
103
131
  For **Filters** and **Sorts**, add the required rows in the node UI and use expressions inside each row's Field/Operator/Value or Field/Direction inputs. The number of rows is treated as workflow structure rather than per-item data. This avoids relying on whole-array expressions for n8n `fixedCollection` parameters.
104
132
 
@@ -125,9 +153,9 @@ Supported operations:
125
153
 
126
154
  For Record operations:
127
155
 
128
- 1. choose a **Space** from `/me/_discovery`;
156
+ 1. choose a **Space** from compact Runtime Discovery inventory;
129
157
  2. choose a **Record Type** available in that Space;
130
- 3. configure the operation.
158
+ 3. configure the operation; the selected model's semantic detail is loaded only when required.
131
159
 
132
160
  You normally do not type Space IDs or model keys manually.
133
161
 
@@ -139,11 +167,11 @@ LifeSpace server defaults are authoritative. A field that is `required` but has
139
167
 
140
168
  For example, lifecycle state such as Task status can remain server/Action-owned instead of being manually entered by the workflow author.
141
169
 
142
- When Runtime Discovery advertises supported Relation Target Lookup, `person` and `person_list` fields are rendered from the current authorized `{ id, label }` target projection instead of asking the workflow author to type raw `per_*` identifiers. The displayed value is the LifeSpace Person label, while the workflow payload still stores and submits the stable Person ID.
170
+ When Runtime Discovery advertises relation semantics, supported `person`, `person_list`, `record` and `record_list` fields are rendered from the current authorized `{ id, label }` target projection instead of asking the workflow author to type raw identifiers. The displayed value is the canonical LifeSpace reference label, while the workflow payload still stores and submits the stable target ID.
143
171
 
144
- Older compatible Discovery responses without relation lookup metadata retain the raw-ID field behavior. `record` / `record_list` fields also retain raw-ID behavior until LifeSpace defines canonical generic Record reference-label semantics; the adapter does not guess labels from fields such as `name`, `title` or `summary`.
172
+ Older compatible Discovery responses without relation lookup metadata retain the raw-ID field behavior. The adapter never guesses record labels from conventional fields such as `name`, `title` or `summary`.
145
173
 
146
- The current n8n Resource Mapper loads bounded relation options when the field schema is requested. Very large target sets should use expressions with stable IDs until n8n exposes a searchable per-field Resource Mapper option surface that can consume LifeSpace's paginated/searchable lookup directly.
174
+ The current n8n UI loads bounded relation options when the relevant field is configured. Very large target sets should use expressions with stable IDs until n8n exposes a searchable dynamic relation option surface that can consume LifeSpace's paginated/searchable lookup directly.
147
175
 
148
176
  ### Update and Delete
149
177
 
@@ -151,6 +179,8 @@ LifeSpace uses optimistic concurrency.
151
179
 
152
180
  By default the node reads the current Record version immediately before Update/Delete and sends that version with the mutation. This keeps the ordinary n8n UI free from mandatory internal `version` entry while preserving stale-write protection for the actual mutation race.
153
181
 
182
+ For Calendar-backed Update, the node also combines the current record with the proposed patch and checks the discovered all-day/timed field roles before sending the mutation. Core validation remains authoritative.
183
+
154
184
  If a workflow intentionally needs to bind a known version, add **Concurrency Options → Version**.
155
185
 
156
186
  ### List / Query
@@ -158,7 +188,7 @@ If a workflow intentionally needs to bind a known version, add **Concurrency Opt
158
188
  The normal UI supports:
159
189
 
160
190
  - optional **Search**;
161
- - one or more **Filters**;
191
+ - one or more typed **Filters**;
162
192
  - **Return All** to follow `nextCursor` automatically;
163
193
  - **Limit** when Return All is disabled.
164
194
 
@@ -174,6 +204,8 @@ Choose an Action from Runtime Discovery.
174
204
 
175
205
  **Action Input** contains only semantic/domain inputs. LifeSpace concurrency metadata is not rendered as a business field. For the current `record-version` contract, the node reads the current Record version immediately before Action execution and sends it using the transport declared by Runtime Discovery.
176
206
 
207
+ Execution-time Action metadata uses the same progressive inventory + selected-model detail path rather than loading the full cross-Space Discovery document.
208
+
177
209
  This means actions such as `complete` / `reopen` no longer ask users to type an internal version value.
178
210
 
179
211
  ### Advanced API Request
@@ -183,7 +215,7 @@ The **API Request** resource is an escape hatch for LifeSpace routes that do not
183
215
  Paths are relative to the configured API Base URL, for example:
184
216
 
185
217
  ```text
186
- /me/_discovery
218
+ /me/_discovery/inventory
187
219
  ```
188
220
 
189
221
  Use normal Record operations when possible because they benefit from Runtime Discovery metadata and n8n-specific UX.
@@ -197,7 +229,7 @@ LifeSpace Eventing separates:
197
229
  - **Webhook Endpoint** — reusable callback URL, signing secret and delivery diagnostics for one Space;
198
230
  - **Event Subscription** — one Record Type plus selected event types attached to that endpoint.
199
231
 
200
- One Webhook Endpoint can therefore carry events for multiple Record Types through the same n8n callback.
232
+ One Webhook Endpoint can therefore carry events for multiple Record Types through the same n8n callback. In n8n this is represented as one Trigger selecting multiple Record Types; Integration/Eventing still keeps one Event Subscription filter per Record Type.
201
233
 
202
234
  ### Trigger setup
203
235
 
@@ -223,7 +255,7 @@ Webhook Endpoint / Event Subscription creation is intentionally not performed by
223
255
  - **LifeSpace Webhook Signing** credential for endpoint-scoped inbound HMAC verification;
224
256
  - **LifeSpace** node with discovery-driven Record operations plus advanced API Request;
225
257
  - **LifeSpace Trigger** with signed multi-Record-Type Domain Event filtering;
226
- - dynamic Space, Record Type, field, relation target, query, Action and Action Input UI based on Runtime Discovery.
258
+ - dynamic Space, Record Type, field, relation target, query, Action and Action Input UI based on progressive Runtime Discovery.
227
259
 
228
260
  LifeSpace remains authoritative for validation, authorization, defaults, Mutation Authority, Action semantics, relation semantics and event contracts. Runtime Discovery and Relation Target Lookup are current capability/reference projections, not execution-authorization proofs.
229
261
 
@@ -271,8 +303,8 @@ The package intentionally has no runtime `dependencies`. It must not read enviro
271
303
 
272
304
  ## Remaining upstream-dependent UX
273
305
 
274
- The adapter deliberately does not invent missing platform semantics. Remaining relation work is limited to `record` / `record_list` selectors after LifeSpace defines canonical generic Record reference-label semantics. Person relation selection already consumes the LifeSpace 0.23 Runtime/Discovery contract.
306
+ The adapter now consumes generic `person`, `person_list`, `record` and `record_list` reference labels/lookups when LifeSpace advertises them, and uses Calendar Capability bindings rather than model-specific field names. Remaining UX work should be driven by explicit future LifeSpace contract additions or n8n UI limitations; the adapter must not invent missing semantics locally.
275
307
 
276
308
  ## License
277
309
 
278
- MIT
310
+ MIT
@@ -7,6 +7,17 @@ export declare class LifeSpace implements INodeType {
7
7
  getRecordTypes(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
8
8
  getActions(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
9
9
  getFilterableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
10
+ getWritableDateFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
11
+ getSingleRelationFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
12
+ getMultiRelationFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
13
+ getRelationTargetsForCurrentField(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
14
+ getTextFilterableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
15
+ getEnumFilterableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
16
+ getBooleanFilterableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
17
+ getNumericFilterableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
18
+ getTemporalFilterableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
19
+ getPersonFilterableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
20
+ getEnumValuesForCurrentFilter(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
10
21
  getSortableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
11
22
  };
12
23
  resourceMapping: {