@algolia/n8n-nodes-algolia 0.4.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/LICENSE.md +19 -0
- package/README.md +58 -0
- package/dist/credentials/AlgoliaApi.credentials.js +41 -0
- package/dist/dist/home/runner/work/n8n-nodes-algolia/n8n-nodes-algolia/nodes/Algolia/Algolia.node.json +21 -0
- package/dist/dist/home/runner/work/n8n-nodes-algolia/n8n-nodes-algolia/nodes/Algolia/algolia.svg +1 -0
- package/dist/nodes/Algolia/Algolia.node.js +579 -0
- package/index.js +0 -0
- package/package.json +61 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright 2022 n8n
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8
|
+
so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# n8n-nodes-algolia
|
|
2
|
+
|
|
3
|
+
This is an n8n community node. It lets you use Algolia in your n8n workflows.
|
|
4
|
+
|
|
5
|
+
Algolia is a hosted search API that provides search-as-a-service solutions. It offers powerful search capabilities including full-text search, faceting, geo-search, and instant search with typo tolerance.
|
|
6
|
+
|
|
7
|
+
[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform.
|
|
8
|
+
|
|
9
|
+
[Installation](#installation)
|
|
10
|
+
[Operations](#operations)
|
|
11
|
+
[Credentials](#credentials)
|
|
12
|
+
[Compatibility](#compatibility)
|
|
13
|
+
[Resources](#resources)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation.
|
|
18
|
+
|
|
19
|
+
## Operations
|
|
20
|
+
|
|
21
|
+
This node supports the following operations:
|
|
22
|
+
|
|
23
|
+
**Index**
|
|
24
|
+
|
|
25
|
+
- List Indices: List all indices in your Algolia application
|
|
26
|
+
- Search Index: Search for records in a specific index
|
|
27
|
+
|
|
28
|
+
**Objects**
|
|
29
|
+
|
|
30
|
+
- Add Object: Add a new object to an index
|
|
31
|
+
|
|
32
|
+
## Credentials
|
|
33
|
+
|
|
34
|
+
To use this node, you need to authenticate with Algolia using API credentials.
|
|
35
|
+
|
|
36
|
+
### Prerequisites
|
|
37
|
+
|
|
38
|
+
1. Sign up for an [Algolia account](https://www.algolia.com)
|
|
39
|
+
2. Create an application in your Algolia dashboard
|
|
40
|
+
|
|
41
|
+
### Authentication Setup
|
|
42
|
+
|
|
43
|
+
1. In your Algolia dashboard, go to Settings > API Keys
|
|
44
|
+
2. Copy your Application ID
|
|
45
|
+
3. Copy your Admin API Key (required for write operations)
|
|
46
|
+
4. In n8n, create new Algolia API credentials with:
|
|
47
|
+
- **Application ID**: Your Algolia Application ID
|
|
48
|
+
- **Admin API Key**: Your Algolia Admin API Key
|
|
49
|
+
|
|
50
|
+
## Compatibility
|
|
51
|
+
|
|
52
|
+
This node requires n8n version 1.0.0 or higher and Node.js 20.15 or higher.
|
|
53
|
+
|
|
54
|
+
## Resources
|
|
55
|
+
|
|
56
|
+
- [n8n community nodes documentation](https://docs.n8n.io/integrations/#community-nodes)
|
|
57
|
+
- [Algolia API documentation](https://www.algolia.com/doc/api-reference/)
|
|
58
|
+
- [Algolia dashboard](https://www.algolia.com/apps)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
|
|
5
|
+
class AlgoliaApi {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.name = "algoliaApi";
|
|
8
|
+
this.displayName = "Algolia API";
|
|
9
|
+
this.documentationUrl = "https://www.algolia.com";
|
|
10
|
+
this.properties = [
|
|
11
|
+
{
|
|
12
|
+
displayName: "Application ID",
|
|
13
|
+
name: "appId",
|
|
14
|
+
type: "string",
|
|
15
|
+
required: true,
|
|
16
|
+
default: ""
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
displayName: "Admin API Key",
|
|
20
|
+
name: "adminApiKey",
|
|
21
|
+
type: "string",
|
|
22
|
+
typeOptions: {
|
|
23
|
+
password: true
|
|
24
|
+
},
|
|
25
|
+
required: true,
|
|
26
|
+
default: ""
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
this.authenticate = {
|
|
30
|
+
type: "generic",
|
|
31
|
+
properties: {
|
|
32
|
+
headers: {
|
|
33
|
+
"X-Algolia-Application-Id": "={{ $credentials.appId }}",
|
|
34
|
+
"X-Algolia-API-Key": "={{ $credentials.adminApiKey }}"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
exports.AlgoliaApi = AlgoliaApi;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-base.Algolia",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"Data & Storage",
|
|
7
|
+
"Development"
|
|
8
|
+
],
|
|
9
|
+
"resources": {
|
|
10
|
+
"credentialDocumentation": [
|
|
11
|
+
{
|
|
12
|
+
"url": "https://www.algolia.com/doc/guides/security/api-keys/"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"primaryDocumentation": [
|
|
16
|
+
{
|
|
17
|
+
"url": "https://www.algolia.com/doc/rest-api/search/"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
}
|
package/dist/dist/home/runner/work/n8n-nodes-algolia/n8n-nodes-algolia/nodes/Algolia/algolia.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#003dff;}.cls-2{fill:#fff;}</style></defs><rect class="cls-1" x="0" y="0" width="500" height="500" rx="250" ry="250"/><path class="cls-2" d="M239.73,122.82c-69.46,0-126.08,56-127.08,125.23-1.02,70.3,56.02,128.56,126.33,128.96,21.72,.13,42.63-5.18,61.2-15.28,1.81-.98,2.09-3.47,.55-4.84l-11.89-10.54c-2.42-2.14-5.86-2.75-8.83-1.48-12.96,5.52-27.05,8.33-41.57,8.16-56.81-.7-102.72-47.97-101.81-104.78,.89-56.09,46.8-101.45,103.1-101.45h103.12v183.28l-58.5-51.98c-1.89-1.68-4.79-1.35-6.32,.67-9.39,12.43-24.69,20.17-41.68,18.99-23.57-1.63-42.67-20.6-44.43-44.16-2.11-28.1,20.16-51.64,47.82-51.64,25.02,0,45.62,19.26,47.77,43.73,.19,2.18,1.17,4.21,2.81,5.66l15.24,13.51c1.73,1.53,4.47,.59,4.9-1.68,1.1-5.87,1.48-12,1.05-18.27-2.45-35.78-31.44-64.57-67.24-66.78-41.04-2.53-75.36,29.58-76.45,69.83-1.06,39.22,31.07,73.03,70.3,73.9,16.38,.36,31.55-4.79,43.82-13.71l76.44,67.76c3.28,2.9,8.45,.58,8.45-3.8V127.64c0-2.66-2.16-4.82-4.82-4.82h-122.27Z"/></svg>
|
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
|
|
5
|
+
const n8nWorkflow = require('n8n-workflow');
|
|
6
|
+
|
|
7
|
+
class Description {
|
|
8
|
+
/**
|
|
9
|
+
* This helper creates a node description that can be added to an n8n node class.
|
|
10
|
+
* @param description A node description as specified by the n8n reference
|
|
11
|
+
* @see https://docs.n8n.io/integrations/creating-nodes/build/reference/node-base-files/#outline-structure-for-a-declarative-style-node
|
|
12
|
+
*/
|
|
13
|
+
constructor(description) {
|
|
14
|
+
this.resources = [];
|
|
15
|
+
this.description = {
|
|
16
|
+
version: 1,
|
|
17
|
+
group: [],
|
|
18
|
+
inputs: [n8nWorkflow.NodeConnectionType.Main],
|
|
19
|
+
outputs: [n8nWorkflow.NodeConnectionType.Main],
|
|
20
|
+
properties: [],
|
|
21
|
+
...description
|
|
22
|
+
};
|
|
23
|
+
this.resourcesDescription = {
|
|
24
|
+
displayName: "Resource",
|
|
25
|
+
name: "resource",
|
|
26
|
+
noDataExpression: true,
|
|
27
|
+
default: void 0,
|
|
28
|
+
// TODO: allow customizing resource type
|
|
29
|
+
// https://docs.n8n.io/integrations/creating-nodes/build/reference/node-base-files/#resource-objects
|
|
30
|
+
type: "options",
|
|
31
|
+
options: []
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Adds a {@link Resource} to this Description.
|
|
36
|
+
* @param resource The resource's option object as specified by the n8n reference
|
|
37
|
+
* @param setDefault Whether to make this Resource selected by default
|
|
38
|
+
* @chainable
|
|
39
|
+
* @see https://docs.n8n.io/integrations/creating-nodes/build/reference/node-base-files/#resource-objects
|
|
40
|
+
*/
|
|
41
|
+
addResource(resource, setDefault = false) {
|
|
42
|
+
this.resources.push(resource);
|
|
43
|
+
if (setDefault) {
|
|
44
|
+
this.resourcesDescription.default = resource.value;
|
|
45
|
+
}
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Returns a description that is compatible with n8n.
|
|
50
|
+
*/
|
|
51
|
+
apply() {
|
|
52
|
+
const resourcesData = this.resources.reduce(
|
|
53
|
+
({ resources, operations, fields }, resource) => {
|
|
54
|
+
const {
|
|
55
|
+
definition,
|
|
56
|
+
operations: resourceOperations,
|
|
57
|
+
fields: resourceFields
|
|
58
|
+
} = resource.apply();
|
|
59
|
+
return {
|
|
60
|
+
resources: [...resources, definition],
|
|
61
|
+
operations: [...operations, resourceOperations],
|
|
62
|
+
fields: [...fields, ...resourceFields]
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
{ resources: [], operations: [], fields: [] }
|
|
66
|
+
);
|
|
67
|
+
return {
|
|
68
|
+
...this.description,
|
|
69
|
+
properties: [
|
|
70
|
+
{
|
|
71
|
+
...this.resourcesDescription,
|
|
72
|
+
default: this.resourcesDescription.default || this.resources[0]?.value,
|
|
73
|
+
options: resourcesData.resources
|
|
74
|
+
},
|
|
75
|
+
...resourcesData.operations,
|
|
76
|
+
...resourcesData.fields
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
class Operation {
|
|
83
|
+
/**
|
|
84
|
+
* This helper creates an operation that can be added to a {@link Resource}.
|
|
85
|
+
* @param operation An operation's option object as specified by the n8n reference
|
|
86
|
+
* @param additionalParams
|
|
87
|
+
* @see https://docs.n8n.io/integrations/creating-nodes/build/reference/node-base-files/#operations-objects
|
|
88
|
+
*/
|
|
89
|
+
constructor(operation, additionalParams = {
|
|
90
|
+
additionalFieldsLabel: "Additional Fields"
|
|
91
|
+
}) {
|
|
92
|
+
this.operation = operation;
|
|
93
|
+
this.additionalParams = additionalParams;
|
|
94
|
+
this.fields = [];
|
|
95
|
+
this.additionalFields = [];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Adds a field to this Operation.
|
|
99
|
+
* `displayOptions` is automatically applied by the Operation.
|
|
100
|
+
* @param field The UI element object as specified by the n8n reference
|
|
101
|
+
* @chainable
|
|
102
|
+
* @see https://docs.n8n.io/integrations/creating-nodes/build/reference/ui-elements/
|
|
103
|
+
*/
|
|
104
|
+
addField(...field) {
|
|
105
|
+
this.fields.push(...field);
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Adds a field to this Operation's additional fields drawer.
|
|
110
|
+
* @param field The UI element object as specified by the n8n reference
|
|
111
|
+
* @chainable
|
|
112
|
+
* @see https://docs.n8n.io/integrations/creating-nodes/build/reference/ui-elements/
|
|
113
|
+
*/
|
|
114
|
+
addAdditionalField(...field) {
|
|
115
|
+
this.additionalFields.push(...field);
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Adds a `postReceive` transformation on the routing output and a UI field that give users the ability to receive a simplified version of the data.
|
|
120
|
+
* @param transformFn The transform method that will return a simplified version of the provided output
|
|
121
|
+
* @chainable
|
|
122
|
+
*/
|
|
123
|
+
addSimplifiedOutput(transformFn) {
|
|
124
|
+
if (!this.operation.routing) {
|
|
125
|
+
throw new Error(
|
|
126
|
+
`The operation "${this.operation.name}" needs a routing object in order to transform its output.`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
if (!this.operation.routing.output?.postReceive) {
|
|
130
|
+
this.operation.routing.output = {
|
|
131
|
+
...this.operation.routing.output || {},
|
|
132
|
+
postReceive: this.operation.routing.output?.postReceive || []
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
this.operation.routing.output.postReceive.push(async function postReceiveFn(items) {
|
|
136
|
+
if (!this.getNodeParameter("simplify", false)) {
|
|
137
|
+
return items;
|
|
138
|
+
}
|
|
139
|
+
return items.map((item) => ({
|
|
140
|
+
...item,
|
|
141
|
+
json: transformFn(item.json)
|
|
142
|
+
}));
|
|
143
|
+
});
|
|
144
|
+
if (!this.fields.find(({ name }) => name === "simplify")) {
|
|
145
|
+
this.addField({
|
|
146
|
+
displayName: "Simplify",
|
|
147
|
+
name: "simplify",
|
|
148
|
+
description: "Whether to return a simplified version of the response instead of the raw data",
|
|
149
|
+
type: "boolean",
|
|
150
|
+
default: false
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return this;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Returns a description of this Operation, to be used by the Resource and the Description helpers in order to create a compatible n8n Node description.
|
|
157
|
+
* @internal
|
|
158
|
+
*/
|
|
159
|
+
apply() {
|
|
160
|
+
const additionalFields = this.additionalFields.length > 0 ? [
|
|
161
|
+
{
|
|
162
|
+
displayName: this.additionalParams.additionalFieldsLabel,
|
|
163
|
+
name: "additionalFields",
|
|
164
|
+
type: "collection",
|
|
165
|
+
default: {},
|
|
166
|
+
options: this.additionalFields
|
|
167
|
+
}
|
|
168
|
+
] : [];
|
|
169
|
+
return {
|
|
170
|
+
definition: this.operation,
|
|
171
|
+
fields: this.fields.sort((field1, field2) => {
|
|
172
|
+
if (field1.name === "simplify" && field2.name !== "simplify") {
|
|
173
|
+
return 1;
|
|
174
|
+
} else if (field1.name !== "simplify" && field2.name === "simplify") {
|
|
175
|
+
return -1;
|
|
176
|
+
}
|
|
177
|
+
return 0;
|
|
178
|
+
}).concat(additionalFields).map((field) => ({
|
|
179
|
+
...field,
|
|
180
|
+
displayOptions: {
|
|
181
|
+
show: {
|
|
182
|
+
...field.displayOptions?.show || {},
|
|
183
|
+
operation: [this.operation.value]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}))
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The Operation's identifier
|
|
191
|
+
*/
|
|
192
|
+
get value() {
|
|
193
|
+
return this.operation.value;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
class Resource {
|
|
198
|
+
/**
|
|
199
|
+
* This helper creates a resource that can be added to a {@link Description}.
|
|
200
|
+
* @param resource A resource's option object as specified by the n8n reference
|
|
201
|
+
* @param additionalParameters
|
|
202
|
+
* @see https://docs.n8n.io/integrations/creating-nodes/build/reference/node-base-files/#resource-objects
|
|
203
|
+
*/
|
|
204
|
+
constructor(resource) {
|
|
205
|
+
this.resource = resource;
|
|
206
|
+
this.operations = [];
|
|
207
|
+
this.operationDescription = {
|
|
208
|
+
displayName: "Operation",
|
|
209
|
+
name: "operation",
|
|
210
|
+
// TODO: allow customizing operation type
|
|
211
|
+
// https://docs.n8n.io/integrations/creating-nodes/build/reference/node-base-files/#operations-objects
|
|
212
|
+
type: "options",
|
|
213
|
+
noDataExpression: true,
|
|
214
|
+
default: void 0,
|
|
215
|
+
options: []
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Adds an {@link Operation} to this Resource.
|
|
220
|
+
* `displayOptions` is automatically applied by the Resource.
|
|
221
|
+
* @param operation The operation's option object as specified by the n8n reference
|
|
222
|
+
* @param setDefault Whether to make this Operation selected by default
|
|
223
|
+
* @chainable
|
|
224
|
+
* @see https://docs.n8n.io/integrations/creating-nodes/build/reference/node-base-files/#operations-objects
|
|
225
|
+
*/
|
|
226
|
+
addOperation(operation, setDefault = false) {
|
|
227
|
+
this.operations.push(operation);
|
|
228
|
+
if (setDefault) {
|
|
229
|
+
this.operationDescription.default = operation.value;
|
|
230
|
+
}
|
|
231
|
+
return this;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Returns a description of the Resource, to be used by the {@link Description} helper in order to create a compatible n8n Node description.
|
|
235
|
+
* @internal
|
|
236
|
+
*/
|
|
237
|
+
apply() {
|
|
238
|
+
const operationsData = this.operations.reduce(
|
|
239
|
+
({ operations: operations2, fields }, operation) => {
|
|
240
|
+
const { definition, fields: operationFields } = operation.apply();
|
|
241
|
+
return {
|
|
242
|
+
operations: [...operations2, definition],
|
|
243
|
+
fields: [...fields, ...operationFields]
|
|
244
|
+
};
|
|
245
|
+
},
|
|
246
|
+
{ operations: [], fields: [] }
|
|
247
|
+
);
|
|
248
|
+
if (this.operations.length === 0) {
|
|
249
|
+
throw new Error(
|
|
250
|
+
`The resource "${this.resource.name}" needs to contain at least one operation.`
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
const operations = {
|
|
254
|
+
...this.operationDescription,
|
|
255
|
+
displayOptions: {
|
|
256
|
+
show: {
|
|
257
|
+
resource: [this.resource.value]
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
default: this.operationDescription.default || this.operations[0]?.value || "",
|
|
261
|
+
options: operationsData.operations
|
|
262
|
+
};
|
|
263
|
+
return {
|
|
264
|
+
definition: this.resource,
|
|
265
|
+
operations,
|
|
266
|
+
fields: operationsData.fields
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* The resource's identifier
|
|
271
|
+
*/
|
|
272
|
+
get value() {
|
|
273
|
+
return this.resource.value;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const name = "@algolia/n8n-nodes-algolia";
|
|
278
|
+
const version = "0.4.2";
|
|
279
|
+
const pkg = {
|
|
280
|
+
name,
|
|
281
|
+
version};
|
|
282
|
+
|
|
283
|
+
const listIndices = new Operation({
|
|
284
|
+
name: "List Indices",
|
|
285
|
+
action: "List indices",
|
|
286
|
+
value: "listIndices",
|
|
287
|
+
description: "List all indices",
|
|
288
|
+
routing: {
|
|
289
|
+
request: {
|
|
290
|
+
method: "GET",
|
|
291
|
+
url: "/1/indexes"
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}).addSimplifiedOutput((json) => json.items);
|
|
295
|
+
|
|
296
|
+
const attributesToRetrieve = {
|
|
297
|
+
displayName: "Attributes to Retrieve",
|
|
298
|
+
name: "attributesToRetrieve",
|
|
299
|
+
type: "string",
|
|
300
|
+
default: [],
|
|
301
|
+
typeOptions: {
|
|
302
|
+
multipleValues: true,
|
|
303
|
+
multipleValueButtonText: "Add attribute"
|
|
304
|
+
},
|
|
305
|
+
routing: {
|
|
306
|
+
request: {
|
|
307
|
+
body: {
|
|
308
|
+
attributesToRetrieve: "={{ $value }}"
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
const hitsPerPage = {
|
|
315
|
+
displayName: "hitsPerPage",
|
|
316
|
+
name: "hitsPerPage",
|
|
317
|
+
description: "The number of hits per page",
|
|
318
|
+
type: "number",
|
|
319
|
+
default: 20,
|
|
320
|
+
typeOptions: {
|
|
321
|
+
minValue: 0,
|
|
322
|
+
maxValue: 1e3
|
|
323
|
+
},
|
|
324
|
+
routing: {
|
|
325
|
+
request: {
|
|
326
|
+
body: {
|
|
327
|
+
hitsPerPage: "={{ $value }}"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const indexName = {
|
|
334
|
+
displayName: "Index Name",
|
|
335
|
+
name: "indexName",
|
|
336
|
+
type: "options",
|
|
337
|
+
required: true,
|
|
338
|
+
default: "",
|
|
339
|
+
typeOptions: {
|
|
340
|
+
loadOptions: {
|
|
341
|
+
routing: {
|
|
342
|
+
request: {
|
|
343
|
+
method: "GET",
|
|
344
|
+
url: "/1/indexes"
|
|
345
|
+
},
|
|
346
|
+
output: {
|
|
347
|
+
postReceive: [
|
|
348
|
+
{
|
|
349
|
+
type: "rootProperty",
|
|
350
|
+
properties: {
|
|
351
|
+
property: "items"
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
type: "setKeyValue",
|
|
356
|
+
properties: {
|
|
357
|
+
name: "={{ $responseItem.name }}",
|
|
358
|
+
value: "={{ $responseItem.name }}"
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
const page = {
|
|
369
|
+
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
|
|
370
|
+
displayName: "page",
|
|
371
|
+
name: "page",
|
|
372
|
+
description: "The page to retrieve",
|
|
373
|
+
type: "number",
|
|
374
|
+
default: 0,
|
|
375
|
+
typeOptions: {
|
|
376
|
+
minValue: 0
|
|
377
|
+
},
|
|
378
|
+
routing: {
|
|
379
|
+
request: {
|
|
380
|
+
body: {
|
|
381
|
+
page: "={{ $value }}"
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const query = {
|
|
388
|
+
displayName: "Query",
|
|
389
|
+
name: "query",
|
|
390
|
+
type: "string",
|
|
391
|
+
description: "The text used to search an index",
|
|
392
|
+
default: "",
|
|
393
|
+
routing: {
|
|
394
|
+
request: {
|
|
395
|
+
body: {
|
|
396
|
+
query: "={{ $value }}"
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const searchIndex = new Operation(
|
|
403
|
+
{
|
|
404
|
+
name: "Search Index",
|
|
405
|
+
action: "Search index",
|
|
406
|
+
value: "searchIndex",
|
|
407
|
+
description: "Returns objects in an index that match the query",
|
|
408
|
+
routing: {
|
|
409
|
+
request: {
|
|
410
|
+
method: "POST",
|
|
411
|
+
url: "=/1/indexes/{{ $parameter.indexName }}/query"
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
additionalFieldsLabel: "Search Parameters"
|
|
417
|
+
}
|
|
418
|
+
).addField(indexName, query).addAdditionalField(attributesToRetrieve, hitsPerPage, page).addSimplifiedOutput((json) => json.hits);
|
|
419
|
+
|
|
420
|
+
const index = new Resource({
|
|
421
|
+
name: "Index",
|
|
422
|
+
value: "index"
|
|
423
|
+
}).addOperation(listIndices).addOperation(searchIndex);
|
|
424
|
+
|
|
425
|
+
const objectTypeSelector = {
|
|
426
|
+
displayName: "Object",
|
|
427
|
+
name: "object",
|
|
428
|
+
type: "options",
|
|
429
|
+
default: "json",
|
|
430
|
+
options: [
|
|
431
|
+
{
|
|
432
|
+
name: "From JSON",
|
|
433
|
+
value: "json"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
name: "Using Fields Below",
|
|
437
|
+
value: "keypair"
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
};
|
|
441
|
+
const jsonObject = {
|
|
442
|
+
displayName: "JSON",
|
|
443
|
+
name: "json",
|
|
444
|
+
type: "json",
|
|
445
|
+
default: "",
|
|
446
|
+
placeholder: `{
|
|
447
|
+
"firstname": "John",
|
|
448
|
+
"lastname": "Doe",
|
|
449
|
+
"age": 25
|
|
450
|
+
}`,
|
|
451
|
+
typeOptions: {
|
|
452
|
+
rows: 5
|
|
453
|
+
},
|
|
454
|
+
displayOptions: {
|
|
455
|
+
show: {
|
|
456
|
+
object: ["json"]
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
const formObject = {
|
|
461
|
+
displayName: "Object Fields",
|
|
462
|
+
name: "keypair",
|
|
463
|
+
type: "fixedCollection",
|
|
464
|
+
placeholder: "Add Field",
|
|
465
|
+
default: {},
|
|
466
|
+
typeOptions: {
|
|
467
|
+
multipleValues: true
|
|
468
|
+
},
|
|
469
|
+
displayOptions: {
|
|
470
|
+
show: {
|
|
471
|
+
object: ["keypair"]
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
options: [
|
|
475
|
+
{
|
|
476
|
+
displayName: "Field",
|
|
477
|
+
name: "list",
|
|
478
|
+
values: [
|
|
479
|
+
{
|
|
480
|
+
displayName: "Name",
|
|
481
|
+
name: "name",
|
|
482
|
+
type: "string",
|
|
483
|
+
default: ""
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
displayName: "Value",
|
|
487
|
+
name: "value",
|
|
488
|
+
type: "string",
|
|
489
|
+
default: ""
|
|
490
|
+
}
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
]
|
|
494
|
+
};
|
|
495
|
+
const object = [objectTypeSelector, jsonObject, formObject];
|
|
496
|
+
|
|
497
|
+
const addObject = new Operation({
|
|
498
|
+
name: "Add Object",
|
|
499
|
+
action: "Add Object",
|
|
500
|
+
value: "addObject",
|
|
501
|
+
description: "Add an object to the index, automatically assigning it an object ID",
|
|
502
|
+
routing: {
|
|
503
|
+
request: {
|
|
504
|
+
method: "POST",
|
|
505
|
+
url: "=/1/indexes/{{ $parameter.indexName }}",
|
|
506
|
+
json: true,
|
|
507
|
+
body: '={{ $parameter.object === "keypair" ? $parameter.keypair.list.smartJoin("name", "value") : JSON.parse($parameter.json) }}'
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}).addField(indexName).addField(...object);
|
|
511
|
+
|
|
512
|
+
const attributesToRetrieveQuery = {
|
|
513
|
+
...attributesToRetrieve,
|
|
514
|
+
routing: {
|
|
515
|
+
request: {
|
|
516
|
+
qs: {
|
|
517
|
+
attributesToRetrieve: '={{ $value.filter(attr => attr.trim() !== "").length > 0 ? $value.filter(attr => attr.trim() !== "").join(",") : undefined }}'
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
const objectId = {
|
|
524
|
+
displayName: "Object ID",
|
|
525
|
+
name: "objectId",
|
|
526
|
+
type: "string",
|
|
527
|
+
default: "",
|
|
528
|
+
required: true,
|
|
529
|
+
description: "The unique identifier of the object to retrieve",
|
|
530
|
+
placeholder: "e.g., myObjectId123"
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
const getObject = new Operation({
|
|
534
|
+
name: "Get Object",
|
|
535
|
+
action: "Get object",
|
|
536
|
+
value: "getObject",
|
|
537
|
+
description: "Retrieve a single object from an index using its object ID",
|
|
538
|
+
routing: {
|
|
539
|
+
request: {
|
|
540
|
+
method: "GET",
|
|
541
|
+
url: "=/1/indexes/{{ $parameter.indexName }}/{{ $parameter.objectId }}"
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}).addField(indexName, objectId).addAdditionalField(attributesToRetrieveQuery);
|
|
545
|
+
|
|
546
|
+
const objects = new Resource({
|
|
547
|
+
name: "Objects",
|
|
548
|
+
value: "objects"
|
|
549
|
+
}).addOperation(addObject).addOperation(getObject);
|
|
550
|
+
|
|
551
|
+
const description = new Description({
|
|
552
|
+
name: "Algolia",
|
|
553
|
+
displayName: "Algolia",
|
|
554
|
+
description: "Use Algolia in your n8n workflows",
|
|
555
|
+
subtitle: '={{ $parameter.operation.replace(/([a-z])([A-Z])/g, "$1 $2").toTitleCase() }}',
|
|
556
|
+
icon: "file:algolia.svg",
|
|
557
|
+
defaults: {
|
|
558
|
+
name: "Algolia"
|
|
559
|
+
},
|
|
560
|
+
credentials: [
|
|
561
|
+
{
|
|
562
|
+
name: "algoliaApi",
|
|
563
|
+
required: true
|
|
564
|
+
}
|
|
565
|
+
],
|
|
566
|
+
requestDefaults: {
|
|
567
|
+
baseURL: "=https://{{ $credentials.appId }}.algolia.net",
|
|
568
|
+
headers: {
|
|
569
|
+
"User-Agent": `${pkg.name} (${pkg.version})`
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}).addResource(index).addResource(objects);
|
|
573
|
+
class Algolia {
|
|
574
|
+
constructor() {
|
|
575
|
+
this.description = description.apply();
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
exports.Algolia = Algolia;
|
package/index.js
ADDED
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@algolia/n8n-nodes-algolia",
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "Algolia nodes for n8n",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"algolia",
|
|
8
|
+
"n8n"
|
|
9
|
+
],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"homepage": "https://github.com/algolia/n8n-nodes-algolia",
|
|
12
|
+
"author": {
|
|
13
|
+
"name": "Algolia",
|
|
14
|
+
"email": "support@algolia.com"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/algolia/n8n-nodes-algolia.git"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=20.15"
|
|
22
|
+
},
|
|
23
|
+
"main": "index.js",
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "vite build",
|
|
26
|
+
"dev": "vite build --watch",
|
|
27
|
+
"format": "prettier nodes credentials --write",
|
|
28
|
+
"lint": "eslint nodes credentials package.json",
|
|
29
|
+
"lintfix": "eslint nodes credentials package.json --fix",
|
|
30
|
+
"prepublishOnly": "npm run build && npm run lint -c .eslintrc.prepublish.js nodes credentials package.json",
|
|
31
|
+
"release": "shipjs prepare"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"n8n": {
|
|
37
|
+
"n8nNodesApiVersion": 1,
|
|
38
|
+
"credentials": [
|
|
39
|
+
"dist/credentials/AlgoliaApi.credentials.js"
|
|
40
|
+
],
|
|
41
|
+
"nodes": [
|
|
42
|
+
"dist/nodes/Algolia/Algolia.node.js"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@typescript-eslint/parser": "~8.32.0",
|
|
47
|
+
"concurrently": "^9.2.0",
|
|
48
|
+
"eslint": "^8.57.0",
|
|
49
|
+
"eslint-plugin-n8n-nodes-base": "^1.16.3",
|
|
50
|
+
"prettier": "^3.5.3",
|
|
51
|
+
"shelljs": "^0.10.0",
|
|
52
|
+
"shipjs": "^0.27.0",
|
|
53
|
+
"tsc-alias": "^1.8.16",
|
|
54
|
+
"typescript": "^5.8.2",
|
|
55
|
+
"vite": "^7.0.6",
|
|
56
|
+
"vite-plugin-static-copy": "^3.1.1"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"n8n-workflow": "*"
|
|
60
|
+
}
|
|
61
|
+
}
|