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 CHANGED
@@ -2,155 +2,283 @@
2
2
 
3
3
  Official n8n community nodes for integrating workflows and AI agents with LifeSpace.
4
4
 
5
- ## Status
5
+ ## Install in n8n
6
6
 
7
- The package currently provides:
7
+ The npm package is:
8
8
 
9
- - a LifeSpace Connection credential using a Connection Base URL plus an opaque `lsp_pat_*` Service API Token;
10
- - a LifeSpace Webhook credential for storing event-subscription signing secrets outside workflow parameters;
11
- - a LifeSpace node with generic Model Record operations plus an advanced connection-relative API request escape hatch;
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
- Domain-specific UX and AI-tool surfaces will be added only against stable upstream LifeSpace contracts/discovery metadata.
13
+ ### Self-hosted n8n: install from the UI
19
14
 
20
- ## Architecture boundary
15
+ You must be an n8n instance Owner or Admin.
21
16
 
22
- LifeSpace is the source of truth for identity, authorization, domain models, contracts and events. This repository is an n8n-specific adapter and must not become a second copy of LifeSpace business contracts.
17
+ 1. Open **Settings Community Nodes**.
18
+ 2. Select **Install**.
19
+ 3. Enter:
23
20
 
24
- LifeSpace does not depend on n8n. n8n is one optional orchestration and integration runtime that consumes LifeSpace APIs and events.
21
+ ```text
22
+ n8n-nodes-lifespace
23
+ ```
25
24
 
26
- ## Development
25
+ 4. Confirm the community-node warning.
26
+ 5. Select **Install**.
27
+ 6. Return to a workflow and search for **LifeSpace**.
27
28
 
28
- Requirements:
29
+ To pin a release, use for example:
29
30
 
30
- - Node.js 22.22.0 or newer;
31
- - npm;
32
- - a local n8n instance for interactive node testing.
31
+ ```text
32
+ n8n-nodes-lifespace@0.1.0
33
+ ```
33
34
 
34
- Install and validate:
35
+ ### Self-hosted n8n: manual npm installation
35
36
 
36
37
  ```bash
37
- npm install
38
- npm run lint
39
- npm run build
38
+ mkdir -p ~/.n8n/nodes
39
+ cd ~/.n8n/nodes
40
+ npm install n8n-nodes-lifespace
40
41
  ```
41
42
 
42
- Run the node in a local n8n development instance:
43
+ Restart n8n afterwards. In queue mode, install the package anywhere that may execute workflows.
43
44
 
44
- ```bash
45
- npm run dev
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
- ## Credentials
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
- Create and authorize the integration in LifeSpace Web first. The Web configuration owns the target Space and its granted model permissions, then exposes the values to copy into n8n:
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
- - **Connection Base URL**, for example `https://core.aisr.online/api/v1/spaces/spc_...`;
53
- - **Service API Token**, an opaque `lsp_pat_*` token issued for that connection.
105
+ Two boundaries are intentional:
54
106
 
55
- The Credential represents one already-configured LifeSpace connection. Individual LifeSpace nodes therefore do not ask for a Space ID.
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
- The Connection Base URL carries routing context only. Authorization still comes from the Service API Token plus LifeSpace credential scopes, Application × Model Access and current Space/Data Grant authority. Revoking the token or grant invalidates the connection without changing the n8n workflow.
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
- Do not store real tokens in source code, workflow examples or repository files.
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
- ## LifeSpace Model Record
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
- The **Model Record** resource is a thin adapter over LifeSpace Generic Runtime routes. It supports:
116
+ Credentials are intentionally static secure configuration and are not workflow-expression inputs.
64
117
 
65
- - Create;
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 node loads its Model selector from `{Connection Base URL}/_discovery`. The list contains only models the current connection can currently use after LifeSpace applies credential scopes, Application × Model Access and current Space membership/Data Grants. The **Action** selector is then loaded dynamically from the selected model and is filtered by the same discovery authority.
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
- ### Discovery-driven fields
122
+ Supported operations:
75
123
 
76
- Create and Update use n8n's resource-mapper UI driven directly by the selected model's bounded Runtime Discovery metadata instead of a handwritten `Fields (JSON)` contract.
124
+ - **Create**;
125
+ - **Get**;
126
+ - **List / Query**;
127
+ - **Update**;
128
+ - **Delete**;
129
+ - **Execute Action**.
77
130
 
78
- - required Create fields follow LifeSpace field metadata;
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
- ### Discovery-driven query
133
+ For Record operations:
87
134
 
88
- List / Query uses bounded query metadata from LifeSpace Runtime Discovery rather than a free-form JSON request.
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
- - searchable fields enable the Search input only where the model declares search support;
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
- ### Discovery-driven Action Input
141
+ ### Create
98
142
 
99
- Execute Action uses a second resource-mapper driven by the selected action's bounded input metadata from LifeSpace Runtime Discovery.
143
+ Writable fields are generated from Runtime Discovery.
100
144
 
