n8n-nodes-lifespace 0.1.23 → 0.1.25
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 +28 -15
- package/dist/credentials/LifeSpaceAgentExecutionApi.credentials.d.ts +13 -0
- package/dist/credentials/LifeSpaceAgentExecutionApi.credentials.js +70 -0
- package/dist/credentials/LifeSpaceAgentExecutionApi.credentials.js.map +1 -0
- package/dist/nodes/LifeSpace/LifeSpace.node.js +322 -16
- package/dist/nodes/LifeSpace/LifeSpace.node.js.map +1 -1
- package/dist/nodes/LifeSpaceDelegation/LifeSpaceDelegation.node.d.ts +6 -0
- package/dist/nodes/LifeSpaceDelegation/LifeSpaceDelegation.node.js +264 -0
- package/dist/nodes/LifeSpaceDelegation/LifeSpaceDelegation.node.js.map +1 -0
- package/dist/nodes/LifeSpaceDelegation/lifespace.dark.svg +14 -0
- package/dist/nodes/LifeSpaceDelegation/lifespace.svg +14 -0
- package/dist/nodes/LifeSpaceTool/LifeSpaceTool.node.js +318 -29
- package/dist/nodes/LifeSpaceTool/LifeSpaceTool.node.js.map +1 -1
- package/dist/nodes/agent/lifeSpaceToolFactory.d.ts +1 -1
- package/dist/nodes/agent/lifeSpaceToolFactory.js +38 -0
- package/dist/nodes/agent/lifeSpaceToolFactory.js.map +1 -1
- package/dist/nodes/lifespaceDiscovery.d.ts +10 -5
- package/dist/nodes/lifespaceDiscovery.js +33 -24
- package/dist/nodes/lifespaceDiscovery.js.map +1 -1
- package/dist/nodes/shared/lifeSpaceExecutionAuthority.d.ts +25 -0
- package/dist/nodes/shared/lifeSpaceExecutionAuthority.js +130 -0
- package/dist/nodes/shared/lifeSpaceExecutionAuthority.js.map +1 -0
- package/dist/package.json +3 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -44,25 +44,26 @@ Restart n8n afterwards. In queue mode, install the package anywhere that may exe
|
|
|
44
44
|
|
|
45
45
|
## Quick start
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
LifeSpace has two explicit execution modes in n8n.
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
For **Service Principal(服务主体)automation**, create a **LifeSpace API** credential with the Core **API Base URL** and an opaque `lsp_pat_*` **Service API Token**. This remains the default for scheduled/system workflows where `Principal = Actor = Service`.
|
|
50
50
|
|
|
51
|
-
- **
|
|
51
|
+
For a user-initiated **Delegated Agent(委托智能体)** Tool or Batch, create a separate **LifeSpace Delegated Agent API** credential containing:
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
- **Core API Base URL**;
|
|
54
|
+
- **Identity API Base URL**;
|
|
55
|
+
- the server-only Application credential `lsa_*`;
|
|
56
|
+
- the registered LifeSpace `agt_*` Agent ID.
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
Delegated mode does **not** require or fall back to a Service PAT. The adapter uses the Application credential only to mint a short-lived `User Principal → Agent Actor` execution token from LifeSpace Identity, then calls Core with that token plus explicit Delegation selectors.
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
`Principal User ID`, `Delegation ID`, `Read Delegation ID` and per-item Batch Delegation IDs are execution/control context, never LLM Tool arguments. `Read Delegation ID` is intentionally separate: it covers delegated design-time Discovery and only the runtime calls that actually need relation-name lookup or optimistic-concurrency pre-reads, so those helper reads cannot accidentally consume a single-use Delegation reserved for the actual query/mutation/action. A pure runtime mutation with no helper read does not exercise the Read Delegation.
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
Credentials are secrets. Store them only in n8n credentials; do not put `lsp_pat_*`, `lsa_*`, Agent JWTs or other secrets in workflow fields, URLs, source files or workflow exports.
|
|
62
63
|
|
|
63
64
|
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
|
|
|
65
|
-
Runtime Discovery determines which Spaces, Record Types, fields, queries, Actions and relation lookup capabilities the current
|
|
66
|
+
Runtime Discovery determines which Spaces, Record Types, fields, queries, Actions and relation lookup capabilities the current execution context can use. Service mode uses the Service PAT. Delegated Agent mode uses the short-lived Agent token; progressive semantic detail uses the configured Read Delegation selector. Relation target lookup remains lazy and field-scoped. Execution authorization is always enforced by LifeSpace from verified Application / Principal / Actor, credential scope, Application × Model Access, current Space/Data Grant authority and the explicitly selected Delegation when Principal and Actor differ.
|
|
66
67
|
|
|
67
68
|
## Generated Record UX
|
|
68
69
|
|
|
@@ -89,7 +90,7 @@ Current Calendar models expose the canonical `capabilityBindings.calendar.rangeF
|
|
|
89
90
|
|
|
90
91
|
## LifeSpace contract compatibility
|
|
91
92
|
|
|
92
|
-
This package follows the current LifeSpace Core Kernel `0.
|
|
93
|
+
This package follows the current LifeSpace Core Kernel `0.40.0` contract family. Integration/Eventing is independently versioned at `0.3.0`. Authority v2 requires an explicit Delegation selector whenever `Principal != Actor`, and Model Contracts expose the first-class atomic Generic Runtime Batch surface.
|
|
93
94
|
|
|
94
95
|
The UX depends on these Kernel capabilities:
|
|
95
96
|
|
|
@@ -112,6 +113,7 @@ The UX depends on these Kernel capabilities:
|
|
|
112
113
|
- `0.34.0`: explicit `eq/lt/lte/gt/gte` comparison transports, first-class `createdAt` / `updatedAt` envelope comparisons and Core-owned datetime local-date-window conversion become discoverable.
|
|
113
114
|
- `0.35.0`: grouped `query.capabilityQueries` introduced capability-owned compatibility queries.
|
|
114
115
|
- `0.36.0`: `query.canonical` unifies Search, typed Boolean Filter, multi-Sort and cursor Pagination behind `POST .../records/query`; Runtime Discovery also exposes canonical `instant`, `range<date>`, `range<instant>`, `temporal_range` field types and the Calendar `rangeField` binding. The human Workflow node consumes those current semantics while retaining historical Discovery spellings only for compatibility.
|
|
116
|
+
- `0.40.0`: Authority v2 separates verified Application / Principal / Actor from the explicit opaque Delegation selector; one Delegation has one Space/Model/Record scope; first-class `POST /spaces/{spaceId}/models/batch` atomically commits 1-20 create/update/delete operations and returns one `changeSetId`.
|
|
115
117
|
|
|
116
118
|
The adapter prefers the `0.27+` progressive flow while configuring a node:
|
|
117
119
|
|
|
@@ -181,7 +183,15 @@ Credentials are intentionally static secure configuration and are not workflow-e
|
|
|
181
183
|
|
|
182
184
|
The normal n8n-facing resource is **Record**. LifeSpace still owns **Model** semantics internally; the adapter uses **Record Type** for the workflow-facing selection.
|
|
183
185
|
|
|
184
|
-
Supported operations
|
|
186
|
+
Supported human Workflow operations include ordinary Record CRUD/Query/Action. **Create / Update / Delete expose an optional Batch Mode under Record Options, default Off.** When enabled, the node consumes the incoming n8n `items[]` directly, requires 1-20 items resolving to one Space and one Record Type, and sends exactly one atomic Core Batch request. The response is expanded back to one n8n output item per input item with preserved pairing and a shared `changeSetId`.
|
|
187
|
+
|
|
188
|
+
Update/Delete `Version` remains optional in both modes. In single mode, omission keeps the historical behavior of reading the current record immediately before mutation. In Batch Mode, omission is delegated to the LifeSpace Batch contract: Core resolves current versions set-wise during Batch preparation and still commits conditionally, so there is no N-read HTTP waterfall and no blind write.
|
|
189
|
+
|
|
190
|
+
**Advanced Mixed Batch** remains available for workflows that deliberately need mixed create/update/delete or cross-Record-Type operations in one atomic ChangeSet. It uses the explicit JSON operations surface and is not the primary Batch UX.
|
|
191
|
+
|
|
192
|
+
The native Agent Tool supports Query/Create/Update/Delete/Action plus **Create Records (Batch)** for 1-20 records of its pinned Record Type. Agent Batch Update/Delete are not exposed by this workflow-UX change; they can be added separately against the same upstream optional-version Batch semantics without reintroducing N pre-read HTTP calls.
|
|
193
|
+
|
|
194
|
+
Ordinary Record operations remain:
|
|
185
195
|
|
|
186
196
|
- **Create**;
|
|
187
197
|
- **Get**;
|
|
@@ -333,13 +343,16 @@ Webhook Endpoint / Event Subscription creation is intentionally not performed by
|
|
|
333
343
|
|
|
334
344
|
## What the package provides
|
|
335
345
|
|
|
336
|
-
- **LifeSpace API** credential for
|
|
346
|
+
- **LifeSpace API** credential for Service Principal authentication and Runtime Discovery;
|
|
347
|
+
- **LifeSpace Delegated Agent API** credential for server-only Application authentication, short-lived Agent token minting, and delegated Core execution without a Service PAT;
|
|
337
348
|
- **LifeSpace Webhook Signing** credential for endpoint-scoped inbound HMAC verification;
|
|
338
|
-
- **LifeSpace** human workflow node with Discovery-driven Record operations plus advanced API Request;
|
|
339
|
-
- **LifeSpace Agent Tool** native AiTool with Discovery-driven semantic schemas;
|
|
349
|
+
- **LifeSpace** human workflow node with Discovery-driven Record operations, first-class 1-20 atomic Batch create/update/delete, plus advanced API Request;
|
|
350
|
+
- **LifeSpace Agent Tool** native AiTool with Discovery-driven semantic schemas and bounded same-model Batch Create;
|
|
340
351
|
- **LifeSpace Trigger** with signed multi-Record-Type Domain Event filtering;
|
|
341
352
|
- shared thin adapter projection from LifeSpace Runtime Discovery into human n8n controls and model-facing Tool schemas.
|
|
342
353
|
|
|
354
|
+
The human Batch surface is the generic cross-model atomic transport. The Agent Tool deliberately exposes only same-model Batch Create in this release: Agent Update/Delete continue to resolve optimistic concurrency through a read before mutation, and the adapter does not turn multiple such reads into an N+1 pseudo-Batch. Cross-model or mutation-mixed Agent Batch should be added only when its full input contract can remain deterministic and bounded without reintroducing per-item Runtime round trips.
|
|
355
|
+
|
|
343
356
|
LifeSpace remains authoritative for validation, authorization, defaults, Mutation Authority, Action semantics, query/time semantics, relation semantics and event contracts. Runtime Discovery and Relation Target Lookup are current capability/reference projections, not execution-authorization proofs.
|
|
344
357
|
|
|
345
358
|
## Architecture boundary
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
export declare class LifeSpaceAgentExecutionApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
icon: {
|
|
6
|
+
readonly light: "file:lifespace.svg";
|
|
7
|
+
readonly dark: "file:lifespace.dark.svg";
|
|
8
|
+
};
|
|
9
|
+
documentationUrl: string;
|
|
10
|
+
properties: INodeProperties[];
|
|
11
|
+
authenticate: IAuthenticateGeneric;
|
|
12
|
+
test: ICredentialTestRequest;
|
|
13
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LifeSpaceAgentExecutionApi = void 0;
|
|
4
|
+
class LifeSpaceAgentExecutionApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'lifeSpaceAgentExecutionApi';
|
|
7
|
+
this.displayName = 'LifeSpace Agent Execution 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/application-authentication.md';
|
|
13
|
+
this.properties = [
|
|
14
|
+
{
|
|
15
|
+
displayName: 'Core API Base URL',
|
|
16
|
+
name: 'coreBaseUrl',
|
|
17
|
+
type: 'string',
|
|
18
|
+
default: '',
|
|
19
|
+
placeholder: 'https://core.example.com/api/v1',
|
|
20
|
+
required: true,
|
|
21
|
+
description: 'LifeSpace Core API root used by Agent business requests and Delegation creation',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
displayName: 'Identity API Base URL',
|
|
25
|
+
name: 'identityBaseUrl',
|
|
26
|
+
type: 'string',
|
|
27
|
+
default: '',
|
|
28
|
+
placeholder: 'https://identity.example.com',
|
|
29
|
+
required: true,
|
|
30
|
+
description: 'LifeSpace Identity origin. Do not include an /internal/v1 token route.',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
displayName: 'Application Credential',
|
|
34
|
+
name: 'applicationSecret',
|
|
35
|
+
type: 'string',
|
|
36
|
+
typeOptions: { password: true },
|
|
37
|
+
default: '',
|
|
38
|
+
placeholder: 'lsa_...',
|
|
39
|
+
required: true,
|
|
40
|
+
description: 'Server-only trusted LifeSpace Application credential used to mint short-lived User and Agent execution tokens',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
displayName: 'Agent ID',
|
|
44
|
+
name: 'agentId',
|
|
45
|
+
type: 'string',
|
|
46
|
+
default: '',
|
|
47
|
+
placeholder: 'agt_...',
|
|
48
|
+
required: true,
|
|
49
|
+
description: 'LifeSpace Agent identity bound to this registered Application',
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
this.authenticate = {
|
|
53
|
+
type: 'generic',
|
|
54
|
+
properties: {
|
|
55
|
+
headers: {
|
|
56
|
+
Authorization: '=Bearer {{$credentials.applicationSecret}}',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
this.test = {
|
|
61
|
+
request: {
|
|
62
|
+
baseURL: '={{$credentials.identityBaseUrl.endsWith("/") ? $credentials.identityBaseUrl.slice(0, -1) : $credentials.identityBaseUrl}}',
|
|
63
|
+
url: '/internal/v1/agents',
|
|
64
|
+
method: 'GET',
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.LifeSpaceAgentExecutionApi = LifeSpaceAgentExecutionApi;
|
|
70
|
+
//# sourceMappingURL=LifeSpaceAgentExecutionApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LifeSpaceAgentExecutionApi.credentials.js","sourceRoot":"","sources":["../../credentials/LifeSpaceAgentExecutionApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,0BAA0B;IAAvC;QACE,SAAI,GAAG,4BAA4B,CAAC;QAEpC,gBAAW,GAAG,+BAA+B,CAAC;QAE9C,SAAI,GAAG;YACL,KAAK,EAAE,oBAAoB;YAC3B,IAAI,EAAE,yBAAyB;SACvB,CAAC;QAEX,qBAAgB,GAAG,uFAAuF,CAAC;QAE3G,eAAU,GAAsB;YAC9B;gBACE,WAAW,EAAE,mBAAmB;gBAChC,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,iCAAiC;gBAC9C,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,iFAAiF;aAC/F;YACD;gBACE,WAAW,EAAE,uBAAuB;gBACpC,IAAI,EAAE,iBAAiB;gBACvB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,8BAA8B;gBAC3C,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,wEAAwE;aACtF;YACD;gBACE,WAAW,EAAE,wBAAwB;gBACrC,IAAI,EAAE,mBAAmB;gBACzB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,SAAS;gBACtB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,+GAA+G;aAC7H;YACD;gBACE,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,SAAS;gBACtB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,+DAA+D;aAC7E;SACF,CAAC;QAEF,iBAAY,GAAyB;YACnC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,aAAa,EAAE,4CAA4C;iBAC5D;aACF;SACF,CAAC;QAEF,SAAI,GAA2B;YAC7B,OAAO,EAAE;gBACP,OAAO,EAAE,4HAA4H;gBACrI,GAAG,EAAE,qBAAqB;gBAC1B,MAAM,EAAE,KAAK;aACd;SACF,CAAC;IACJ,CAAC;CAAA;AApED,gEAoEC"}
|
|
@@ -4,6 +4,7 @@ exports.LifeSpace = void 0;
|
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
5
|
const lifespaceDiscovery_1 = require("../lifespaceDiscovery");
|
|
6
6
|
const lifeSpaceActionSnapshot_1 = require("../shared/lifeSpaceActionSnapshot");
|
|
7
|
+
const lifeSpaceExecutionAuthority_1 = require("../shared/lifeSpaceExecutionAuthority");
|
|
7
8
|
const LEGACY_MODEL_ROUTE_TO_KEY = Object.freeze({
|
|
8
9
|
tasks: 'task',
|
|
9
10
|
wishes: 'wish',
|
|
@@ -86,6 +87,86 @@ function parseJsonObject(context, itemIndex, value, fieldName) {
|
|
|
86
87
|
}
|
|
87
88
|
return parsed;
|
|
88
89
|
}
|
|
90
|
+
function batchMutationOperations(context, itemIndex, value, delegated) {
|
|
91
|
+
let parsed;
|
|
92
|
+
try {
|
|
93
|
+
parsed = typeof value === 'string' ? JSON.parse(value) : value;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), error, { itemIndex });
|
|
97
|
+
}
|
|
98
|
+
if (!Array.isArray(parsed) || parsed.length < 1 || parsed.length > 20) {
|
|
99
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'Batch Operations must be a JSON array containing 1 to 20 create/update/delete operations', { itemIndex });
|
|
100
|
+
}
|
|
101
|
+
return parsed.map((raw, index) => {
|
|
102
|
+
var _a, _b, _c, _d;
|
|
103
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
104
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch operation ${index} must be a JSON object`, { itemIndex });
|
|
105
|
+
}
|
|
106
|
+
const input = raw;
|
|
107
|
+
const operation = String((_a = input.operation) !== null && _a !== void 0 ? _a : '');
|
|
108
|
+
const modelKey = String((_b = input.modelKey) !== null && _b !== void 0 ? _b : '').trim();
|
|
109
|
+
if (!['create', 'update', 'delete'].includes(operation)) {
|
|
110
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch operation ${index} must be create, update, or delete`, { itemIndex });
|
|
111
|
+
}
|
|
112
|
+
if (!/^[A-Za-z][A-Za-z0-9_]{0,99}$/u.test(modelKey)) {
|
|
113
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch operation ${index} has an invalid modelKey`, { itemIndex });
|
|
114
|
+
}
|
|
115
|
+
const delegationId = String((_c = input.delegationId) !== null && _c !== void 0 ? _c : '').trim();
|
|
116
|
+
if (delegated && !/^dlg_[A-Za-z0-9_-]+$/u.test(delegationId)) {
|
|
117
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch operation ${index} requires its own valid delegationId in Delegated Agent mode`, { itemIndex });
|
|
118
|
+
}
|
|
119
|
+
if (!delegated && delegationId) {
|
|
120
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch operation ${index} cannot use delegationId in Service Principal mode`, { itemIndex });
|
|
121
|
+
}
|
|
122
|
+
if (operation === 'create') {
|
|
123
|
+
const data = input.data;
|
|
124
|
+
if (!data || typeof data !== 'object' || Array.isArray(data)) {
|
|
125
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch create ${index} requires an object data field`, { itemIndex });
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
operation: 'create',
|
|
129
|
+
modelKey,
|
|
130
|
+
data: data,
|
|
131
|
+
...(delegationId ? { delegationId } : {}),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const recordId = String((_d = input.recordId) !== null && _d !== void 0 ? _d : '').trim();
|
|
135
|
+
const rawVersion = input.version;
|
|
136
|
+
let version;
|
|
137
|
+
if (rawVersion !== undefined && rawVersion !== null && rawVersion !== '') {
|
|
138
|
+
const parsedVersion = Number(rawVersion);
|
|
139
|
+
if (!Number.isInteger(parsedVersion) || parsedVersion < 1) {
|
|
140
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch operation ${index} version must be a positive integer when supplied`, { itemIndex });
|
|
141
|
+
}
|
|
142
|
+
version = parsedVersion;
|
|
143
|
+
}
|
|
144
|
+
if (!/^rec_[A-Za-z0-9_-]+$/u.test(recordId)) {
|
|
145
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch operation ${index} has an invalid recordId`, { itemIndex });
|
|
146
|
+
}
|
|
147
|
+
if (operation === 'delete') {
|
|
148
|
+
return {
|
|
149
|
+
operation: 'delete',
|
|
150
|
+
modelKey,
|
|
151
|
+
recordId,
|
|
152
|
+
...(version === undefined ? {} : { version }),
|
|
153
|
+
...(delegationId ? { delegationId } : {}),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const data = input.data;
|
|
157
|
+
if (!data || typeof data !== 'object' || Array.isArray(data) || Object.keys(data).length === 0) {
|
|
158
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Batch update ${index} requires non-empty object data`, { itemIndex });
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
operation: 'update',
|
|
162
|
+
modelKey,
|
|
163
|
+
recordId,
|
|
164
|
+
...(version === undefined ? {} : { version }),
|
|
165
|
+
data: data,
|
|
166
|
+
...(delegationId ? { delegationId } : {}),
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
}
|
|
89
170
|
function mappedValue(context, itemIndex, parameterName) {
|
|
90
171
|
const value = context.getNodeParameter(`${parameterName}.value`, itemIndex, {});
|
|
91
172
|
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
@@ -464,13 +545,120 @@ async function currentRecord(context, itemIndex, baseUrl, recordPath) {
|
|
|
464
545
|
async function currentRecordVersion(context, itemIndex, baseUrl, recordPath) {
|
|
465
546
|
return recordVersion(context, itemIndex, await currentRecord(context, itemIndex, baseUrl, recordPath));
|
|
466
547
|
}
|
|
467
|
-
|
|
548
|
+
function configuredMutationVersion(context, itemIndex) {
|
|
468
549
|
const options = context.getNodeParameter('mutationOptions', itemIndex, {});
|
|
469
550
|
const configuredVersion = options.version;
|
|
551
|
+
if (configuredVersion === undefined || configuredVersion === null || configuredVersion === '') {
|
|
552
|
+
return undefined;
|
|
553
|
+
}
|
|
470
554
|
if (typeof configuredVersion === 'number' && Number.isInteger(configuredVersion) && configuredVersion >= 1) {
|
|
471
555
|
return configuredVersion;
|
|
472
556
|
}
|
|
473
|
-
|
|
557
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'Version must be a positive integer when supplied', { itemIndex });
|
|
558
|
+
}
|
|
559
|
+
async function mutationVersion(context, itemIndex, baseUrl, recordPath) {
|
|
560
|
+
var _a;
|
|
561
|
+
return (_a = configuredMutationVersion(context, itemIndex)) !== null && _a !== void 0 ? _a : currentRecordVersion(context, itemIndex, baseUrl, recordPath);
|
|
562
|
+
}
|
|
563
|
+
function recordBatchMode(context, itemIndex) {
|
|
564
|
+
const options = context.getNodeParameter('recordOptions', itemIndex, {});
|
|
565
|
+
return options.batchMode === true;
|
|
566
|
+
}
|
|
567
|
+
function configuredRecordModelKey(context, itemIndex) {
|
|
568
|
+
var _a, _b;
|
|
569
|
+
const recordType = (0, lifespaceDiscovery_1.decodeRecordTypeSelector)(context.getNodeParameter('recordType', itemIndex, ''));
|
|
570
|
+
const legacyModelRoute = String((_a = context.getNodeParameter('modelRoute', itemIndex, '')) !== null && _a !== void 0 ? _a : '').trim();
|
|
571
|
+
const modelKey = (_b = recordType === null || recordType === void 0 ? void 0 : recordType.modelKey) !== null && _b !== void 0 ? _b : LEGACY_MODEL_ROUTE_TO_KEY[legacyModelRoute];
|
|
572
|
+
if (!modelKey) {
|
|
573
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'LifeSpace Record Type selector is invalid. Choose a Record Type from Discovery or pass a Trigger recordType value.', { itemIndex });
|
|
574
|
+
}
|
|
575
|
+
return modelKey;
|
|
576
|
+
}
|
|
577
|
+
async function executeNativeRecordBatch(context, items) {
|
|
578
|
+
var _a, _b, _c, _d, _e;
|
|
579
|
+
if (items.length < 1)
|
|
580
|
+
return [];
|
|
581
|
+
if (items.length > 20) {
|
|
582
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'LifeSpace Batch Mode accepts at most 20 input items and never auto-chunks an atomic Batch');
|
|
583
|
+
}
|
|
584
|
+
const operation = String(context.getNodeParameter('operation', 0, ''));
|
|
585
|
+
if (!['create', 'update', 'delete'].includes(operation)) {
|
|
586
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'LifeSpace Batch Mode is available only for Create, Update, or Delete');
|
|
587
|
+
}
|
|
588
|
+
let sourceSpaceId = '';
|
|
589
|
+
let sourceModelKey = '';
|
|
590
|
+
const operations = [];
|
|
591
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex += 1) {
|
|
592
|
+
const itemOperation = String(context.getNodeParameter('operation', itemIndex, operation));
|
|
593
|
+
if (itemOperation !== operation) {
|
|
594
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'All input items in LifeSpace Batch Mode must use the same operation', { itemIndex });
|
|
595
|
+
}
|
|
596
|
+
const rawSpaceId = String((_a = context.getNodeParameter('spaceId', itemIndex, '')) !== null && _a !== void 0 ? _a : '').trim();
|
|
597
|
+
if (!rawSpaceId) {
|
|
598
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'LifeSpace Batch Mode requires a Space ID', { itemIndex });
|
|
599
|
+
}
|
|
600
|
+
const modelKey = configuredRecordModelKey(context, itemIndex);
|
|
601
|
+
if (!sourceSpaceId)
|
|
602
|
+
sourceSpaceId = rawSpaceId;
|
|
603
|
+
if (!sourceModelKey)
|
|
604
|
+
sourceModelKey = modelKey;
|
|
605
|
+
if (rawSpaceId !== sourceSpaceId || modelKey !== sourceModelKey) {
|
|
606
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'All input items in LifeSpace Batch Mode must resolve to the same Space and Record Type', { itemIndex });
|
|
607
|
+
}
|
|
608
|
+
if (operation === 'create') {
|
|
609
|
+
operations.push({
|
|
610
|
+
operation: 'create',
|
|
611
|
+
modelKey,
|
|
612
|
+
data: mutationMappedValues(context, itemIndex),
|
|
613
|
+
});
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
const recordId = String((_b = context.getNodeParameter('recordId', itemIndex, '')) !== null && _b !== void 0 ? _b : '').trim();
|
|
617
|
+
if (!/^rec_[A-Za-z0-9_-]+$/u.test(recordId)) {
|
|
618
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'Record ID must be a valid rec_* identifier in Batch Mode', { itemIndex });
|
|
619
|
+
}
|
|
620
|
+
const version = configuredMutationVersion(context, itemIndex);
|
|
621
|
+
if (operation === 'delete') {
|
|
622
|
+
operations.push({
|
|
623
|
+
operation: 'delete',
|
|
624
|
+
modelKey,
|
|
625
|
+
recordId,
|
|
626
|
+
...(version === undefined ? {} : { version }),
|
|
627
|
+
});
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
operations.push({
|
|
631
|
+
operation: 'update',
|
|
632
|
+
modelKey,
|
|
633
|
+
recordId,
|
|
634
|
+
...(version === undefined ? {} : { version }),
|
|
635
|
+
data: mutationMappedValues(context, itemIndex),
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
const baseUrl = (0, lifespaceDiscovery_1.normalizeBaseUrl)((await context.getCredentials('lifeSpaceApi', 0)).baseUrl);
|
|
639
|
+
const response = await context.helpers.httpRequestWithAuthentication.call(context, 'lifeSpaceApi', {
|
|
640
|
+
method: 'POST',
|
|
641
|
+
url: `${baseUrl}/spaces/${encodeURIComponent(sourceSpaceId)}/models/batch`,
|
|
642
|
+
body: { operations },
|
|
643
|
+
json: true,
|
|
644
|
+
});
|
|
645
|
+
const changeSetId = String((_d = (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.changeSetId) !== null && _d !== void 0 ? _d : '').trim();
|
|
646
|
+
const results = (_e = response === null || response === void 0 ? void 0 : response.data) === null || _e === void 0 ? void 0 : _e.items;
|
|
647
|
+
if (!/^cgs_[A-Za-z0-9_-]+$/u.test(changeSetId) || !Array.isArray(results) || results.length !== items.length) {
|
|
648
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), 'LifeSpace Batch response did not match the input item count or ChangeSet contract');
|
|
649
|
+
}
|
|
650
|
+
return results.map((result, itemIndex) => {
|
|
651
|
+
if (!result || typeof result !== 'object' || Array.isArray(result)) {
|
|
652
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `LifeSpace Batch result ${itemIndex} is invalid`, { itemIndex });
|
|
653
|
+
}
|
|
654
|
+
return {
|
|
655
|
+
json: {
|
|
656
|
+
...result,
|
|
657
|
+
changeSetId,
|
|
658
|
+
},
|
|
659
|
+
pairedItem: { item: itemIndex },
|
|
660
|
+
};
|
|
661
|
+
});
|
|
474
662
|
}
|
|
475
663
|
async function actionBodyWithConcurrency(context, itemIndex, baseUrl, recordPath, action, semanticInput) {
|
|
476
664
|
const normalizedInput = normalizeActionInput(context, itemIndex, semanticInput, action.input.fields);
|
|
@@ -565,7 +753,7 @@ class LifeSpace {
|
|
|
565
753
|
},
|
|
566
754
|
group: ['transform'],
|
|
567
755
|
version: 1,
|
|
568
|
-
subtitle: '={{$parameter["resource"] === "modelRecord" ? $parameter["operation"] : "API Request"}}',
|
|
756
|
+
subtitle: '={{$parameter["resource"] === "modelRecord" ? $parameter["operation"] : ($parameter["resource"] === "batchMutation" ? "Batch Mutation" : "API Request")}}',
|
|
569
757
|
description: 'Use LifeSpace records and APIs in n8n workflows',
|
|
570
758
|
defaults: {
|
|
571
759
|
name: 'LifeSpace',
|
|
@@ -577,6 +765,22 @@ class LifeSpace {
|
|
|
577
765
|
{
|
|
578
766
|
name: 'lifeSpaceApi',
|
|
579
767
|
required: true,
|
|
768
|
+
displayOptions: {
|
|
769
|
+
hide: {
|
|
770
|
+
resource: ['batchMutation'],
|
|
771
|
+
batchAuthorityMode: ['delegatedAgent'],
|
|
772
|
+
},
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
name: 'lifeSpaceAgentExecutionApi',
|
|
777
|
+
required: true,
|
|
778
|
+
displayOptions: {
|
|
779
|
+
show: {
|
|
780
|
+
resource: ['batchMutation'],
|
|
781
|
+
batchAuthorityMode: ['delegatedAgent'],
|
|
782
|
+
},
|
|
783
|
+
},
|
|
580
784
|
},
|
|
581
785
|
],
|
|
582
786
|
properties: [
|
|
@@ -590,6 +794,10 @@ class LifeSpace {
|
|
|
590
794
|
name: 'Record',
|
|
591
795
|
value: 'modelRecord',
|
|
592
796
|
},
|
|
797
|
+
{
|
|
798
|
+
name: 'Advanced Mixed Batch',
|
|
799
|
+
value: 'batchMutation',
|
|
800
|
+
},
|
|
593
801
|
{
|
|
594
802
|
name: 'API Request',
|
|
595
803
|
value: 'apiRequest',
|
|
@@ -597,6 +805,50 @@ class LifeSpace {
|
|
|
597
805
|
],
|
|
598
806
|
default: 'modelRecord',
|
|
599
807
|
},
|
|
808
|
+
{
|
|
809
|
+
displayName: 'Batch Authority Mode',
|
|
810
|
+
name: 'batchAuthorityMode',
|
|
811
|
+
type: 'options',
|
|
812
|
+
noDataExpression: true,
|
|
813
|
+
displayOptions: { show: { resource: ['batchMutation'] } },
|
|
814
|
+
options: [
|
|
815
|
+
{
|
|
816
|
+
name: 'Service Principal',
|
|
817
|
+
value: 'service',
|
|
818
|
+
description: 'Use the existing LifeSpace Service API Token for the atomic Batch',
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
name: 'Delegated Agent',
|
|
822
|
+
value: 'delegatedAgent',
|
|
823
|
+
description: 'Mint one short-lived User Principal -> Agent Actor token; every Batch item supplies its explicit Delegation selector',
|
|
824
|
+
},
|
|
825
|
+
],
|
|
826
|
+
default: 'service',
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
displayName: 'Principal User ID',
|
|
830
|
+
name: 'batchPrincipalUserId',
|
|
831
|
+
type: 'string',
|
|
832
|
+
default: '',
|
|
833
|
+
required: true,
|
|
834
|
+
placeholder: 'usr_...',
|
|
835
|
+
displayOptions: {
|
|
836
|
+
show: {
|
|
837
|
+
resource: ['batchMutation'],
|
|
838
|
+
batchAuthorityMode: ['delegatedAgent'],
|
|
839
|
+
},
|
|
840
|
+
},
|
|
841
|
+
description: 'Execution context for delegated Batch only. This value is not part of any AI Tool input.',
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
displayName: 'Batch Operations',
|
|
845
|
+
name: 'batchOperations',
|
|
846
|
+
type: 'json',
|
|
847
|
+
default: '[]',
|
|
848
|
+
required: true,
|
|
849
|
+
displayOptions: { show: { resource: ['batchMutation'] } },
|
|
850
|
+
description: 'Advanced JSON surface for one atomic mixed/cross-model Batch. Update/delete require recordId; version is optional when the current Core Batch contract supports server-resolved concurrency. Delegated Agent mode requires delegationId on every item.',
|
|
851
|
+
},
|
|
600
852
|
{
|
|
601
853
|
displayName: 'Operation',
|
|
602
854
|
name: 'operation',
|
|
@@ -613,10 +865,26 @@ class LifeSpace {
|
|
|
613
865
|
],
|
|
614
866
|
default: 'list',
|
|
615
867
|
},
|
|
868
|
+
{
|
|
869
|
+
displayName: 'Options',
|
|
870
|
+
name: 'recordOptions',
|
|
871
|
+
type: 'collection',
|
|
872
|
+
placeholder: 'Add Option',
|
|
873
|
+
default: {},
|
|
874
|
+
noDataExpression: true,
|
|
875
|
+
displayOptions: { show: { resource: ['modelRecord'], operation: ['create', 'update', 'delete'] } },
|
|
876
|
+
options: [{
|
|
877
|
+
displayName: 'Batch Mode',
|
|
878
|
+
name: 'batchMode',
|
|
879
|
+
type: 'boolean',
|
|
880
|
+
default: false,
|
|
881
|
+
description: 'Whether to send all incoming n8n items as one atomic LifeSpace Batch. Limited to 20 items in one Space and Record Type; the node never auto-chunks because that would weaken atomic semantics.',
|
|
882
|
+
}],
|
|
883
|
+
},
|
|
616
884
|
{
|
|
617
885
|
displayName: 'Space Name or ID', name: 'spaceId', type: 'options',
|
|
618
886
|
typeOptions: { loadOptionsMethod: 'getSpaces' }, options: [], default: '', required: true,
|
|
619
|
-
displayOptions: { show: { resource: ['modelRecord'] } },
|
|
887
|
+
displayOptions: { show: { resource: ['modelRecord', 'batchMutation'] } },
|
|
620
888
|
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
621
889
|
},
|
|
622
890
|
{
|
|
@@ -821,7 +1089,7 @@ class LifeSpace {
|
|
|
821
1089
|
{
|
|
822
1090
|
displayName: 'Concurrency Options', name: 'mutationOptions', type: 'collection', placeholder: 'Add Option', default: {},
|
|
823
1091
|
displayOptions: { show: { resource: ['modelRecord'], operation: ['update', 'delete'] } },
|
|
824
|
-
options: [{ displayName: 'Version', name: 'version', type: 'number', typeOptions: { minValue: 1, numberPrecision: 0 }, default: 1, description: 'Optional known record version.
|
|
1092
|
+
options: [{ displayName: 'Version', name: 'version', type: 'number', typeOptions: { minValue: 1, numberPrecision: 0 }, default: 1, description: 'Optional known record version. In single mode, omission makes the node read the current version immediately before mutation. In Batch Mode, omission is sent to Core for set-wise current-version resolution before atomic commit.' }],
|
|
825
1093
|
},
|
|
826
1094
|
{
|
|
827
1095
|
displayName: 'Action Name or ID', name: 'actionKey', type: 'options', noDataExpression: true,
|
|
@@ -1087,30 +1355,67 @@ class LifeSpace {
|
|
|
1087
1355
|
};
|
|
1088
1356
|
}
|
|
1089
1357
|
async execute() {
|
|
1090
|
-
var _a, _b
|
|
1358
|
+
var _a, _b;
|
|
1091
1359
|
const items = this.getInputData();
|
|
1360
|
+
if (items.length > 0) {
|
|
1361
|
+
const resource = this.getNodeParameter('resource', 0);
|
|
1362
|
+
const operation = this.getNodeParameter('operation', 0, '');
|
|
1363
|
+
if (resource === 'modelRecord'
|
|
1364
|
+
&& ['create', 'update', 'delete'].includes(operation)
|
|
1365
|
+
&& recordBatchMode(this, 0)) {
|
|
1366
|
+
try {
|
|
1367
|
+
return [await executeNativeRecordBatch(this, items)];
|
|
1368
|
+
}
|
|
1369
|
+
catch (error) {
|
|
1370
|
+
if (this.continueOnFail()) {
|
|
1371
|
+
return [items.map((_item, itemIndex) => ({
|
|
1372
|
+
json: { error: error instanceof Error ? error.message : String(error) },
|
|
1373
|
+
pairedItem: { item: itemIndex },
|
|
1374
|
+
}))];
|
|
1375
|
+
}
|
|
1376
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1092
1380
|
const output = [];
|
|
1093
|
-
const credentials = await this.getCredentials('lifeSpaceApi');
|
|
1094
|
-
const baseUrl = (0, lifespaceDiscovery_1.normalizeBaseUrl)(credentials.baseUrl);
|
|
1095
1381
|
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
1096
1382
|
try {
|
|
1097
1383
|
const resource = this.getNodeParameter('resource', itemIndex);
|
|
1098
1384
|
let response;
|
|
1099
|
-
if (resource === '
|
|
1385
|
+
if (resource === 'batchMutation') {
|
|
1386
|
+
const rawSpaceId = String(this.getNodeParameter('spaceId', itemIndex)).trim();
|
|
1387
|
+
if (!rawSpaceId) {
|
|
1388
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'LifeSpace Batch Mutation requires a Space ID', { itemIndex });
|
|
1389
|
+
}
|
|
1390
|
+
const batchAuthorityMode = String((_a = this.getNodeParameter('batchAuthorityMode', itemIndex, 'service')) !== null && _a !== void 0 ? _a : 'service');
|
|
1391
|
+
const baseUrl = batchAuthorityMode === 'delegatedAgent'
|
|
1392
|
+
? (0, lifeSpaceExecutionAuthority_1.delegatedAgentCoreBaseUrl)(this, await this.getCredentials('lifeSpaceAgentExecutionApi', itemIndex))
|
|
1393
|
+
: (0, lifespaceDiscovery_1.normalizeBaseUrl)((await this.getCredentials('lifeSpaceApi', itemIndex)).baseUrl);
|
|
1394
|
+
const operations = batchMutationOperations(this, itemIndex, this.getNodeParameter('batchOperations', itemIndex, '[]'), batchAuthorityMode === 'delegatedAgent');
|
|
1395
|
+
const authority = await (0, lifeSpaceExecutionAuthority_1.executionAuthority)(this, itemIndex, 'write', {
|
|
1396
|
+
modeParameter: 'batchAuthorityMode',
|
|
1397
|
+
principalParameter: 'batchPrincipalUserId',
|
|
1398
|
+
delegationParameter: 'batchDelegationId',
|
|
1399
|
+
requireDelegation: false,
|
|
1400
|
+
});
|
|
1401
|
+
response = await (0, lifeSpaceExecutionAuthority_1.lifeSpaceRequest)(this, authority, {
|
|
1402
|
+
method: 'POST',
|
|
1403
|
+
url: `${baseUrl}/spaces/${encodeURIComponent(rawSpaceId)}/models/batch`,
|
|
1404
|
+
body: { operations },
|
|
1405
|
+
json: true,
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
else if (resource === 'modelRecord') {
|
|
1409
|
+
const baseUrl = (0, lifespaceDiscovery_1.normalizeBaseUrl)((await this.getCredentials('lifeSpaceApi', itemIndex)).baseUrl);
|
|
1100
1410
|
const operation = this.getNodeParameter('operation', itemIndex);
|
|
1101
1411
|
const rawSpaceId = String(this.getNodeParameter('spaceId', itemIndex));
|
|
1102
|
-
const
|
|
1103
|
-
const legacyModelRoute = String((_a = this.getNodeParameter('modelRoute', itemIndex, '')) !== null && _a !== void 0 ? _a : '').trim();
|
|
1104
|
-
const rawModelKey = (_b = recordType === null || recordType === void 0 ? void 0 : recordType.modelKey) !== null && _b !== void 0 ? _b : LEGACY_MODEL_ROUTE_TO_KEY[legacyModelRoute];
|
|
1105
|
-
if (!rawModelKey) {
|
|
1106
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'LifeSpace Record Type selector is invalid. Choose a Record Type from Discovery or pass a Trigger recordType value.', { itemIndex });
|
|
1107
|
-
}
|
|
1412
|
+
const rawModelKey = configuredRecordModelKey(this, itemIndex);
|
|
1108
1413
|
const spaceId = encodeURIComponent(rawSpaceId);
|
|
1109
1414
|
const modelKey = encodeURIComponent(rawModelKey);
|
|
1110
1415
|
const collectionPath = `/spaces/${spaceId}/models/${modelKey}/records`;
|
|
1111
1416
|
if (operation === 'list') {
|
|
1112
1417
|
const returnAll = this.getNodeParameter('returnAll', itemIndex, false);
|
|
1113
|
-
const canonical = String((
|
|
1418
|
+
const canonical = String((_b = this.getNodeParameter('queryMode', itemIndex, '')) !== null && _b !== void 0 ? _b : '') === 'canonical';
|
|
1114
1419
|
const queryPageRequest = (limit, cursor) => {
|
|
1115
1420
|
if (canonical) {
|
|
1116
1421
|
return {
|
|
@@ -1203,6 +1508,7 @@ class LifeSpace {
|
|
|
1203
1508
|
}
|
|
1204
1509
|
}
|
|
1205
1510
|
else {
|
|
1511
|
+
const baseUrl = (0, lifespaceDiscovery_1.normalizeBaseUrl)((await this.getCredentials('lifeSpaceApi', itemIndex)).baseUrl);
|
|
1206
1512
|
const method = this.getNodeParameter('method', itemIndex);
|
|
1207
1513
|
const path = String(this.getNodeParameter('path', itemIndex));
|
|
1208
1514
|
const options = {
|