n8n-nodes-lifespace 0.1.0 → 0.1.2
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 +224 -96
- package/dist/credentials/LifeSpaceApi.credentials.d.ts +4 -1
- package/dist/credentials/LifeSpaceApi.credentials.js +12 -8
- package/dist/credentials/LifeSpaceApi.credentials.js.map +1 -1
- package/dist/credentials/LifeSpaceWebhookApi.credentials.d.ts +4 -1
- package/dist/credentials/LifeSpaceWebhookApi.credentials.js +8 -4
- package/dist/credentials/LifeSpaceWebhookApi.credentials.js.map +1 -1
- package/dist/credentials/lifespace.dark.svg +14 -0
- package/dist/credentials/lifespace.svg +5 -6
- package/dist/nodes/LifeSpace/LifeSpace.node.d.ts +14 -2
- package/dist/nodes/LifeSpace/LifeSpace.node.js +747 -173
- package/dist/nodes/LifeSpace/LifeSpace.node.js.map +1 -1
- package/dist/nodes/LifeSpace/lifespace.dark.svg +8 -9
- package/dist/nodes/LifeSpace/lifespace.svg +5 -9
- package/dist/nodes/LifeSpaceTrigger/LifeSpaceTrigger.node.d.ts +5 -1
- package/dist/nodes/LifeSpaceTrigger/LifeSpaceTrigger.node.js +74 -24
- package/dist/nodes/LifeSpaceTrigger/LifeSpaceTrigger.node.js.map +1 -1
- package/dist/nodes/LifeSpaceTrigger/lifespace.dark.svg +8 -9
- package/dist/nodes/LifeSpaceTrigger/lifespace.svg +5 -6
- package/dist/nodes/lifespaceDiscovery.d.ts +102 -0
- package/dist/nodes/lifespaceDiscovery.js +123 -0
- package/dist/nodes/lifespaceDiscovery.js.map +1 -0
- package/dist/package.json +5 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -2,155 +2,283 @@
|
|
|
2
2
|
|
|
3
3
|
Official n8n community nodes for integrating workflows and AI agents with LifeSpace.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install in n8n
|
|
6
6
|
|
|
7
|
-
The package
|
|
7
|
+
The npm package is:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
- discovery-driven Model, Action, Create/Update field, Query and Action Input UX against the connection's current LifeSpace authority;
|
|
13
|
-
- a LifeSpace Trigger that receives signed LifeSpace domain-event webhooks;
|
|
14
|
-
- the official `n8n-node` development toolchain;
|
|
15
|
-
- CI for lint and build validation;
|
|
16
|
-
- a GitHub Actions npm publishing path with provenance support.
|
|
9
|
+
```text
|
|
10
|
+
n8n-nodes-lifespace
|
|
11
|
+
```
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
### Self-hosted n8n: install from the UI
|
|
19
14
|
|
|
20
|
-
|
|
15
|
+
You must be an n8n instance Owner or Admin.
|
|
21
16
|
|
|
22
|
-
|
|
17
|
+
1. Open **Settings → Community Nodes**.
|
|
18
|
+
2. Select **Install**.
|
|
19
|
+
3. Enter:
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
```text
|
|
22
|
+
n8n-nodes-lifespace
|
|
23
|
+
```
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
4. Confirm the community-node warning.
|
|
26
|
+
5. Select **Install**.
|
|
27
|
+
6. Return to a workflow and search for **LifeSpace**.
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
To pin a release, use for example:
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
|
|
31
|
+
```text
|
|
32
|
+
n8n-nodes-lifespace@0.1.0
|
|
33
|
+
```
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
### Self-hosted n8n: manual npm installation
|
|
35
36
|
|
|
36
37
|
```bash
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
npm
|
|
38
|
+
mkdir -p ~/.n8n/nodes
|
|
39
|
+
cd ~/.n8n/nodes
|
|
40
|
+
npm install n8n-nodes-lifespace
|
|
40
41
|
```
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
Restart n8n afterwards. In queue mode, install the package anywhere that may execute workflows.
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
Create a **LifeSpace API** credential for Runtime Discovery and LifeSpace API calls.
|
|
48
|
+
|
|
49
|
+
It contains:
|
|
50
|
+
|
|
51
|
+
- **API Base URL**, for example:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
https://api.example.com/api/v1
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- **Service API Token**, an opaque LifeSpace `lsp_pat_*` token.
|
|
58
|
+
|
|
59
|
+
The API Base URL is the LifeSpace Core API root. Do not include a Space ID or Record Type path.
|
|
60
|
+
|
|
61
|
+
The token is shown only when it is created or rotated. Store it in n8n immediately; do not put it in workflow fields, URLs, source files, or workflow exports.
|
|
62
|
+
|
|
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
|
+
|
|
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.
|
|
66
|
+
|
|
67
|
+
## Generated Record UX
|
|
68
|
+
|
|
69
|
+
Create/Update now keep scalar fields in n8n Resource Mapper while using native n8n controls for LifeSpace calendar-date fields and supported relations. Single Person relations use a selector; multi-Person relations use multi-select. List / Query offers typed filter variants for text, enum, boolean, number, date/time and authorized Person relations, while retaining the raw legacy filter as an expression/compatibility escape hatch.
|
|
70
|
+
|
|
71
|
+
Core Kernel 0.24 adds the optional human-readable `spaceName` Runtime Discovery projection. The node displays it when present and continues to submit the stable `spc_*` ID; Core 0.23 remains compatible and falls back to displaying the raw Space ID.
|
|
72
|
+
|
|
73
|
+
## LifeSpace contract compatibility
|
|
74
|
+
|
|
75
|
+
This package follows the current LifeSpace Core Kernel `0.24.0` contract family.
|
|
76
|
+
|
|
77
|
+
The UX depends on these Kernel capabilities:
|
|
78
|
+
|
|
79
|
+
- `0.18.0`: cross-Space current-principal Runtime Discovery at `GET /api/v1/me/_discovery`;
|
|
80
|
+
- `0.19.0`: authoritative server defaults exposed in Runtime Discovery;
|
|
81
|
+
- `0.20.0`: Action semantic input separated from optimistic-concurrency metadata;
|
|
82
|
+
- `0.21.0`: invitation-token transport hardening retained by the current baseline;
|
|
83
|
+
- `0.22.0`: authoritative field `title` metadata plus ordered repeatable Generic Query sort metadata;
|
|
84
|
+
- `0.23.0`: authorized source-field-aware Relation Target Lookup for `person` / `person_list` fields;
|
|
85
|
+
- `0.24.0`: authorized human-readable `spaceName` projection in Runtime Discovery while `spaceId` remains the stable identifier.
|
|
86
|
+
|
|
87
|
+
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.
|
|
88
|
+
|
|
89
|
+
## Expressions and variables
|
|
90
|
+
|
|
91
|
+
Runtime/business inputs follow normal n8n expression behavior. A value that can be entered or selected in the node can also be supplied through an n8n expression unless it is deliberately a structural control.
|
|
92
|
+
|
|
93
|
+
Examples:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
{{$json.spaceId}}
|
|
97
|
+
{{$json.recordId}}
|
|
98
|
+
{{$vars.lifeSpaceRecordType}}
|
|
46
99
|
```
|
|
47
100
|
|
|
48
|
-
|
|
101
|
+
Discovery-backed selectors such as **Space**, **Record Type**, **Filter Field**, **Sort Field** and **Action** support the normal n8n pattern: choose a value from the list, or switch the parameter to an expression and provide the corresponding stable ID/key.
|
|
49
102
|
|
|
50
|
-
|
|
103
|
+
The same applies to ordinary values such as Record ID, Search, Filter Value, Return All, Limit, Sort Direction, Cursor, explicit Version, API Method, API Path and JSON Body.
|
|
51
104
|
|
|
52
|
-
|
|
53
|
-
- **Service API Token**, an opaque `lsp_pat_*` token issued for that connection.
|
|
105
|
+
Two boundaries are intentional:
|
|
54
106
|
|
|
55
|
-
|
|
107
|
+
- **Resource** and **Operation** are structural node controls and do not accept expressions because they determine which parameter schema and execution path the node has.
|
|
108
|
+
- **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.
|
|
56
109
|
|
|
57
|
-
|
|
110
|
+
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.
|
|
58
111
|
|
|
59
|
-
|
|
112
|
+
If **Record Type** itself varies per input item and those Record Types have different schemas, one discovery-generated mapper cannot safely represent every possible schema at design time. In that case, branch to separate LifeSpace nodes per schema or use **API Request** for a deliberately fully dynamic request.
|
|
60
113
|
|
|
61
|
-
|
|
114
|
+
A Trigger has no upstream input item. Trigger parameters can still use stable n8n variables/expressions, but should not rely on previous-item `$json` data. Because LifeSpace Webhook Endpoint/Event Subscription configuration is external to the Trigger today, variable-driven Trigger filters should remain stable with that external subscription configuration.
|
|
62
115
|
|
|
63
|
-
|
|
116
|
+
Credentials are intentionally static secure configuration and are not workflow-expression inputs.
|
|
64
117
|
|
|
65
|
-
|
|
66
|
-
- Get;
|
|
67
|
-
- List / Query;
|
|
68
|
-
- Update with optimistic concurrency;
|
|
69
|
-
- Delete with optimistic concurrency;
|
|
70
|
-
- Execute Action for published Capability/workflow actions.
|
|
118
|
+
## Use the LifeSpace node
|
|
71
119
|
|
|
72
|
-
The
|
|
120
|
+
The normal n8n-facing resource is **Record**. LifeSpace still owns **Model** semantics internally; the adapter uses **Record Type** for the workflow-facing selection.
|
|
73
121
|
|
|
74
|
-
|
|
122
|
+
Supported operations:
|
|
75
123
|
|
|
76
|
-
|
|
124
|
+
- **Create**;
|
|
125
|
+
- **Get**;
|
|
126
|
+
- **List / Query**;
|
|
127
|
+
- **Update**;
|
|
128
|
+
- **Delete**;
|
|
129
|
+
- **Execute Action**.
|
|
77
130
|
|
|
78
|
-
|
|
79
|
-
- read-only fields are excluded;
|
|
80
|
-
- immutable fields are additionally excluded from Update;
|
|
81
|
-
- enum fields render as options;
|
|
82
|
-
- number, boolean, datetime and list fields use the corresponding n8n input types;
|
|
83
|
-
- LifeSpace date-only fields intentionally remain strings so `YYYY-MM-DD` values are never converted into timezone-bearing instants;
|
|
84
|
-
- automatic input-data mapping is intentionally disabled for now so unrelated incoming keys are not silently sent to LifeSpace's strict model schema.
|
|
131
|
+
### Choose Space and Record Type
|
|
85
132
|
|
|
86
|
-
|
|
133
|
+
For Record operations:
|
|
87
134
|
|
|
88
|
-
|
|
135
|
+
1. choose a **Space** from `/me/_discovery`;
|
|
136
|
+
2. choose a **Record Type** available in that Space;
|
|
137
|
+
3. configure the operation.
|
|
89
138
|
|
|
90
|
-
|
|
91
|
-
- filter fields are limited to the model's published filterable fields;
|
|
92
|
-
- equality and supported range operators map to LifeSpace Generic Runtime query parameters;
|
|
93
|
-
- sort fields are limited to published sortable fields;
|
|
94
|
-
- pagination uses the LifeSpace `limit` and opaque `cursor` contract;
|
|
95
|
-
- the node does not invent query operators or field semantics that are absent from upstream Discovery metadata.
|
|
139
|
+
You normally do not type Space IDs or model keys manually.
|
|
96
140
|
|
|
97
|
-
###
|
|
141
|
+
### Create
|
|
98
142
|
|
|
99
|
-
|
|
143
|
+
Writable fields are generated from Runtime Discovery.
|
|
100
144
|
|
|
101
|
-
|
|
102
|
-
- the `record-occurrence` Capability action exposes `version`, `occurredOn` and optional `note` according to the upstream contract;
|
|
103
|
-
- required/optional status, primitive input types, date-only handling and length/range constraints come from LifeSpace metadata;
|
|
104
|
-
- the node does not copy action schemas into this package or accept an unrestricted Action Input JSON object for normal use.
|
|
145
|
+
LifeSpace server defaults are authoritative. A field that is `required` but has a declared server default is not required from the n8n user. Read-only state owned by a LifeSpace Action/Capability is not exposed as a normal Create/Update field.
|
|
105
146
|
|
|
106
|
-
|
|
147
|
+
For example, lifecycle state such as Task status can remain server/Action-owned instead of being manually entered by the workflow author.
|
|
107
148
|
|
|
108
|
-
|
|
149
|
+
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.
|
|
109
150
|
|
|
110
|
-
|
|
151
|
+
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`.
|
|
111
152
|
|
|
112
|
-
|
|
153
|
+
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.
|
|
113
154
|
|
|
114
|
-
|
|
155
|
+
### Update and Delete
|
|
115
156
|
|
|
116
|
-
|
|
157
|
+
LifeSpace uses optimistic concurrency.
|
|
117
158
|
|
|
118
|
-
|
|
119
|
-
2. copy the node's production webhook URL;
|
|
120
|
-
3. create a LifeSpace Webhook Endpoint for the target Space and use that URL as its destination;
|
|
121
|
-
4. attach one or more LifeSpace Event Subscription filters for the required model/events to that endpoint;
|
|
122
|
-
5. create a **LifeSpace Webhook API** credential and store the endpoint's one-time signing secret in that credential;
|
|
123
|
-
6. attach the credential to the Trigger and optionally set expected Space/model filters as an additional local check;
|
|
124
|
-
7. use LifeSpace's endpoint test action to verify delivery.
|
|
159
|
+
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.
|
|
125
160
|
|
|
126
|
-
|
|
161
|
+
If a workflow intentionally needs to bind a known version, add **Concurrency Options → Version**.
|
|
127
162
|
|
|
128
|
-
|
|
163
|
+
### List / Query
|
|
129
164
|
|
|
130
|
-
|
|
165
|
+
The normal UI supports:
|
|
166
|
+
|
|
167
|
+
- optional **Search**;
|
|
168
|
+
- one or more **Filters**;
|
|
169
|
+
- **Return All** to follow `nextCursor` automatically;
|
|
170
|
+
- **Limit** when Return All is disabled.
|
|
171
|
+
|
|
172
|
+
Use **Sorts → Add Sort** to add zero or more sort criteria in priority order. Sortable model fields use authoritative `title` metadata from Runtime Discovery, while envelope fields such as `createdAt` / `updatedAt` are offered only when Discovery advertises them. Multiple criteria are sent as ordered repeated `sort=field:direction` query parameters.
|
|
173
|
+
|
|
174
|
+
Advanced **Options** contain manual **Cursor** as an escape hatch.
|
|
175
|
+
|
|
176
|
+
If Sorts is omitted, the adapter omits the query parameter and LifeSpace supplies its deterministic default order. Existing workflow exports that still contain the former single `options.sortField` / `options.sortDirection` parameters remain executable for compatibility.
|
|
177
|
+
|
|
178
|
+
### Execute Action
|
|
179
|
+
|
|
180
|
+
Choose an Action from Runtime Discovery.
|
|
181
|
+
|
|
182
|
+
**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.
|
|
183
|
+
|
|
184
|
+
This means actions such as `complete` / `reopen` no longer ask users to type an internal version value.
|
|
185
|
+
|
|
186
|
+
### Advanced API Request
|
|
131
187
|
|
|
132
|
-
|
|
188
|
+
The **API Request** resource is an escape hatch for LifeSpace routes that do not yet have dedicated node UX.
|
|
133
189
|
|
|
134
|
-
|
|
190
|
+
Paths are relative to the configured API Base URL, for example:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
/me/_discovery
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Use normal Record operations when possible because they benefit from Runtime Discovery metadata and n8n-specific UX.
|
|
197
|
+
|
|
198
|
+
## Use the LifeSpace Trigger
|
|
199
|
+
|
|
200
|
+
The **LifeSpace Trigger** receives signed LifeSpace Domain Event webhooks.
|
|
201
|
+
|
|
202
|
+
LifeSpace Eventing separates:
|
|
203
|
+
|
|
204
|
+
- **Webhook Endpoint** — reusable callback URL, signing secret and delivery diagnostics for one Space;
|
|
205
|
+
- **Event Subscription** — one Record Type plus selected event types attached to that endpoint.
|
|
206
|
+
|
|
207
|
+
One Webhook Endpoint can therefore carry events for multiple Record Types through the same n8n callback.
|
|
208
|
+
|
|
209
|
+
### Trigger setup
|
|
210
|
+
|
|
211
|
+
1. Add a **LifeSpace Trigger** node.
|
|
212
|
+
2. Attach a **LifeSpace API** credential. The Trigger uses it only for Runtime Discovery and normal LifeSpace API context.
|
|
213
|
+
3. Attach a **LifeSpace Webhook Signing** credential containing the signing secret for this Webhook Endpoint.
|
|
214
|
+
4. Choose the **Space** from Runtime Discovery.
|
|
215
|
+
5. Choose one or more **Record Types**.
|
|
216
|
+
6. Choose the required **Event Types**.
|
|
217
|
+
7. Activate the workflow and copy the production webhook URL.
|
|
218
|
+
8. In the application/LifeSpace integration management surface, configure one **Webhook Endpoint** using that URL.
|
|
219
|
+
9. Store the endpoint's one-time signing secret in the Webhook Signing credential.
|
|
220
|
+
10. Attach one LifeSpace **Event Subscription** per selected Record Type to the same endpoint, with matching event-type filters.
|
|
221
|
+
11. Use the LifeSpace Webhook Endpoint test operation to verify delivery.
|
|
222
|
+
|
|
223
|
+
The Trigger verifies `X-LifeSpace-Timestamp` and `X-LifeSpace-Signature` with the LifeSpace HMAC-SHA256 contract before emitting workflow data. `endpoint.test` payloads are always accepted after signature verification.
|
|
224
|
+
|
|
225
|
+
Webhook Endpoint / Event Subscription creation is intentionally not performed by the n8n Service API Token today because LifeSpace treats that configuration as a Space-management operation. The adapter does not bypass that authority boundary.
|
|
226
|
+
|
|
227
|
+
## What the package provides
|
|
228
|
+
|
|
229
|
+
- **LifeSpace API** credential for API authentication and Runtime Discovery;
|
|
230
|
+
- **LifeSpace Webhook Signing** credential for endpoint-scoped inbound HMAC verification;
|
|
231
|
+
- **LifeSpace** node with discovery-driven Record operations plus advanced API Request;
|
|
232
|
+
- **LifeSpace Trigger** with signed multi-Record-Type Domain Event filtering;
|
|
233
|
+
- dynamic Space, Record Type, field, relation target, query, Action and Action Input UI based on Runtime Discovery.
|
|
234
|
+
|
|
235
|
+
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.
|
|
236
|
+
|
|
237
|
+
## Architecture boundary
|
|
238
|
+
|
|
239
|
+
LifeSpace is the source of truth for Identity, Authority, Shared Reality semantics, contracts and Eventing. This repository is an n8n Adapter and must not become a second LifeSpace business-contract implementation.
|
|
240
|
+
|
|
241
|
+
LifeSpace does not depend on n8n. n8n is one optional orchestration/integration runtime consuming LifeSpace APIs and events.
|
|
242
|
+
|
|
243
|
+
The adapter does not use privileged model-admin endpoints for ordinary workflow discovery and does not copy Model Definitions into this repository.
|
|
244
|
+
|
|
245
|
+
## Development
|
|
246
|
+
|
|
247
|
+
Requirements:
|
|
248
|
+
|
|
249
|
+
- Node.js 22.22.0 or newer;
|
|
250
|
+
- npm;
|
|
251
|
+
- local n8n for interactive testing.
|
|
252
|
+
|
|
253
|
+
Validate:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npm install
|
|
257
|
+
npm run lint
|
|
258
|
+
npm test
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
`npm test` builds the package before running adapter contract tests.
|
|
262
|
+
|
|
263
|
+
Run a local n8n development instance:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
npm run dev
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Publishing and verification
|
|
135
270
|
|
|
136
|
-
|
|
271
|
+
This repository is public and is intended to remain eligible for n8n Community Node verification.
|
|
137
272
|
|
|
138
|
-
|
|
273
|
+
Publishing is performed by `.github/workflows/publish.yml` from a version tag matching `*.*.*`. npm authentication uses Trusted Publishing through GitHub Actions OIDC and provenance.
|
|
139
274
|
|
|
140
|
-
|
|
141
|
-
2. configure npm Trusted Publishing for `huangshirui/lifespace-n8n-nodes` and workflow `publish.yml`, or install a narrowly scoped fallback `NPM_TOKEN`;
|
|
142
|
-
3. ensure CI passes on the exact release commit;
|
|
143
|
-
4. create the release through the `n8n-node` release flow so the pushed version tag triggers the provenance workflow;
|
|
144
|
-
5. verify the npm package links back to this public GitHub repository and exposes the MIT license and expected node metadata.
|
|
275
|
+
Do not publish a verification candidate directly from a developer workstation and do not add a long-lived npm publishing token to the repository.
|
|
145
276
|
|
|
146
|
-
The package intentionally has no runtime `dependencies`. It must not read environment variables or the local filesystem. Node UI
|
|
277
|
+
The package intentionally has no runtime `dependencies`. It must not read environment variables or the local filesystem. Node UI/help text/errors/README/examples remain English-only for n8n verification compatibility.
|
|
147
278
|
|
|
148
|
-
##
|
|
279
|
+
## Remaining upstream-dependent UX
|
|
149
280
|
|
|
150
|
-
|
|
151
|
-
- a more explicit n8n AI Tool experience for approved LifeSpace actions if the generic tool-capable node proves insufficient;
|
|
152
|
-
- delegated Webhook Endpoint / Event Subscription management if LifeSpace later exposes an appropriate user-authorized integration contract;
|
|
153
|
-
- OAuth `client_credentials` support where required.
|
|
281
|
+
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 consumes the LifeSpace 0.23 relation lookup contract, and Space labels consume the 0.24 Runtime Discovery projection.
|
|
154
282
|
|
|
155
283
|
## License
|
|
156
284
|
|
|
@@ -2,7 +2,10 @@ import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INo
|
|
|
2
2
|
export declare class LifeSpaceApi implements ICredentialType {
|
|
3
3
|
name: string;
|
|
4
4
|
displayName: string;
|
|
5
|
-
icon:
|
|
5
|
+
icon: {
|
|
6
|
+
readonly light: "file:lifespace.svg";
|
|
7
|
+
readonly dark: "file:lifespace.dark.svg";
|
|
8
|
+
};
|
|
6
9
|
documentationUrl: string;
|
|
7
10
|
properties: INodeProperties[];
|
|
8
11
|
authenticate: IAuthenticateGeneric;
|
|
@@ -4,18 +4,21 @@ exports.LifeSpaceApi = void 0;
|
|
|
4
4
|
class LifeSpaceApi {
|
|
5
5
|
constructor() {
|
|
6
6
|
this.name = 'lifeSpaceApi';
|
|
7
|
-
this.displayName = 'LifeSpace
|
|
8
|
-
this.icon =
|
|
9
|
-
|
|
7
|
+
this.displayName = 'LifeSpace API';
|
|
8
|
+
this.icon = {
|
|
9
|
+
light: 'file:lifespace.svg',
|
|
10
|
+
dark: 'file:lifespace.dark.svg',
|
|
11
|
+
};
|
|
12
|
+
this.documentationUrl = 'https://github.com/huangshirui/LifeSpace/blob/main/docs/service-authentication.md';
|
|
10
13
|
this.properties = [
|
|
11
14
|
{
|
|
12
|
-
displayName: '
|
|
15
|
+
displayName: 'API Base URL',
|
|
13
16
|
name: 'baseUrl',
|
|
14
17
|
type: 'string',
|
|
15
18
|
default: '',
|
|
16
|
-
placeholder: 'https://
|
|
19
|
+
placeholder: 'https://api.example.com/api/v1',
|
|
17
20
|
required: true,
|
|
18
|
-
description: '
|
|
21
|
+
description: 'LifeSpace Core API root. Do not include a Space or Record Type path.',
|
|
19
22
|
},
|
|
20
23
|
{
|
|
21
24
|
displayName: 'Service API Token',
|
|
@@ -23,8 +26,9 @@ class LifeSpaceApi {
|
|
|
23
26
|
type: 'string',
|
|
24
27
|
typeOptions: { password: true },
|
|
25
28
|
default: '',
|
|
29
|
+
placeholder: 'lsp_pat_...',
|
|
26
30
|
required: true,
|
|
27
|
-
description: '
|
|
31
|
+
description: 'Opaque LifeSpace Service API Token used by n8n for API calls and Runtime Discovery',
|
|
28
32
|
},
|
|
29
33
|
];
|
|
30
34
|
this.authenticate = {
|
|
@@ -38,7 +42,7 @@ class LifeSpaceApi {
|
|
|
38
42
|
this.test = {
|
|
39
43
|
request: {
|
|
40
44
|
baseURL: '={{$credentials.baseUrl.replace(/\\/$/, "")}}',
|
|
41
|
-
url: '/_discovery',
|
|
45
|
+
url: '/me/_discovery',
|
|
42
46
|
method: 'GET',
|
|
43
47
|
},
|
|
44
48
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LifeSpaceApi.credentials.js","sourceRoot":"","sources":["../../credentials/LifeSpaceApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,YAAY;IAAzB;QACE,SAAI,GAAG,cAAc,CAAC;QAEtB,gBAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"LifeSpaceApi.credentials.js","sourceRoot":"","sources":["../../credentials/LifeSpaceApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,YAAY;IAAzB;QACE,SAAI,GAAG,cAAc,CAAC;QAEtB,gBAAW,GAAG,eAAe,CAAC;QAE9B,SAAI,GAAG;YACL,KAAK,EAAE,oBAAoB;YAC3B,IAAI,EAAE,yBAAyB;SACvB,CAAC;QAEX,qBAAgB,GAAG,mFAAmF,CAAC;QAEvG,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,cAAc;gBAC3B,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,gCAAgC;gBAC7C,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,sEAAsE;aACpF;YACD;gBACE,WAAW,EAAE,mBAAmB;gBAChC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,aAAa;gBAC1B,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,oFAAoF;aAClG;SACF,CAAC;QAEF,iBAAY,GAAyB;YACnC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,aAAa,EAAE,gCAAgC;iBAChD;aACF;SACF,CAAC;QAEF,SAAI,GAA2B;YAC7B,OAAO,EAAE;gBACP,OAAO,EAAE,+CAA+C;gBACxD,GAAG,EAAE,gBAAgB;gBACrB,MAAM,EAAE,KAAK;aACd;SACF,CAAC;IACJ,CAAC;CAAA;AAlDD,oCAkDC"}
|
|
@@ -2,7 +2,10 @@ import type { ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
|
2
2
|
export declare class LifeSpaceWebhookApi implements ICredentialType {
|
|
3
3
|
name: string;
|
|
4
4
|
displayName: string;
|
|
5
|
-
icon:
|
|
5
|
+
icon: {
|
|
6
|
+
readonly light: "file:lifespace.svg";
|
|
7
|
+
readonly dark: "file:lifespace.dark.svg";
|
|
8
|
+
};
|
|
6
9
|
documentationUrl: string;
|
|
7
10
|
properties: INodeProperties[];
|
|
8
11
|
}
|
|
@@ -5,17 +5,21 @@ class LifeSpaceWebhookApi {
|
|
|
5
5
|
constructor() {
|
|
6
6
|
this.name = 'lifeSpaceWebhookApi';
|
|
7
7
|
this.displayName = 'LifeSpace Webhook API';
|
|
8
|
-
this.icon =
|
|
9
|
-
|
|
8
|
+
this.icon = {
|
|
9
|
+
light: 'file:lifespace.svg',
|
|
10
|
+
dark: 'file:lifespace.dark.svg',
|
|
11
|
+
};
|
|
12
|
+
this.documentationUrl = 'https://github.com/huangshirui/LifeSpace/blob/main/docs/contracts.md';
|
|
10
13
|
this.properties = [
|
|
11
14
|
{
|
|
12
|
-
displayName: 'Signing Secret',
|
|
15
|
+
displayName: 'Webhook Signing Secret',
|
|
13
16
|
name: 'signingSecret',
|
|
14
17
|
type: 'string',
|
|
15
18
|
typeOptions: { password: true },
|
|
16
19
|
default: '',
|
|
20
|
+
placeholder: '64-character hexadecimal secret',
|
|
17
21
|
required: true,
|
|
18
|
-
description: '
|
|
22
|
+
description: 'Endpoint-scoped signing secret returned by LifeSpace when a Webhook Endpoint is created or rotated',
|
|
19
23
|
},
|
|
20
24
|
];
|
|
21
25
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LifeSpaceWebhookApi.credentials.js","sourceRoot":"","sources":["../../credentials/LifeSpaceWebhookApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,mBAAmB;IAAhC;QACE,SAAI,GAAG,qBAAqB,CAAC;QAE7B,gBAAW,GAAG,uBAAuB,CAAC;QAEtC,SAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"LifeSpaceWebhookApi.credentials.js","sourceRoot":"","sources":["../../credentials/LifeSpaceWebhookApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,mBAAmB;IAAhC;QACE,SAAI,GAAG,qBAAqB,CAAC;QAE7B,gBAAW,GAAG,uBAAuB,CAAC;QAEtC,SAAI,GAAG;YACL,KAAK,EAAE,oBAAoB;YAC3B,IAAI,EAAE,yBAAyB;SACvB,CAAC;QAEX,qBAAgB,GAAG,sEAAsE,CAAC;QAE1F,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,wBAAwB;gBACrC,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,iCAAiC;gBAC9C,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,oGAAoG;aAClH;SACF,CAAC;IACJ,CAAC;CAAA;AAxBD,kDAwBC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="LifeSpace">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="lifespace-mark-dark" x1="10" y1="54" x2="54" y2="10" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop offset="0" stop-color="#5C8DFF"/>
|
|
5
|
+
<stop offset="0.55" stop-color="#69B7FF"/>
|
|
6
|
+
<stop offset="1" stop-color="#9EDBFF"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
</defs>
|
|
9
|
+
<g fill="none" stroke="url(#lifespace-mark-dark)" stroke-width="6" stroke-linecap="round" stroke-linejoin="round">
|
|
10
|
+
<path d="M28.5 10.5 17.5 17a7 7 0 0 0-3.5 6.1v17.8a7 7 0 0 0 3.5 6.1l11 6.5"/>
|
|
11
|
+
<path d="M35.5 10.5 46.5 17a7 7 0 0 1 3.5 6.1v17.8a7 7 0 0 1-3.5 6.1l-11 6.5"/>
|
|
12
|
+
</g>
|
|
13
|
+
<circle cx="32" cy="32" r="5" fill="url(#lifespace-mark-dark)"/>
|
|
14
|
+
</svg>
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="LifeSpace">
|
|
2
2
|
<defs>
|
|
3
|
-
<linearGradient id="lifespace-
|
|
3
|
+
<linearGradient id="lifespace-mark" x1="10" y1="54" x2="54" y2="10" gradientUnits="userSpaceOnUse">
|
|
4
4
|
<stop offset="0" stop-color="#075FEA"/>
|
|
5
5
|
<stop offset="0.55" stop-color="#087CF5"/>
|
|
6
6
|
<stop offset="1" stop-color="#25A8FF"/>
|
|
7
7
|
</linearGradient>
|
|
8
8
|
</defs>
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
<path d="
|
|
12
|
-
<path d="M35 14.5 45 20.5a5 5 0 0 1 2.5 4.3v14.4a5 5 0 0 1-2.5 4.3l-10 6"/>
|
|
9
|
+
<g fill="none" stroke="url(#lifespace-mark)" stroke-width="6" stroke-linecap="round" stroke-linejoin="round">
|
|
10
|
+
<path d="M28.5 10.5 17.5 17a7 7 0 0 0-3.5 6.1v17.8a7 7 0 0 0 3.5 6.1l11 6.5"/>
|
|
11
|
+
<path d="M35.5 10.5 46.5 17a7 7 0 0 1 3.5 6.1v17.8a7 7 0 0 1-3.5 6.1l-11 6.5"/>
|
|
13
12
|
</g>
|
|
14
|
-
<circle cx="32" cy="32" r="
|
|
13
|
+
<circle cx="32" cy="32" r="5" fill="url(#lifespace-mark)"/>
|
|
15
14
|
</svg>
|
|
@@ -3,13 +3,25 @@ export declare class LifeSpace implements INodeType {
|
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
4
|
methods: {
|
|
5
5
|
loadOptions: {
|
|
6
|
-
|
|
6
|
+
getSpaces(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
|
+
getRecordTypes(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
7
8
|
getActions(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
8
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[]>;
|
|
9
21
|
getSortableFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
10
22
|
};
|
|
11
23
|
resourceMapping: {
|
|
12
|
-
|
|
24
|
+
getRecordFields(this: ILoadOptionsFunctions): Promise<ResourceMapperFields>;
|
|
13
25
|
getActionInputFields(this: ILoadOptionsFunctions): Promise<ResourceMapperFields>;
|
|
14
26
|
};
|
|
15
27
|
};
|