101
- - Model Definition v1 workflow actions currently expose the optimistic-concurrency `version` input;
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
- LifeSpace Core remains authoritative for validation and authorization when an operation executes. Runtime Discovery is a dynamic UX/capability preview, not an execution-authorization proof.
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
- The node does not use the privileged `model-admin/contracts/*` surface for ordinary workflow discovery and does not copy model definitions into this repository.
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
- The **API Request** resource remains available as an advanced escape hatch for paths relative to the configured Connection Base URL.
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
- ## LifeSpace Trigger
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
- LifeSpace event subscriptions are currently managed by an authenticated LifeSpace user with Space-management permission. A service token intentionally cannot create or modify subscriptions.
155
+ ### Update and Delete
115
156
 
116
- To use the trigger:
157
+ LifeSpace uses optimistic concurrency.
117
158
 
118
- 1. add a LifeSpace Trigger to an n8n workflow and activate the workflow;
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
- The signing secret is intentionally stored as an n8n Credential rather than as a workflow parameter. Workflow exports therefore reference the credential instead of embedding the secret as ordinary node configuration.
161
+ If a workflow intentionally needs to bind a known version, add **Concurrency Options Version**.
127
162
 
128
- The trigger validates `X-LifeSpace-Timestamp` and `X-LifeSpace-Signature` using the upstream LifeSpace HMAC-SHA256 contract before emitting workflow data.
163
+ ### List / Query
129
164
 
130
- ## Publishing and verification
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
- This repository is public and is intended to remain eligible for n8n community-node verification.
188
+ The **API Request** resource is an escape hatch for LifeSpace routes that do not yet have dedicated node UX.
133
189
 
134
- Publishing is performed only by `.github/workflows/publish.yml` from a version tag matching `*.*.*`. The workflow grants only `contents: read` plus `id-token: write`, so npm can attach a provenance attestation to the public package.
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
- Preferred npm authentication is Trusted Publishing through GitHub Actions. A scoped `NPM_TOKEN` is supported only as a fallback. Do not publish a verification candidate directly from a developer workstation.
271
+ This repository is public and is intended to remain eligible for n8n Community Node verification.
137
272
 
138
- Before the first npm release:
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
- 1. ensure the `n8n-nodes-lifespace` package is available to the publishing npm account;
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, help text, errors, README content and examples remain English-only for n8n verification compatibility.
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
- ## Planned surfaces
279
+ ## Remaining upstream-dependent UX
149
280
 
150
- - richer relation selectors when LifeSpace exposes an appropriate authorized lookup surface;
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: "file:lifespace.svg";
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 Connection API';
8
- this.icon = 'file:lifespace.svg';
9
- this.documentationUrl = 'https://github.com/huangshirui/LifeSpace';
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: 'Connection Base URL',
15
+ displayName: 'API Base URL',
13
16
  name: 'baseUrl',
14
17
  type: 'string',
15
18
  default: '',
16
- placeholder: 'https://core.aisr.online/api/v1/spaces/spc_...',
19
+ placeholder: 'https://api.example.com/api/v1',
17
20
  required: true,
18
- description: 'Copy the Connection Base URL from the LifeSpace Web integration configuration',
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: 'Copy the LifeSpace Service API Token (lsp_pat_*) issued for this connection',
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,0BAA0B,CAAC;QAEzC,SAAI,GAAG,oBAA6B,CAAC;QAErC,qBAAgB,GAAG,0CAA0C,CAAC;QAE9D,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,qBAAqB;gBAClC,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,gDAAgD;gBAC7D,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,+EAA+E;aAC7F;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,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,6EAA6E;aAC3F;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,aAAa;gBAClB,MAAM,EAAE,KAAK;aACd;SACF,CAAC;IACJ,CAAC;CAAA;AA9CD,oCA8CC"}
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: "file:lifespace.svg";
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 = 'file:lifespace.svg';
9
- this.documentationUrl = 'https://github.com/huangshirui/lifespace-n8n-nodes#lifespace-trigger';
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: 'One-time signing secret returned when the LifeSpace event subscription is created or rotated',
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,oBAA6B,CAAC;QAErC,qBAAgB,GAAG,sEAAsE,CAAC;QAE1F,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,gBAAgB;gBAC7B,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,8FAA8F;aAC5G;SACF,CAAC;IACJ,CAAC;CAAA;AApBD,kDAoBC"}
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-bg" x1="7" y1="57" x2="57" y2="7" gradientUnits="userSpaceOnUse">
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
- <rect width="64" height="64" rx="14" fill="url(#lifespace-bg)"/>
10
- <g fill="none" stroke="#FFFFFF" stroke-width="5" stroke-linecap="round" stroke-linejoin="round">
11
- <path d="M29 14.5 19 20.5a5 5 0 0 0-2.5 4.3v14.4a5 5 0 0 0 2.5 4.3l10 6"/>
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="4.6" fill="#FFFFFF"/>
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
- getModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
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
- getModelFields(this: ILoadOptionsFunctions): Promise<ResourceMapperFields>;
24
+ getRecordFields(this: ILoadOptionsFunctions): Promise<ResourceMapperFields>;
13
25
  getActionInputFields(this: ILoadOptionsFunctions): Promise<ResourceMapperFields>;
14
26
  };
15
27
  };